amd-drm-next-6.3-2023-01-06: amdgpu: - secure display support for multiple displays - DML optimizations - DCN 3.2 updates - PSR updates - DP 2.1 updates - SR-IOV RAS updates - VCN RAS support - SMU 13.x updates - Switch 1 element arrays to flexible arrays - Add RAS support for DF 4.3 - Stack size improvements - S0ix rework - Soft reset fix - Allow 0 as a vram limit on APUs - Display fixes - Misc code cleanups - Documentation fixes - Handle profiling modes for SMU13.x amdkfd: - Error handling fixes - PASID fixes radeon: - Switch 1 element arrays to flexible arrays drm: - Add DP adaptive sync DPCD definitions UAPI: - Add new INFO queries for peak and min sclk/mclk for profile modes on newer chips Proposed mesa patch: https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/278
Unified · Split
| @@ -81,7 +81,8 @@ amdgpu-y += \ · 80 unmodified lines | ||
| 81 | 81 | # add DF block |
| 82 | 82 | amdgpu-y += \ |
| 83 | 83 | df_v1_7.o \ |
| 84 | − df_v3_6.o | |
| 84 | + df_v3_6.o \ | |
| 85 | + df_v4_3.o | |
| 85 | 86 | |
| 86 | 87 | # add GMC block |
| 87 | 88 | amdgpu-y += \ |
| @@ -149,7 +149,7 @@ struct amdgpu_watchdog_timer · 148 unmodified lines | ||
| 149 | 149 | * Modules parameters. |
| 150 | 150 | */ |
| 151 | 151 | extern int amdgpu_modeset; |
| 152 | −extern int amdgpu_vram_limit; | |
| 152 | +extern unsigned int amdgpu_vram_limit; | |
| 153 | 153 | extern int amdgpu_vis_vram_limit; |
| 154 | 154 | extern int amdgpu_gart_size; |
| 155 | 155 | extern int amdgpu_gtt_size; |
| @@ -194,6 +194,7 @@ extern int amdgpu_emu_mode; · 38 unmodified lines | ||
| 194 | 194 | extern uint amdgpu_smu_memory_pool_size; |
| 195 | 195 | extern int amdgpu_smu_pptable_id; |
| 196 | 196 | extern uint amdgpu_dc_feature_mask; |
| 197 | +extern uint amdgpu_freesync_vid_mode; | |
| 197 | 198 | extern uint amdgpu_dc_debug_mask; |
| 198 | 199 | extern uint amdgpu_dc_visual_confirm; |
| 199 | 200 | extern uint amdgpu_dm_abm_level; |
| @@ -607,7 +608,7 @@ int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data, · 407 unmodified lines | ||
| 607 | 608 | struct drm_file *filp); |
| 608 | 609 | |
| 609 | 610 | /* VRAM scratch page for HDP bug, default vram page */ |
| 610 | −struct amdgpu_vram_scratch { | |
| 611 | +struct amdgpu_mem_scratch { | |
| 611 | 612 | struct amdgpu_bo *robj; |
| 612 | 613 | volatile uint32_t *ptr; |
| 613 | 614 | u64 gpu_addr; |
| @@ -754,6 +755,11 @@ struct amdgpu_mqd { · 140 unmodified lines | ||
| 754 | 755 | #define AMDGPU_PRODUCT_NAME_LEN 64 |
| 755 | 756 | struct amdgpu_reset_domain; |
| 756 | 757 | |
| 758 | +/* | |
| 759 | + * Non-zero (true) if the GPU has VRAM. Zero (false) otherwise. | |
| 760 | + */ | |
| 761 | +#define AMDGPU_HAS_VRAM(_adev) ((_adev)->gmc.real_vram_size) | |
| 762 | + | |
| 757 | 763 | struct amdgpu_device { |
| 758 | 764 | struct device *dev; |
| 759 | 765 | struct pci_dev *pdev; |
| @@ -847,7 +853,7 @@ struct amdgpu_device { · 87 unmodified lines | ||
| 847 | 853 | |
| 848 | 854 | /* memory management */ |
| 849 | 855 | struct amdgpu_mman mman; |
| 850 | − struct amdgpu_vram_scratch vram_scratch; | |
| 856 | + struct amdgpu_mem_scratch mem_scratch; | |
| 851 | 857 | struct amdgpu_wb wb; |
| 852 | 858 | atomic64_t num_bytes_moved; |
| 853 | 859 | atomic64_t num_evictions; |
| @@ -869,7 +875,7 @@ struct amdgpu_device { · 15 unmodified lines | ||
| 869 | 875 | struct amdgpu_vkms_output *amdgpu_vkms_output; |
| 870 | 876 | struct amdgpu_mode_info mode_info; |
| 871 | 877 | /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */ |
| 872 | − struct work_struct hotplug_work; | |
| 878 | + struct delayed_work hotplug_work; | |
| 873 | 879 | struct amdgpu_irq_src crtc_irq; |
| 874 | 880 | struct amdgpu_irq_src vline0_irq; |
| 875 | 881 | struct amdgpu_irq_src vupdate_irq; |
| @@ -996,13 +996,33 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force) · 995 unmodified lines | ||
| 996 | 996 | } |
| 997 | 997 | } |
| 998 | 998 | |
| 999 | + if (amdgpu_connector->detected_hpd_without_ddc) { | |
| 1000 | + force = true; | |
| 1001 | + amdgpu_connector->detected_hpd_without_ddc = false; | |
| 1002 | + } | |
| 1003 | + | |
| 999 | 1004 | if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) { |
| 1000 | 1005 | ret = connector->status; |
| 1001 | 1006 | goto exit; |
| 1002 | 1007 | } |
| 1003 | 1008 | |
| 1004 | − if (amdgpu_connector->ddc_bus) | |
| 1009 | + if (amdgpu_connector->ddc_bus) { | |
| 1005 | 1010 | dret = amdgpu_display_ddc_probe(amdgpu_connector, false); |
| 1011 | + | |
| 1012 | + /* Sometimes the pins required for the DDC probe on DVI | |
| 1013 | + * connectors don't make contact at the same time that the ones | |
| 1014 | + * for HPD do. If the DDC probe fails even though we had an HPD | |
| 1015 | + * signal, try again later | |
| 1016 | + */ | |
| 1017 | + if (!dret && !force && | |
| 1018 | + amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) { | |
| 1019 | + DRM_DEBUG_KMS("hpd detected without ddc, retrying in 1 second\n"); | |
| 1020 | + amdgpu_connector->detected_hpd_without_ddc = true; | |
| 1021 | + schedule_delayed_work(&adev->hotplug_work, | |
| 1022 | + msecs_to_jiffies(1000)); | |
| 1023 | + goto exit; | |
| 1024 | + } | |
| 1025 | + } | |
| 1006 | 1026 | if (dret) { |
| 1007 | 1027 | amdgpu_connector->detected_by_load = false; |
| 1008 | 1028 | amdgpu_connector_free_edid(connector); |
| @@ -924,32 +924,33 @@ static int amdgpu_device_asic_init(struct amdgpu_device *adev) · 923 unmodified lines | ||
| 924 | 924 | } |
| 925 | 925 | |
| 926 | 926 | /** |
| 927 | − * amdgpu_device_vram_scratch_init - allocate the VRAM scratch page | |
| 927 | + * amdgpu_device_mem_scratch_init - allocate the VRAM scratch page | |
| 928 | 928 | * |
| 929 | 929 | * @adev: amdgpu_device pointer |
| 930 | 930 | * |
| 931 | 931 | * Allocates a scratch page of VRAM for use by various things in the |
| 932 | 932 | * driver. |
| 933 | 933 | */ |
| 934 | −static int amdgpu_device_vram_scratch_init(struct amdgpu_device *adev) | |
| 934 | +static int amdgpu_device_mem_scratch_init(struct amdgpu_device *adev) | |
| 935 | 935 | { |
| 936 | − return amdgpu_bo_create_kernel(adev, AMDGPU_GPU_PAGE_SIZE, | |
| 937 | − PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, | |
| 938 | − &adev->vram_scratch.robj, | |
| 939 | − &adev->vram_scratch.gpu_addr, | |
| 940 | − (void **)&adev->vram_scratch.ptr); | |
| 936 | + return amdgpu_bo_create_kernel(adev, AMDGPU_GPU_PAGE_SIZE, PAGE_SIZE, | |
| 937 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 938 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 939 | + &adev->mem_scratch.robj, | |
| 940 | + &adev->mem_scratch.gpu_addr, | |
| 941 | + (void **)&adev->mem_scratch.ptr); | |
| 941 | 942 | } |
| 942 | 943 | |
| 943 | 944 | /** |
| 944 | − * amdgpu_device_vram_scratch_fini - Free the VRAM scratch page | |
| 945 | + * amdgpu_device_mem_scratch_fini - Free the VRAM scratch page | |
| 945 | 946 | * |
| 946 | 947 | * @adev: amdgpu_device pointer |
| 947 | 948 | * |
| 948 | 949 | * Frees the VRAM scratch page. |
| 949 | 950 | */ |
| 950 | −static void amdgpu_device_vram_scratch_fini(struct amdgpu_device *adev) | |
| 951 | +static void amdgpu_device_mem_scratch_fini(struct amdgpu_device *adev) | |
| 951 | 952 | { |
| 952 | − amdgpu_bo_free_kernel(&adev->vram_scratch.robj, NULL, NULL); | |
| 953 | + amdgpu_bo_free_kernel(&adev->mem_scratch.robj, NULL, NULL); | |
| 953 | 954 | } |
| 954 | 955 | |
| 955 | 956 | /** |
| @@ -2390,9 +2391,9 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) · 1434 unmodified lines | ||
| 2390 | 2391 | if (amdgpu_sriov_vf(adev)) |
| 2391 | 2392 | amdgpu_virt_exchange_data(adev); |
| 2392 | 2393 | |
| 2393 | − r = amdgpu_device_vram_scratch_init(adev); | |
| 2394 | + r = amdgpu_device_mem_scratch_init(adev); | |
| 2394 | 2395 | if (r) { |
| 2395 | − DRM_ERROR("amdgpu_vram_scratch_init failed %d\n", r); | |
| 2396 | + DRM_ERROR("amdgpu_mem_scratch_init failed %d\n", r); | |
| 2396 | 2397 | goto init_failed; |
| 2397 | 2398 | } |
| 2398 | 2399 | r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev); |
| @@ -2410,8 +2411,9 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) · 11 unmodified lines | ||
| 2410 | 2411 | /* right after GMC hw init, we create CSA */ |
| 2411 | 2412 | if (amdgpu_mcbp) { |
| 2412 | 2413 | r = amdgpu_allocate_static_csa(adev, &adev->virt.csa_obj, |
| 2413 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 2414 | − AMDGPU_CSA_SIZE); | |
| 2414 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 2415 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 2416 | + AMDGPU_CSA_SIZE); | |
| 2415 | 2417 | if (r) { |
| 2416 | 2418 | DRM_ERROR("allocate CSA failed %d\n", r); |
| 2417 | 2419 | goto init_failed; |
| @@ -2581,9 +2583,10 @@ int amdgpu_device_set_cg_state(struct amdgpu_device *adev, · 163 unmodified lines | ||
| 2581 | 2583 | i = state == AMD_CG_STATE_GATE ? j : adev->num_ip_blocks - j - 1; |
| 2582 | 2584 | if (!adev->ip_blocks[i].status.late_initialized) |
| 2583 | 2585 | continue; |
| 2584 | − /* skip CG for GFX on S0ix */ | |
| 2586 | + /* skip CG for GFX, SDMA on S0ix */ | |
| 2585 | 2587 | if (adev->in_s0ix && |
| 2586 | − adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX) | |
| 2588 | + (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX || | |
| 2589 | + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SDMA)) | |
| 2587 | 2590 | continue; |
| 2588 | 2591 | /* skip CG for VCE/UVD, it's handled specially */ |
| 2589 | 2592 | if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && |
| @@ -2617,9 +2620,10 @@ int amdgpu_device_set_pg_state(struct amdgpu_device *adev, · 27 unmodified lines | ||
| 2617 | 2620 | i = state == AMD_PG_STATE_GATE ? j : adev->num_ip_blocks - j - 1; |
| 2618 | 2621 | if (!adev->ip_blocks[i].status.late_initialized) |
| 2619 | 2622 | continue; |
| 2620 | − /* skip PG for GFX on S0ix */ | |
| 2623 | + /* skip PG for GFX, SDMA on S0ix */ | |
| 2621 | 2624 | if (adev->in_s0ix && |
| 2622 | − adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX) | |
| 2625 | + (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX || | |
| 2626 | + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SDMA)) | |
| 2623 | 2627 | continue; |
| 2624 | 2628 | /* skip CG for VCE/UVD, it's handled specially */ |
| 2625 | 2629 | if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && |
| @@ -2871,7 +2875,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) · 245 unmodified lines | ||
| 2871 | 2875 | amdgpu_ucode_free_bo(adev); |
| 2872 | 2876 | amdgpu_free_static_csa(&adev->virt.csa_obj); |
| 2873 | 2877 | amdgpu_device_wb_fini(adev); |
| 2874 | − amdgpu_device_vram_scratch_fini(adev); | |
| 2878 | + amdgpu_device_mem_scratch_fini(adev); | |
| 2875 | 2879 | amdgpu_ib_pool_fini(adev); |
| 2876 | 2880 | } |
| 2877 | 2881 | |
| @@ -3027,6 +3031,12 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev) · 149 unmodified lines | ||
| 3027 | 3031 | adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_MES)) |
| 3028 | 3032 | continue; |
| 3029 | 3033 | |
| 3034 | + /* SDMA 5.x+ is part of GFX power domain so it's covered by GFXOFF */ | |
| 3035 | + if (adev->in_s0ix && | |
| 3036 | + (adev->ip_versions[SDMA0_HWIP][0] >= IP_VERSION(5, 0, 0)) && | |
| 3037 | + (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SDMA)) | |
| 3038 | + continue; | |
| 3039 | + | |
| 3030 | 3040 | /* XXX handle errors */ |
| 3031 | 3041 | r = adev->ip_blocks[i].version->funcs->suspend(adev); |
| 3032 | 3042 | /* XXX handle errors */ |
| @@ -3227,15 +3237,6 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev) · 194 unmodified lines | ||
| 3227 | 3237 | return r; |
| 3228 | 3238 | } |
| 3229 | 3239 | adev->ip_blocks[i].status.hw = true; |
| 3230 | − | |
| 3231 | − if (adev->in_s0ix && adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) { | |
| 3232 | − /* disable gfxoff for IP resume. The gfxoff will be re-enabled in | |
| 3233 | − * amdgpu_device_resume() after IP resume. | |
| 3234 | − */ | |
| 3235 | − amdgpu_gfx_off_ctrl(adev, false); | |
| 3236 | − DRM_DEBUG("will disable gfxoff for re-initializing other blocks\n"); | |
| 3237 | − } | |
| 3238 | − | |
| 3239 | 3240 | } |
| 3240 | 3241 | |
| 3241 | 3242 | return 0; |
| @@ -4221,13 +4222,6 @@ exit: · 979 unmodified lines | ||
| 4221 | 4222 | /* Make sure IB tests flushed */ |
| 4222 | 4223 | flush_delayed_work(&adev->delayed_init_work); |
| 4223 | 4224 | |
| 4224 | − if (adev->in_s0ix) { | |
| 4225 | − /* re-enable gfxoff after IP resume. This re-enables gfxoff after | |
| 4226 | − * it was disabled for IP resume in amdgpu_device_ip_resume_phase2(). | |
| 4227 | − */ | |
| 4228 | − amdgpu_gfx_off_ctrl(adev, true); | |
| 4229 | − DRM_DEBUG("will enable gfxoff for the mission mode\n"); | |
| 4230 | − } | |
| 4231 | 4225 | if (fbcon) |
| 4232 | 4226 | drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false); |
| 4233 | 4227 | |
| @@ -4608,11 +4602,6 @@ bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev) · 374 unmodified lines | ||
| 4608 | 4602 | if (!amdgpu_ras_is_poison_mode_supported(adev)) |
| 4609 | 4603 | return true; |
| 4610 | 4604 | |
| 4611 | − if (!amdgpu_device_ip_check_soft_reset(adev)) { | |
| 4612 | − dev_info(adev->dev,"Timeout, but no hardware hang detected.\n"); | |
| 4613 | − return false; | |
| 4614 | − } | |
| 4615 | − | |
| 4616 | 4605 | if (amdgpu_sriov_vf(adev)) |
| 4617 | 4606 | return true; |
| 4618 | 4607 | |
| @@ -4737,7 +4726,8 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, · 118 unmodified lines | ||
| 4737 | 4726 | if (!need_full_reset) |
| 4738 | 4727 | need_full_reset = amdgpu_device_ip_need_full_reset(adev); |
| 4739 | 4728 | |
| 4740 | − if (!need_full_reset && amdgpu_gpu_recovery) { | |
| 4729 | + if (!need_full_reset && amdgpu_gpu_recovery && | |
| 4730 | + amdgpu_device_ip_check_soft_reset(adev)) { | |
| 4741 | 4731 | amdgpu_device_ip_pre_soft_reset(adev); |
| 4742 | 4732 | r = amdgpu_device_ip_soft_reset(adev); |
| 4743 | 4733 | amdgpu_device_ip_post_soft_reset(adev); |
| @@ -33,6 +33,7 @@ · 32 unmodified lines | ||
| 33 | 33 | #include "gmc_v9_0.h" |
| 34 | 34 | #include "df_v1_7.h" |
| 35 | 35 | #include "df_v3_6.h" |
| 36 | +#include "df_v4_3.h" | |
| 36 | 37 | #include "nbio_v6_1.h" |
| 37 | 38 | #include "nbio_v7_0.h" |
| 38 | 39 | #include "nbio_v7_4.h" |
| @@ -2329,6 +2330,9 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev) · 2290 unmodified lines | ||
| 2329 | 2330 | case IP_VERSION(3, 5, 2): |
| 2330 | 2331 | adev->df.funcs = &df_v1_7_funcs; |
| 2331 | 2332 | break; |
| 2333 | + case IP_VERSION(4, 3, 0): | |
| 2334 | + adev->df.funcs = &df_v4_3_funcs; | |
| 2335 | + break; | |
| 2332 | 2336 | default: |
| 2333 | 2337 | break; |
| 2334 | 2338 | } |
| @@ -63,7 +63,7 @@ · 62 unmodified lines | ||
| 63 | 63 | void amdgpu_display_hotplug_work_func(struct work_struct *work) |
| 64 | 64 | { |
| 65 | 65 | struct amdgpu_device *adev = container_of(work, struct amdgpu_device, |
| 66 | − hotplug_work); | |
| 66 | + hotplug_work.work); | |
| 67 | 67 | struct drm_device *dev = adev_to_drm(adev); |
| 68 | 68 | struct drm_mode_config *mode_config = &dev->mode_config; |
| 69 | 69 | struct drm_connector *connector; |
| @@ -105,13 +105,15 @@ · 104 unmodified lines | ||
| 105 | 105 | * - 3.46.0 - To enable hot plug amdgpu tests in libdrm |
| 106 | 106 | * - 3.47.0 - Add AMDGPU_GEM_CREATE_DISCARDABLE and AMDGPU_VM_NOALLOC flags |
| 107 | 107 | * - 3.48.0 - Add IP discovery version info to HW INFO |
| 108 | − * 3.49.0 - Add gang submit into CS IOCTL | |
| 108 | + * - 3.49.0 - Add gang submit into CS IOCTL | |
| 109 | + * - 3.50.0 - Update AMDGPU_INFO_DEV_INFO IOCTL for minimum engine and memory clock | |
| 110 | + * Update AMDGPU_INFO_SENSOR IOCTL for PEAK_PSTATE engine and memory clock | |
| 109 | 111 | */ |
| 110 | 112 | #define KMS_DRIVER_MAJOR 3 |
| 111 | −#define KMS_DRIVER_MINOR 49 | |
| 113 | +#define KMS_DRIVER_MINOR 50 | |
| 112 | 114 | #define KMS_DRIVER_PATCHLEVEL 0 |
| 113 | 115 | |
| 114 | −int amdgpu_vram_limit; | |
| 116 | +unsigned int amdgpu_vram_limit = UINT_MAX; | |
| 115 | 117 | int amdgpu_vis_vram_limit; |
| 116 | 118 | int amdgpu_gart_size = -1; /* auto */ |
| 117 | 119 | int amdgpu_gtt_size = -1; /* auto */ |
| @@ -181,6 +183,7 @@ int amdgpu_mes_kiq; · 63 unmodified lines | ||
| 181 | 183 | int amdgpu_noretry = -1; |
| 182 | 184 | int amdgpu_force_asic_type = -1; |
| 183 | 185 | int amdgpu_tmz = -1; /* auto */ |
| 186 | +uint amdgpu_freesync_vid_mode; | |
| 184 | 187 | int amdgpu_reset_method = -1; /* auto */ |
| 185 | 188 | int amdgpu_num_kcq = -1; |
| 186 | 189 | int amdgpu_smartshift_bias; |
| @@ -879,6 +882,32 @@ module_param_named(backlight, amdgpu_backlight, bint, 0444); · 692 unmodified lines | ||
| 879 | 882 | MODULE_PARM_DESC(tmz, "Enable TMZ feature (-1 = auto (default), 0 = off, 1 = on)"); |
| 880 | 883 | module_param_named(tmz, amdgpu_tmz, int, 0444); |
| 881 | 884 | |
| 885 | +/** | |
| 886 | + * DOC: freesync_video (uint) | |
| 887 | + * Enable the optimization to adjust front porch timing to achieve seamless | |
| 888 | + * mode change experience when setting a freesync supported mode for which full | |
| 889 | + * modeset is not needed. | |
| 890 | + * | |
| 891 | + * The Display Core will add a set of modes derived from the base FreeSync | |
| 892 | + * video mode into the corresponding connector's mode list based on commonly | |
| 893 | + * used refresh rates and VRR range of the connected display, when users enable | |
| 894 | + * this feature. From the userspace perspective, they can see a seamless mode | |
| 895 | + * change experience when the change between different refresh rates under the | |
| 896 | + * same resolution. Additionally, userspace applications such as Video playback | |
| 897 | + * can read this modeset list and change the refresh rate based on the video | |
| 898 | + * frame rate. Finally, the userspace can also derive an appropriate mode for a | |
| 899 | + * particular refresh rate based on the FreeSync Mode and add it to the | |
| 900 | + * connector's mode list. | |
| 901 | + * | |
| 902 | + * Note: This is an experimental feature. | |
| 903 | + * | |
| 904 | + * The default value: 0 (off). | |
| 905 | + */ | |
| 906 | +MODULE_PARM_DESC( | |
| 907 | + freesync_video, | |
| 908 | + "Enable freesync modesetting optimization feature (0 = off (default), 1 = on)"); | |
| 909 | +module_param_named(freesync_video, amdgpu_freesync_vid_mode, uint, 0444); | |
| 910 | + | |
| 882 | 911 | /** |
| 883 | 912 | * DOC: reset_method (int) |
| 884 | 913 | * GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco) |
| @@ -372,8 +372,11 @@ int amdgpu_gfx_mqd_sw_init(struct amdgpu_device *adev, · 371 unmodified lines | ||
| 372 | 372 | * KIQ MQD no matter SRIOV or Bare-metal |
| 373 | 373 | */ |
| 374 | 374 | r = amdgpu_bo_create_kernel(adev, mqd_size, PAGE_SIZE, |
| 375 | − AMDGPU_GEM_DOMAIN_VRAM, &ring->mqd_obj, | |
| 376 | − &ring->mqd_gpu_addr, &ring->mqd_ptr); | |
| 375 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 376 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 377 | + &ring->mqd_obj, | |
| 378 | + &ring->mqd_gpu_addr, | |
| 379 | + &ring->mqd_ptr); | |
| 377 | 380 | if (r) { |
| 378 | 381 | dev_warn(adev->dev, "failed to create ring mqd ob (%d)", r); |
| 379 | 382 | return r; |
| @@ -202,13 +202,20 @@ uint64_t amdgpu_gmc_agp_addr(struct ttm_buffer_object *bo) · 201 unmodified lines | ||
| 202 | 202 | void amdgpu_gmc_vram_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc, |
| 203 | 203 | u64 base) |
| 204 | 204 | { |
| 205 | + uint64_t vis_limit = (uint64_t)amdgpu_vis_vram_limit << 20; | |
| 205 | 206 | uint64_t limit = (uint64_t)amdgpu_vram_limit << 20; |
| 206 | 207 | |
| 207 | 208 | mc->vram_start = base; |
| 208 | 209 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
| 209 | − if (limit && limit < mc->real_vram_size) | |
| 210 | + if (limit < mc->real_vram_size) | |
| 210 | 211 | mc->real_vram_size = limit; |
| 211 | 212 | |
| 213 | + if (vis_limit && vis_limit < mc->visible_vram_size) | |
| 214 | + mc->visible_vram_size = vis_limit; | |
| 215 | + | |
| 216 | + if (mc->real_vram_size < mc->visible_vram_size) | |
| 217 | + mc->visible_vram_size = mc->real_vram_size; | |
| 218 | + | |
| 212 | 219 | if (mc->xgmi.num_physical_nodes == 0) { |
| 213 | 220 | mc->fb_start = mc->vram_start; |
| 214 | 221 | mc->fb_end = mc->vram_end; |
| @@ -785,9 +785,15 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) · 784 unmodified lines | ||
| 785 | 785 | if (adev->pm.dpm_enabled) { |
| 786 | 786 | dev_info->max_engine_clock = amdgpu_dpm_get_sclk(adev, false) * 10; |
| 787 | 787 | dev_info->max_memory_clock = amdgpu_dpm_get_mclk(adev, false) * 10; |
| 788 | + dev_info->min_engine_clock = amdgpu_dpm_get_sclk(adev, true) * 10; | |
| 789 | + dev_info->min_memory_clock = amdgpu_dpm_get_mclk(adev, true) * 10; | |
| 788 | 790 | } else { |
| 789 | − dev_info->max_engine_clock = adev->clock.default_sclk * 10; | |
| 790 | − dev_info->max_memory_clock = adev->clock.default_mclk * 10; | |
| 791 | + dev_info->max_engine_clock = | |
| 792 | + dev_info->min_engine_clock = | |
| 793 | + adev->clock.default_sclk * 10; | |
| 794 | + dev_info->max_memory_clock = | |
| 795 | + dev_info->min_memory_clock = | |
| 796 | + adev->clock.default_mclk * 10; | |
| 791 | 797 | } |
| 792 | 798 | dev_info->enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask; |
| 793 | 799 | dev_info->num_rb_pipes = adev->gfx.config.max_backends_per_se * |
| @@ -1014,6 +1020,24 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) · 220 unmodified lines | ||
| 1014 | 1020 | } |
| 1015 | 1021 | ui32 /= 100; |
| 1016 | 1022 | break; |
| 1023 | + case AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_SCLK: | |
| 1024 | + /* get peak pstate sclk in Mhz */ | |
| 1025 | + if (amdgpu_dpm_read_sensor(adev, | |
| 1026 | + AMDGPU_PP_SENSOR_PEAK_PSTATE_SCLK, | |
| 1027 | + (void *)&ui32, &ui32_size)) { | |
| 1028 | + return -EINVAL; | |
| 1029 | + } | |
| 1030 | + ui32 /= 100; | |
| 1031 | + break; | |
| 1032 | + case AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_MCLK: | |
| 1033 | + /* get peak pstate mclk in Mhz */ | |
| 1034 | + if (amdgpu_dpm_read_sensor(adev, | |
| 1035 | + AMDGPU_PP_SENSOR_PEAK_PSTATE_MCLK, | |
| 1036 | + (void *)&ui32, &ui32_size)) { | |
| 1037 | + return -EINVAL; | |
| 1038 | + } | |
| 1039 | + ui32 /= 100; | |
| 1040 | + break; | |
| 1017 | 1041 | default: |
| 1018 | 1042 | DRM_DEBUG_KMS("Invalid request %d\n", |
| 1019 | 1043 | info->sensor_info.type); |
| @@ -534,6 +534,7 @@ struct amdgpu_connector { · 533 unmodified lines | ||
| 534 | 534 | void *con_priv; |
| 535 | 535 | bool dac_load_detect; |
| 536 | 536 | bool detected_by_load; /* if the connection status was determined by load */ |
| 537 | + bool detected_hpd_without_ddc; /* if an HPD signal was detected on DVI, but ddc probing failed */ | |
| 537 | 538 | uint16_t connector_object_id; |
| 538 | 539 | struct amdgpu_hpd hpd; |
| 539 | 540 | struct amdgpu_router router; |
| @@ -66,7 +66,8 @@ static int psp_ring_init(struct psp_context *psp, · 65 unmodified lines | ||
| 66 | 66 | /* allocate 4k Page of Local Frame Buffer memory for ring */ |
| 67 | 67 | ring->ring_size = 0x1000; |
| 68 | 68 | ret = amdgpu_bo_create_kernel(adev, ring->ring_size, PAGE_SIZE, |
| 69 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 69 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 70 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 70 | 71 | &adev->firmware.rbuf, |
| 71 | 72 | &ring->ring_mem_mc_addr, |
| 72 | 73 | (void **)&ring->ring_mem); |
| @@ -797,9 +798,13 @@ static int psp_tmr_init(struct psp_context *psp) · 724 unmodified lines | ||
| 797 | 798 | |
| 798 | 799 | if (!psp->tmr_bo) { |
| 799 | 800 | pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; |
| 800 | − ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT, | |
| 801 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 802 | − &psp->tmr_bo, &psp->tmr_mc_addr, pptr); | |
| 801 | + ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, | |
| 802 | + PSP_TMR_ALIGNMENT, | |
| 803 | + AMDGPU_HAS_VRAM(psp->adev) ? | |
| 804 | + AMDGPU_GEM_DOMAIN_VRAM : | |
| 805 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 806 | + &psp->tmr_bo, &psp->tmr_mc_addr, | |
| 807 | + pptr); | |
| 803 | 808 | } |
| 804 | 809 | |
| 805 | 810 | return ret; |
| @@ -1092,7 +1097,8 @@ int psp_ta_init_shared_buf(struct psp_context *psp, · 286 unmodified lines | ||
| 1092 | 1097 | * physical) for ta to host memory |
| 1093 | 1098 | */ |
| 1094 | 1099 | return amdgpu_bo_create_kernel(psp->adev, mem_ctx->shared_mem_size, |
| 1095 | − PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, | |
| 1100 | + PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM | | |
| 1101 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 1096 | 1102 | &mem_ctx->shared_bo, |
| 1097 | 1103 | &mem_ctx->shared_mc_addr, |
| 1098 | 1104 | &mem_ctx->shared_buf); |
| @@ -1901,7 +1907,7 @@ out_unlock: · 802 unmodified lines | ||
| 1901 | 1907 | static int psp_securedisplay_initialize(struct psp_context *psp) |
| 1902 | 1908 | { |
| 1903 | 1909 | int ret; |
| 1904 | − struct securedisplay_cmd *securedisplay_cmd; | |
| 1910 | + struct ta_securedisplay_cmd *securedisplay_cmd; | |
| 1905 | 1911 | |
| 1906 | 1912 | /* |
| 1907 | 1913 | * TODO: bypass the initialize in sriov for now |
| @@ -3444,10 +3450,10 @@ static ssize_t psp_usbc_pd_fw_sysfs_write(struct device *dev, · 1536 unmodified lines | ||
| 3444 | 3450 | |
| 3445 | 3451 | /* LFB address which is aligned to 1MB boundary per PSP request */ |
| 3446 | 3452 | ret = amdgpu_bo_create_kernel(adev, usbc_pd_fw->size, 0x100000, |
| 3447 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 3448 | − &fw_buf_bo, | |
| 3449 | − &fw_pri_mc_addr, | |
| 3450 | − &fw_pri_cpu_addr); | |
| 3453 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 3454 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 3455 | + &fw_buf_bo, &fw_pri_mc_addr, | |
| 3456 | + &fw_pri_cpu_addr); | |
| 3451 | 3457 | if (ret) |
| 3452 | 3458 | goto rel_buf; |
| 3453 | 3459 | |
| @@ -706,13 +706,23 @@ static int __amdgpu_ras_feature_enable(struct amdgpu_device *adev, · 705 unmodified lines | ||
| 706 | 706 | return 0; |
| 707 | 707 | } |
| 708 | 708 | |
| 709 | +static int amdgpu_ras_check_feature_allowed(struct amdgpu_device *adev, | |
| 710 | + struct ras_common_if *head) | |
| 711 | +{ | |
| 712 | + if (amdgpu_ras_is_feature_allowed(adev, head) || | |
| 713 | + amdgpu_ras_is_poison_mode_supported(adev)) | |
| 714 | + return 1; | |
| 715 | + else | |
| 716 | + return 0; | |
| 717 | +} | |
| 718 | + | |
| 709 | 719 | /* wrapper of psp_ras_enable_features */ |
| 710 | 720 | int amdgpu_ras_feature_enable(struct amdgpu_device *adev, |
| 711 | 721 | struct ras_common_if *head, bool enable) |
| 712 | 722 | { |
| 713 | 723 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
| 714 | 724 | union ta_ras_cmd_input *info; |
| 715 | − int ret; | |
| 725 | + int ret = 0; | |
| 716 | 726 | |
| 717 | 727 | if (!con) |
| 718 | 728 | return -EINVAL; |
| @@ -736,7 +746,8 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev, · 17 unmodified lines | ||
| 736 | 746 | } |
| 737 | 747 | |
| 738 | 748 | /* Do not enable if it is not allowed. */ |
| 739 | − WARN_ON(enable && !amdgpu_ras_is_feature_allowed(adev, head)); | |
| 749 | + if (enable && !amdgpu_ras_check_feature_allowed(adev, head)) | |
| 750 | + goto out; | |
| 740 | 751 | |
| 741 | 752 | /* Only enable ras feature operation handle on host side */ |
| 742 | 753 | if (head->block == AMDGPU_RAS_BLOCK__GFX && |
| @@ -754,7 +765,6 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev, · 11 unmodified lines | ||
| 754 | 765 | |
| 755 | 766 | /* setup the obj */ |
| 756 | 767 | __amdgpu_ras_feature_enable(adev, head, enable); |
| 757 | − ret = 0; | |
| 758 | 768 | out: |
| 759 | 769 | if (head->block == AMDGPU_RAS_BLOCK__GFX) |
| 760 | 770 | kfree(info); |
| @@ -1087,6 +1097,10 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev, · 326 unmodified lines | ||
| 1087 | 1097 | info->head.block, |
| 1088 | 1098 | info->head.sub_block_index); |
| 1089 | 1099 | |
| 1100 | + /* inject on guest isn't allowed, return success directly */ | |
| 1101 | + if (amdgpu_sriov_vf(adev)) | |
| 1102 | + return 0; | |
| 1103 | + | |
| 1090 | 1104 | if (!obj) |
| 1091 | 1105 | return -EINVAL; |
| 1092 | 1106 | |
| @@ -1122,11 +1136,54 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev, · 29 unmodified lines | ||
| 1122 | 1136 | } |
| 1123 | 1137 | |
| 1124 | 1138 | /** |
| 1125 | − * amdgpu_ras_query_error_count -- Get error counts of all IPs | |
| 1139 | + * amdgpu_ras_query_error_count_helper -- Get error counter for specific IP | |
| 1140 | + * @adev: pointer to AMD GPU device | |
| 1141 | + * @ce_count: pointer to an integer to be set to the count of correctible errors. | |
| 1142 | + * @ue_count: pointer to an integer to be set to the count of uncorrectible errors. | |
| 1143 | + * @query_info: pointer to ras_query_if | |
| 1144 | + * | |
| 1145 | + * Return 0 for query success or do nothing, otherwise return an error | |
| 1146 | + * on failures | |
| 1147 | + */ | |
| 1148 | +static int amdgpu_ras_query_error_count_helper(struct amdgpu_device *adev, | |
| 1149 | + unsigned long *ce_count, | |
| 1150 | + unsigned long *ue_count, | |
| 1151 | + struct ras_query_if *query_info) | |
| 1152 | +{ | |
| 1153 | + int ret; | |
| 1154 | + | |
| 1155 | + if (!query_info) | |
| 1156 | + /* do nothing if query_info is not specified */ | |
| 1157 | + return 0; | |
| 1158 | + | |
| 1159 | + ret = amdgpu_ras_query_error_status(adev, query_info); | |
| 1160 | + if (ret) | |
| 1161 | + return ret; | |
| 1162 | + | |
| 1163 | + *ce_count += query_info->ce_count; | |
| 1164 | + *ue_count += query_info->ue_count; | |
| 1165 | + | |
| 1166 | + /* some hardware/IP supports read to clear | |
| 1167 | + * no need to explictly reset the err status after the query call */ | |
| 1168 | + if (adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 2) && | |
| 1169 | + adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 4)) { | |
| 1170 | + if (amdgpu_ras_reset_error_status(adev, query_info->head.block)) | |
| 1171 | + dev_warn(adev->dev, | |
| 1172 | + "Failed to reset error counter and error status\n"); | |
| 1173 | + } | |
| 1174 | + | |
| 1175 | + return 0; | |
| 1176 | +} | |
| 1177 | + | |
| 1178 | +/** | |
| 1179 | + * amdgpu_ras_query_error_count -- Get error counts of all IPs or specific IP | |
| 1126 | 1180 | * @adev: pointer to AMD GPU device |
| 1127 | 1181 | * @ce_count: pointer to an integer to be set to the count of correctible errors. |
| 1128 | 1182 | * @ue_count: pointer to an integer to be set to the count of uncorrectible |
| 1129 | 1183 | * errors. |
| 1184 | + * @query_info: pointer to ras_query_if if the query request is only for | |
| 1185 | + * specific ip block; if info is NULL, then the qurey request is for | |
| 1186 | + * all the ip blocks that support query ras error counters/status | |
| 1130 | 1187 | * |
| 1131 | 1188 | * If set, @ce_count or @ue_count, count and return the corresponding |
| 1132 | 1189 | * error counts in those integer pointers. Return 0 if the device |
| @@ -1134,11 +1191,13 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev, · 1 unmodified line | ||
| 1134 | 1191 | */ |
| 1135 | 1192 | int amdgpu_ras_query_error_count(struct amdgpu_device *adev, |
| 1136 | 1193 | unsigned long *ce_count, |
| 1137 | − unsigned long *ue_count) | |
| 1194 | + unsigned long *ue_count, | |
| 1195 | + struct ras_query_if *query_info) | |
| 1138 | 1196 | { |
| 1139 | 1197 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
| 1140 | 1198 | struct ras_manager *obj; |
| 1141 | 1199 | unsigned long ce, ue; |
| 1200 | + int ret; | |
| 1142 | 1201 | |
| 1143 | 1202 | if (!adev->ras_enabled || !con) |
| 1144 | 1203 | return -EOPNOTSUPP; |
| @@ -1150,26 +1209,23 @@ int amdgpu_ras_query_error_count(struct amdgpu_device *adev, · 5 unmodified lines | ||
| 1150 | 1209 | |
| 1151 | 1210 | ce = 0; |
| 1152 | 1211 | ue = 0; |
| 1153 | − list_for_each_entry(obj, &con->head, node) { | |
| 1154 | − struct ras_query_if info = { | |
| 1155 | − .head = obj->head, | |
| 1156 | − }; | |
| 1157 | − int res; | |
| 1158 | − | |
| 1159 | − res = amdgpu_ras_query_error_status(adev, &info); | |
| 1160 | − if (res) | |
| 1161 | − return res; | |
| 1212 | + if (!query_info) { | |
| 1213 | + /* query all the ip blocks that support ras query interface */ | |
| 1214 | + list_for_each_entry(obj, &con->head, node) { | |
| 1215 | + struct ras_query_if info = { | |
| 1216 | + .head = obj->head, | |
| 1217 | + }; | |
| 1162 | 1218 | |
| 1163 | − if (adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 2) && | |
| 1164 | − adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 4)) { | |
| 1165 | − if (amdgpu_ras_reset_error_status(adev, info.head.block)) | |
| 1166 | − dev_warn(adev->dev, "Failed to reset error counter and error status"); | |
| 1219 | + ret = amdgpu_ras_query_error_count_helper(adev, &ce, &ue, &info); | |
| 1167 | 1220 | } |
| 1168 | − | |
| 1169 | − ce += info.ce_count; | |
| 1170 | − ue += info.ue_count; | |
| 1221 | + } else { | |
| 1222 | + /* query specific ip block */ | |
| 1223 | + ret = amdgpu_ras_query_error_count_helper(adev, &ce, &ue, query_info); | |
| 1171 | 1224 | } |
| 1172 | 1225 | |
| 1226 | + if (ret) | |
| 1227 | + return ret; | |
| 1228 | + | |
| 1173 | 1229 | if (ce_count) |
| 1174 | 1230 | *ce_count = ce; |
| 1175 | 1231 | |
| @@ -2344,22 +2400,24 @@ static void amdgpu_ras_check_supported(struct amdgpu_device *adev) · 1168 unmodified lines | ||
| 2344 | 2400 | |
| 2345 | 2401 | if (amdgpu_atomfirmware_sram_ecc_supported(adev)) { |
| 2346 | 2402 | dev_info(adev->dev, "SRAM ECC is active.\n"); |
| 2347 | − if (!amdgpu_sriov_vf(adev)) { | |
| 2403 | + if (!amdgpu_sriov_vf(adev)) | |
| 2348 | 2404 | adev->ras_hw_enabled |= ~(1 << AMDGPU_RAS_BLOCK__UMC | |
| 2349 | 2405 | 1 << AMDGPU_RAS_BLOCK__DF); |
| 2350 | − | |
| 2351 | − if (adev->ip_versions[VCN_HWIP][0] == IP_VERSION(2, 6, 0) || | |
| 2352 | − adev->ip_versions[VCN_HWIP][0] == IP_VERSION(4, 0, 0)) | |
| 2353 | − adev->ras_hw_enabled |= (1 << AMDGPU_RAS_BLOCK__VCN | | |
| 2354 | − 1 << AMDGPU_RAS_BLOCK__JPEG); | |
| 2355 | − else | |
| 2356 | − adev->ras_hw_enabled &= ~(1 << AMDGPU_RAS_BLOCK__VCN | | |
| 2357 | − 1 << AMDGPU_RAS_BLOCK__JPEG); | |
| 2358 | − } else { | |
| 2406 | + else | |
| 2359 | 2407 | adev->ras_hw_enabled |= (1 << AMDGPU_RAS_BLOCK__PCIE_BIF | |
| 2360 | 2408 | 1 << AMDGPU_RAS_BLOCK__SDMA | |
| 2361 | 2409 | 1 << AMDGPU_RAS_BLOCK__GFX); |
| 2362 | − } | |
| 2410 | + | |
| 2411 | + /* VCN/JPEG RAS can be supported on both bare metal and | |
| 2412 | + * SRIOV environment | |
| 2413 | + */ | |
| 2414 | + if (adev->ip_versions[VCN_HWIP][0] == IP_VERSION(2, 6, 0) || | |
| 2415 | + adev->ip_versions[VCN_HWIP][0] == IP_VERSION(4, 0, 0)) | |
| 2416 | + adev->ras_hw_enabled |= (1 << AMDGPU_RAS_BLOCK__VCN | | |
| 2417 | + 1 << AMDGPU_RAS_BLOCK__JPEG); | |
| 2418 | + else | |
| 2419 | + adev->ras_hw_enabled &= ~(1 << AMDGPU_RAS_BLOCK__VCN | | |
| 2420 | + 1 << AMDGPU_RAS_BLOCK__JPEG); | |
| 2363 | 2421 | } else { |
| 2364 | 2422 | dev_info(adev->dev, "SRAM ECC is not presented.\n"); |
| 2365 | 2423 | } |
| @@ -2395,7 +2453,7 @@ static void amdgpu_ras_counte_dw(struct work_struct *work) · 29 unmodified lines | ||
| 2395 | 2453 | |
| 2396 | 2454 | /* Cache new values. |
| 2397 | 2455 | */ |
| 2398 | − if (amdgpu_ras_query_error_count(adev, &ce_count, &ue_count) == 0) { | |
| 2456 | + if (amdgpu_ras_query_error_count(adev, &ce_count, &ue_count, NULL) == 0) { | |
| 2399 | 2457 | atomic_set(&con->ras_ce_count, ce_count); |
| 2400 | 2458 | atomic_set(&con->ras_ue_count, ue_count); |
| 2401 | 2459 | } |
| @@ -2405,11 +2463,42 @@ Out: · 3 unmodified lines | ||
| 2405 | 2463 | pm_runtime_put_autosuspend(dev->dev); |
| 2406 | 2464 | } |
| 2407 | 2465 | |
| 2466 | +static void amdgpu_ras_query_poison_mode(struct amdgpu_device *adev) | |
| 2467 | +{ | |
| 2468 | + struct amdgpu_ras *con = amdgpu_ras_get_context(adev); | |
| 2469 | + bool df_poison, umc_poison; | |
| 2470 | + | |
| 2471 | + /* poison setting is useless on SRIOV guest */ | |
| 2472 | + if (amdgpu_sriov_vf(adev) || !con) | |
| 2473 | + return; | |
| 2474 | + | |
| 2475 | + /* Init poison supported flag, the default value is false */ | |
| 2476 | + if (adev->gmc.xgmi.connected_to_cpu) { | |
| 2477 | + /* enabled by default when GPU is connected to CPU */ | |
| 2478 | + con->poison_supported = true; | |
| 2479 | + } else if (adev->df.funcs && | |
| 2480 | + adev->df.funcs->query_ras_poison_mode && | |
| 2481 | + adev->umc.ras && | |
| 2482 | + adev->umc.ras->query_ras_poison_mode) { | |
| 2483 | + df_poison = | |
| 2484 | + adev->df.funcs->query_ras_poison_mode(adev); | |
| 2485 | + umc_poison = | |
| 2486 | + adev->umc.ras->query_ras_poison_mode(adev); | |
| 2487 | + | |
| 2488 | + /* Only poison is set in both DF and UMC, we can support it */ | |
| 2489 | + if (df_poison && umc_poison) | |
| 2490 | + con->poison_supported = true; | |
| 2491 | + else if (df_poison != umc_poison) | |
| 2492 | + dev_warn(adev->dev, | |
| 2493 | + "Poison setting is inconsistent in DF/UMC(%d:%d)!\n", | |
| 2494 | + df_poison, umc_poison); | |
| 2495 | + } | |
| 2496 | +} | |
| 2497 | + | |
| 2408 | 2498 | int amdgpu_ras_init(struct amdgpu_device *adev) |
| 2409 | 2499 | { |
| 2410 | 2500 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
| 2411 | 2501 | int r; |
| 2412 | − bool df_poison, umc_poison; | |
| 2413 | 2502 | |
| 2414 | 2503 | if (con) |
| 2415 | 2504 | return 0; |
| @@ -2484,26 +2573,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev) · 68 unmodified lines | ||
| 2484 | 2573 | goto release_con; |
| 2485 | 2574 | } |
| 2486 | 2575 | |
| 2487 | − /* Init poison supported flag, the default value is false */ | |
| 2488 | − if (adev->gmc.xgmi.connected_to_cpu) { | |
| 2489 | − /* enabled by default when GPU is connected to CPU */ | |
| 2490 | − con->poison_supported = true; | |
| 2491 | − } | |
| 2492 | − else if (adev->df.funcs && | |
| 2493 | − adev->df.funcs->query_ras_poison_mode && | |
| 2494 | − adev->umc.ras && | |
| 2495 | − adev->umc.ras->query_ras_poison_mode) { | |
| 2496 | − df_poison = | |
| 2497 | − adev->df.funcs->query_ras_poison_mode(adev); | |
| 2498 | − umc_poison = | |
| 2499 | − adev->umc.ras->query_ras_poison_mode(adev); | |
| 2500 | − /* Only poison is set in both DF and UMC, we can support it */ | |
| 2501 | − if (df_poison && umc_poison) | |
| 2502 | − con->poison_supported = true; | |
| 2503 | − else if (df_poison != umc_poison) | |
| 2504 | − dev_warn(adev->dev, "Poison setting is inconsistent in DF/UMC(%d:%d)!\n", | |
| 2505 | − df_poison, umc_poison); | |
| 2506 | − } | |
| 2576 | + amdgpu_ras_query_poison_mode(adev); | |
| 2507 | 2577 | |
| 2508 | 2578 | if (amdgpu_ras_fs_init(adev)) { |
| 2509 | 2579 | r = -EINVAL; |
| @@ -2564,6 +2634,7 @@ int amdgpu_ras_block_late_init(struct amdgpu_device *adev, · 54 unmodified lines | ||
| 2564 | 2634 | { |
| 2565 | 2635 | struct amdgpu_ras_block_object *ras_obj = NULL; |
| 2566 | 2636 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
| 2637 | + struct ras_query_if *query_info; | |
| 2567 | 2638 | unsigned long ue_count, ce_count; |
| 2568 | 2639 | int r; |
| 2569 | 2640 | |
| @@ -2605,11 +2676,17 @@ int amdgpu_ras_block_late_init(struct amdgpu_device *adev, · 35 unmodified lines | ||
| 2605 | 2676 | |
| 2606 | 2677 | /* Those are the cached values at init. |
| 2607 | 2678 | */ |
| 2608 | − if (amdgpu_ras_query_error_count(adev, &ce_count, &ue_count) == 0) { | |
| 2679 | + query_info = kzalloc(sizeof(struct ras_query_if), GFP_KERNEL); | |
| 2680 | + if (!query_info) | |
| 2681 | + return -ENOMEM; | |
| 2682 | + memcpy(&query_info->head, ras_block, sizeof(struct ras_common_if)); | |
| 2683 | + | |
| 2684 | + if (amdgpu_ras_query_error_count(adev, &ce_count, &ue_count, query_info) == 0) { | |
| 2609 | 2685 | atomic_set(&con->ras_ce_count, ce_count); |
| 2610 | 2686 | atomic_set(&con->ras_ue_count, ue_count); |
| 2611 | 2687 | } |
| 2612 | 2688 | |
| 2689 | + kfree(query_info); | |
| 2613 | 2690 | return 0; |
| 2614 | 2691 | |
| 2615 | 2692 | interrupt: |
| @@ -540,7 +540,8 @@ void amdgpu_ras_suspend(struct amdgpu_device *adev); · 539 unmodified lines | ||
| 540 | 540 | |
| 541 | 541 | int amdgpu_ras_query_error_count(struct amdgpu_device *adev, |
| 542 | 542 | unsigned long *ce_count, |
| 543 | − unsigned long *ue_count); | |
| 543 | + unsigned long *ue_count, | |
| 544 | + struct ras_query_if *query_info); | |
| 544 | 545 | |
| 545 | 546 | /* error handling functions */ |
| 546 | 547 | int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev, |
| @@ -93,7 +93,8 @@ int amdgpu_gfx_rlc_init_sr(struct amdgpu_device *adev, u32 dws) · 92 unmodified lines | ||
| 93 | 93 | |
| 94 | 94 | /* allocate save restore block */ |
| 95 | 95 | r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE, |
| 96 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 96 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 97 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 97 | 98 | &adev->gfx.rlc.save_restore_obj, |
| 98 | 99 | &adev->gfx.rlc.save_restore_gpu_addr, |
| 99 | 100 | (void **)&adev->gfx.rlc.sr_ptr); |
| @@ -130,7 +131,8 @@ int amdgpu_gfx_rlc_init_csb(struct amdgpu_device *adev) · 30 unmodified lines | ||
| 130 | 131 | /* allocate clear state block */ |
| 131 | 132 | adev->gfx.rlc.clear_state_size = dws = adev->gfx.rlc.funcs->get_csb_size(adev); |
| 132 | 133 | r = amdgpu_bo_create_kernel(adev, dws * 4, PAGE_SIZE, |
| 133 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 134 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 135 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 134 | 136 | &adev->gfx.rlc.clear_state_obj, |
| 135 | 137 | &adev->gfx.rlc.clear_state_gpu_addr, |
| 136 | 138 | (void **)&adev->gfx.rlc.cs_ptr); |
| @@ -156,7 +158,8 @@ int amdgpu_gfx_rlc_init_cpt(struct amdgpu_device *adev) · 19 unmodified lines | ||
| 156 | 158 | int r; |
| 157 | 159 | |
| 158 | 160 | r = amdgpu_bo_create_reserved(adev, adev->gfx.rlc.cp_table_size, |
| 159 | − PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, | |
| 161 | + PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM | | |
| 162 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 160 | 163 | &adev->gfx.rlc.cp_table_obj, |
| 161 | 164 | &adev->gfx.rlc.cp_table_gpu_addr, |
| 162 | 165 | (void **)&adev->gfx.rlc.cp_table_ptr); |
| @@ -77,11 +77,11 @@ void psp_securedisplay_parse_resp_status(struct psp_context *psp, · 76 unmodified lines | ||
| 77 | 77 | } |
| 78 | 78 | } |
| 79 | 79 | |
| 80 | −void psp_prep_securedisplay_cmd_buf(struct psp_context *psp, struct securedisplay_cmd **cmd, | |
| 80 | +void psp_prep_securedisplay_cmd_buf(struct psp_context *psp, struct ta_securedisplay_cmd **cmd, | |
| 81 | 81 | enum ta_securedisplay_command command_id) |
| 82 | 82 | { |
| 83 | − *cmd = (struct securedisplay_cmd *)psp->securedisplay_context.context.mem_context.shared_buf; | |
| 84 | − memset(*cmd, 0, sizeof(struct securedisplay_cmd)); | |
| 83 | + *cmd = (struct ta_securedisplay_cmd *)psp->securedisplay_context.context.mem_context.shared_buf; | |
| 84 | + memset(*cmd, 0, sizeof(struct ta_securedisplay_cmd)); | |
| 85 | 85 | (*cmd)->status = TA_SECUREDISPLAY_STATUS__GENERIC_FAILURE; |
| 86 | 86 | (*cmd)->cmd_id = command_id; |
| 87 | 87 | } |
| @@ -93,7 +93,7 @@ static ssize_t amdgpu_securedisplay_debugfs_write(struct file *f, const char __u · 5 unmodified lines | ||
| 93 | 93 | { |
| 94 | 94 | struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private; |
| 95 | 95 | struct psp_context *psp = &adev->psp; |
| 96 | − struct securedisplay_cmd *securedisplay_cmd; | |
| 96 | + struct ta_securedisplay_cmd *securedisplay_cmd; | |
| 97 | 97 | struct drm_device *dev = adev_to_drm(adev); |
| 98 | 98 | uint32_t phy_id; |
| 99 | 99 | uint32_t op; |
| @@ -30,7 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | void amdgpu_securedisplay_debugfs_init(struct amdgpu_device *adev); |
| 31 | 31 | void psp_securedisplay_parse_resp_status(struct psp_context *psp, |
| 32 | 32 | enum ta_securedisplay_status status); |
| 33 | −void psp_prep_securedisplay_cmd_buf(struct psp_context *psp, struct securedisplay_cmd **cmd, | |
| 33 | +void psp_prep_securedisplay_cmd_buf(struct psp_context *psp, struct ta_securedisplay_cmd **cmd, | |
| 34 | 34 | enum ta_securedisplay_command command_id); |
| 35 | 35 | |
| 36 | 36 | #endif |
| @@ -1679,10 +1679,10 @@ static int amdgpu_ttm_reserve_tmr(struct amdgpu_device *adev) · 1678 unmodified lines | ||
| 1679 | 1679 | /* reserve vram for mem train according to TMR location */ |
| 1680 | 1680 | amdgpu_ttm_training_data_block_init(adev); |
| 1681 | 1681 | ret = amdgpu_bo_create_kernel_at(adev, |
| 1682 | − ctx->c2p_train_data_offset, | |
| 1683 | − ctx->train_data_size, | |
| 1684 | − &ctx->c2p_bo, | |
| 1685 | − NULL); | |
| 1682 | + ctx->c2p_train_data_offset, | |
| 1683 | + ctx->train_data_size, | |
| 1684 | + &ctx->c2p_bo, | |
| 1685 | + NULL); | |
| 1686 | 1686 | if (ret) { |
| 1687 | 1687 | DRM_ERROR("alloc c2p_bo failed(%d)!\n", ret); |
| 1688 | 1688 | amdgpu_ttm_training_reserve_vram_fini(adev); |
| @@ -1692,10 +1692,10 @@ static int amdgpu_ttm_reserve_tmr(struct amdgpu_device *adev) · 3 unmodified lines | ||
| 1692 | 1692 | } |
| 1693 | 1693 | |
| 1694 | 1694 | ret = amdgpu_bo_create_kernel_at(adev, |
| 1695 | − adev->gmc.real_vram_size - adev->mman.discovery_tmr_size, | |
| 1696 | − adev->mman.discovery_tmr_size, | |
| 1697 | − &adev->mman.discovery_memory, | |
| 1698 | − NULL); | |
| 1695 | + adev->gmc.real_vram_size - adev->mman.discovery_tmr_size, | |
| 1696 | + adev->mman.discovery_tmr_size, | |
| 1697 | + &adev->mman.discovery_memory, | |
| 1698 | + NULL); | |
| 1699 | 1699 | if (ret) { |
| 1700 | 1700 | DRM_ERROR("alloc tmr failed(%d)!\n", ret); |
| 1701 | 1701 | amdgpu_bo_free_kernel(&adev->mman.discovery_memory, NULL, NULL); |
| @@ -1718,7 +1718,6 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) · 16 unmodified lines | ||
| 1718 | 1718 | { |
| 1719 | 1719 | uint64_t gtt_size; |
| 1720 | 1720 | int r; |
| 1721 | − u64 vis_vram_limit; | |
| 1722 | 1721 | |
| 1723 | 1722 | mutex_init(&adev->mman.gtt_window_lock); |
| 1724 | 1723 | |
| @@ -1741,12 +1740,6 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) · 16 unmodified lines | ||
| 1741 | 1740 | return r; |
| 1742 | 1741 | } |
| 1743 | 1742 | |
| 1744 | − /* Reduce size of CPU-visible VRAM if requested */ | |
| 1745 | − vis_vram_limit = (u64)amdgpu_vis_vram_limit * 1024 * 1024; | |
| 1746 | − if (amdgpu_vis_vram_limit > 0 && | |
| 1747 | − vis_vram_limit <= adev->gmc.visible_vram_size) | |
| 1748 | − adev->gmc.visible_vram_size = vis_vram_limit; | |
| 1749 | − | |
| 1750 | 1743 | /* Change the size here instead of the init above so only lpfn is affected */ |
| 1751 | 1744 | amdgpu_ttm_set_buffer_funcs_status(adev, false); |
| 1752 | 1745 | #ifdef CONFIG_64BIT |
| @@ -169,25 +169,33 @@ int amdgpu_umc_poison_handler(struct amdgpu_device *adev, bool reset) · 168 unmodified lines | ||
| 169 | 169 | { |
| 170 | 170 | int ret = AMDGPU_RAS_SUCCESS; |
| 171 | 171 | |
| 172 | − if (!adev->gmc.xgmi.connected_to_cpu) { | |
| 173 | − struct ras_err_data err_data = {0, 0, 0, NULL}; | |
| 174 | − struct ras_common_if head = { | |
| 175 | − .block = AMDGPU_RAS_BLOCK__UMC, | |
| 176 | − }; | |
| 177 | − struct ras_manager *obj = amdgpu_ras_find_obj(adev, &head); | |
| 178 | − | |
| 179 | − ret = amdgpu_umc_do_page_retirement(adev, &err_data, NULL, reset); | |
| 180 | − | |
| 181 | − if (ret == AMDGPU_RAS_SUCCESS && obj) { | |
| 182 | − obj->err_data.ue_count += err_data.ue_count; | |
| 183 | − obj->err_data.ce_count += err_data.ce_count; | |
| 172 | + if (!amdgpu_sriov_vf(adev)) { | |
| 173 | + if (!adev->gmc.xgmi.connected_to_cpu) { | |
| 174 | + struct ras_err_data err_data = {0, 0, 0, NULL}; | |
| 175 | + struct ras_common_if head = { | |
| 176 | + .block = AMDGPU_RAS_BLOCK__UMC, | |
| 177 | + }; | |
| 178 | + struct ras_manager *obj = amdgpu_ras_find_obj(adev, &head); | |
| 179 | + | |
| 180 | + ret = amdgpu_umc_do_page_retirement(adev, &err_data, NULL, reset); | |
| 181 | + | |
| 182 | + if (ret == AMDGPU_RAS_SUCCESS && obj) { | |
| 183 | + obj->err_data.ue_count += err_data.ue_count; | |
| 184 | + obj->err_data.ce_count += err_data.ce_count; | |
| 185 | + } | |
| 186 | + } else if (reset) { | |
| 187 | + /* MCA poison handler is only responsible for GPU reset, | |
| 188 | + * let MCA notifier do page retirement. | |
| 189 | + */ | |
| 190 | + kgd2kfd_set_sram_ecc_flag(adev->kfd.dev); | |
| 191 | + amdgpu_ras_reset_gpu(adev); | |
| 184 | 192 | } |
| 185 | − } else if (reset) { | |
| 186 | − /* MCA poison handler is only responsible for GPU reset, | |
| 187 | − * let MCA notifier do page retirement. | |
| 188 | − */ | |
| 189 | − kgd2kfd_set_sram_ecc_flag(adev->kfd.dev); | |
| 190 | − amdgpu_ras_reset_gpu(adev); | |
| 193 | + } else { | |
| 194 | + if (adev->virt.ops && adev->virt.ops->ras_poison_handler) | |
| 195 | + adev->virt.ops->ras_poison_handler(adev); | |
| 196 | + else | |
| 197 | + dev_warn(adev->dev, | |
| 198 | + "No ras_poison_handler interface in SRIOV!\n"); | |
| 191 | 199 | } |
| 192 | 200 | |
| 193 | 201 | return ret; |
| @@ -331,8 +331,11 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) · 330 unmodified lines | ||
| 331 | 331 | if (adev->uvd.harvest_config & (1 << j)) |
| 332 | 332 | continue; |
| 333 | 333 | r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE, |
| 334 | − AMDGPU_GEM_DOMAIN_VRAM, &adev->uvd.inst[j].vcpu_bo, | |
| 335 | − &adev->uvd.inst[j].gpu_addr, &adev->uvd.inst[j].cpu_addr); | |
| 334 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 335 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 336 | + &adev->uvd.inst[j].vcpu_bo, | |
| 337 | + &adev->uvd.inst[j].gpu_addr, | |
| 338 | + &adev->uvd.inst[j].cpu_addr); | |
| 336 | 339 | if (r) { |
| 337 | 340 | dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r); |
| 338 | 341 | return r; |
| @@ -186,7 +186,9 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size) · 185 unmodified lines | ||
| 186 | 186 | (binary_id << 8)); |
| 187 | 187 | |
| 188 | 188 | r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE, |
| 189 | − AMDGPU_GEM_DOMAIN_VRAM, &adev->vce.vcpu_bo, | |
| 189 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 190 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 191 | + &adev->vce.vcpu_bo, | |
| 190 | 192 | &adev->vce.gpu_addr, &adev->vce.cpu_addr); |
| 191 | 193 | if (r) { |
| 192 | 194 | dev_err(adev->dev, "(%d) failed to allocate VCE bo\n", r); |
| @@ -274,8 +274,11 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) · 273 unmodified lines | ||
| 274 | 274 | continue; |
| 275 | 275 | |
| 276 | 276 | r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE, |
| 277 | − AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].vcpu_bo, | |
| 278 | − &adev->vcn.inst[i].gpu_addr, &adev->vcn.inst[i].cpu_addr); | |
| 277 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 278 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 279 | + &adev->vcn.inst[i].vcpu_bo, | |
| 280 | + &adev->vcn.inst[i].gpu_addr, | |
| 281 | + &adev->vcn.inst[i].cpu_addr); | |
| 279 | 282 | if (r) { |
| 280 | 283 | dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r); |
| 281 | 284 | return r; |
| @@ -296,8 +299,11 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) · 14 unmodified lines | ||
| 296 | 299 | |
| 297 | 300 | if (adev->vcn.indirect_sram) { |
| 298 | 301 | r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE, |
| 299 | − AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].dpg_sram_bo, | |
| 300 | − &adev->vcn.inst[i].dpg_sram_gpu_addr, &adev->vcn.inst[i].dpg_sram_cpu_addr); | |
| 302 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 303 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 304 | + &adev->vcn.inst[i].dpg_sram_bo, | |
| 305 | + &adev->vcn.inst[i].dpg_sram_gpu_addr, | |
| 306 | + &adev->vcn.inst[i].dpg_sram_cpu_addr); | |
| 301 | 307 | if (r) { |
| 302 | 308 | dev_err(adev->dev, "VCN %d (%d) failed to allocate DPG bo\n", i, r); |
| 303 | 309 | return r; |
| @@ -1250,8 +1256,16 @@ int amdgpu_vcn_process_poison_irq(struct amdgpu_device *adev, · 946 unmodified lines | ||
| 1250 | 1256 | if (!ras_if) |
| 1251 | 1257 | return 0; |
| 1252 | 1258 | |
| 1253 | − ih_data.head = *ras_if; | |
| 1254 | − amdgpu_ras_interrupt_dispatch(adev, &ih_data); | |
| 1259 | + if (!amdgpu_sriov_vf(adev)) { | |
| 1260 | + ih_data.head = *ras_if; | |
| 1261 | + amdgpu_ras_interrupt_dispatch(adev, &ih_data); | |
| 1262 | + } else { | |
| 1263 | + if (adev->virt.ops && adev->virt.ops->ras_poison_handler) | |
| 1264 | + adev->virt.ops->ras_poison_handler(adev); | |
| 1265 | + else | |
| 1266 | + dev_warn(adev->dev, | |
| 1267 | + "No ras_poison_handler interface in SRIOV for VCN!\n"); | |
| 1268 | + } | |
| 1255 | 1269 | |
| 1256 | 1270 | return 0; |
| 1257 | 1271 | } |
| @@ -232,7 +232,8 @@ int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev) · 231 unmodified lines | ||
| 232 | 232 | return 0; |
| 233 | 233 | |
| 234 | 234 | r = amdgpu_bo_create_kernel(adev, PAGE_SIZE, PAGE_SIZE, |
| 235 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 235 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 236 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 236 | 237 | &adev->virt.mm_table.bo, |
| 237 | 238 | &adev->virt.mm_table.gpu_addr, |
| 238 | 239 | (void *)&adev->virt.mm_table.cpu_addr); |
| @@ -88,6 +88,7 @@ struct amdgpu_virt_ops { · 87 unmodified lines | ||
| 88 | 88 | int (*wait_reset)(struct amdgpu_device *adev); |
| 89 | 89 | void (*trans_msg)(struct amdgpu_device *adev, enum idh_request req, |
| 90 | 90 | u32 data1, u32 data2, u32 data3); |
| 91 | + void (*ras_poison_handler)(struct amdgpu_device *adev); | |
| 91 | 92 | }; |
| 92 | 93 | |
| 93 | 94 | /* |
| @@ -2837,7 +2837,7 @@ static int dce_v10_0_sw_init(void *handle) · 2836 unmodified lines | ||
| 2837 | 2837 | if (r) |
| 2838 | 2838 | return r; |
| 2839 | 2839 | |
| 2840 | − INIT_WORK(&adev->hotplug_work, | |
| 2840 | + INIT_DELAYED_WORK(&adev->hotplug_work, | |
| 2841 | 2841 | amdgpu_display_hotplug_work_func); |
| 2842 | 2842 | |
| 2843 | 2843 | drm_kms_helper_poll_init(adev_to_drm(adev)); |
| @@ -2902,7 +2902,7 @@ static int dce_v10_0_hw_fini(void *handle) · 58 unmodified lines | ||
| 2902 | 2902 | |
| 2903 | 2903 | dce_v10_0_pageflip_interrupt_fini(adev); |
| 2904 | 2904 | |
| 2905 | − flush_work(&adev->hotplug_work); | |
| 2905 | + flush_delayed_work(&adev->hotplug_work); | |
| 2906 | 2906 | |
| 2907 | 2907 | return 0; |
| 2908 | 2908 | } |
| @@ -3302,7 +3302,7 @@ static int dce_v10_0_hpd_irq(struct amdgpu_device *adev, · 393 unmodified lines | ||
| 3302 | 3302 | |
| 3303 | 3303 | if (disp_int & mask) { |
| 3304 | 3304 | dce_v10_0_hpd_int_ack(adev, hpd); |
| 3305 | − schedule_work(&adev->hotplug_work); | |
| 3305 | + schedule_delayed_work(&adev->hotplug_work, 0); | |
| 3306 | 3306 | DRM_DEBUG("IH: HPD%d\n", hpd + 1); |
| 3307 | 3307 | } |
| 3308 | 3308 | |
| @@ -2956,7 +2956,7 @@ static int dce_v11_0_sw_init(void *handle) · 2955 unmodified lines | ||
| 2956 | 2956 | if (r) |
| 2957 | 2957 | return r; |
| 2958 | 2958 | |
| 2959 | − INIT_WORK(&adev->hotplug_work, | |
| 2959 | + INIT_DELAYED_WORK(&adev->hotplug_work, | |
| 2960 | 2960 | amdgpu_display_hotplug_work_func); |
| 2961 | 2961 | |
| 2962 | 2962 | drm_kms_helper_poll_init(adev_to_drm(adev)); |
| @@ -3032,7 +3032,7 @@ static int dce_v11_0_hw_fini(void *handle) · 69 unmodified lines | ||
| 3032 | 3032 | |
| 3033 | 3033 | dce_v11_0_pageflip_interrupt_fini(adev); |
| 3034 | 3034 | |
| 3035 | − flush_work(&adev->hotplug_work); | |
| 3035 | + flush_delayed_work(&adev->hotplug_work); | |
| 3036 | 3036 | |
| 3037 | 3037 | return 0; |
| 3038 | 3038 | } |
| @@ -3426,7 +3426,7 @@ static int dce_v11_0_hpd_irq(struct amdgpu_device *adev, · 387 unmodified lines | ||
| 3426 | 3426 | |
| 3427 | 3427 | if (disp_int & mask) { |
| 3428 | 3428 | dce_v11_0_hpd_int_ack(adev, hpd); |
| 3429 | − schedule_work(&adev->hotplug_work); | |
| 3429 | + schedule_delayed_work(&adev->hotplug_work, 0); | |
| 3430 | 3430 | DRM_DEBUG("IH: HPD%d\n", hpd + 1); |
| 3431 | 3431 | } |
| 3432 | 3432 | |
| @@ -2715,7 +2715,7 @@ static int dce_v6_0_sw_init(void *handle) · 2714 unmodified lines | ||
| 2715 | 2715 | return r; |
| 2716 | 2716 | |
| 2717 | 2717 | /* Pre-DCE11 */ |
| 2718 | − INIT_WORK(&adev->hotplug_work, | |
| 2718 | + INIT_DELAYED_WORK(&adev->hotplug_work, | |
| 2719 | 2719 | amdgpu_display_hotplug_work_func); |
| 2720 | 2720 | |
| 2721 | 2721 | drm_kms_helper_poll_init(adev_to_drm(adev)); |
| @@ -2776,7 +2776,7 @@ static int dce_v6_0_hw_fini(void *handle) · 54 unmodified lines | ||
| 2776 | 2776 | |
| 2777 | 2777 | dce_v6_0_pageflip_interrupt_fini(adev); |
| 2778 | 2778 | |
| 2779 | − flush_work(&adev->hotplug_work); | |
| 2779 | + flush_delayed_work(&adev->hotplug_work); | |
| 2780 | 2780 | |
| 2781 | 2781 | return 0; |
| 2782 | 2782 | } |
| @@ -3103,7 +3103,7 @@ static int dce_v6_0_hpd_irq(struct amdgpu_device *adev, · 320 unmodified lines | ||
| 3103 | 3103 | tmp = RREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd]); |
| 3104 | 3104 | tmp |= DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK; |
| 3105 | 3105 | WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd], tmp); |
| 3106 | − schedule_work(&adev->hotplug_work); | |
| 3106 | + schedule_delayed_work(&adev->hotplug_work, 0); | |
| 3107 | 3107 | DRM_DEBUG("IH: HPD%d\n", hpd + 1); |
| 3108 | 3108 | } |
| 3109 | 3109 | |
| @@ -2739,7 +2739,7 @@ static int dce_v8_0_sw_init(void *handle) · 2738 unmodified lines | ||
| 2739 | 2739 | return r; |
| 2740 | 2740 | |
| 2741 | 2741 | /* Pre-DCE11 */ |
| 2742 | − INIT_WORK(&adev->hotplug_work, | |
| 2742 | + INIT_DELAYED_WORK(&adev->hotplug_work, | |
| 2743 | 2743 | amdgpu_display_hotplug_work_func); |
| 2744 | 2744 | |
| 2745 | 2745 | drm_kms_helper_poll_init(adev_to_drm(adev)); |
| @@ -2802,7 +2802,7 @@ static int dce_v8_0_hw_fini(void *handle) · 56 unmodified lines | ||
| 2802 | 2802 | |
| 2803 | 2803 | dce_v8_0_pageflip_interrupt_fini(adev); |
| 2804 | 2804 | |
| 2805 | − flush_work(&adev->hotplug_work); | |
| 2805 | + flush_delayed_work(&adev->hotplug_work); | |
| 2806 | 2806 | |
| 2807 | 2807 | return 0; |
| 2808 | 2808 | } |
| @@ -3195,7 +3195,7 @@ static int dce_v8_0_hpd_irq(struct amdgpu_device *adev, · 386 unmodified lines | ||
| 3195 | 3195 | tmp = RREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd]); |
| 3196 | 3196 | tmp |= DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK; |
| 3197 | 3197 | WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd], tmp); |
| 3198 | − schedule_work(&adev->hotplug_work); | |
| 3198 | + schedule_delayed_work(&adev->hotplug_work, 0); | |
| 3199 | 3199 | DRM_DEBUG("IH: HPD%d\n", hpd + 1); |
| 3200 | 3200 | } |
| 3201 | 3201 | |
| @@ -0,0 +1,61 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2022 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + */ | |
| 23 | +#include "amdgpu.h" | |
| 24 | +#include "df_v4_3.h" | |
| 25 | + | |
| 26 | +#include "df/df_4_3_offset.h" | |
| 27 | +#include "df/df_4_3_sh_mask.h" | |
| 28 | + | |
| 29 | +static bool df_v4_3_query_ras_poison_mode(struct amdgpu_device *adev) | |
| 30 | +{ | |
| 31 | + uint32_t hw_assert_msklo, hw_assert_mskhi; | |
| 32 | + uint32_t v0, v1, v28, v31; | |
| 33 | + | |
| 34 | + hw_assert_msklo = RREG32_SOC15(DF, 0, | |
| 35 | + regDF_CS_UMC_AON0_HardwareAssertMaskLow); | |
| 36 | + hw_assert_mskhi = RREG32_SOC15(DF, 0, | |
| 37 | + regDF_NCS_PG0_HardwareAssertMaskHigh); | |
| 38 | + | |
| 39 | + v0 = REG_GET_FIELD(hw_assert_msklo, | |
| 40 | + DF_CS_UMC_AON0_HardwareAssertMaskLow, HWAssertMsk0); | |
| 41 | + v1 = REG_GET_FIELD(hw_assert_msklo, | |
| 42 | + DF_CS_UMC_AON0_HardwareAssertMaskLow, HWAssertMsk1); | |
| 43 | + v28 = REG_GET_FIELD(hw_assert_mskhi, | |
| 44 | + DF_NCS_PG0_HardwareAssertMaskHigh, HWAssertMsk28); | |
| 45 | + v31 = REG_GET_FIELD(hw_assert_mskhi, | |
| 46 | + DF_NCS_PG0_HardwareAssertMaskHigh, HWAssertMsk31); | |
| 47 | + | |
| 48 | + if (v0 && v1 && v28 && v31) | |
| 49 | + return true; | |
| 50 | + else if (!v0 && !v1 && !v28 && !v31) | |
| 51 | + return false; | |
| 52 | + else { | |
| 53 | + dev_warn(adev->dev, "DF poison setting is inconsistent(%d:%d:%d:%d)!\n", | |
| 54 | + v0, v1, v28, v31); | |
| 55 | + return false; | |
| 56 | + } | |
| 57 | +} | |
| 58 | + | |
| 59 | +const struct amdgpu_df_funcs df_v4_3_funcs = { | |
| 60 | + .query_ras_poison_mode = df_v4_3_query_ras_poison_mode, | |
| 61 | +}; | |
| @@ -0,0 +1,31 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2022 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + */ | |
| 23 | + | |
| 24 | +#ifndef __DF_V4_3_H__ | |
| 25 | +#define __DF_V4_3_H__ | |
| 26 | + | |
| 27 | +#include "soc15_common.h" | |
| 28 | + | |
| 29 | +extern const struct amdgpu_df_funcs df_v4_3_funcs; | |
| 30 | + | |
| 31 | +#endif | |
| @@ -987,10 +987,11 @@ static int gfx_v11_0_rlc_autoload_buffer_init(struct amdgpu_device *adev) · 986 unmodified lines | ||
| 987 | 987 | total_size = gfx_v11_0_calc_toc_total_size(adev); |
| 988 | 988 | |
| 989 | 989 | r = amdgpu_bo_create_reserved(adev, total_size, 64 * 1024, |
| 990 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 991 | − &adev->gfx.rlc.rlc_autoload_bo, | |
| 992 | − &adev->gfx.rlc.rlc_autoload_gpu_addr, | |
| 993 | − (void **)&adev->gfx.rlc.rlc_autoload_ptr); | |
| 990 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 991 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 992 | + &adev->gfx.rlc.rlc_autoload_bo, | |
| 993 | + &adev->gfx.rlc.rlc_autoload_gpu_addr, | |
| 994 | + (void **)&adev->gfx.rlc.rlc_autoload_ptr); | |
| 994 | 995 | |
| 995 | 996 | if (r) { |
| 996 | 997 | dev_err(adev->dev, "(%d) failed to create fw autoload bo\n", r); |
| @@ -2649,7 +2650,9 @@ static int gfx_v11_0_cp_gfx_load_pfp_microcode_rs64(struct amdgpu_device *adev) · 1652 unmodified lines | ||
| 2649 | 2650 | |
| 2650 | 2651 | /* 64kb align */ |
| 2651 | 2652 | r = amdgpu_bo_create_reserved(adev, fw_ucode_size, |
| 2652 | − 64 * 1024, AMDGPU_GEM_DOMAIN_VRAM, | |
| 2653 | + 64 * 1024, | |
| 2654 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 2655 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 2653 | 2656 | &adev->gfx.pfp.pfp_fw_obj, |
| 2654 | 2657 | &adev->gfx.pfp.pfp_fw_gpu_addr, |
| 2655 | 2658 | (void **)&adev->gfx.pfp.pfp_fw_ptr); |
| @@ -2660,7 +2663,9 @@ static int gfx_v11_0_cp_gfx_load_pfp_microcode_rs64(struct amdgpu_device *adev) · 4 unmodified lines | ||
| 2660 | 2663 | } |
| 2661 | 2664 | |
| 2662 | 2665 | r = amdgpu_bo_create_reserved(adev, fw_data_size, |
| 2663 | − 64 * 1024, AMDGPU_GEM_DOMAIN_VRAM, | |
| 2666 | + 64 * 1024, | |
| 2667 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 2668 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 2664 | 2669 | &adev->gfx.pfp.pfp_fw_data_obj, |
| 2665 | 2670 | &adev->gfx.pfp.pfp_fw_data_gpu_addr, |
| 2666 | 2671 | (void **)&adev->gfx.pfp.pfp_fw_data_ptr); |
| @@ -2863,7 +2868,9 @@ static int gfx_v11_0_cp_gfx_load_me_microcode_rs64(struct amdgpu_device *adev) · 196 unmodified lines | ||
| 2863 | 2868 | |
| 2864 | 2869 | /* 64kb align*/ |
| 2865 | 2870 | r = amdgpu_bo_create_reserved(adev, fw_ucode_size, |
| 2866 | − 64 * 1024, AMDGPU_GEM_DOMAIN_VRAM, | |
| 2871 | + 64 * 1024, | |
| 2872 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 2873 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 2867 | 2874 | &adev->gfx.me.me_fw_obj, |
| 2868 | 2875 | &adev->gfx.me.me_fw_gpu_addr, |
| 2869 | 2876 | (void **)&adev->gfx.me.me_fw_ptr); |
| @@ -2874,7 +2881,9 @@ static int gfx_v11_0_cp_gfx_load_me_microcode_rs64(struct amdgpu_device *adev) · 4 unmodified lines | ||
| 2874 | 2881 | } |
| 2875 | 2882 | |
| 2876 | 2883 | r = amdgpu_bo_create_reserved(adev, fw_data_size, |
| 2877 | − 64 * 1024, AMDGPU_GEM_DOMAIN_VRAM, | |
| 2884 | + 64 * 1024, | |
| 2885 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 2886 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 2878 | 2887 | &adev->gfx.me.me_fw_data_obj, |
| 2879 | 2888 | &adev->gfx.me.me_fw_data_gpu_addr, |
| 2880 | 2889 | (void **)&adev->gfx.me.me_fw_data_ptr); |
| @@ -3380,7 +3389,9 @@ static int gfx_v11_0_cp_compute_load_microcode_rs64(struct amdgpu_device *adev) · 499 unmodified lines | ||
| 3380 | 3389 | fw_data_size = le32_to_cpu(mec_hdr->data_size_bytes); |
| 3381 | 3390 | |
| 3382 | 3391 | r = amdgpu_bo_create_reserved(adev, fw_ucode_size, |
| 3383 | − 64 * 1024, AMDGPU_GEM_DOMAIN_VRAM, | |
| 3392 | + 64 * 1024, | |
| 3393 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 3394 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 3384 | 3395 | &adev->gfx.mec.mec_fw_obj, |
| 3385 | 3396 | &adev->gfx.mec.mec_fw_gpu_addr, |
| 3386 | 3397 | (void **)&fw_ucode_ptr); |
| @@ -3391,7 +3402,9 @@ static int gfx_v11_0_cp_compute_load_microcode_rs64(struct amdgpu_device *adev) · 4 unmodified lines | ||
| 3391 | 3402 | } |
| 3392 | 3403 | |
| 3393 | 3404 | r = amdgpu_bo_create_reserved(adev, fw_data_size, |
| 3394 | − 64 * 1024, AMDGPU_GEM_DOMAIN_VRAM, | |
| 3405 | + 64 * 1024, | |
| 3406 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 3407 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 3395 | 3408 | &adev->gfx.mec.mec_fw_data_obj, |
| 3396 | 3409 | &adev->gfx.mec.mec_fw_data_gpu_addr, |
| 3397 | 3410 | (void **)&fw_data_ptr); |
| @@ -2375,7 +2375,8 @@ static int gfx_v6_0_rlc_init(struct amdgpu_device *adev) · 2374 unmodified lines | ||
| 2375 | 2375 | dws = adev->gfx.rlc.clear_state_size + (256 / 4); |
| 2376 | 2376 | |
| 2377 | 2377 | r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE, |
| 2378 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 2378 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 2379 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 2379 | 2380 | &adev->gfx.rlc.clear_state_obj, |
| 2380 | 2381 | &adev->gfx.rlc.clear_state_gpu_addr, |
| 2381 | 2382 | (void **)&adev->gfx.rlc.cs_ptr); |
| @@ -2772,7 +2772,8 @@ static int gfx_v7_0_mec_init(struct amdgpu_device *adev) · 2771 unmodified lines | ||
| 2772 | 2772 | * GFX7_MEC_HPD_SIZE * 2; |
| 2773 | 2773 | |
| 2774 | 2774 | r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE, |
| 2775 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 2775 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 2776 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 2776 | 2777 | &adev->gfx.mec.hpd_eop_obj, |
| 2777 | 2778 | &adev->gfx.mec.hpd_eop_gpu_addr, |
| 2778 | 2779 | (void **)&hpd); |
| @@ -1340,7 +1340,8 @@ static int gfx_v8_0_mec_init(struct amdgpu_device *adev) · 1339 unmodified lines | ||
| 1340 | 1340 | mec_hpd_size = adev->gfx.num_compute_rings * GFX8_MEC_HPD_SIZE; |
| 1341 | 1341 | if (mec_hpd_size) { |
| 1342 | 1342 | r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE, |
| 1343 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 1343 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 1344 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 1344 | 1345 | &adev->gfx.mec.hpd_eop_obj, |
| 1345 | 1346 | &adev->gfx.mec.hpd_eop_gpu_addr, |
| 1346 | 1347 | (void **)&hpd); |
| @@ -1783,7 +1783,8 @@ static int gfx_v9_0_mec_init(struct amdgpu_device *adev) · 1782 unmodified lines | ||
| 1783 | 1783 | mec_hpd_size = adev->gfx.num_compute_rings * GFX9_MEC_HPD_SIZE; |
| 1784 | 1784 | if (mec_hpd_size) { |
| 1785 | 1785 | r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE, |
| 1786 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 1786 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 1787 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 1787 | 1788 | &adev->gfx.mec.hpd_eop_obj, |
| 1788 | 1789 | &adev->gfx.mec.hpd_eop_gpu_addr, |
| 1789 | 1790 | (void **)&hpd); |
| @@ -120,7 +120,7 @@ static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev) · 119 unmodified lines | ||
| 120 | 120 | max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18); |
| 121 | 121 | |
| 122 | 122 | /* Set default page address. */ |
| 123 | − value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr); | |
| 123 | + value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr); | |
| 124 | 124 | WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, |
| 125 | 125 | (u32)(value >> 12)); |
| 126 | 126 | WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, |
| @@ -165,7 +165,7 @@ static void gfxhub_v2_0_init_system_aperture_regs(struct amdgpu_device *adev) · 164 unmodified lines | ||
| 165 | 165 | max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18); |
| 166 | 166 | |
| 167 | 167 | /* Set default page address. */ |
| 168 | − value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr); | |
| 168 | + value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr); | |
| 169 | 169 | WREG32_SOC15(GC, 0, mmGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, |
| 170 | 170 | (u32)(value >> 12)); |
| 171 | 171 | WREG32_SOC15(GC, 0, mmGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, |
| @@ -167,7 +167,7 @@ static void gfxhub_v2_1_init_system_aperture_regs(struct amdgpu_device *adev) · 166 unmodified lines | ||
| 167 | 167 | max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18); |
| 168 | 168 | |
| 169 | 169 | /* Set default page address. */ |
| 170 | − value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr); | |
| 170 | + value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr); | |
| 171 | 171 | WREG32_SOC15(GC, 0, mmGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, |
| 172 | 172 | (u32)(value >> 12)); |
| 173 | 173 | WREG32_SOC15(GC, 0, mmGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, |
| @@ -163,7 +163,7 @@ static void gfxhub_v3_0_init_system_aperture_regs(struct amdgpu_device *adev) · 162 unmodified lines | ||
| 163 | 163 | adev->gmc.vram_end >> 18); |
| 164 | 164 | |
| 165 | 165 | /* Set default page address. */ |
| 166 | − value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start | |
| 166 | + value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start | |
| 167 | 167 | + adev->vm_manager.vram_base_offset; |
| 168 | 168 | WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, |
| 169 | 169 | (u32)(value >> 12)); |
| @@ -169,7 +169,7 @@ static void gfxhub_v3_0_3_init_system_aperture_regs(struct amdgpu_device *adev) · 168 unmodified lines | ||
| 169 | 169 | adev->gmc.vram_end >> 18); |
| 170 | 170 | |
| 171 | 171 | /* Set default page address. */ |
| 172 | − value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start | |
| 172 | + value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start | |
| 173 | 173 | + adev->vm_manager.vram_base_offset; |
| 174 | 174 | WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, |
| 175 | 175 | (u32)(value >> 12)); |
| @@ -78,13 +78,25 @@ gmc_v10_0_vm_fault_interrupt_state(struct amdgpu_device *adev, · 77 unmodified lines | ||
| 78 | 78 | /* MM HUB */ |
| 79 | 79 | amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_MMHUB_0, false); |
| 80 | 80 | /* GFX HUB */ |
| 81 | − amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_GFXHUB_0, false); | |
| 81 | + /* This works because this interrupt is only | |
| 82 | + * enabled at init/resume and disabled in | |
| 83 | + * fini/suspend, so the overall state doesn't | |
| 84 | + * change over the course of suspend/resume. | |
| 85 | + */ | |
| 86 | + if (!adev->in_s0ix) | |
| 87 | + amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_GFXHUB_0, false); | |
| 82 | 88 | break; |
| 83 | 89 | case AMDGPU_IRQ_STATE_ENABLE: |
| 84 | 90 | /* MM HUB */ |
| 85 | 91 | amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_MMHUB_0, true); |
| 86 | 92 | /* GFX HUB */ |
| 87 | − amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_GFXHUB_0, true); | |
| 93 | + /* This works because this interrupt is only | |
| 94 | + * enabled at init/resume and disabled in | |
| 95 | + * fini/suspend, so the overall state doesn't | |
| 96 | + * change over the course of suspend/resume. | |
| 97 | + */ | |
| 98 | + if (!adev->in_s0ix) | |
| 99 | + amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_GFXHUB_0, true); | |
| 88 | 100 | break; |
| 89 | 101 | default: |
| 90 | 102 | break; |
| @@ -835,10 +847,7 @@ static int gmc_v10_0_mc_init(struct amdgpu_device *adev) · 744 unmodified lines | ||
| 835 | 847 | } |
| 836 | 848 | #endif |
| 837 | 849 | |
| 838 | − /* In case the PCI BAR is larger than the actual amount of vram */ | |
| 839 | 850 | adev->gmc.visible_vram_size = adev->gmc.aper_size; |
| 840 | − if (adev->gmc.visible_vram_size > adev->gmc.real_vram_size) | |
| 841 | − adev->gmc.visible_vram_size = adev->gmc.real_vram_size; | |
| 842 | 851 | |
| 843 | 852 | /* set the gart size */ |
| 844 | 853 | if (amdgpu_gart_size == -1) { |
| @@ -1061,9 +1070,12 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev) · 216 unmodified lines | ||
| 1061 | 1070 | } |
| 1062 | 1071 | |
| 1063 | 1072 | amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr); |
| 1064 | − r = adev->gfxhub.funcs->gart_enable(adev); | |
| 1065 | − if (r) | |
| 1066 | − return r; | |
| 1073 | + | |
| 1074 | + if (!adev->in_s0ix) { | |
| 1075 | + r = adev->gfxhub.funcs->gart_enable(adev); | |
| 1076 | + if (r) | |
| 1077 | + return r; | |
| 1078 | + } | |
| 1067 | 1079 | |
| 1068 | 1080 | r = adev->mmhub.funcs->gart_enable(adev); |
| 1069 | 1081 | if (r) |
| @@ -1077,10 +1089,12 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev) · 7 unmodified lines | ||
| 1077 | 1089 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? |
| 1078 | 1090 | false : true; |
| 1079 | 1091 | |
| 1080 | − adev->gfxhub.funcs->set_fault_enable_default(adev, value); | |
| 1092 | + if (!adev->in_s0ix) | |
| 1093 | + adev->gfxhub.funcs->set_fault_enable_default(adev, value); | |
| 1081 | 1094 | adev->mmhub.funcs->set_fault_enable_default(adev, value); |
| 1082 | 1095 | gmc_v10_0_flush_gpu_tlb(adev, 0, AMDGPU_MMHUB_0, 0); |
| 1083 | − gmc_v10_0_flush_gpu_tlb(adev, 0, AMDGPU_GFXHUB_0, 0); | |
| 1096 | + if (!adev->in_s0ix) | |
| 1097 | + gmc_v10_0_flush_gpu_tlb(adev, 0, AMDGPU_GFXHUB_0, 0); | |
| 1084 | 1098 | |
| 1085 | 1099 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", |
| 1086 | 1100 | (unsigned)(adev->gmc.gart_size >> 20), |
| @@ -1101,7 +1115,7 @@ static int gmc_v10_0_hw_init(void *handle) · 14 unmodified lines | ||
| 1101 | 1115 | * harvestable groups in gc_utcl2 need to be programmed before any GFX block |
| 1102 | 1116 | * register setup within GMC, or else system hang when harvesting SA. |
| 1103 | 1117 | */ |
| 1104 | − if (adev->gfxhub.funcs && adev->gfxhub.funcs->utcl2_harvest) | |
| 1118 | + if (!adev->in_s0ix && adev->gfxhub.funcs && adev->gfxhub.funcs->utcl2_harvest) | |
| 1105 | 1119 | adev->gfxhub.funcs->utcl2_harvest(adev); |
| 1106 | 1120 | |
| 1107 | 1121 | r = gmc_v10_0_gart_enable(adev); |
| @@ -1129,7 +1143,8 @@ static int gmc_v10_0_hw_init(void *handle) · 21 unmodified lines | ||
| 1129 | 1143 | */ |
| 1130 | 1144 | static void gmc_v10_0_gart_disable(struct amdgpu_device *adev) |
| 1131 | 1145 | { |
| 1132 | − adev->gfxhub.funcs->gart_disable(adev); | |
| 1146 | + if (!adev->in_s0ix) | |
| 1147 | + adev->gfxhub.funcs->gart_disable(adev); | |
| 1133 | 1148 | adev->mmhub.funcs->gart_disable(adev); |
| 1134 | 1149 | } |
| 1135 | 1150 | |
| @@ -64,13 +64,25 @@ gmc_v11_0_vm_fault_interrupt_state(struct amdgpu_device *adev, · 63 unmodified lines | ||
| 64 | 64 | /* MM HUB */ |
| 65 | 65 | amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_MMHUB_0, false); |
| 66 | 66 | /* GFX HUB */ |
| 67 | − amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_GFXHUB_0, false); | |
| 67 | + /* This works because this interrupt is only | |
| 68 | + * enabled at init/resume and disabled in | |
| 69 | + * fini/suspend, so the overall state doesn't | |
| 70 | + * change over the course of suspend/resume. | |
| 71 | + */ | |
| 72 | + if (!adev->in_s0ix) | |
| 73 | + amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_GFXHUB_0, false); | |
| 68 | 74 | break; |
| 69 | 75 | case AMDGPU_IRQ_STATE_ENABLE: |
| 70 | 76 | /* MM HUB */ |
| 71 | 77 | amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_MMHUB_0, true); |
| 72 | 78 | /* GFX HUB */ |
| 73 | − amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_GFXHUB_0, true); | |
| 79 | + /* This works because this interrupt is only | |
| 80 | + * enabled at init/resume and disabled in | |
| 81 | + * fini/suspend, so the overall state doesn't | |
| 82 | + * change over the course of suspend/resume. | |
| 83 | + */ | |
| 84 | + if (!adev->in_s0ix) | |
| 85 | + amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_GFXHUB_0, true); | |
| 74 | 86 | break; |
| 75 | 87 | default: |
| 76 | 88 | break; |
| @@ -258,7 +258,7 @@ static void gmc_v6_0_mc_program(struct amdgpu_device *adev) · 257 unmodified lines | ||
| 258 | 258 | WREG32(mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR, |
| 259 | 259 | adev->gmc.vram_end >> 12); |
| 260 | 260 | WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, |
| 261 | − adev->vram_scratch.gpu_addr >> 12); | |
| 261 | + adev->mem_scratch.gpu_addr >> 12); | |
| 262 | 262 | WREG32(mmMC_VM_AGP_BASE, 0); |
| 263 | 263 | WREG32(mmMC_VM_AGP_TOP, 0x0FFFFFFF); |
| 264 | 264 | WREG32(mmMC_VM_AGP_BOT, 0x0FFFFFFF); |
| @@ -292,7 +292,7 @@ static void gmc_v7_0_mc_program(struct amdgpu_device *adev) · 291 unmodified lines | ||
| 292 | 292 | WREG32(mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR, |
| 293 | 293 | adev->gmc.vram_end >> 12); |
| 294 | 294 | WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, |
| 295 | − adev->vram_scratch.gpu_addr >> 12); | |
| 295 | + adev->mem_scratch.gpu_addr >> 12); | |
| 296 | 296 | WREG32(mmMC_VM_AGP_BASE, 0); |
| 297 | 297 | WREG32(mmMC_VM_AGP_TOP, 0x0FFFFFFF); |
| 298 | 298 | WREG32(mmMC_VM_AGP_BOT, 0x0FFFFFFF); |
| @@ -389,10 +389,7 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev) · 90 unmodified lines | ||
| 389 | 389 | } |
| 390 | 390 | #endif |
| 391 | 391 | |
| 392 | − /* In case the PCI BAR is larger than the actual amount of vram */ | |
| 393 | 392 | adev->gmc.visible_vram_size = adev->gmc.aper_size; |
| 394 | − if (adev->gmc.visible_vram_size > adev->gmc.real_vram_size) | |
| 395 | − adev->gmc.visible_vram_size = adev->gmc.real_vram_size; | |
| 396 | 393 | |
| 397 | 394 | /* set the gart size */ |
| 398 | 395 | if (amdgpu_gart_size == -1) { |
| @@ -474,7 +474,7 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev) · 473 unmodified lines | ||
| 474 | 474 | WREG32(mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR, |
| 475 | 475 | adev->gmc.vram_end >> 12); |
| 476 | 476 | WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, |
| 477 | − adev->vram_scratch.gpu_addr >> 12); | |
| 477 | + adev->mem_scratch.gpu_addr >> 12); | |
| 478 | 478 | |
| 479 | 479 | if (amdgpu_sriov_vf(adev)) { |
| 480 | 480 | tmp = ((adev->gmc.vram_end >> 24) & 0xFFFF) << 16; |
| @@ -587,10 +587,7 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev) · 106 unmodified lines | ||
| 587 | 587 | } |
| 588 | 588 | #endif |
| 589 | 589 | |
| 590 | − /* In case the PCI BAR is larger than the actual amount of vram */ | |
| 591 | 590 | adev->gmc.visible_vram_size = adev->gmc.aper_size; |
| 592 | − if (adev->gmc.visible_vram_size > adev->gmc.real_vram_size) | |
| 593 | − adev->gmc.visible_vram_size = adev->gmc.real_vram_size; | |
| 594 | 591 | |
| 595 | 592 | /* set the gart size */ |
| 596 | 593 | if (amdgpu_gart_size == -1) { |
| @@ -484,6 +484,14 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev, · 483 unmodified lines | ||
| 484 | 484 | for (i = 0; i < 16; i++) { |
| 485 | 485 | reg = hub->vm_context0_cntl + i; |
| 486 | 486 | |
| 487 | + /* This works because this interrupt is only | |
| 488 | + * enabled at init/resume and disabled in | |
| 489 | + * fini/suspend, so the overall state doesn't | |
| 490 | + * change over the course of suspend/resume. | |
| 491 | + */ | |
| 492 | + if (adev->in_s0ix && (j == AMDGPU_GFXHUB_0)) | |
| 493 | + continue; | |
| 494 | + | |
| 487 | 495 | if (j == AMDGPU_GFXHUB_0) |
| 488 | 496 | tmp = RREG32_SOC15_IP(GC, reg); |
| 489 | 497 | else |
| @@ -504,6 +512,14 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev, · 14 unmodified lines | ||
| 504 | 512 | for (i = 0; i < 16; i++) { |
| 505 | 513 | reg = hub->vm_context0_cntl + i; |
| 506 | 514 | |
| 515 | + /* This works because this interrupt is only | |
| 516 | + * enabled at init/resume and disabled in | |
| 517 | + * fini/suspend, so the overall state doesn't | |
| 518 | + * change over the course of suspend/resume. | |
| 519 | + */ | |
| 520 | + if (adev->in_s0ix && (j == AMDGPU_GFXHUB_0)) | |
| 521 | + continue; | |
| 522 | + | |
| 507 | 523 | if (j == AMDGPU_GFXHUB_0) |
| 508 | 524 | tmp = RREG32_SOC15_IP(GC, reg); |
| 509 | 525 | else |
| @@ -1536,10 +1552,7 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev) · 1026 unmodified lines | ||
| 1536 | 1552 | } |
| 1537 | 1553 | |
| 1538 | 1554 | #endif |
| 1539 | − /* In case the PCI BAR is larger than the actual amount of vram */ | |
| 1540 | 1555 | adev->gmc.visible_vram_size = adev->gmc.aper_size; |
| 1541 | − if (adev->gmc.visible_vram_size > adev->gmc.real_vram_size) | |
| 1542 | − adev->gmc.visible_vram_size = adev->gmc.real_vram_size; | |
| 1543 | 1556 | |
| 1544 | 1557 | /* set the gart size */ |
| 1545 | 1558 | if (amdgpu_gart_size == -1) { |
| @@ -1862,9 +1875,12 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) · 316 unmodified lines | ||
| 1862 | 1875 | } |
| 1863 | 1876 | |
| 1864 | 1877 | amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr); |
| 1865 | − r = adev->gfxhub.funcs->gart_enable(adev); | |
| 1866 | − if (r) | |
| 1867 | − return r; | |
| 1878 | + | |
| 1879 | + if (!adev->in_s0ix) { | |
| 1880 | + r = adev->gfxhub.funcs->gart_enable(adev); | |
| 1881 | + if (r) | |
| 1882 | + return r; | |
| 1883 | + } | |
| 1868 | 1884 | |
| 1869 | 1885 | r = adev->mmhub.funcs->gart_enable(adev); |
| 1870 | 1886 | if (r) |
| @@ -1911,11 +1927,15 @@ static int gmc_v9_0_hw_init(void *handle) · 40 unmodified lines | ||
| 1911 | 1927 | value = true; |
| 1912 | 1928 | |
| 1913 | 1929 | if (!amdgpu_sriov_vf(adev)) { |
| 1914 | − adev->gfxhub.funcs->set_fault_enable_default(adev, value); | |
| 1930 | + if (!adev->in_s0ix) | |
| 1931 | + adev->gfxhub.funcs->set_fault_enable_default(adev, value); | |
| 1915 | 1932 | adev->mmhub.funcs->set_fault_enable_default(adev, value); |
| 1916 | 1933 | } |
| 1917 | − for (i = 0; i < adev->num_vmhubs; ++i) | |
| 1934 | + for (i = 0; i < adev->num_vmhubs; ++i) { | |
| 1935 | + if (adev->in_s0ix && (i == AMDGPU_GFXHUB_0)) | |
| 1936 | + continue; | |
| 1918 | 1937 | gmc_v9_0_flush_gpu_tlb(adev, 0, i, 0); |
| 1938 | + } | |
| 1919 | 1939 | |
| 1920 | 1940 | if (adev->umc.funcs && adev->umc.funcs->init_registers) |
| 1921 | 1941 | adev->umc.funcs->init_registers(adev); |
| @@ -1939,7 +1959,8 @@ static int gmc_v9_0_hw_init(void *handle) · 17 unmodified lines | ||
| 1939 | 1959 | */ |
| 1940 | 1960 | static void gmc_v9_0_gart_disable(struct amdgpu_device *adev) |
| 1941 | 1961 | { |
| 1942 | − adev->gfxhub.funcs->gart_disable(adev); | |
| 1962 | + if (!adev->in_s0ix) | |
| 1963 | + adev->gfxhub.funcs->gart_disable(adev); | |
| 1943 | 1964 | adev->mmhub.funcs->gart_disable(adev); |
| 1944 | 1965 | } |
| 1945 | 1966 | |
| @@ -549,7 +549,9 @@ static int mes_v11_0_allocate_ucode_buffer(struct amdgpu_device *adev, · 548 unmodified lines | ||
| 549 | 549 | fw_size = le32_to_cpu(mes_hdr->mes_ucode_size_bytes); |
| 550 | 550 | |
| 551 | 551 | r = amdgpu_bo_create_reserved(adev, fw_size, |
| 552 | − PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, | |
| 552 | + PAGE_SIZE, | |
| 553 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 554 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 553 | 555 | &adev->mes.ucode_fw_obj[pipe], |
| 554 | 556 | &adev->mes.ucode_fw_gpu_addr[pipe], |
| 555 | 557 | (void **)&adev->mes.ucode_fw_ptr[pipe]); |
| @@ -582,7 +584,9 @@ static int mes_v11_0_allocate_ucode_data_buffer(struct amdgpu_device *adev, · 26 unmodified lines | ||
| 582 | 584 | fw_size = le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes); |
| 583 | 585 | |
| 584 | 586 | r = amdgpu_bo_create_reserved(adev, fw_size, |
| 585 | − 64 * 1024, AMDGPU_GEM_DOMAIN_VRAM, | |
| 587 | + 64 * 1024, | |
| 588 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 589 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 586 | 590 | &adev->mes.data_fw_obj[pipe], |
| 587 | 591 | &adev->mes.data_fw_gpu_addr[pipe], |
| 588 | 592 | (void **)&adev->mes.data_fw_ptr[pipe]); |
| @@ -114,7 +114,7 @@ static void mmhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev) · 113 unmodified lines | ||
| 114 | 114 | return; |
| 115 | 115 | |
| 116 | 116 | /* Set default page address. */ |
| 117 | − value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr); | |
| 117 | + value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr); | |
| 118 | 118 | WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, |
| 119 | 119 | (u32)(value >> 12)); |
| 120 | 120 | WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, |
| @@ -134,7 +134,7 @@ static void mmhub_v1_7_init_system_aperture_regs(struct amdgpu_device *adev) · 133 unmodified lines | ||
| 134 | 134 | } |
| 135 | 135 | |
| 136 | 136 | /* Set default page address. */ |
| 137 | − value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr); | |
| 137 | + value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr); | |
| 138 | 138 | WREG32_SOC15(MMHUB, 0, regMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, |
| 139 | 139 | (u32)(value >> 12)); |
| 140 | 140 | WREG32_SOC15(MMHUB, 0, regMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, |
| @@ -234,7 +234,7 @@ static void mmhub_v2_0_init_system_aperture_regs(struct amdgpu_device *adev) · 233 unmodified lines | ||
| 234 | 234 | } |
| 235 | 235 | |
| 236 | 236 | /* Set default page address. */ |
| 237 | − value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr); | |
| 237 | + value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr); | |
| 238 | 238 | WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, |
| 239 | 239 | (u32)(value >> 12)); |
| 240 | 240 | WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, |
| @@ -164,7 +164,7 @@ static void mmhub_v2_3_init_system_aperture_regs(struct amdgpu_device *adev) · 163 unmodified lines | ||
| 164 | 164 | max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18); |
| 165 | 165 | |
| 166 | 166 | /* Set default page address. */ |
| 167 | − value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr); | |
| 167 | + value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr); | |
| 168 | 168 | WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, |
| 169 | 169 | (u32)(value >> 12)); |
| 170 | 170 | WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, |
| @@ -188,7 +188,7 @@ static void mmhub_v3_0_init_system_aperture_regs(struct amdgpu_device *adev) · 187 unmodified lines | ||
| 188 | 188 | } |
| 189 | 189 | |
| 190 | 190 | /* Set default page address. */ |
| 191 | − value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start + | |
| 191 | + value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start + | |
| 192 | 192 | adev->vm_manager.vram_base_offset; |
| 193 | 193 | WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, |
| 194 | 194 | (u32)(value >> 12)); |
| @@ -188,7 +188,7 @@ static void mmhub_v3_0_1_init_system_aperture_regs(struct amdgpu_device *adev) · 187 unmodified lines | ||
| 188 | 188 | adev->gmc.vram_end >> 18); |
| 189 | 189 | |
| 190 | 190 | /* Set default page address. */ |
| 191 | − value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start + | |
| 191 | + value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start + | |
| 192 | 192 | adev->vm_manager.vram_base_offset; |
| 193 | 193 | WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, |
| 194 | 194 | (u32)(value >> 12)); |
| @@ -181,7 +181,7 @@ static void mmhub_v3_0_2_init_system_aperture_regs(struct amdgpu_device *adev) · 180 unmodified lines | ||
| 181 | 181 | } |
| 182 | 182 | |
| 183 | 183 | /* Set default page address. */ |
| 184 | − value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start + | |
| 184 | + value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start + | |
| 185 | 185 | adev->vm_manager.vram_base_offset; |
| 186 | 186 | WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, |
| 187 | 187 | (u32)(value >> 12)); |
| @@ -136,7 +136,7 @@ static void mmhub_v9_4_init_system_aperture_regs(struct amdgpu_device *adev, · 135 unmodified lines | ||
| 136 | 136 | max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18); |
| 137 | 137 | |
| 138 | 138 | /* Set default page address. */ |
| 139 | − value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr); | |
| 139 | + value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr); | |
| 140 | 140 | WREG32_SOC15_OFFSET( |
| 141 | 141 | MMHUB, 0, |
| 142 | 142 | mmVMSHAREDPF0_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, |
| @@ -404,6 +404,11 @@ static int xgpu_ai_request_init_data(struct amdgpu_device *adev) · 403 unmodified lines | ||
| 404 | 404 | return xgpu_ai_send_access_requests(adev, IDH_REQ_GPU_INIT_DATA); |
| 405 | 405 | } |
| 406 | 406 | |
| 407 | +static void xgpu_ai_ras_poison_handler(struct amdgpu_device *adev) | |
| 408 | +{ | |
| 409 | + xgpu_ai_send_access_requests(adev, IDH_RAS_POISON); | |
| 410 | +} | |
| 411 | + | |
| 407 | 412 | const struct amdgpu_virt_ops xgpu_ai_virt_ops = { |
| 408 | 413 | .req_full_gpu = xgpu_ai_request_full_gpu_access, |
| 409 | 414 | .rel_full_gpu = xgpu_ai_release_full_gpu_access, |
| @@ -411,4 +416,5 @@ const struct amdgpu_virt_ops xgpu_ai_virt_ops = { · 1 unmodified line | ||
| 411 | 416 | .wait_reset = NULL, |
| 412 | 417 | .trans_msg = xgpu_ai_mailbox_trans_msg, |
| 413 | 418 | .req_init_data = xgpu_ai_request_init_data, |
| 419 | + .ras_poison_handler = xgpu_ai_ras_poison_handler, | |
| 414 | 420 | }; |
| @@ -39,6 +39,7 @@ enum idh_request { · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | IDH_LOG_VF_ERROR = 200, |
| 41 | 41 | IDH_READY_TO_RESET = 201, |
| 42 | + IDH_RAS_POISON = 202, | |
| 42 | 43 | }; |
| 43 | 44 | |
| 44 | 45 | enum idh_event { |
| @@ -426,6 +426,11 @@ void xgpu_nv_mailbox_put_irq(struct amdgpu_device *adev) · 425 unmodified lines | ||
| 426 | 426 | amdgpu_irq_put(adev, &adev->virt.rcv_irq, 0); |
| 427 | 427 | } |
| 428 | 428 | |
| 429 | +static void xgpu_nv_ras_poison_handler(struct amdgpu_device *adev) | |
| 430 | +{ | |
| 431 | + xgpu_nv_send_access_requests(adev, IDH_RAS_POISON); | |
| 432 | +} | |
| 433 | + | |
| 429 | 434 | const struct amdgpu_virt_ops xgpu_nv_virt_ops = { |
| 430 | 435 | .req_full_gpu = xgpu_nv_request_full_gpu_access, |
| 431 | 436 | .rel_full_gpu = xgpu_nv_release_full_gpu_access, |
| @@ -433,4 +438,5 @@ const struct amdgpu_virt_ops xgpu_nv_virt_ops = { · 1 unmodified line | ||
| 433 | 438 | .reset_gpu = xgpu_nv_request_reset, |
| 434 | 439 | .wait_reset = NULL, |
| 435 | 440 | .trans_msg = xgpu_nv_mailbox_trans_msg, |
| 441 | + .ras_poison_handler = xgpu_nv_ras_poison_handler, | |
| 436 | 442 | }; |
| @@ -39,6 +39,7 @@ enum idh_request { · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | IDH_LOG_VF_ERROR = 200, |
| 41 | 41 | IDH_READY_TO_RESET = 201, |
| 42 | + IDH_RAS_POISON = 202, | |
| 42 | 43 | }; |
| 43 | 44 | |
| 44 | 45 | enum idh_event { |
| @@ -809,12 +809,6 @@ static int sdma_v5_2_start(struct amdgpu_device *adev) · 808 unmodified lines | ||
| 809 | 809 | msleep(1000); |
| 810 | 810 | } |
| 811 | 811 | |
| 812 | − /* TODO: check whether can submit a doorbell request to raise | |
| 813 | − * a doorbell fence to exit gfxoff. | |
| 814 | − */ | |
| 815 | − if (adev->in_s0ix) | |
| 816 | − amdgpu_gfx_off_ctrl(adev, false); | |
| 817 | − | |
| 818 | 812 | sdma_v5_2_soft_reset(adev); |
| 819 | 813 | /* unhalt the MEs */ |
| 820 | 814 | sdma_v5_2_enable(adev, true); |
| @@ -823,8 +817,6 @@ static int sdma_v5_2_start(struct amdgpu_device *adev) · 2 unmodified lines | ||
| 823 | 817 | |
| 824 | 818 | /* start the gfx rings and rlc compute queues */ |
| 825 | 819 | r = sdma_v5_2_gfx_resume(adev); |
| 826 | − if (adev->in_s0ix) | |
| 827 | − amdgpu_gfx_off_ctrl(adev, true); | |
| 828 | 820 | if (r) |
| 829 | 821 | return r; |
| 830 | 822 | r = sdma_v5_2_rlc_resume(adev); |
| @@ -55,10 +55,10 @@ enum ta_securedisplay_status { · 54 unmodified lines | ||
| 55 | 55 | TA_SECUREDISPLAY_STATUS__MAX = 0x7FFFFFFF,/* Maximum Value for status*/ |
| 56 | 56 | }; |
| 57 | 57 | |
| 58 | −/** @enum ta_securedisplay_max_phy | |
| 58 | +/** @enum ta_securedisplay_phy_ID | |
| 59 | 59 | * Physical ID number to use for reading corresponding DIO Scratch register for ROI |
| 60 | 60 | */ |
| 61 | −enum ta_securedisplay_max_phy { | |
| 61 | +enum ta_securedisplay_phy_ID { | |
| 62 | 62 | TA_SECUREDISPLAY_PHY0 = 0, |
| 63 | 63 | TA_SECUREDISPLAY_PHY1 = 1, |
| 64 | 64 | TA_SECUREDISPLAY_PHY2 = 2, |
| @@ -139,16 +139,16 @@ union ta_securedisplay_cmd_output { · 74 unmodified lines | ||
| 139 | 139 | uint32_t reserved[4]; |
| 140 | 140 | }; |
| 141 | 141 | |
| 142 | −/** @struct securedisplay_cmd | |
| 143 | − * Secure Display Command which is shared buffer memory | |
| 144 | − */ | |
| 145 | −struct securedisplay_cmd { | |
| 146 | − uint32_t cmd_id; /* +0 Bytes Command ID */ | |
| 147 | − enum ta_securedisplay_status status; /* +4 Bytes Status of Secure Display TA */ | |
| 148 | − uint32_t reserved[2]; /* +8 Bytes Reserved */ | |
| 149 | − union ta_securedisplay_cmd_input securedisplay_in_message; /* +16 Bytes Input Buffer */ | |
| 150 | − union ta_securedisplay_cmd_output securedisplay_out_message;/* +32 Bytes Output Buffer */ | |
| 151 | − /**@note Total 48 Bytes */ | |
| 142 | +/** @struct ta_securedisplay_cmd | |
| 143 | +* Secure display command which is shared buffer memory | |
| 144 | +*/ | |
| 145 | +struct ta_securedisplay_cmd { | |
| 146 | + uint32_t cmd_id; /**< +0 Bytes Command ID */ | |
| 147 | + enum ta_securedisplay_status status; /**< +4 Bytes Status code returned by the secure display TA */ | |
| 148 | + uint32_t reserved[2]; /**< +8 Bytes Reserved */ | |
| 149 | + union ta_securedisplay_cmd_input securedisplay_in_message; /**< +16 Bytes Command input buffer */ | |
| 150 | + union ta_securedisplay_cmd_output securedisplay_out_message; /**< +32 Bytes Command output buffer */ | |
| 151 | + /**@note Total 48 Bytes */ | |
| 152 | 152 | }; |
| 153 | 153 | |
| 154 | 154 | #endif //_TA_SECUREDISPLAY_IF_H |
| @@ -340,29 +340,13 @@ static void umc_v8_10_err_cnt_init(struct amdgpu_device *adev) · 339 unmodified lines | ||
| 340 | 340 | } |
| 341 | 341 | } |
| 342 | 342 | |
| 343 | −static uint32_t umc_v8_10_query_ras_poison_mode_per_channel( | |
| 344 | − struct amdgpu_device *adev, | |
| 345 | − uint32_t umc_reg_offset) | |
| 346 | −{ | |
| 347 | − uint32_t ecc_ctrl_addr, ecc_ctrl; | |
| 348 | − | |
| 349 | − ecc_ctrl_addr = | |
| 350 | − SOC15_REG_OFFSET(UMC, 0, regUMCCH0_0_GeccCtrl); | |
| 351 | − ecc_ctrl = RREG32_PCIE((ecc_ctrl_addr + | |
| 352 | − umc_reg_offset) * 4); | |
| 353 | − | |
| 354 | − return REG_GET_FIELD(ecc_ctrl, UMCCH0_0_GeccCtrl, UCFatalEn); | |
| 355 | −} | |
| 356 | − | |
| 357 | 343 | static bool umc_v8_10_query_ras_poison_mode(struct amdgpu_device *adev) |
| 358 | 344 | { |
| 359 | − uint32_t umc_reg_offset = 0; | |
| 360 | − | |
| 361 | − /* Enabling fatal error in umc node0 instance0 channel0 will be | |
| 362 | − * considered as fatal error mode | |
| 345 | + /* | |
| 346 | + * Force return true, because UMCCH0_0_GeccCtrl | |
| 347 | + * is not accessible from host side | |
| 363 | 348 | */ |
| 364 | − umc_reg_offset = get_umc_v8_10_reg_offset(adev, 0, 0, 0); | |
| 365 | − return !umc_v8_10_query_ras_poison_mode_per_channel(adev, umc_reg_offset); | |
| 349 | + return true; | |
| 366 | 350 | } |
| 367 | 351 | |
| 368 | 352 | const struct amdgpu_ras_block_hw_ops umc_v8_10_ras_hw_ops = { |
| @@ -262,23 +262,12 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf) · 261 unmodified lines | ||
| 262 | 262 | f2g = &gfx_v8_kfd2kgd; |
| 263 | 263 | break; |
| 264 | 264 | case CHIP_FIJI: |
| 265 | − gfx_target_version = 80003; | |
| 266 | − f2g = &gfx_v8_kfd2kgd; | |
| 267 | − break; | |
| 268 | 265 | case CHIP_POLARIS10: |
| 269 | 266 | gfx_target_version = 80003; |
| 270 | 267 | f2g = &gfx_v8_kfd2kgd; |
| 271 | 268 | break; |
| 272 | 269 | case CHIP_POLARIS11: |
| 273 | − gfx_target_version = 80003; | |
| 274 | − if (!vf) | |
| 275 | − f2g = &gfx_v8_kfd2kgd; | |
| 276 | − break; | |
| 277 | 270 | case CHIP_POLARIS12: |
| 278 | − gfx_target_version = 80003; | |
| 279 | − if (!vf) | |
| 280 | − f2g = &gfx_v8_kfd2kgd; | |
| 281 | − break; | |
| 282 | 271 | case CHIP_VEGAM: |
| 283 | 272 | gfx_target_version = 80003; |
| 284 | 273 | if (!vf) |
| @@ -801,7 +801,7 @@ static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev, · 800 unmodified lines | ||
| 801 | 801 | |
| 802 | 802 | p2plink->attr.name = "properties"; |
| 803 | 803 | p2plink->attr.mode = KFD_SYSFS_FILE_MODE; |
| 804 | − sysfs_attr_init(&iolink->attr); | |
| 804 | + sysfs_attr_init(&p2plink->attr); | |
| 805 | 805 | ret = sysfs_create_file(p2plink->kobj, &p2plink->attr); |
| 806 | 806 | if (ret < 0) |
| 807 | 807 | return ret; |
| @@ -210,7 +210,7 @@ static void amdgpu_dm_destroy_drm_device(struct amdgpu_display_manager *dm); · 209 unmodified lines | ||
| 210 | 210 | |
| 211 | 211 | static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, |
| 212 | 212 | struct amdgpu_dm_connector *amdgpu_dm_connector, |
| 213 | − uint32_t link_index, | |
| 213 | + u32 link_index, | |
| 214 | 214 | struct amdgpu_encoder *amdgpu_encoder); |
| 215 | 215 | static int amdgpu_dm_encoder_init(struct drm_device *dev, |
| 216 | 216 | struct amdgpu_encoder *aencoder, |
| @@ -262,7 +262,7 @@ static u32 dm_vblank_get_counter(struct amdgpu_device *adev, int crtc) · 45 unmodified lines | ||
| 262 | 262 | static int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc, |
| 263 | 263 | u32 *vbl, u32 *position) |
| 264 | 264 | { |
| 265 | − uint32_t v_blank_start, v_blank_end, h_position, v_position; | |
| 265 | + u32 v_blank_start, v_blank_end, h_position, v_position; | |
| 266 | 266 | |
| 267 | 267 | if ((crtc < 0) || (crtc >= adev->mode_info.num_crtc)) |
| 268 | 268 | return -EINVAL; |
| @@ -361,7 +361,7 @@ static void dm_pflip_high_irq(void *interrupt_params) · 92 unmodified lines | ||
| 361 | 361 | struct amdgpu_device *adev = irq_params->adev; |
| 362 | 362 | unsigned long flags; |
| 363 | 363 | struct drm_pending_vblank_event *e; |
| 364 | − uint32_t vpos, hpos, v_blank_start, v_blank_end; | |
| 364 | + u32 vpos, hpos, v_blank_start, v_blank_end; | |
| 365 | 365 | bool vrr_active; |
| 366 | 366 | |
| 367 | 367 | amdgpu_crtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_PFLIP); |
| @@ -648,7 +648,7 @@ static void dmub_hpd_callback(struct amdgpu_device *adev, · 280 unmodified lines | ||
| 648 | 648 | struct drm_connector *connector; |
| 649 | 649 | struct drm_connector_list_iter iter; |
| 650 | 650 | struct dc_link *link; |
| 651 | − uint8_t link_index = 0; | |
| 651 | + u8 link_index = 0; | |
| 652 | 652 | struct drm_device *dev; |
| 653 | 653 | |
| 654 | 654 | if (adev == NULL) |
| @@ -749,7 +749,7 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params) · 94 unmodified lines | ||
| 749 | 749 | struct amdgpu_device *adev = irq_params->adev; |
| 750 | 750 | struct amdgpu_display_manager *dm = &adev->dm; |
| 751 | 751 | struct dmcub_trace_buf_entry entry = { 0 }; |
| 752 | − uint32_t count = 0; | |
| 752 | + u32 count = 0; | |
| 753 | 753 | struct dmub_hpd_work *dmub_hpd_wrk; |
| 754 | 754 | struct dc_link *plink = NULL; |
| 755 | 755 | |
| @@ -1015,7 +1015,7 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) · 259 unmodified lines | ||
| 1015 | 1015 | struct dmub_srv_hw_params hw_params; |
| 1016 | 1016 | enum dmub_status status; |
| 1017 | 1017 | const unsigned char *fw_inst_const, *fw_bss_data; |
| 1018 | − uint32_t i, fw_inst_const_size, fw_bss_data_size; | |
| 1018 | + u32 i, fw_inst_const_size, fw_bss_data_size; | |
| 1019 | 1019 | bool has_hw_support; |
| 1020 | 1020 | |
| 1021 | 1021 | if (!dmub_srv) |
| @@ -1176,10 +1176,10 @@ static void dm_dmub_hw_resume(struct amdgpu_device *adev) · 154 unmodified lines | ||
| 1176 | 1176 | |
| 1177 | 1177 | static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_addr_space_config *pa_config) |
| 1178 | 1178 | { |
| 1179 | − uint64_t pt_base; | |
| 1180 | − uint32_t logical_addr_low; | |
| 1181 | − uint32_t logical_addr_high; | |
| 1182 | − uint32_t agp_base, agp_bot, agp_top; | |
| 1179 | + u64 pt_base; | |
| 1180 | + u32 logical_addr_low; | |
| 1181 | + u32 logical_addr_high; | |
| 1182 | + u32 agp_base, agp_bot, agp_top; | |
| 1183 | 1183 | PHYSICAL_ADDRESS_LOC page_table_start, page_table_end, page_table_base; |
| 1184 | 1184 | |
| 1185 | 1185 | memset(pa_config, 0, sizeof(*pa_config)); |
| @@ -1642,7 +1642,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 456 unmodified lines | ||
| 1642 | 1642 | } |
| 1643 | 1643 | #endif |
| 1644 | 1644 | #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) |
| 1645 | − adev->dm.crc_rd_wrk = amdgpu_dm_crtc_secure_display_create_work(); | |
| 1645 | + adev->dm.secure_display_ctxs = amdgpu_dm_crtc_secure_display_create_contexts(adev); | |
| 1646 | + if (!adev->dm.secure_display_ctxs) { | |
| 1647 | + DRM_ERROR("amdgpu: failed to initialize secure_display_ctxs.\n"); | |
| 1648 | + } | |
| 1646 | 1649 | #endif |
| 1647 | 1650 | if (dc_is_dmub_outbox_supported(adev->dm.dc)) { |
| 1648 | 1651 | init_completion(&adev->dm.dmub_aux_transfer_done); |
| @@ -1737,10 +1740,15 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev) · 88 unmodified lines | ||
| 1737 | 1740 | amdgpu_dm_destroy_drm_device(&adev->dm); |
| 1738 | 1741 | |
| 1739 | 1742 | #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) |
| 1740 | − if (adev->dm.crc_rd_wrk) { | |
| 1741 | − flush_work(&adev->dm.crc_rd_wrk->notify_ta_work); | |
| 1742 | − kfree(adev->dm.crc_rd_wrk); | |
| 1743 | − adev->dm.crc_rd_wrk = NULL; | |
| 1743 | + if (adev->dm.secure_display_ctxs) { | |
| 1744 | + for (i = 0; i < adev->dm.dc->caps.max_links; i++) { | |
| 1745 | + if (adev->dm.secure_display_ctxs[i].crtc) { | |
| 1746 | + flush_work(&adev->dm.secure_display_ctxs[i].notify_ta_work); | |
| 1747 | + flush_work(&adev->dm.secure_display_ctxs[i].forward_roi_work); | |
| 1748 | + } | |
| 1749 | + } | |
| 1750 | + kfree(adev->dm.secure_display_ctxs); | |
| 1751 | + adev->dm.secure_display_ctxs = NULL; | |
| 1744 | 1752 | } |
| 1745 | 1753 | #endif |
| 1746 | 1754 | #ifdef CONFIG_DRM_AMD_DC_HDCP |
| @@ -2080,7 +2088,9 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) · 333 unmodified lines | ||
| 2080 | 2088 | * TODO: Move this into GART. |
| 2081 | 2089 | */ |
| 2082 | 2090 | r = amdgpu_bo_create_kernel(adev, region_info.fb_size, PAGE_SIZE, |
| 2083 | − AMDGPU_GEM_DOMAIN_VRAM, &adev->dm.dmub_bo, | |
| 2091 | + AMDGPU_GEM_DOMAIN_VRAM | | |
| 2092 | + AMDGPU_GEM_DOMAIN_GTT, | |
| 2093 | + &adev->dm.dmub_bo, | |
| 2084 | 2094 | &adev->dm.dmub_bo_gpu_addr, |
| 2085 | 2095 | &adev->dm.dmub_bo_cpu_addr); |
| 2086 | 2096 | if (r) |
| @@ -2165,6 +2175,8 @@ static int detect_mst_link_for_all_connectors(struct drm_device *dev) · 78 unmodified lines | ||
| 2165 | 2175 | DRM_ERROR("DM_MST: Failed to start MST\n"); |
| 2166 | 2176 | aconnector->dc_link->type = |
| 2167 | 2177 | dc_connection_single; |
| 2178 | + ret = dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx, | |
| 2179 | + aconnector->dc_link); | |
| 2168 | 2180 | break; |
| 2169 | 2181 | } |
| 2170 | 2182 | } |
| @@ -2486,7 +2498,7 @@ struct amdgpu_dm_connector * · 315 unmodified lines | ||
| 2486 | 2498 | amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state, |
| 2487 | 2499 | struct drm_crtc *crtc) |
| 2488 | 2500 | { |
| 2489 | − uint32_t i; | |
| 2501 | + u32 i; | |
| 2490 | 2502 | struct drm_connector_state *new_con_state; |
| 2491 | 2503 | struct drm_connector *connector; |
| 2492 | 2504 | struct drm_crtc *crtc_from_state; |
| @@ -2734,12 +2746,14 @@ static int dm_resume(void *handle) · 241 unmodified lines | ||
| 2734 | 2746 | drm_for_each_connector_iter(connector, &iter) { |
| 2735 | 2747 | aconnector = to_amdgpu_dm_connector(connector); |
| 2736 | 2748 | |
| 2749 | + if (!aconnector->dc_link) | |
| 2750 | + continue; | |
| 2751 | + | |
| 2737 | 2752 | /* |
| 2738 | 2753 | * this is the case when traversing through already created |
| 2739 | 2754 | * MST connectors, should be skipped |
| 2740 | 2755 | */ |
| 2741 | − if (aconnector->dc_link && | |
| 2742 | − aconnector->dc_link->type == dc_connection_mst_branch) | |
| 2756 | + if (aconnector->dc_link->type == dc_connection_mst_branch) | |
| 2743 | 2757 | continue; |
| 2744 | 2758 | |
| 2745 | 2759 | mutex_lock(&aconnector->hpd_lock); |
| @@ -3117,8 +3131,8 @@ static void handle_hpd_irq(void *param) · 371 unmodified lines | ||
| 3117 | 3131 | |
| 3118 | 3132 | static void dm_handle_mst_sideband_msg(struct amdgpu_dm_connector *aconnector) |
| 3119 | 3133 | { |
| 3120 | − uint8_t esi[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = { 0 }; | |
| 3121 | − uint8_t dret; | |
| 3134 | + u8 esi[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = { 0 }; | |
| 3135 | + u8 dret; | |
| 3122 | 3136 | bool new_irq_handled = false; |
| 3123 | 3137 | int dpcd_addr; |
| 3124 | 3138 | int dpcd_bytes_to_read; |
| @@ -3146,7 +3160,7 @@ static void dm_handle_mst_sideband_msg(struct amdgpu_dm_connector *aconnector) · 21 unmodified lines | ||
| 3146 | 3160 | |
| 3147 | 3161 | while (dret == dpcd_bytes_to_read && |
| 3148 | 3162 | process_count < max_process_count) { |
| 3149 | − uint8_t retry; | |
| 3163 | + u8 retry; | |
| 3150 | 3164 | dret = 0; |
| 3151 | 3165 | |
| 3152 | 3166 | process_count++; |
| @@ -3165,7 +3179,7 @@ static void dm_handle_mst_sideband_msg(struct amdgpu_dm_connector *aconnector) · 12 unmodified lines | ||
| 3165 | 3179 | dpcd_bytes_to_read - 1; |
| 3166 | 3180 | |
| 3167 | 3181 | for (retry = 0; retry < 3; retry++) { |
| 3168 | − uint8_t wret; | |
| 3182 | + u8 wret; | |
| 3169 | 3183 | |
| 3170 | 3184 | wret = drm_dp_dpcd_write( |
| 3171 | 3185 | &aconnector->dm_dp_aux.aux, |
| @@ -4179,12 +4193,12 @@ static void amdgpu_set_panel_orientation(struct drm_connector *connector); · 1007 unmodified lines | ||
| 4179 | 4193 | static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) |
| 4180 | 4194 | { |
| 4181 | 4195 | struct amdgpu_display_manager *dm = &adev->dm; |
| 4182 | − int32_t i; | |
| 4196 | + s32 i; | |
| 4183 | 4197 | struct amdgpu_dm_connector *aconnector = NULL; |
| 4184 | 4198 | struct amdgpu_encoder *aencoder = NULL; |
| 4185 | 4199 | struct amdgpu_mode_info *mode_info = &adev->mode_info; |
| 4186 | − uint32_t link_cnt; | |
| 4187 | − int32_t primary_planes; | |
| 4200 | + u32 link_cnt; | |
| 4201 | + s32 primary_planes; | |
| 4188 | 4202 | enum dc_connection_type new_connection_type = dc_connection_none; |
| 4189 | 4203 | const struct dc_plane_cap *plane; |
| 4190 | 4204 | bool psr_feature_enabled = false; |
| @@ -4701,7 +4715,7 @@ fill_plane_color_attributes(const struct drm_plane_state *plane_state, · 510 unmodified lines | ||
| 4701 | 4715 | static int |
| 4702 | 4716 | fill_dc_plane_info_and_addr(struct amdgpu_device *adev, |
| 4703 | 4717 | const struct drm_plane_state *plane_state, |
| 4704 | − const uint64_t tiling_flags, | |
| 4718 | + const u64 tiling_flags, | |
| 4705 | 4719 | struct dc_plane_info *plane_info, |
| 4706 | 4720 | struct dc_plane_address *address, |
| 4707 | 4721 | bool tmz_surface, |
| @@ -4876,7 +4890,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, · 168 unmodified lines | ||
| 4876 | 4890 | |
| 4877 | 4891 | static inline void fill_dc_dirty_rect(struct drm_plane *plane, |
| 4878 | 4892 | struct rect *dirty_rect, int32_t x, |
| 4879 | − int32_t y, int32_t width, int32_t height, | |
| 4893 | + s32 y, s32 width, s32 height, | |
| 4880 | 4894 | int *i, bool ffu) |
| 4881 | 4895 | { |
| 4882 | 4896 | if (*i > DC_MAX_DIRTY_RECTS) |
| @@ -4932,11 +4946,11 @@ static void fill_dc_dirty_rects(struct drm_plane *plane, · 49 unmodified lines | ||
| 4932 | 4946 | { |
| 4933 | 4947 | struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state); |
| 4934 | 4948 | struct rect *dirty_rects = flip_addrs->dirty_rects; |
| 4935 | − uint32_t num_clips; | |
| 4949 | + u32 num_clips; | |
| 4936 | 4950 | struct drm_mode_rect *clips; |
| 4937 | 4951 | bool bb_changed; |
| 4938 | 4952 | bool fb_changed; |
| 4939 | − uint32_t i = 0; | |
| 4953 | + u32 i = 0; | |
| 4940 | 4954 | |
| 4941 | 4955 | /* |
| 4942 | 4956 | * Cursor plane has it's own dirty rect update interface. See |
| @@ -5082,7 +5096,7 @@ static enum dc_color_depth · 139 unmodified lines | ||
| 5082 | 5096 | convert_color_depth_from_display_info(const struct drm_connector *connector, |
| 5083 | 5097 | bool is_y420, int requested_bpc) |
| 5084 | 5098 | { |
| 5085 | − uint8_t bpc; | |
| 5099 | + u8 bpc; | |
| 5086 | 5100 | |
| 5087 | 5101 | if (is_y420) { |
| 5088 | 5102 | bpc = 8; |
| @@ -5626,8 +5640,8 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector, · 537 unmodified lines | ||
| 5626 | 5640 | uint32_t max_dsc_target_bpp_limit_override) |
| 5627 | 5641 | { |
| 5628 | 5642 | const struct dc_link_settings *verified_link_cap = NULL; |
| 5629 | − uint32_t link_bw_in_kbps; | |
| 5630 | − uint32_t edp_min_bpp_x16, edp_max_bpp_x16; | |
| 5643 | + u32 link_bw_in_kbps; | |
| 5644 | + u32 edp_min_bpp_x16, edp_max_bpp_x16; | |
| 5631 | 5645 | struct dc *dc = sink->ctx->dc; |
| 5632 | 5646 | struct dc_dsc_bw_range bw_range = {0}; |
| 5633 | 5647 | struct dc_dsc_config dsc_cfg = {0}; |
| @@ -5684,11 +5698,11 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector, · 50 unmodified lines | ||
| 5684 | 5698 | struct dsc_dec_dpcd_caps *dsc_caps) |
| 5685 | 5699 | { |
| 5686 | 5700 | struct drm_connector *drm_connector = &aconnector->base; |
| 5687 | − uint32_t link_bandwidth_kbps; | |
| 5701 | + u32 link_bandwidth_kbps; | |
| 5688 | 5702 | struct dc *dc = sink->ctx->dc; |
| 5689 | − uint32_t max_supported_bw_in_kbps, timing_bw_in_kbps; | |
| 5690 | − uint32_t dsc_max_supported_bw_in_kbps; | |
| 5691 | − uint32_t max_dsc_target_bpp_limit_override = | |
| 5703 | + u32 max_supported_bw_in_kbps, timing_bw_in_kbps; | |
| 5704 | + u32 dsc_max_supported_bw_in_kbps; | |
| 5705 | + u32 max_dsc_target_bpp_limit_override = | |
| 5692 | 5706 | drm_connector->display_info.max_dsc_bpp; |
| 5693 | 5707 | |
| 5694 | 5708 | link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link, |
| @@ -5835,7 +5849,8 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, · 140 unmodified lines | ||
| 5835 | 5849 | */ |
| 5836 | 5850 | DRM_DEBUG_DRIVER("No preferred mode found\n"); |
| 5837 | 5851 | } else { |
| 5838 | − recalculate_timing = is_freesync_video_mode(&mode, aconnector); | |
| 5852 | + recalculate_timing = amdgpu_freesync_vid_mode && | |
| 5853 | + is_freesync_video_mode(&mode, aconnector); | |
| 5839 | 5854 | if (recalculate_timing) { |
| 5840 | 5855 | freesync_mode = get_highest_refresh_rate_mode(aconnector, false); |
| 5841 | 5856 | drm_mode_copy(&saved_mode, &mode); |
| @@ -6909,7 +6924,7 @@ static uint add_fs_modes(struct amdgpu_dm_connector *aconnector) · 1067 unmodified lines | ||
| 6909 | 6924 | const struct drm_display_mode *m; |
| 6910 | 6925 | struct drm_display_mode *new_mode; |
| 6911 | 6926 | uint i; |
| 6912 | − uint32_t new_modes_count = 0; | |
| 6927 | + u32 new_modes_count = 0; | |
| 6913 | 6928 | |
| 6914 | 6929 | /* Standard FPS values |
| 6915 | 6930 | * |
| @@ -6923,7 +6938,7 @@ static uint add_fs_modes(struct amdgpu_dm_connector *aconnector) · 7 unmodified lines | ||
| 6923 | 6938 | * 60 - Commonly used |
| 6924 | 6939 | * 48,72,96,120 - Multiples of 24 |
| 6925 | 6940 | */ |
| 6926 | − static const uint32_t common_rates[] = { | |
| 6941 | + static const u32 common_rates[] = { | |
| 6927 | 6942 | 23976, 24000, 25000, 29970, 30000, |
| 6928 | 6943 | 48000, 50000, 60000, 72000, 96000, 120000 |
| 6929 | 6944 | }; |
| @@ -6939,8 +6954,8 @@ static uint add_fs_modes(struct amdgpu_dm_connector *aconnector) · 9 unmodified lines | ||
| 6939 | 6954 | return 0; |
| 6940 | 6955 | |
| 6941 | 6956 | for (i = 0; i < ARRAY_SIZE(common_rates); i++) { |
| 6942 | − uint64_t target_vtotal, target_vtotal_diff; | |
| 6943 | − uint64_t num, den; | |
| 6957 | + u64 target_vtotal, target_vtotal_diff; | |
| 6958 | + u64 num, den; | |
| 6944 | 6959 | |
| 6945 | 6960 | if (drm_mode_vrefresh(m) * 1000 < common_rates[i]) |
| 6946 | 6961 | continue; |
| @@ -6986,7 +7001,7 @@ static void amdgpu_dm_connector_add_freesync_modes(struct drm_connector *connect · 39 unmodified lines | ||
| 6986 | 7001 | struct amdgpu_dm_connector *amdgpu_dm_connector = |
| 6987 | 7002 | to_amdgpu_dm_connector(connector); |
| 6988 | 7003 | |
| 6989 | − if (!edid) | |
| 7004 | + if (!(amdgpu_freesync_vid_mode && edid)) | |
| 6990 | 7005 | return; |
| 6991 | 7006 | |
| 6992 | 7007 | if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10) |
| @@ -7182,7 +7197,7 @@ create_i2c(struct ddc_service *ddc_service, · 189 unmodified lines | ||
| 7182 | 7197 | */ |
| 7183 | 7198 | static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, |
| 7184 | 7199 | struct amdgpu_dm_connector *aconnector, |
| 7185 | − uint32_t link_index, | |
| 7200 | + u32 link_index, | |
| 7186 | 7201 | struct amdgpu_encoder *aencoder) |
| 7187 | 7202 | { |
| 7188 | 7203 | int res = 0; |
| @@ -7367,27 +7382,55 @@ is_scaling_state_different(const struct dm_connector_state *dm_state, · 178 unmodified lines | ||
| 7367 | 7382 | } |
| 7368 | 7383 | |
| 7369 | 7384 | #ifdef CONFIG_DRM_AMD_DC_HDCP |
| 7370 | −static bool is_content_protection_different(struct drm_connector_state *state, | |
| 7371 | − const struct drm_connector_state *old_state, | |
| 7372 | − const struct drm_connector *connector, struct hdcp_workqueue *hdcp_w) | |
| 7385 | +static bool is_content_protection_different(struct drm_crtc_state *new_crtc_state, | |
| 7386 | + struct drm_crtc_state *old_crtc_state, | |
| 7387 | + struct drm_connector_state *new_conn_state, | |
| 7388 | + struct drm_connector_state *old_conn_state, | |
| 7389 | + const struct drm_connector *connector, | |
| 7390 | + struct hdcp_workqueue *hdcp_w) | |
| 7373 | 7391 | { |
| 7374 | 7392 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); |
| 7375 | 7393 | struct dm_connector_state *dm_con_state = to_dm_connector_state(connector->state); |
| 7376 | 7394 | |
| 7377 | − /* Handle: Type0/1 change */ | |
| 7378 | − if (old_state->hdcp_content_type != state->hdcp_content_type && | |
| 7379 | − state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { | |
| 7380 | − state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; | |
| 7395 | + pr_debug("[HDCP_DM] connector->index: %x connect_status: %x dpms: %x\n", | |
| 7396 | + connector->index, connector->status, connector->dpms); | |
| 7397 | + pr_debug("[HDCP_DM] state protection old: %x new: %x\n", | |
| 7398 | + old_conn_state->content_protection, new_conn_state->content_protection); | |
| 7399 | + | |
| 7400 | + if (old_crtc_state) | |
| 7401 | + pr_debug("[HDCP_DM] old crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", | |
| 7402 | + old_crtc_state->enable, | |
| 7403 | + old_crtc_state->active, | |
| 7404 | + old_crtc_state->mode_changed, | |
| 7405 | + old_crtc_state->active_changed, | |
| 7406 | + old_crtc_state->connectors_changed); | |
| 7407 | + | |
| 7408 | + if (new_crtc_state) | |
| 7409 | + pr_debug("[HDCP_DM] NEW crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", | |
| 7410 | + new_crtc_state->enable, | |
| 7411 | + new_crtc_state->active, | |
| 7412 | + new_crtc_state->mode_changed, | |
| 7413 | + new_crtc_state->active_changed, | |
| 7414 | + new_crtc_state->connectors_changed); | |
| 7415 | + | |
| 7416 | + /* hdcp content type change */ | |
| 7417 | + if (old_conn_state->hdcp_content_type != new_conn_state->hdcp_content_type && | |
| 7418 | + new_conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { | |
| 7419 | + new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; | |
| 7420 | + pr_debug("[HDCP_DM] Type0/1 change %s :true\n", __func__); | |
| 7381 | 7421 | return true; |
| 7382 | 7422 | } |
| 7383 | 7423 | |
| 7384 | − /* CP is being re enabled, ignore this | |
| 7385 | − * | |
| 7386 | − * Handles: ENABLED -> DESIRED | |
| 7387 | − */ | |
| 7388 | − if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED && | |
| 7389 | − state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) { | |
| 7390 | − state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED; | |
| 7424 | + /* CP is being re enabled, ignore this */ | |
| 7425 | + if (old_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED && | |
| 7426 | + new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) { | |
| 7427 | + if (new_crtc_state && new_crtc_state->mode_changed) { | |
| 7428 | + new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; | |
| 7429 | + pr_debug("[HDCP_DM] ENABLED->DESIRED & mode_changed %s :true\n", __func__); | |
| 7430 | + return true; | |
| 7431 | + }; | |
| 7432 | + new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED; | |
| 7433 | + pr_debug("[HDCP_DM] ENABLED -> DESIRED %s :false\n", __func__); | |
| 7391 | 7434 | return false; |
| 7392 | 7435 | } |
| 7393 | 7436 | |
| @@ -7395,9 +7438,9 @@ static bool is_content_protection_different(struct drm_connector_state *state, · 1 unmodified line | ||
| 7395 | 7438 | * |
| 7396 | 7439 | * Handles: UNDESIRED -> ENABLED |
| 7397 | 7440 | */ |
| 7398 | − if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED && | |
| 7399 | − state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) | |
| 7400 | − state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; | |
| 7441 | + if (old_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED && | |
| 7442 | + new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) | |
| 7443 | + new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; | |
| 7401 | 7444 | |
| 7402 | 7445 | /* Stream removed and re-enabled |
| 7403 | 7446 | * |
| @@ -7407,10 +7450,12 @@ static bool is_content_protection_different(struct drm_connector_state *state, · 3 unmodified lines | ||
| 7407 | 7450 | * |
| 7408 | 7451 | * Handles: DESIRED -> DESIRED (Special case) |
| 7409 | 7452 | */ |
| 7410 | − if (!(old_state->crtc && old_state->crtc->enabled) && | |
| 7411 | − state->crtc && state->crtc->enabled && | |
| 7453 | + if (!(old_conn_state->crtc && old_conn_state->crtc->enabled) && | |
| 7454 | + new_conn_state->crtc && new_conn_state->crtc->enabled && | |
| 7412 | 7455 | connector->state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) { |
| 7413 | 7456 | dm_con_state->update_hdcp = false; |
| 7457 | + pr_debug("[HDCP_DM] DESIRED->DESIRED (Stream removed and re-enabled) %s :true\n", | |
| 7458 | + __func__); | |
| 7414 | 7459 | return true; |
| 7415 | 7460 | } |
| 7416 | 7461 | |
| @@ -7422,35 +7467,42 @@ static bool is_content_protection_different(struct drm_connector_state *state, · 5 unmodified lines | ||
| 7422 | 7467 | * |
| 7423 | 7468 | * Handles: DESIRED -> DESIRED (Special case) |
| 7424 | 7469 | */ |
| 7425 | − if (dm_con_state->update_hdcp && state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED && | |
| 7426 | − connector->dpms == DRM_MODE_DPMS_ON && aconnector->dc_sink != NULL) { | |
| 7470 | + if (dm_con_state->update_hdcp && | |
| 7471 | + new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED && | |
| 7472 | + connector->dpms == DRM_MODE_DPMS_ON && aconnector->dc_sink != NULL) { | |
| 7427 | 7473 | dm_con_state->update_hdcp = false; |
| 7474 | + pr_debug("[HDCP_DM] DESIRED->DESIRED (Hot-plug, headless s3, dpms) %s :true\n", | |
| 7475 | + __func__); | |
| 7428 | 7476 | return true; |
| 7429 | 7477 | } |
| 7430 | 7478 | |
| 7431 | − /* | |
| 7432 | − * Handles: UNDESIRED -> UNDESIRED | |
| 7433 | − * DESIRED -> DESIRED | |
| 7434 | − * ENABLED -> ENABLED | |
| 7435 | − */ | |
| 7436 | − if (old_state->content_protection == state->content_protection) | |
| 7479 | + if (old_conn_state->content_protection == new_conn_state->content_protection) { | |
| 7480 | + if (new_conn_state->content_protection >= DRM_MODE_CONTENT_PROTECTION_DESIRED) { | |
| 7481 | + if (new_crtc_state && new_crtc_state->mode_changed) { | |
| 7482 | + pr_debug("[HDCP_DM] DESIRED->DESIRED or ENABLE->ENABLE mode_change %s :true\n", | |
| 7483 | + __func__); | |
| 7484 | + return true; | |
| 7485 | + }; | |
| 7486 | + pr_debug("[HDCP_DM] DESIRED->DESIRED & ENABLE->ENABLE %s :false\n", | |
| 7487 | + __func__); | |
| 7488 | + return false; | |
| 7489 | + }; | |
| 7490 | + | |
| 7491 | + pr_debug("[HDCP_DM] UNDESIRED->UNDESIRED %s :false\n", __func__); | |
| 7437 | 7492 | return false; |
| 7493 | + } | |
| 7438 | 7494 | |
| 7439 | − /* | |
| 7440 | − * Handles: UNDESIRED -> DESIRED | |
| 7441 | − * DESIRED -> UNDESIRED | |
| 7442 | − * ENABLED -> UNDESIRED | |
| 7443 | − */ | |
| 7444 | − if (state->content_protection != DRM_MODE_CONTENT_PROTECTION_ENABLED) | |
| 7495 | + if (new_conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_ENABLED) { | |
| 7496 | + pr_debug("[HDCP_DM] UNDESIRED->DESIRED or DESIRED->UNDESIRED or ENABLED->UNDESIRED %s :true\n", | |
| 7497 | + __func__); | |
| 7445 | 7498 | return true; |
| 7499 | + } | |
| 7446 | 7500 | |
| 7447 | − /* | |
| 7448 | − * Handles: DESIRED -> ENABLED | |
| 7449 | − */ | |
| 7501 | + pr_debug("[HDCP_DM] DESIRED->ENABLED %s :false\n", __func__); | |
| 7450 | 7502 | return false; |
| 7451 | 7503 | } |
| 7452 | − | |
| 7453 | 7504 | #endif |
| 7505 | + | |
| 7454 | 7506 | static void remove_stream(struct amdgpu_device *adev, |
| 7455 | 7507 | struct amdgpu_crtc *acrtc, |
| 7456 | 7508 | struct dc_stream_state *stream) |
| @@ -7666,8 +7718,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 209 unmodified lines | ||
| 7666 | 7718 | struct drm_crtc *pcrtc, |
| 7667 | 7719 | bool wait_for_vblank) |
| 7668 | 7720 | { |
| 7669 | − uint32_t i; | |
| 7670 | − uint64_t timestamp_ns; | |
| 7721 | + u32 i; | |
| 7722 | + u64 timestamp_ns; | |
| 7671 | 7723 | struct drm_plane *plane; |
| 7672 | 7724 | struct drm_plane_state *old_plane_state, *new_plane_state; |
| 7673 | 7725 | struct amdgpu_crtc *acrtc_attach = to_amdgpu_crtc(pcrtc); |
| @@ -7678,7 +7730,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 4 unmodified lines | ||
| 7678 | 7730 | to_dm_crtc_state(drm_atomic_get_old_crtc_state(state, pcrtc)); |
| 7679 | 7731 | int planes_count = 0, vpos, hpos; |
| 7680 | 7732 | unsigned long flags; |
| 7681 | − uint32_t target_vblank, last_flip_vblank; | |
| 7733 | + u32 target_vblank, last_flip_vblank; | |
| 7682 | 7734 | bool vrr_active = amdgpu_dm_vrr_active(acrtc_state); |
| 7683 | 7735 | bool cursor_update = false; |
| 7684 | 7736 | bool pflip_present = false; |
| @@ -8116,7 +8168,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 431 unmodified lines | ||
| 8116 | 8168 | struct amdgpu_display_manager *dm = &adev->dm; |
| 8117 | 8169 | struct dm_atomic_state *dm_state; |
| 8118 | 8170 | struct dc_state *dc_state = NULL, *dc_state_temp = NULL; |
| 8119 | − uint32_t i, j; | |
| 8171 | + u32 i, j; | |
| 8120 | 8172 | struct drm_crtc *crtc; |
| 8121 | 8173 | struct drm_crtc_state *old_crtc_state, *new_crtc_state; |
| 8122 | 8174 | unsigned long flags; |
| @@ -8290,10 +8342,61 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 167 unmodified lines | ||
| 8290 | 8342 | struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); |
| 8291 | 8343 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); |
| 8292 | 8344 | |
| 8345 | + pr_debug("[HDCP_DM] -------------- i : %x ----------\n", i); | |
| 8346 | + | |
| 8347 | + if (!connector) | |
| 8348 | + continue; | |
| 8349 | + | |
| 8350 | + pr_debug("[HDCP_DM] connector->index: %x connect_status: %x dpms: %x\n", | |
| 8351 | + connector->index, connector->status, connector->dpms); | |
| 8352 | + pr_debug("[HDCP_DM] state protection old: %x new: %x\n", | |
| 8353 | + old_con_state->content_protection, new_con_state->content_protection); | |
| 8354 | + | |
| 8355 | + if (aconnector->dc_sink) { | |
| 8356 | + if (aconnector->dc_sink->sink_signal != SIGNAL_TYPE_VIRTUAL && | |
| 8357 | + aconnector->dc_sink->sink_signal != SIGNAL_TYPE_NONE) { | |
| 8358 | + pr_debug("[HDCP_DM] pipe_ctx dispname=%s\n", | |
| 8359 | + aconnector->dc_sink->edid_caps.display_name); | |
| 8360 | + } | |
| 8361 | + } | |
| 8362 | + | |
| 8293 | 8363 | new_crtc_state = NULL; |
| 8364 | + old_crtc_state = NULL; | |
| 8294 | 8365 | |
| 8295 | − if (acrtc) | |
| 8366 | + if (acrtc) { | |
| 8296 | 8367 | new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base); |
| 8368 | + old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base); | |
| 8369 | + } | |
| 8370 | + | |
| 8371 | + if (old_crtc_state) | |
| 8372 | + pr_debug("old crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", | |
| 8373 | + old_crtc_state->enable, | |
| 8374 | + old_crtc_state->active, | |
| 8375 | + old_crtc_state->mode_changed, | |
| 8376 | + old_crtc_state->active_changed, | |
| 8377 | + old_crtc_state->connectors_changed); | |
| 8378 | + | |
| 8379 | + if (new_crtc_state) | |
| 8380 | + pr_debug("NEW crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", | |
| 8381 | + new_crtc_state->enable, | |
| 8382 | + new_crtc_state->active, | |
| 8383 | + new_crtc_state->mode_changed, | |
| 8384 | + new_crtc_state->active_changed, | |
| 8385 | + new_crtc_state->connectors_changed); | |
| 8386 | + } | |
| 8387 | + | |
| 8388 | + for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) { | |
| 8389 | + struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state); | |
| 8390 | + struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); | |
| 8391 | + struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | |
| 8392 | + | |
| 8393 | + new_crtc_state = NULL; | |
| 8394 | + old_crtc_state = NULL; | |
| 8395 | + | |
| 8396 | + if (acrtc) { | |
| 8397 | + new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base); | |
| 8398 | + old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base); | |
| 8399 | + } | |
| 8297 | 8400 | |
| 8298 | 8401 | dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); |
| 8299 | 8402 | |
| @@ -8305,11 +8408,44 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 5 unmodified lines | ||
| 8305 | 8408 | continue; |
| 8306 | 8409 | } |
| 8307 | 8410 | |
| 8308 | − if (is_content_protection_different(new_con_state, old_con_state, connector, adev->dm.hdcp_workqueue)) | |
| 8411 | + if (is_content_protection_different(new_crtc_state, old_crtc_state, new_con_state, | |
| 8412 | + old_con_state, connector, adev->dm.hdcp_workqueue)) { | |
| 8413 | + /* when display is unplugged from mst hub, connctor will | |
| 8414 | + * be destroyed within dm_dp_mst_connector_destroy. connector | |
| 8415 | + * hdcp perperties, like type, undesired, desired, enabled, | |
| 8416 | + * will be lost. So, save hdcp properties into hdcp_work within | |
| 8417 | + * amdgpu_dm_atomic_commit_tail. if the same display is | |
| 8418 | + * plugged back with same display index, its hdcp properties | |
| 8419 | + * will be retrieved from hdcp_work within dm_dp_mst_get_modes | |
| 8420 | + */ | |
| 8421 | + | |
| 8422 | + bool enable_encryption = false; | |
| 8423 | + | |
| 8424 | + if (new_con_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) | |
| 8425 | + enable_encryption = true; | |
| 8426 | + | |
| 8427 | + if (aconnector->dc_link && aconnector->dc_sink && | |
| 8428 | + aconnector->dc_link->type == dc_connection_mst_branch) { | |
| 8429 | + struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue; | |
| 8430 | + struct hdcp_workqueue *hdcp_w = | |
| 8431 | + &hdcp_work[aconnector->dc_link->link_index]; | |
| 8432 | + | |
| 8433 | + hdcp_w->hdcp_content_type[connector->index] = | |
| 8434 | + new_con_state->hdcp_content_type; | |
| 8435 | + hdcp_w->content_protection[connector->index] = | |
| 8436 | + new_con_state->content_protection; | |
| 8437 | + } | |
| 8438 | + | |
| 8439 | + if (new_crtc_state && new_crtc_state->mode_changed && | |
| 8440 | + new_con_state->content_protection >= DRM_MODE_CONTENT_PROTECTION_DESIRED) | |
| 8441 | + enable_encryption = true; | |
| 8442 | + | |
| 8443 | + DRM_INFO("[HDCP_DM] hdcp_update_display enable_encryption = %x\n", enable_encryption); | |
| 8444 | + | |
| 8309 | 8445 | hdcp_update_display( |
| 8310 | 8446 | adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector, |
| 8311 | − new_con_state->hdcp_content_type, | |
| 8312 | − new_con_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED); | |
| 8447 | + new_con_state->hdcp_content_type, enable_encryption); | |
| 8448 | + } | |
| 8313 | 8449 | } |
| 8314 | 8450 | #endif |
| 8315 | 8451 | |
| @@ -8407,9 +8543,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 91 unmodified lines | ||
| 8407 | 8543 | struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); |
| 8408 | 8544 | #ifdef CONFIG_DEBUG_FS |
| 8409 | 8545 | enum amdgpu_dm_pipe_crc_source cur_crc_src; |
| 8410 | −#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) | |
| 8411 | − struct crc_rd_work *crc_rd_wrk; | |
| 8412 | −#endif | |
| 8413 | 8546 | #endif |
| 8414 | 8547 | /* Count number of newly disabled CRTCs for dropping PM refs later. */ |
| 8415 | 8548 | if (old_crtc_state->active && !new_crtc_state->active) |
| @@ -8422,9 +8555,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 6 unmodified lines | ||
| 8422 | 8555 | update_stream_irq_parameters(dm, dm_new_crtc_state); |
| 8423 | 8556 | |
| 8424 | 8557 | #ifdef CONFIG_DEBUG_FS |
| 8425 | −#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) | |
| 8426 | − crc_rd_wrk = dm->crc_rd_wrk; | |
| 8427 | −#endif | |
| 8428 | 8558 | spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); |
| 8429 | 8559 | cur_crc_src = acrtc->dm_irq_params.crc_src; |
| 8430 | 8560 | spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); |
| @@ -8453,10 +8583,12 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 22 unmodified lines | ||
| 8453 | 8583 | if (amdgpu_dm_crc_window_is_activated(crtc)) { |
| 8454 | 8584 | spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); |
| 8455 | 8585 | acrtc->dm_irq_params.window_param.update_win = true; |
| 8586 | + | |
| 8587 | + /** | |
| 8588 | + * It takes 2 frames for HW to stably generate CRC when | |
| 8589 | + * resuming from suspend, so we set skip_frame_cnt 2. | |
| 8590 | + */ | |
| 8456 | 8591 | acrtc->dm_irq_params.window_param.skip_frame_cnt = 2; |
| 8457 | − spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock); | |
| 8458 | − crc_rd_wrk->crtc = crtc; | |
| 8459 | − spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock); | |
| 8460 | 8592 | spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); |
| 8461 | 8593 | } |
| 8462 | 8594 | #endif |
| @@ -8679,15 +8811,22 @@ static void get_freesync_config_for_crtc( · 216 unmodified lines | ||
| 8679 | 8811 | struct drm_display_mode *mode = &new_crtc_state->base.mode; |
| 8680 | 8812 | int vrefresh = drm_mode_vrefresh(mode); |
| 8681 | 8813 | bool fs_vid_mode = false; |
| 8814 | + bool drr_active = false; | |
| 8682 | 8815 | |
| 8683 | 8816 | new_crtc_state->vrr_supported = new_con_state->freesync_capable && |
| 8684 | 8817 | vrefresh >= aconnector->min_vfreq && |
| 8685 | 8818 | vrefresh <= aconnector->max_vfreq; |
| 8686 | 8819 | |
| 8687 | − if (new_crtc_state->vrr_supported) { | |
| 8820 | + drr_active = new_crtc_state->vrr_supported && | |
| 8821 | + new_crtc_state->freesync_config.state != VRR_STATE_DISABLED && | |
| 8822 | + new_crtc_state->freesync_config.state != VRR_STATE_INACTIVE && | |
| 8823 | + new_crtc_state->freesync_config.state != VRR_STATE_UNSUPPORTED; | |
| 8824 | + | |
| 8825 | + if (drr_active) | |
| 8688 | 8826 | new_crtc_state->stream->ignore_msa_timing_param = true; |
| 8689 | − fs_vid_mode = new_crtc_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED; | |
| 8690 | 8827 | |
| 8828 | + if (new_crtc_state->vrr_supported) { | |
| 8829 | + fs_vid_mode = new_crtc_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED; | |
| 8691 | 8830 | config.min_refresh_in_uhz = aconnector->min_vfreq * 1000000; |
| 8692 | 8831 | config.max_refresh_in_uhz = aconnector->max_vfreq * 1000000; |
| 8693 | 8832 | config.vsif_supported = true; |
| @@ -8747,7 +8886,7 @@ is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state, · 53 unmodified lines | ||
| 8747 | 8886 | } |
| 8748 | 8887 | |
| 8749 | 8888 | static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state) { |
| 8750 | − uint64_t num, den, res; | |
| 8889 | + u64 num, den, res; | |
| 8751 | 8890 | struct drm_crtc_state *new_crtc_state = &dm_new_crtc_state->base; |
| 8752 | 8891 | |
| 8753 | 8892 | dm_new_crtc_state->freesync_config.state = VRR_STATE_ACTIVE_FIXED; |
| @@ -8850,7 +8989,8 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, · 96 unmodified lines | ||
| 8850 | 8989 | * TODO: Refactor this function to allow this check to work |
| 8851 | 8990 | * in all conditions. |
| 8852 | 8991 | */ |
| 8853 | − if (dm_new_crtc_state->stream && | |
| 8992 | + if (amdgpu_freesync_vid_mode && | |
| 8993 | + dm_new_crtc_state->stream && | |
| 8854 | 8994 | is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state)) |
| 8855 | 8995 | goto skip_modeset; |
| 8856 | 8996 | |
| @@ -8885,7 +9025,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, · 28 unmodified lines | ||
| 8885 | 9025 | if (!dm_old_crtc_state->stream) |
| 8886 | 9026 | goto skip_modeset; |
| 8887 | 9027 | |
| 8888 | − if (dm_new_crtc_state->stream && | |
| 9028 | + if (amdgpu_freesync_vid_mode && dm_new_crtc_state->stream && | |
| 8889 | 9029 | is_timing_unchanged_for_freesync(new_crtc_state, |
| 8890 | 9030 | old_crtc_state)) { |
| 8891 | 9031 | new_crtc_state->mode_changed = false; |
| @@ -8897,7 +9037,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, · 5 unmodified lines | ||
| 8897 | 9037 | set_freesync_fixed_config(dm_new_crtc_state); |
| 8898 | 9038 | |
| 8899 | 9039 | goto skip_modeset; |
| 8900 | − } else if (aconnector && | |
| 9040 | + } else if (amdgpu_freesync_vid_mode && aconnector && | |
| 8901 | 9041 | is_freesync_video_mode(&new_crtc_state->mode, |
| 8902 | 9042 | aconnector)) { |
| 8903 | 9043 | struct drm_display_mode *high_mode; |
| @@ -9883,7 +10023,7 @@ fail: · 979 unmodified lines | ||
| 9883 | 10023 | static bool is_dp_capable_without_timing_msa(struct dc *dc, |
| 9884 | 10024 | struct amdgpu_dm_connector *amdgpu_dm_connector) |
| 9885 | 10025 | { |
| 9886 | − uint8_t dpcd_data; | |
| 10026 | + u8 dpcd_data; | |
| 9887 | 10027 | bool capable = false; |
| 9888 | 10028 | |
| 9889 | 10029 | if (amdgpu_dm_connector->dc_link && |
| @@ -9902,7 +10042,7 @@ static bool is_dp_capable_without_timing_msa(struct dc *dc, · 12 unmodified lines | ||
| 9902 | 10042 | static bool dm_edid_parser_send_cea(struct amdgpu_display_manager *dm, |
| 9903 | 10043 | unsigned int offset, |
| 9904 | 10044 | unsigned int total_length, |
| 9905 | − uint8_t *data, | |
| 10045 | + u8 *data, | |
| 9906 | 10046 | unsigned int length, |
| 9907 | 10047 | struct amdgpu_hdmi_vsdb_info *vsdb) |
| 9908 | 10048 | { |
| @@ -9957,7 +10097,7 @@ static bool dm_edid_parser_send_cea(struct amdgpu_display_manager *dm, · 48 unmodified lines | ||
| 9957 | 10097 | } |
| 9958 | 10098 | |
| 9959 | 10099 | static bool parse_edid_cea_dmcu(struct amdgpu_display_manager *dm, |
| 9960 | − uint8_t *edid_ext, int len, | |
| 10100 | + u8 *edid_ext, int len, | |
| 9961 | 10101 | struct amdgpu_hdmi_vsdb_info *vsdb_info) |
| 9962 | 10102 | { |
| 9963 | 10103 | int i; |
| @@ -9998,7 +10138,7 @@ static bool parse_edid_cea_dmcu(struct amdgpu_display_manager *dm, · 34 unmodified lines | ||
| 9998 | 10138 | } |
| 9999 | 10139 | |
| 10000 | 10140 | static bool parse_edid_cea_dmub(struct amdgpu_display_manager *dm, |
| 10001 | − uint8_t *edid_ext, int len, | |
| 10141 | + u8 *edid_ext, int len, | |
| 10002 | 10142 | struct amdgpu_hdmi_vsdb_info *vsdb_info) |
| 10003 | 10143 | { |
| 10004 | 10144 | int i; |
| @@ -10014,7 +10154,7 @@ static bool parse_edid_cea_dmub(struct amdgpu_display_manager *dm, · 9 unmodified lines | ||
| 10014 | 10154 | } |
| 10015 | 10155 | |
| 10016 | 10156 | static bool parse_edid_cea(struct amdgpu_dm_connector *aconnector, |
| 10017 | − uint8_t *edid_ext, int len, | |
| 10157 | + u8 *edid_ext, int len, | |
| 10018 | 10158 | struct amdgpu_hdmi_vsdb_info *vsdb_info) |
| 10019 | 10159 | { |
| 10020 | 10160 | struct amdgpu_device *adev = drm_to_adev(aconnector->base.dev); |
| @@ -10028,7 +10168,7 @@ static bool parse_edid_cea(struct amdgpu_dm_connector *aconnector, · 7 unmodified lines | ||
| 10028 | 10168 | static int parse_hdmi_amd_vsdb(struct amdgpu_dm_connector *aconnector, |
| 10029 | 10169 | struct edid *edid, struct amdgpu_hdmi_vsdb_info *vsdb_info) |
| 10030 | 10170 | { |
| 10031 | − uint8_t *edid_ext = NULL; | |
| 10171 | + u8 *edid_ext = NULL; | |
| 10032 | 10172 | int i; |
| 10033 | 10173 | bool valid_vsdb_found = false; |
| 10034 | 10174 | |
| @@ -10204,7 +10344,7 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev) · 169 unmodified lines | ||
| 10204 | 10344 | } |
| 10205 | 10345 | |
| 10206 | 10346 | void dm_write_reg_func(const struct dc_context *ctx, uint32_t address, |
| 10207 | − uint32_t value, const char *func_name) | |
| 10347 | + u32 value, const char *func_name) | |
| 10208 | 10348 | { |
| 10209 | 10349 | #ifdef DM_CHECK_ADDR_0 |
| 10210 | 10350 | if (address == 0) { |
| @@ -10219,7 +10359,7 @@ void dm_write_reg_func(const struct dc_context *ctx, uint32_t address, · 8 unmodified lines | ||
| 10219 | 10359 | uint32_t dm_read_reg_func(const struct dc_context *ctx, uint32_t address, |
| 10220 | 10360 | const char *func_name) |
| 10221 | 10361 | { |
| 10222 | − uint32_t value; | |
| 10362 | + u32 value; | |
| 10223 | 10363 | #ifdef DM_CHECK_ADDR_0 |
| 10224 | 10364 | if (address == 0) { |
| 10225 | 10365 | DC_ERR("invalid register read; address = 0\n"); |
| @@ -494,11 +494,12 @@ struct amdgpu_display_manager { · 493 unmodified lines | ||
| 494 | 494 | |
| 495 | 495 | #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) |
| 496 | 496 | /** |
| 497 | − * @crc_rd_wrk: | |
| 497 | + * @secure_display_ctxs: | |
| 498 | 498 | * |
| 499 | − * Work to be executed in a separate thread to communicate with PSP. | |
| 499 | + * Store the ROI information and the work_struct to command dmub and psp for | |
| 500 | + * all crtcs. | |
| 500 | 501 | */ |
| 501 | − struct crc_rd_work *crc_rd_wrk; | |
| 502 | + struct secure_display_context *secure_display_ctxs; | |
| 502 | 503 | #endif |
| 503 | 504 | /** |
| 504 | 505 | * @hpd_rx_offload_wq: |
| @@ -101,35 +101,44 @@ static void amdgpu_dm_set_crc_window_default(struct drm_crtc *crtc) · 100 unmodified lines | ||
| 101 | 101 | |
| 102 | 102 | static void amdgpu_dm_crtc_notify_ta_to_read(struct work_struct *work) |
| 103 | 103 | { |
| 104 | − struct crc_rd_work *crc_rd_wrk; | |
| 105 | − struct amdgpu_device *adev; | |
| 104 | + struct secure_display_context *secure_display_ctx; | |
| 106 | 105 | struct psp_context *psp; |
| 107 | − struct securedisplay_cmd *securedisplay_cmd; | |
| 106 | + struct ta_securedisplay_cmd *securedisplay_cmd; | |
| 108 | 107 | struct drm_crtc *crtc; |
| 109 | − uint8_t phy_id; | |
| 108 | + struct dc_stream_state *stream; | |
| 109 | + uint8_t phy_inst; | |
| 110 | 110 | int ret; |
| 111 | 111 | |
| 112 | − crc_rd_wrk = container_of(work, struct crc_rd_work, notify_ta_work); | |
| 113 | − spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock); | |
| 114 | − crtc = crc_rd_wrk->crtc; | |
| 112 | + secure_display_ctx = container_of(work, struct secure_display_context, notify_ta_work); | |
| 113 | + crtc = secure_display_ctx->crtc; | |
| 115 | 114 | |
| 116 | 115 | if (!crtc) { |
| 117 | − spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock); | |
| 118 | 116 | return; |
| 119 | 117 | } |
| 120 | 118 | |
| 121 | − adev = drm_to_adev(crtc->dev); | |
| 122 | − psp = &adev->psp; | |
| 123 | − phy_id = crc_rd_wrk->phy_inst; | |
| 124 | − spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock); | |
| 119 | + psp = &drm_to_adev(crtc->dev)->psp; | |
| 120 | + | |
| 121 | + if (!psp->securedisplay_context.context.initialized) { | |
| 122 | + DRM_DEBUG_DRIVER("Secure Display fails to notify PSP TA\n"); | |
| 123 | + return; | |
| 124 | + } | |
| 125 | + | |
| 126 | + stream = to_amdgpu_crtc(crtc)->dm_irq_params.stream; | |
| 127 | + phy_inst = stream->link->link_enc_hw_inst; | |
| 125 | 128 | |
| 129 | + /* need lock for multiple crtcs to use the command buffer */ | |
| 126 | 130 | mutex_lock(&psp->securedisplay_context.mutex); |
| 127 | 131 | |
| 128 | 132 | psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd, |
| 129 | 133 | TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC); |
| 130 | − securedisplay_cmd->securedisplay_in_message.send_roi_crc.phy_id = | |
| 131 | − phy_id; | |
| 134 | + | |
| 135 | + securedisplay_cmd->securedisplay_in_message.send_roi_crc.phy_id = phy_inst; | |
| 136 | + | |
| 137 | + /* PSP TA is expected to finish data transmission over I2C within current frame, | |
| 138 | + * even there are up to 4 crtcs request to send in this frame. | |
| 139 | + */ | |
| 132 | 140 | ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC); |
| 141 | + | |
| 133 | 142 | if (!ret) { |
| 134 | 143 | if (securedisplay_cmd->status != TA_SECUREDISPLAY_STATUS__SUCCESS) { |
| 135 | 144 | psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status); |
| @@ -142,17 +151,23 @@ static void amdgpu_dm_crtc_notify_ta_to_read(struct work_struct *work) · 6 unmodified lines | ||
| 142 | 151 | static void |
| 143 | 152 | amdgpu_dm_forward_crc_window(struct work_struct *work) |
| 144 | 153 | { |
| 145 | − struct crc_fw_work *crc_fw_wrk; | |
| 154 | + struct secure_display_context *secure_display_ctx; | |
| 146 | 155 | struct amdgpu_display_manager *dm; |
| 156 | + struct drm_crtc *crtc; | |
| 157 | + struct dc_stream_state *stream; | |
| 147 | 158 | |
| 148 | − crc_fw_wrk = container_of(work, struct crc_fw_work, forward_roi_work); | |
| 149 | − dm = crc_fw_wrk->dm; | |
| 159 | + secure_display_ctx = container_of(work, struct secure_display_context, forward_roi_work); | |
| 160 | + crtc = secure_display_ctx->crtc; | |
| 161 | + | |
| 162 | + if (!crtc) | |
| 163 | + return; | |
| 164 | + | |
| 165 | + dm = &drm_to_adev(crtc->dev)->dm; | |
| 166 | + stream = to_amdgpu_crtc(crtc)->dm_irq_params.stream; | |
| 150 | 167 | |
| 151 | 168 | mutex_lock(&dm->dc_lock); |
| 152 | − dc_stream_forward_crc_window(dm->dc, &crc_fw_wrk->rect, crc_fw_wrk->stream, crc_fw_wrk->is_stop_cmd); | |
| 169 | + dc_stream_forward_crc_window(stream, &secure_display_ctx->rect, false); | |
| 153 | 170 | mutex_unlock(&dm->dc_lock); |
| 154 | − | |
| 155 | − kfree(crc_fw_wrk); | |
| 156 | 171 | } |
| 157 | 172 | |
| 158 | 173 | bool amdgpu_dm_crc_window_is_activated(struct drm_crtc *crtc) |
| @@ -189,6 +204,9 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, · 30 unmodified lines | ||
| 189 | 204 | struct dm_crtc_state *dm_crtc_state, |
| 190 | 205 | enum amdgpu_dm_pipe_crc_source source) |
| 191 | 206 | { |
| 207 | +#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) | |
| 208 | + int i; | |
| 209 | +#endif | |
| 192 | 210 | struct amdgpu_device *adev = drm_to_adev(crtc->dev); |
| 193 | 211 | struct dc_stream_state *stream_state = dm_crtc_state->stream; |
| 194 | 212 | bool enable = amdgpu_dm_is_valid_crc_source(source); |
| @@ -200,21 +218,18 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, · 5 unmodified lines | ||
| 200 | 218 | |
| 201 | 219 | mutex_lock(&adev->dm.dc_lock); |
| 202 | 220 | |
| 203 | − /* Enable CRTC CRC generation if necessary. */ | |
| 221 | + /* Enable or disable CRTC CRC generation */ | |
| 204 | 222 | if (dm_is_crc_source_crtc(source) || source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE) { |
| 205 | 223 | #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) |
| 224 | + /* Disable secure_display if it was enabled */ | |
| 206 | 225 | if (!enable) { |
| 207 | − if (adev->dm.crc_rd_wrk) { | |
| 208 | − flush_work(&adev->dm.crc_rd_wrk->notify_ta_work); | |
| 209 | − spin_lock_irq(&adev->dm.crc_rd_wrk->crc_rd_work_lock); | |
| 210 | − | |
| 211 | − if (adev->dm.crc_rd_wrk->crtc == crtc) { | |
| 226 | + for (i = 0; i < adev->dm.dc->caps.max_links; i++) { | |
| 227 | + if (adev->dm.secure_display_ctxs[i].crtc == crtc) { | |
| 212 | 228 | /* stop ROI update on this crtc */ |
| 213 | − dc_stream_forward_crc_window(stream_state->ctx->dc, | |
| 214 | − NULL, stream_state, true); | |
| 215 | − adev->dm.crc_rd_wrk->crtc = NULL; | |
| 229 | + flush_work(&adev->dm.secure_display_ctxs[i].notify_ta_work); | |
| 230 | + flush_work(&adev->dm.secure_display_ctxs[i].forward_roi_work); | |
| 231 | + dc_stream_forward_crc_window(stream_state, NULL, true); | |
| 216 | 232 | } |
| 217 | − spin_unlock_irq(&adev->dm.crc_rd_wrk->crc_rd_work_lock); | |
| 218 | 233 | } |
| 219 | 234 | } |
| 220 | 235 | #endif |
| @@ -347,6 +362,7 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) · 126 unmodified lines | ||
| 347 | 362 | } |
| 348 | 363 | |
| 349 | 364 | #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) |
| 365 | + /* Reset secure_display when we change crc source from debugfs */ | |
| 350 | 366 | amdgpu_dm_set_crc_window_default(crtc); |
| 351 | 367 | #endif |
| 352 | 368 | |
| @@ -456,14 +472,12 @@ void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc) · 103 unmodified lines | ||
| 456 | 472 | #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) |
| 457 | 473 | void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc) |
| 458 | 474 | { |
| 459 | − struct dc_stream_state *stream_state; | |
| 460 | 475 | struct drm_device *drm_dev = NULL; |
| 461 | 476 | enum amdgpu_dm_pipe_crc_source cur_crc_src; |
| 462 | 477 | struct amdgpu_crtc *acrtc = NULL; |
| 463 | 478 | struct amdgpu_device *adev = NULL; |
| 464 | − struct crc_rd_work *crc_rd_wrk; | |
| 465 | − struct crc_fw_work *crc_fw_wrk; | |
| 466 | − unsigned long flags1, flags2; | |
| 479 | + struct secure_display_context *secure_display_ctx = NULL; | |
| 480 | + unsigned long flags1; | |
| 467 | 481 | |
| 468 | 482 | if (crtc == NULL) |
| 469 | 483 | return; |
| @@ -473,75 +487,74 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc) · 3 unmodified lines | ||
| 473 | 487 | drm_dev = crtc->dev; |
| 474 | 488 | |
| 475 | 489 | spin_lock_irqsave(&drm_dev->event_lock, flags1); |
| 476 | − stream_state = acrtc->dm_irq_params.stream; | |
| 477 | 490 | cur_crc_src = acrtc->dm_irq_params.crc_src; |
| 478 | 491 | |
| 479 | 492 | /* Early return if CRC capture is not enabled. */ |
| 480 | − if (!amdgpu_dm_is_valid_crc_source(cur_crc_src)) | |
| 493 | + if (!amdgpu_dm_is_valid_crc_source(cur_crc_src) || | |
| 494 | + !dm_is_crc_source_crtc(cur_crc_src)) | |
| 481 | 495 | goto cleanup; |
| 482 | 496 | |
| 483 | − if (!dm_is_crc_source_crtc(cur_crc_src)) | |
| 497 | + if (!acrtc->dm_irq_params.window_param.activated) | |
| 484 | 498 | goto cleanup; |
| 485 | 499 | |
| 486 | − if (!acrtc->dm_irq_params.window_param.activated) | |
| 500 | + if (acrtc->dm_irq_params.window_param.skip_frame_cnt) { | |
| 501 | + acrtc->dm_irq_params.window_param.skip_frame_cnt -= 1; | |
| 487 | 502 | goto cleanup; |
| 503 | + } | |
| 488 | 504 | |
| 489 | − if (acrtc->dm_irq_params.window_param.update_win) { | |
| 490 | − if (acrtc->dm_irq_params.window_param.skip_frame_cnt) { | |
| 491 | − acrtc->dm_irq_params.window_param.skip_frame_cnt -= 1; | |
| 492 | − goto cleanup; | |
| 493 | − } | |
| 505 | + secure_display_ctx = &adev->dm.secure_display_ctxs[acrtc->crtc_id]; | |
| 506 | + if (WARN_ON(secure_display_ctx->crtc != crtc)) { | |
| 507 | + /* We have set the crtc when creating secure_display_context, | |
| 508 | + * don't expect it to be changed here. | |
| 509 | + */ | |
| 510 | + secure_display_ctx->crtc = crtc; | |
| 511 | + } | |
| 494 | 512 | |
| 513 | + if (acrtc->dm_irq_params.window_param.update_win) { | |
| 495 | 514 | /* prepare work for dmub to update ROI */ |
| 496 | − crc_fw_wrk = kzalloc(sizeof(*crc_fw_wrk), GFP_ATOMIC); | |
| 497 | − if (!crc_fw_wrk) | |
| 498 | − goto cleanup; | |
| 499 | − | |
| 500 | − INIT_WORK(&crc_fw_wrk->forward_roi_work, amdgpu_dm_forward_crc_window); | |
| 501 | − crc_fw_wrk->dm = &adev->dm; | |
| 502 | − crc_fw_wrk->stream = stream_state; | |
| 503 | − crc_fw_wrk->rect.x = acrtc->dm_irq_params.window_param.x_start; | |
| 504 | − crc_fw_wrk->rect.y = acrtc->dm_irq_params.window_param.y_start; | |
| 505 | − crc_fw_wrk->rect.width = acrtc->dm_irq_params.window_param.x_end - | |
| 515 | + secure_display_ctx->rect.x = acrtc->dm_irq_params.window_param.x_start; | |
| 516 | + secure_display_ctx->rect.y = acrtc->dm_irq_params.window_param.y_start; | |
| 517 | + secure_display_ctx->rect.width = acrtc->dm_irq_params.window_param.x_end - | |
| 506 | 518 | acrtc->dm_irq_params.window_param.x_start; |
| 507 | − crc_fw_wrk->rect.height = acrtc->dm_irq_params.window_param.y_end - | |
| 519 | + secure_display_ctx->rect.height = acrtc->dm_irq_params.window_param.y_end - | |
| 508 | 520 | acrtc->dm_irq_params.window_param.y_start; |
| 509 | − schedule_work(&crc_fw_wrk->forward_roi_work); | |
| 521 | + schedule_work(&secure_display_ctx->forward_roi_work); | |
| 510 | 522 | |
| 511 | 523 | acrtc->dm_irq_params.window_param.update_win = false; |
| 524 | + | |
| 525 | + /* Statically skip 1 frame, because we may need to wait below things | |
| 526 | + * before sending ROI to dmub: | |
| 527 | + * 1. We defer the work by using system workqueue. | |
| 528 | + * 2. We may need to wait for dc_lock before accessing dmub. | |
| 529 | + */ | |
| 512 | 530 | acrtc->dm_irq_params.window_param.skip_frame_cnt = 1; |
| 513 | 531 | |
| 514 | 532 | } else { |
| 515 | − if (acrtc->dm_irq_params.window_param.skip_frame_cnt) { | |
| 516 | − acrtc->dm_irq_params.window_param.skip_frame_cnt -= 1; | |
| 517 | − goto cleanup; | |
| 518 | − } | |
| 519 | − | |
| 520 | − if (adev->dm.crc_rd_wrk) { | |
| 521 | − crc_rd_wrk = adev->dm.crc_rd_wrk; | |
| 522 | − spin_lock_irqsave(&crc_rd_wrk->crc_rd_work_lock, flags2); | |
| 523 | − crc_rd_wrk->phy_inst = stream_state->link->link_enc_hw_inst; | |
| 524 | − spin_unlock_irqrestore(&crc_rd_wrk->crc_rd_work_lock, flags2); | |
| 525 | − schedule_work(&crc_rd_wrk->notify_ta_work); | |
| 526 | − } | |
| 533 | + /* prepare work for psp to read ROI/CRC and send to I2C */ | |
| 534 | + schedule_work(&secure_display_ctx->notify_ta_work); | |
| 527 | 535 | } |
| 528 | 536 | |
| 529 | 537 | cleanup: |
| 530 | 538 | spin_unlock_irqrestore(&drm_dev->event_lock, flags1); |
| 531 | 539 | } |
| 532 | 540 | |
| 533 | −struct crc_rd_work *amdgpu_dm_crtc_secure_display_create_work(void) | |
| 541 | +struct secure_display_context * | |
| 542 | +amdgpu_dm_crtc_secure_display_create_contexts(struct amdgpu_device *adev) | |
| 534 | 543 | { |
| 535 | − struct crc_rd_work *crc_rd_wrk = NULL; | |
| 544 | + struct secure_display_context *secure_display_ctxs = NULL; | |
| 545 | + int i; | |
| 536 | 546 | |
| 537 | − crc_rd_wrk = kzalloc(sizeof(*crc_rd_wrk), GFP_KERNEL); | |
| 547 | + secure_display_ctxs = kcalloc(AMDGPU_MAX_CRTCS, sizeof(struct secure_display_context), GFP_KERNEL); | |
| 538 | 548 | |
| 539 | − if (!crc_rd_wrk) | |
| 549 | + if (!secure_display_ctxs) | |
| 540 | 550 | return NULL; |
| 541 | 551 | |
| 542 | − spin_lock_init(&crc_rd_wrk->crc_rd_work_lock); | |
| 543 | − INIT_WORK(&crc_rd_wrk->notify_ta_work, amdgpu_dm_crtc_notify_ta_to_read); | |
| 552 | + for (i = 0; i < adev->dm.dc->caps.max_links; i++) { | |
| 553 | + INIT_WORK(&secure_display_ctxs[i].forward_roi_work, amdgpu_dm_forward_crc_window); | |
| 554 | + INIT_WORK(&secure_display_ctxs[i].notify_ta_work, amdgpu_dm_crtc_notify_ta_to_read); | |
| 555 | + secure_display_ctxs[i].crtc = &adev->mode_info.crtcs[i]->base; | |
| 556 | + } | |
| 544 | 557 | |
| 545 | − return crc_rd_wrk; | |
| 558 | + return secure_display_ctxs; | |
| 546 | 559 | } |
| 547 | 560 | #endif |
| @@ -45,7 +45,7 @@ struct crc_window_param { · 44 unmodified lines | ||
| 45 | 45 | uint16_t y_start; |
| 46 | 46 | uint16_t x_end; |
| 47 | 47 | uint16_t y_end; |
| 48 | − /* CRC windwo is activated or not*/ | |
| 48 | + /* CRC window is activated or not*/ | |
| 49 | 49 | bool activated; |
| 50 | 50 | /* Update crc window during vertical blank or not */ |
| 51 | 51 | bool update_win; |
| @@ -53,22 +53,17 @@ struct crc_window_param { · 1 unmodified line | ||
| 53 | 53 | int skip_frame_cnt; |
| 54 | 54 | }; |
| 55 | 55 | |
| 56 | −/* read_work for driver to call PSP to read */ | |
| 57 | −struct crc_rd_work { | |
| 56 | +struct secure_display_context { | |
| 57 | + /* work to notify PSP TA*/ | |
| 58 | 58 | struct work_struct notify_ta_work; |
| 59 | − /* To protect crc_rd_work carried fields*/ | |
| 60 | − spinlock_t crc_rd_work_lock; | |
| 61 | − struct drm_crtc *crtc; | |
| 62 | − uint8_t phy_inst; | |
| 63 | −}; | |
| 64 | 59 | |
| 65 | −/* forward_work for driver to forward ROI to dmu */ | |
| 66 | −struct crc_fw_work { | |
| 60 | + /* work to forward ROI to dmcu/dmub */ | |
| 67 | 61 | struct work_struct forward_roi_work; |
| 68 | − struct amdgpu_display_manager *dm; | |
| 69 | − struct dc_stream_state *stream; | |
| 62 | + | |
| 63 | + struct drm_crtc *crtc; | |
| 64 | + | |
| 65 | + /* Region of Interest (ROI) */ | |
| 70 | 66 | struct rect rect; |
| 71 | − bool is_stop_cmd; | |
| 72 | 67 | }; |
| 73 | 68 | #endif |
| 74 | 69 | |
| @@ -100,11 +95,12 @@ void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc); · 25 unmodified lines | ||
| 100 | 95 | #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY |
| 101 | 96 | bool amdgpu_dm_crc_window_is_activated(struct drm_crtc *crtc); |
| 102 | 97 | void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc); |
| 103 | −struct crc_rd_work *amdgpu_dm_crtc_secure_display_create_work(void); | |
| 98 | +struct secure_display_context *amdgpu_dm_crtc_secure_display_create_contexts( | |
| 99 | + struct amdgpu_device *adev); | |
| 104 | 100 | #else |
| 105 | 101 | #define amdgpu_dm_crc_window_is_activated(x) |
| 106 | 102 | #define amdgpu_dm_crtc_handle_crc_window_irq(x) |
| 107 | −#define amdgpu_dm_crtc_secure_display_create_work() | |
| 103 | +#define amdgpu_dm_crtc_secure_display_create_contexts() | |
| 108 | 104 | #endif |
| 109 | 105 | |
| 110 | 106 | #endif /* AMD_DAL_DEV_AMDGPU_DM_AMDGPU_DM_CRC_H_ */ |
| @@ -1375,16 +1375,11 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf, · 1374 unmodified lines | ||
| 1375 | 1375 | |
| 1376 | 1376 | for (i = 0; i < MAX_PIPES; i++) { |
| 1377 | 1377 | pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 1378 | − if (pipe_ctx && pipe_ctx->stream && | |
| 1378 | + if (pipe_ctx->stream && | |
| 1379 | 1379 | pipe_ctx->stream->link == aconnector->dc_link) |
| 1380 | 1380 | break; |
| 1381 | 1381 | } |
| 1382 | 1382 | |
| 1383 | − if (!pipe_ctx) { | |
| 1384 | − kfree(rd_buf); | |
| 1385 | − return -ENXIO; | |
| 1386 | − } | |
| 1387 | − | |
| 1388 | 1383 | dsc = pipe_ctx->stream_res.dsc; |
| 1389 | 1384 | if (dsc) |
| 1390 | 1385 | dsc->funcs->dsc_read_state(dsc, &dsc_state); |
| @@ -1481,12 +1476,12 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf, · 90 unmodified lines | ||
| 1481 | 1476 | |
| 1482 | 1477 | for (i = 0; i < MAX_PIPES; i++) { |
| 1483 | 1478 | pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 1484 | − if (pipe_ctx && pipe_ctx->stream && | |
| 1479 | + if (pipe_ctx->stream && | |
| 1485 | 1480 | pipe_ctx->stream->link == aconnector->dc_link) |
| 1486 | 1481 | break; |
| 1487 | 1482 | } |
| 1488 | 1483 | |
| 1489 | − if (!pipe_ctx || !pipe_ctx->stream) | |
| 1484 | + if (!pipe_ctx->stream) | |
| 1490 | 1485 | goto done; |
| 1491 | 1486 | |
| 1492 | 1487 | // Get CRTC state |
| @@ -1566,16 +1561,11 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf, · 73 unmodified lines | ||
| 1566 | 1561 | |
| 1567 | 1562 | for (i = 0; i < MAX_PIPES; i++) { |
| 1568 | 1563 | pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 1569 | − if (pipe_ctx && pipe_ctx->stream && | |
| 1564 | + if (pipe_ctx->stream && | |
| 1570 | 1565 | pipe_ctx->stream->link == aconnector->dc_link) |
| 1571 | 1566 | break; |
| 1572 | 1567 | } |
| 1573 | 1568 | |
| 1574 | − if (!pipe_ctx) { | |
| 1575 | − kfree(rd_buf); | |
| 1576 | − return -ENXIO; | |
| 1577 | − } | |
| 1578 | − | |
| 1579 | 1569 | dsc = pipe_ctx->stream_res.dsc; |
| 1580 | 1570 | if (dsc) |
| 1581 | 1571 | dsc->funcs->dsc_read_state(dsc, &dsc_state); |
| @@ -1670,12 +1660,12 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf, · 88 unmodified lines | ||
| 1670 | 1660 | |
| 1671 | 1661 | for (i = 0; i < MAX_PIPES; i++) { |
| 1672 | 1662 | pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 1673 | − if (pipe_ctx && pipe_ctx->stream && | |
| 1663 | + if (pipe_ctx->stream && | |
| 1674 | 1664 | pipe_ctx->stream->link == aconnector->dc_link) |
| 1675 | 1665 | break; |
| 1676 | 1666 | } |
| 1677 | 1667 | |
| 1678 | − if (!pipe_ctx || !pipe_ctx->stream) | |
| 1668 | + if (!pipe_ctx->stream) | |
| 1679 | 1669 | goto done; |
| 1680 | 1670 | |
| 1681 | 1671 | // Safely get CRTC state |
| @@ -1755,16 +1745,11 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf, · 73 unmodified lines | ||
| 1755 | 1745 | |
| 1756 | 1746 | for (i = 0; i < MAX_PIPES; i++) { |
| 1757 | 1747 | pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 1758 | − if (pipe_ctx && pipe_ctx->stream && | |
| 1748 | + if (pipe_ctx->stream && | |
| 1759 | 1749 | pipe_ctx->stream->link == aconnector->dc_link) |
| 1760 | 1750 | break; |
| 1761 | 1751 | } |
| 1762 | 1752 | |
| 1763 | − if (!pipe_ctx) { | |
| 1764 | − kfree(rd_buf); | |
| 1765 | − return -ENXIO; | |
| 1766 | − } | |
| 1767 | − | |
| 1768 | 1753 | dsc = pipe_ctx->stream_res.dsc; |
| 1769 | 1754 | if (dsc) |
| 1770 | 1755 | dsc->funcs->dsc_read_state(dsc, &dsc_state); |
| @@ -1859,12 +1844,12 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf, · 88 unmodified lines | ||
| 1859 | 1844 | |
| 1860 | 1845 | for (i = 0; i < MAX_PIPES; i++) { |
| 1861 | 1846 | pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 1862 | − if (pipe_ctx && pipe_ctx->stream && | |
| 1847 | + if (pipe_ctx->stream && | |
| 1863 | 1848 | pipe_ctx->stream->link == aconnector->dc_link) |
| 1864 | 1849 | break; |
| 1865 | 1850 | } |
| 1866 | 1851 | |
| 1867 | − if (!pipe_ctx || !pipe_ctx->stream) | |
| 1852 | + if (!pipe_ctx->stream) | |
| 1868 | 1853 | goto done; |
| 1869 | 1854 | |
| 1870 | 1855 | // Get CRTC state |
| @@ -1940,16 +1925,11 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf, · 69 unmodified lines | ||
| 1940 | 1925 | |
| 1941 | 1926 | for (i = 0; i < MAX_PIPES; i++) { |
| 1942 | 1927 | pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 1943 | − if (pipe_ctx && pipe_ctx->stream && | |
| 1928 | + if (pipe_ctx->stream && | |
| 1944 | 1929 | pipe_ctx->stream->link == aconnector->dc_link) |
| 1945 | 1930 | break; |
| 1946 | 1931 | } |
| 1947 | 1932 | |
| 1948 | − if (!pipe_ctx) { | |
| 1949 | − kfree(rd_buf); | |
| 1950 | − return -ENXIO; | |
| 1951 | − } | |
| 1952 | − | |
| 1953 | 1933 | dsc = pipe_ctx->stream_res.dsc; |
| 1954 | 1934 | if (dsc) |
| 1955 | 1935 | dsc->funcs->dsc_read_state(dsc, &dsc_state); |
| @@ -2041,12 +2021,12 @@ static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *bu · 85 unmodified lines | ||
| 2041 | 2021 | |
| 2042 | 2022 | for (i = 0; i < MAX_PIPES; i++) { |
| 2043 | 2023 | pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 2044 | − if (pipe_ctx && pipe_ctx->stream && | |
| 2024 | + if (pipe_ctx->stream && | |
| 2045 | 2025 | pipe_ctx->stream->link == aconnector->dc_link) |
| 2046 | 2026 | break; |
| 2047 | 2027 | } |
| 2048 | 2028 | |
| 2049 | − if (!pipe_ctx || !pipe_ctx->stream) | |
| 2029 | + if (!pipe_ctx->stream) | |
| 2050 | 2030 | goto done; |
| 2051 | 2031 | |
| 2052 | 2032 | // Get CRTC state |
| @@ -2120,16 +2100,11 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf, · 67 unmodified lines | ||
| 2120 | 2100 | |
| 2121 | 2101 | for (i = 0; i < MAX_PIPES; i++) { |
| 2122 | 2102 | pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 2123 | − if (pipe_ctx && pipe_ctx->stream && | |
| 2103 | + if (pipe_ctx->stream && | |
| 2124 | 2104 | pipe_ctx->stream->link == aconnector->dc_link) |
| 2125 | 2105 | break; |
| 2126 | 2106 | } |
| 2127 | 2107 | |
| 2128 | − if (!pipe_ctx) { | |
| 2129 | − kfree(rd_buf); | |
| 2130 | − return -ENXIO; | |
| 2131 | − } | |
| 2132 | − | |
| 2133 | 2108 | dsc = pipe_ctx->stream_res.dsc; |
| 2134 | 2109 | if (dsc) |
| 2135 | 2110 | dsc->funcs->dsc_read_state(dsc, &dsc_state); |
| @@ -2181,16 +2156,11 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf, · 45 unmodified lines | ||
| 2181 | 2156 | |
| 2182 | 2157 | for (i = 0; i < MAX_PIPES; i++) { |
| 2183 | 2158 | pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 2184 | − if (pipe_ctx && pipe_ctx->stream && | |
| 2159 | + if (pipe_ctx->stream && | |
| 2185 | 2160 | pipe_ctx->stream->link == aconnector->dc_link) |
| 2186 | 2161 | break; |
| 2187 | 2162 | } |
| 2188 | 2163 | |
| 2189 | − if (!pipe_ctx) { | |
| 2190 | − kfree(rd_buf); | |
| 2191 | − return -ENXIO; | |
| 2192 | − } | |
| 2193 | − | |
| 2194 | 2164 | dsc = pipe_ctx->stream_res.dsc; |
| 2195 | 2165 | if (dsc) |
| 2196 | 2166 | dsc->funcs->dsc_read_state(dsc, &dsc_state); |
| @@ -2257,16 +2227,11 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf, · 60 unmodified lines | ||
| 2257 | 2227 | |
| 2258 | 2228 | for (i = 0; i < MAX_PIPES; i++) { |
| 2259 | 2229 | pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 2260 | − if (pipe_ctx && pipe_ctx->stream && | |
| 2230 | + if (pipe_ctx->stream && | |
| 2261 | 2231 | pipe_ctx->stream->link == aconnector->dc_link) |
| 2262 | 2232 | break; |
| 2263 | 2233 | } |
| 2264 | 2234 | |
| 2265 | − if (!pipe_ctx) { | |
| 2266 | − kfree(rd_buf); | |
| 2267 | − return -ENXIO; | |
| 2268 | − } | |
| 2269 | − | |
| 2270 | 2235 | dsc = pipe_ctx->stream_res.dsc; |
| 2271 | 2236 | if (dsc) |
| 2272 | 2237 | dsc->funcs->dsc_read_state(dsc, &dsc_state); |
| @@ -2333,16 +2298,11 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf, · 60 unmodified lines | ||
| 2333 | 2298 | |
| 2334 | 2299 | for (i = 0; i < MAX_PIPES; i++) { |
| 2335 | 2300 | pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 2336 | − if (pipe_ctx && pipe_ctx->stream && | |
| 2301 | + if (pipe_ctx->stream && | |
| 2337 | 2302 | pipe_ctx->stream->link == aconnector->dc_link) |
| 2338 | 2303 | break; |
| 2339 | 2304 | } |
| 2340 | 2305 | |
| 2341 | − if (!pipe_ctx) { | |
| 2342 | − kfree(rd_buf); | |
| 2343 | − return -ENXIO; | |
| 2344 | − } | |
| 2345 | − | |
| 2346 | 2306 | dsc = pipe_ctx->stream_res.dsc; |
| 2347 | 2307 | if (dsc) |
| 2348 | 2308 | dsc->funcs->dsc_read_state(dsc, &dsc_state); |
| @@ -3245,46 +3205,24 @@ DEFINE_DEBUGFS_ATTRIBUTE(crc_win_y_end_fops, crc_win_y_end_get, · 896 unmodified lines | ||
| 3245 | 3205 | */ |
| 3246 | 3206 | static int crc_win_update_set(void *data, u64 val) |
| 3247 | 3207 | { |
| 3248 | − struct drm_crtc *new_crtc = data; | |
| 3249 | − struct drm_crtc *old_crtc = NULL; | |
| 3250 | − struct amdgpu_crtc *new_acrtc, *old_acrtc; | |
| 3251 | − struct amdgpu_device *adev = drm_to_adev(new_crtc->dev); | |
| 3252 | − struct crc_rd_work *crc_rd_wrk = adev->dm.crc_rd_wrk; | |
| 3253 | − | |
| 3254 | − if (!crc_rd_wrk) | |
| 3255 | − return 0; | |
| 3208 | + struct drm_crtc *crtc = data; | |
| 3209 | + struct amdgpu_crtc *acrtc; | |
| 3210 | + struct amdgpu_device *adev = drm_to_adev(crtc->dev); | |
| 3256 | 3211 | |
| 3257 | 3212 | if (val) { |
| 3258 | − new_acrtc = to_amdgpu_crtc(new_crtc); | |
| 3213 | + acrtc = to_amdgpu_crtc(crtc); | |
| 3259 | 3214 | mutex_lock(&adev->dm.dc_lock); |
| 3260 | 3215 | /* PSR may write to OTG CRC window control register, |
| 3261 | 3216 | * so close it before starting secure_display. |
| 3262 | 3217 | */ |
| 3263 | − amdgpu_dm_psr_disable(new_acrtc->dm_irq_params.stream); | |
| 3218 | + amdgpu_dm_psr_disable(acrtc->dm_irq_params.stream); | |
| 3264 | 3219 | |
| 3265 | 3220 | spin_lock_irq(&adev_to_drm(adev)->event_lock); |
| 3266 | − spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock); | |
| 3267 | − if (crc_rd_wrk->crtc) { | |
| 3268 | − old_crtc = crc_rd_wrk->crtc; | |
| 3269 | − old_acrtc = to_amdgpu_crtc(old_crtc); | |
| 3270 | − } | |
| 3271 | 3221 | |
| 3272 | − if (old_crtc && old_crtc != new_crtc) { | |
| 3273 | − old_acrtc->dm_irq_params.window_param.activated = false; | |
| 3274 | − old_acrtc->dm_irq_params.window_param.update_win = false; | |
| 3275 | − old_acrtc->dm_irq_params.window_param.skip_frame_cnt = 0; | |
| 3222 | + acrtc->dm_irq_params.window_param.activated = true; | |
| 3223 | + acrtc->dm_irq_params.window_param.update_win = true; | |
| 3224 | + acrtc->dm_irq_params.window_param.skip_frame_cnt = 0; | |
| 3276 | 3225 | |
| 3277 | − new_acrtc->dm_irq_params.window_param.activated = true; | |
| 3278 | − new_acrtc->dm_irq_params.window_param.update_win = true; | |
| 3279 | − new_acrtc->dm_irq_params.window_param.skip_frame_cnt = 0; | |
| 3280 | − crc_rd_wrk->crtc = new_crtc; | |
| 3281 | − } else { | |
| 3282 | − new_acrtc->dm_irq_params.window_param.activated = true; | |
| 3283 | − new_acrtc->dm_irq_params.window_param.update_win = true; | |
| 3284 | − new_acrtc->dm_irq_params.window_param.skip_frame_cnt = 0; | |
| 3285 | − crc_rd_wrk->crtc = new_crtc; | |
| 3286 | − } | |
| 3287 | − spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock); | |
| 3288 | 3226 | spin_unlock_irq(&adev_to_drm(adev)->event_lock); |
| 3289 | 3227 | mutex_unlock(&adev->dm.dc_lock); |
| 3290 | 3228 | } |
| @@ -52,6 +52,20 @@ struct hdcp_workqueue { · 51 unmodified lines | ||
| 52 | 52 | struct mod_hdcp_link link; |
| 53 | 53 | |
| 54 | 54 | enum mod_hdcp_encryption_status encryption_status; |
| 55 | + | |
| 56 | + /* when display is unplugged from mst hub, connctor will be | |
| 57 | + * destroyed within dm_dp_mst_connector_destroy. connector | |
| 58 | + * hdcp perperties, like type, undesired, desired, enabled, | |
| 59 | + * will be lost. So, save hdcp properties into hdcp_work within | |
| 60 | + * amdgpu_dm_atomic_commit_tail. if the same display is | |
| 61 | + * plugged back with same display index, its hdcp properties | |
| 62 | + * will be retrieved from hdcp_work within dm_dp_mst_get_modes | |
| 63 | + */ | |
| 64 | + /* un-desired, desired, enabled */ | |
| 65 | + unsigned int content_protection[AMDGPU_DM_MAX_DISPLAY_INDEX]; | |
| 66 | + /* hdcp1.x, hdcp2.x */ | |
| 67 | + unsigned int hdcp_content_type[AMDGPU_DM_MAX_DISPLAY_INDEX]; | |
| 68 | + | |
| 55 | 69 | uint8_t max_link; |
| 56 | 70 | |
| 57 | 71 | uint8_t *srm; |
| @@ -32,6 +32,10 @@ · 31 unmodified lines | ||
| 32 | 32 | #include "amdgpu_dm.h" |
| 33 | 33 | #include "amdgpu_dm_mst_types.h" |
| 34 | 34 | |
| 35 | +#ifdef CONFIG_DRM_AMD_DC_HDCP | |
| 36 | +#include "amdgpu_dm_hdcp.h" | |
| 37 | +#endif | |
| 38 | + | |
| 35 | 39 | #include "dc.h" |
| 36 | 40 | #include "dm_helpers.h" |
| 37 | 41 | |
| @@ -344,6 +348,28 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) · 306 unmodified lines | ||
| 344 | 348 | /* dc_link_add_remote_sink returns a new reference */ |
| 345 | 349 | aconnector->dc_sink = dc_sink; |
| 346 | 350 | |
| 351 | + /* when display is unplugged from mst hub, connctor will be | |
| 352 | + * destroyed within dm_dp_mst_connector_destroy. connector | |
| 353 | + * hdcp perperties, like type, undesired, desired, enabled, | |
| 354 | + * will be lost. So, save hdcp properties into hdcp_work within | |
| 355 | + * amdgpu_dm_atomic_commit_tail. if the same display is | |
| 356 | + * plugged back with same display index, its hdcp properties | |
| 357 | + * will be retrieved from hdcp_work within dm_dp_mst_get_modes | |
| 358 | + */ | |
| 359 | +#ifdef CONFIG_DRM_AMD_DC_HDCP | |
| 360 | + if (aconnector->dc_sink && connector->state) { | |
| 361 | + struct drm_device *dev = connector->dev; | |
| 362 | + struct amdgpu_device *adev = drm_to_adev(dev); | |
| 363 | + struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue; | |
| 364 | + struct hdcp_workqueue *hdcp_w = &hdcp_work[aconnector->dc_link->link_index]; | |
| 365 | + | |
| 366 | + connector->state->hdcp_content_type = | |
| 367 | + hdcp_w->hdcp_content_type[connector->index]; | |
| 368 | + connector->state->content_protection = | |
| 369 | + hdcp_w->content_protection[connector->index]; | |
| 370 | + } | |
| 371 | +#endif | |
| 372 | + | |
| 347 | 373 | if (aconnector->dc_sink) { |
| 348 | 374 | amdgpu_dm_update_freesync_caps( |
| 349 | 375 | connector, aconnector->edid); |
| @@ -382,16 +382,18 @@ static void dc_perf_trace_destroy(struct dc_perf_trace **perf_trace) · 381 unmodified lines | ||
| 382 | 382 | } |
| 383 | 383 | |
| 384 | 384 | /** |
| 385 | − * dc_stream_adjust_vmin_vmax: | |
| 385 | + * dc_stream_adjust_vmin_vmax - look up pipe context & update parts of DRR | |
| 386 | + * @dc: dc reference | |
| 387 | + * @stream: Initial dc stream state | |
| 388 | + * @adjust: Updated parameters for vertical_total_min and vertical_total_max | |
| 386 | 389 | * |
| 387 | 390 | * Looks up the pipe context of dc_stream_state and updates the |
| 388 | 391 | * vertical_total_min and vertical_total_max of the DRR, Dynamic Refresh |
| 389 | 392 | * Rate, which is a power-saving feature that targets reducing panel |
| 390 | 393 | * refresh rate while the screen is static |
| 391 | 394 | * |
| 392 | − * @dc: dc reference | |
| 393 | − * @stream: Initial dc stream state | |
| 394 | − * @adjust: Updated parameters for vertical_total_min and vertical_total_max | |
| 395 | + * Return: %true if the pipe context is found and adjusted; | |
| 396 | + * %false if the pipe context is not found. | |
| 395 | 397 | */ |
| 396 | 398 | bool dc_stream_adjust_vmin_vmax(struct dc *dc, |
| 397 | 399 | struct dc_stream_state *stream, |
| @@ -419,14 +421,17 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc, · 21 unmodified lines | ||
| 419 | 421 | } |
| 420 | 422 | |
| 421 | 423 | /** |
| 422 | − * dc_stream_get_last_used_drr_vtotal - dc_stream_get_last_vrr_vtotal | |
| 424 | + * dc_stream_get_last_used_drr_vtotal - Looks up the pipe context of | |
| 425 | + * dc_stream_state and gets the last VTOTAL used by DRR (Dynamic Refresh Rate) | |
| 423 | 426 | * |
| 424 | 427 | * @dc: [in] dc reference |
| 425 | 428 | * @stream: [in] Initial dc stream state |
| 426 | − * @adjust: [in] Updated parameters for vertical_total_min and | |
| 429 | + * @refresh_rate: [in] new refresh_rate | |
| 427 | 430 | * |
| 428 | − * Looks up the pipe context of dc_stream_state and gets the last VTOTAL used | |
| 429 | − * by DRR (Dynamic Refresh Rate) | |
| 431 | + * Return: %true if the pipe context is found and there is an associated | |
| 432 | + * timing_generator for the DC; | |
| 433 | + * %false if the pipe context is not found or there is no | |
| 434 | + * timing_generator for the DC. | |
| 430 | 435 | */ |
| 431 | 436 | bool dc_stream_get_last_used_drr_vtotal(struct dc *dc, |
| 432 | 437 | struct dc_stream_state *stream, |
| @@ -518,14 +523,15 @@ dc_stream_forward_dmcu_crc_window(struct dmcu *dmcu, · 85 unmodified lines | ||
| 518 | 523 | } |
| 519 | 524 | |
| 520 | 525 | bool |
| 521 | −dc_stream_forward_crc_window(struct dc *dc, | |
| 522 | − struct rect *rect, struct dc_stream_state *stream, bool is_stop) | |
| 526 | +dc_stream_forward_crc_window(struct dc_stream_state *stream, | |
| 527 | + struct rect *rect, bool is_stop) | |
| 523 | 528 | { |
| 524 | 529 | struct dmcu *dmcu; |
| 525 | 530 | struct dc_dmub_srv *dmub_srv; |
| 526 | 531 | struct otg_phy_mux mux_mapping; |
| 527 | 532 | struct pipe_ctx *pipe; |
| 528 | 533 | int i; |
| 534 | + struct dc *dc = stream->ctx->dc; | |
| 529 | 535 | |
| 530 | 536 | for (i = 0; i < MAX_PIPES; i++) { |
| 531 | 537 | pipe = &dc->current_state->res_ctx.pipe_ctx[i]; |
| @@ -566,7 +572,10 @@ dc_stream_forward_crc_window(struct dc *dc, · 34 unmodified lines | ||
| 566 | 572 | * once. |
| 567 | 573 | * |
| 568 | 574 | * By default, only CRC0 is configured, and the entire frame is used to |
| 569 | − * calculate the crc. | |
| 575 | + * calculate the CRC. | |
| 576 | + * | |
| 577 | + * Return: %false if the stream is not found or CRC capture is not supported; | |
| 578 | + * %true if the stream has been configured. | |
| 570 | 579 | */ |
| 571 | 580 | bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream, |
| 572 | 581 | struct crc_params *crc_window, bool enable, bool continuous) |
| @@ -635,7 +644,7 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream, · 62 unmodified lines | ||
| 635 | 644 | * dc_stream_configure_crc needs to be called beforehand to enable CRCs. |
| 636 | 645 | * |
| 637 | 646 | * Return: |
| 638 | − * false if stream is not found, or if CRCs are not enabled. | |
| 647 | + * %false if stream is not found, or if CRCs are not enabled. | |
| 639 | 648 | */ |
| 640 | 649 | bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream, |
| 641 | 650 | uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb) |
| @@ -1740,6 +1749,8 @@ void dc_z10_save_init(struct dc *dc) · 1098 unmodified lines | ||
| 1740 | 1749 | * |
| 1741 | 1750 | * Applies given context to the hardware and copy it into current context. |
| 1742 | 1751 | * It's up to the user to release the src context afterwards. |
| 1752 | + * | |
| 1753 | + * Return: an enum dc_status result code for the operation | |
| 1743 | 1754 | */ |
| 1744 | 1755 | static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context) |
| 1745 | 1756 | { |
| @@ -2007,8 +2018,9 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context) · 261 unmodified lines | ||
| 2007 | 2018 | return result == DC_OK; |
| 2008 | 2019 | } |
| 2009 | 2020 | |
| 2010 | − if (!streams_changed(dc, context->streams, context->stream_count)) | |
| 2021 | + if (!streams_changed(dc, context->streams, context->stream_count)) { | |
| 2011 | 2022 | return DC_OK; |
| 2023 | + } | |
| 2012 | 2024 | |
| 2013 | 2025 | DC_LOG_DC("%s: %d streams\n", |
| 2014 | 2026 | __func__, context->stream_count); |
| @@ -3325,6 +3337,7 @@ static void commit_planes_for_stream(struct dc *dc, · 1310 unmodified lines | ||
| 3325 | 3337 | struct pipe_ctx *top_pipe_to_program = NULL; |
| 3326 | 3338 | bool should_lock_all_pipes = (update_type != UPDATE_TYPE_FAST); |
| 3327 | 3339 | bool subvp_prev_use = false; |
| 3340 | + bool subvp_curr_use = false; | |
| 3328 | 3341 | |
| 3329 | 3342 | // Once we apply the new subvp context to hardware it won't be in the |
| 3330 | 3343 | // dc->current_state anymore, so we have to cache it before we apply |
| @@ -3381,6 +3394,15 @@ static void commit_planes_for_stream(struct dc *dc, · 50 unmodified lines | ||
| 3381 | 3394 | break; |
| 3382 | 3395 | } |
| 3383 | 3396 | |
| 3397 | + for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 3398 | + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; | |
| 3399 | + | |
| 3400 | + if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) { | |
| 3401 | + subvp_curr_use = true; | |
| 3402 | + break; | |
| 3403 | + } | |
| 3404 | + } | |
| 3405 | + | |
| 3384 | 3406 | if (stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE) { |
| 3385 | 3407 | struct pipe_ctx *mpcc_pipe; |
| 3386 | 3408 | struct pipe_ctx *odm_pipe; |
| @@ -3652,42 +3674,22 @@ static void commit_planes_for_stream(struct dc *dc, · 265 unmodified lines | ||
| 3652 | 3674 | top_pipe_to_program->stream_res.tg); |
| 3653 | 3675 | } |
| 3654 | 3676 | |
| 3655 | − /* For phantom pipe OTG enable, it has to be done after any previous pipe | |
| 3656 | − * that was in use has already been programmed at gotten its double buffer | |
| 3657 | − * update for "disable". | |
| 3658 | − */ | |
| 3659 | − if (update_type != UPDATE_TYPE_FAST) { | |
| 3660 | − for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 3661 | − struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; | |
| 3662 | − struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; | |
| 3663 | − | |
| 3664 | − /* If an active, non-phantom pipe is being transitioned into a phantom | |
| 3665 | − * pipe, wait for the double buffer update to complete first before we do | |
| 3666 | − * ANY phantom pipe programming. | |
| 3667 | − */ | |
| 3668 | − if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM && | |
| 3669 | − old_pipe->stream && old_pipe->stream->mall_stream_config.type != SUBVP_PHANTOM) { | |
| 3670 | − old_pipe->stream_res.tg->funcs->wait_for_state( | |
| 3671 | − old_pipe->stream_res.tg, | |
| 3672 | − CRTC_STATE_VBLANK); | |
| 3673 | − old_pipe->stream_res.tg->funcs->wait_for_state( | |
| 3674 | − old_pipe->stream_res.tg, | |
| 3675 | − CRTC_STATE_VACTIVE); | |
| 3676 | − } | |
| 3677 | + if (subvp_curr_use) { | |
| 3678 | + /* If enabling subvp or transitioning from subvp->subvp, enable the | |
| 3679 | + * phantom streams before we program front end for the phantom pipes. | |
| 3680 | + */ | |
| 3681 | + if (update_type != UPDATE_TYPE_FAST) { | |
| 3682 | + if (dc->hwss.enable_phantom_streams) | |
| 3683 | + dc->hwss.enable_phantom_streams(dc, context); | |
| 3677 | 3684 | } |
| 3678 | − for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 3679 | − struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; | |
| 3685 | + } | |
| 3680 | 3686 | |
| 3681 | − if ((new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) || | |
| 3682 | − subvp_prev_use) { | |
| 3683 | − // If old context or new context has phantom pipes, apply | |
| 3684 | − // the phantom timings now. We can't change the phantom | |
| 3685 | − // pipe configuration safely without driver acquiring | |
| 3686 | − // the DMCUB lock first. | |
| 3687 | − dc->hwss.apply_ctx_to_hw(dc, context); | |
| 3688 | − break; | |
| 3689 | − } | |
| 3690 | − } | |
| 3687 | + if (subvp_prev_use && !subvp_curr_use) { | |
| 3688 | + /* If disabling subvp, disable phantom streams after front end | |
| 3689 | + * programming has completed (we turn on phantom OTG in order | |
| 3690 | + * to complete the plane disable for phantom pipes). | |
| 3691 | + */ | |
| 3692 | + dc->hwss.apply_ctx_to_hw(dc, context); | |
| 3691 | 3693 | } |
| 3692 | 3694 | |
| 3693 | 3695 | if (update_type != UPDATE_TYPE_FAST) |
| @@ -4704,7 +4706,7 @@ bool dc_enable_dmub_notifications(struct dc *dc) · 1010 unmodified lines | ||
| 4704 | 4706 | /** |
| 4705 | 4707 | * dc_enable_dmub_outbox - Enables DMUB unsolicited notification |
| 4706 | 4708 | * |
| 4707 | − * dc: [in] dc structure | |
| 4709 | + * @dc: [in] dc structure | |
| 4708 | 4710 | * |
| 4709 | 4711 | * Enables DMUB unsolicited notifications to x86 via outbox. |
| 4710 | 4712 | */ |
| @@ -4905,8 +4907,8 @@ enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc, · 194 unmodified lines | ||
| 4905 | 4907 | /** |
| 4906 | 4908 | * dc_process_dmub_dpia_hpd_int_enable - Submits DPIA DPD interruption |
| 4907 | 4909 | * |
| 4908 | − * @dc [in]: dc structure | |
| 4909 | − * @hpd_int_enable [in]: 1 for hpd int enable, 0 to disable | |
| 4910 | + * @dc: [in] dc structure | |
| 4911 | + * @hpd_int_enable: [in] 1 for hpd int enable, 0 to disable | |
| 4910 | 4912 | * |
| 4911 | 4913 | * Submits dpia hpd int enable command to dmub via inbox message |
| 4912 | 4914 | */ |
| @@ -4987,7 +4989,7 @@ void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bo · 74 unmodified lines | ||
| 4987 | 4989 | } |
| 4988 | 4990 | |
| 4989 | 4991 | /** |
| 4990 | − * dc_extended_blank_supported 0 Decide whether extended blank is supported | |
| 4992 | + * dc_extended_blank_supported - Decide whether extended blank is supported | |
| 4991 | 4993 | * |
| 4992 | 4994 | * @dc: [in] Current DC state |
| 4993 | 4995 | * |
| @@ -4996,7 +4998,7 @@ void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bo · 2 unmodified lines | ||
| 4996 | 4998 | * ability to enter z9/z10. |
| 4997 | 4999 | * |
| 4998 | 5000 | * Return: |
| 4999 | − * Indicate whether extended blank is supported (true or false) | |
| 5001 | + * Indicate whether extended blank is supported (%true or %false) | |
| 5000 | 5002 | */ |
| 5001 | 5003 | bool dc_extended_blank_supported(struct dc *dc) |
| 5002 | 5004 | { |
| @@ -1916,12 +1916,6 @@ struct dc_link *link_create(const struct link_init_data *init_params) · 1915 unmodified lines | ||
| 1916 | 1916 | if (false == dc_link_construct(link, init_params)) |
| 1917 | 1917 | goto construct_fail; |
| 1918 | 1918 | |
| 1919 | − /* | |
| 1920 | − * Must use preferred_link_setting, not reported_link_cap or verified_link_cap, | |
| 1921 | − * since struct preferred_link_setting won't be reset after S3. | |
| 1922 | − */ | |
| 1923 | − link->preferred_link_setting.dpcd_source_device_specific_field_support = true; | |
| 1924 | − | |
| 1925 | 1919 | return link; |
| 1926 | 1920 | |
| 1927 | 1921 | construct_fail: |
| @@ -4655,9 +4649,6 @@ void dc_link_set_preferred_training_settings(struct dc *dc, · 2727 unmodified lines | ||
| 4655 | 4649 | |
| 4656 | 4650 | if (link_setting != NULL) { |
| 4657 | 4651 | link->preferred_link_setting = *link_setting; |
| 4658 | − if (dp_get_link_encoding_format(link_setting) == DP_128b_132b_ENCODING) | |
| 4659 | − /* TODO: add dc update for acquiring link res */ | |
| 4660 | − skip_immediate_retrain = true; | |
| 4661 | 4652 | } else { |
| 4662 | 4653 | link->preferred_link_setting.lane_count = LANE_COUNT_UNKNOWN; |
| 4663 | 4654 | link->preferred_link_setting.link_rate = LINK_RATE_UNKNOWN; |
| @@ -82,7 +82,6 @@ struct dp_hdmi_dongle_signature_data { · 81 unmodified lines | ||
| 82 | 82 | #define HDMI_SCDC_STATUS_FLAGS 0x40 |
| 83 | 83 | #define HDMI_SCDC_ERR_DETECT 0x50 |
| 84 | 84 | #define HDMI_SCDC_TEST_CONFIG 0xC0 |
| 85 | −#define HDMI_SCDC_DEVICE_ID 0xD3 | |
| 86 | 85 | |
| 87 | 86 | union hdmi_scdc_update_read_data { |
| 88 | 87 | uint8_t byte[2]; |
| @@ -4094,6 +4094,12 @@ static void dp_test_send_link_training(struct dc_link *link) · 4093 unmodified lines | ||
| 4094 | 4094 | dp_retrain_link_dp_test(link, &link_settings, false); |
| 4095 | 4095 | } |
| 4096 | 4096 | |
| 4097 | +static bool is_dp_phy_sqaure_pattern(enum dp_test_pattern test_pattern) | |
| 4098 | +{ | |
| 4099 | + return (DP_TEST_PATTERN_SQUARE_BEGIN <= test_pattern && | |
| 4100 | + test_pattern <= DP_TEST_PATTERN_SQUARE_END); | |
| 4101 | +} | |
| 4102 | + | |
| 4097 | 4103 | /* TODO Raven hbr2 compliance eye output is unstable |
| 4098 | 4104 | * (toggling on and off) with debugger break |
| 4099 | 4105 | * This caueses intermittent PHY automation failure |
| @@ -4111,6 +4117,8 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) · 11 unmodified lines | ||
| 4111 | 4117 | union lane_adjust dpcd_lane_adjust; |
| 4112 | 4118 | unsigned int lane; |
| 4113 | 4119 | struct link_training_settings link_training_settings; |
| 4120 | + unsigned char no_preshoot = 0; | |
| 4121 | + unsigned char no_deemphasis = 0; | |
| 4114 | 4122 | |
| 4115 | 4123 | dpcd_test_pattern.raw = 0; |
| 4116 | 4124 | memset(dpcd_lane_adjustment, 0, sizeof(dpcd_lane_adjustment)); |
| @@ -4204,8 +4212,21 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) · 87 unmodified lines | ||
| 4204 | 4212 | case PHY_TEST_PATTERN_264BIT_CUSTOM: |
| 4205 | 4213 | test_pattern = DP_TEST_PATTERN_264BIT_CUSTOM; |
| 4206 | 4214 | break; |
| 4207 | − case PHY_TEST_PATTERN_SQUARE_PULSE: | |
| 4208 | − test_pattern = DP_TEST_PATTERN_SQUARE_PULSE; | |
| 4215 | + case PHY_TEST_PATTERN_SQUARE: | |
| 4216 | + test_pattern = DP_TEST_PATTERN_SQUARE; | |
| 4217 | + break; | |
| 4218 | + case PHY_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED: | |
| 4219 | + test_pattern = DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED; | |
| 4220 | + no_preshoot = 1; | |
| 4221 | + break; | |
| 4222 | + case PHY_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED: | |
| 4223 | + test_pattern = DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED; | |
| 4224 | + no_deemphasis = 1; | |
| 4225 | + break; | |
| 4226 | + case PHY_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED: | |
| 4227 | + test_pattern = DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED; | |
| 4228 | + no_preshoot = 1; | |
| 4229 | + no_deemphasis = 1; | |
| 4209 | 4230 | break; |
| 4210 | 4231 | default: |
| 4211 | 4232 | test_pattern = DP_TEST_PATTERN_VIDEO_MODE; |
| @@ -4222,7 +4243,7 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) · 10 unmodified lines | ||
| 4222 | 4243 | test_pattern_size); |
| 4223 | 4244 | } |
| 4224 | 4245 | |
| 4225 | − if (test_pattern == DP_TEST_PATTERN_SQUARE_PULSE) { | |
| 4246 | + if (is_dp_phy_sqaure_pattern(test_pattern)) { | |
| 4226 | 4247 | test_pattern_size = 1; // Square pattern data is 1 byte (DP spec) |
| 4227 | 4248 | core_link_read_dpcd( |
| 4228 | 4249 | link, |
| @@ -4259,8 +4280,10 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) · 30 unmodified lines | ||
| 4259 | 4280 | ((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03); |
| 4260 | 4281 | } else if (dp_get_link_encoding_format(&link->cur_link_settings) == |
| 4261 | 4282 | DP_128b_132b_ENCODING) { |
| 4262 | − link_training_settings.hw_lane_settings[lane].FFE_PRESET.raw = | |
| 4283 | + link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.level = | |
| 4263 | 4284 | dpcd_lane_adjust.tx_ffe.PRESET_VALUE; |
| 4285 | + link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.no_preshoot = no_preshoot; | |
| 4286 | + link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.no_deemphasis = no_deemphasis; | |
| 4264 | 4287 | } |
| 4265 | 4288 | } |
| 4266 | 4289 | |
| @@ -6114,7 +6137,7 @@ bool dc_link_dp_set_test_pattern( · 1847 unmodified lines | ||
| 6114 | 6137 | * MuteAudioEndpoint(pPathMode->pDisplayPath, true); |
| 6115 | 6138 | */ |
| 6116 | 6139 | /* Blank stream */ |
| 6117 | − pipes->stream_res.stream_enc->funcs->dp_blank(link, pipe_ctx->stream_res.stream_enc); | |
| 6140 | + link->dc->hwss.blank_stream(pipe_ctx); | |
| 6118 | 6141 | } |
| 6119 | 6142 | |
| 6120 | 6143 | dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern, |
| @@ -6178,8 +6201,17 @@ bool dc_link_dp_set_test_pattern( · 57 unmodified lines | ||
| 6178 | 6201 | case DP_TEST_PATTERN_264BIT_CUSTOM: |
| 6179 | 6202 | pattern = PHY_TEST_PATTERN_264BIT_CUSTOM; |
| 6180 | 6203 | break; |
| 6181 | − case DP_TEST_PATTERN_SQUARE_PULSE: | |
| 6182 | − pattern = PHY_TEST_PATTERN_SQUARE_PULSE; | |
| 6204 | + case DP_TEST_PATTERN_SQUARE: | |
| 6205 | + pattern = PHY_TEST_PATTERN_SQUARE; | |
| 6206 | + break; | |
| 6207 | + case DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED: | |
| 6208 | + pattern = PHY_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED; | |
| 6209 | + break; | |
| 6210 | + case DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED: | |
| 6211 | + pattern = PHY_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED; | |
| 6212 | + break; | |
| 6213 | + case DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED: | |
| 6214 | + pattern = PHY_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED; | |
| 6183 | 6215 | break; |
| 6184 | 6216 | default: |
| 6185 | 6217 | return false; |
| @@ -6190,14 +6222,12 @@ bool dc_link_dp_set_test_pattern( · 4 unmodified lines | ||
| 6190 | 6222 | return false; |
| 6191 | 6223 | |
| 6192 | 6224 | if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) { |
| 6193 | −#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 6194 | − if (test_pattern == DP_TEST_PATTERN_SQUARE_PULSE) | |
| 6225 | + if (is_dp_phy_sqaure_pattern(test_pattern)) | |
| 6195 | 6226 | core_link_write_dpcd(link, |
| 6196 | 6227 | DP_LINK_SQUARE_PATTERN, |
| 6197 | 6228 | p_custom_pattern, |
| 6198 | 6229 | 1); |
| 6199 | 6230 | |
| 6200 | −#endif | |
| 6201 | 6231 | /* tell receiver that we are sending qualification |
| 6202 | 6232 | * pattern DP 1.2 or later - DP receiver's link quality |
| 6203 | 6233 | * pattern is set using DPCD LINK_QUAL_LANEx_SET |
| @@ -6554,18 +6584,10 @@ void dpcd_set_source_specific_data(struct dc_link *link) · 350 unmodified lines | ||
| 6554 | 6584 | |
| 6555 | 6585 | uint8_t hblank_size = (uint8_t)link->dc->caps.min_horizontal_blanking_period; |
| 6556 | 6586 | |
| 6557 | − if (link->preferred_link_setting.dpcd_source_device_specific_field_support) { | |
| 6558 | − result_write_min_hblank = core_link_write_dpcd(link, | |
| 6559 | − DP_SOURCE_MINIMUM_HBLANK_SUPPORTED, (uint8_t *)(&hblank_size), | |
| 6560 | − sizeof(hblank_size)); | |
| 6561 | − | |
| 6562 | − if (result_write_min_hblank == DC_ERROR_UNEXPECTED) | |
| 6563 | − link->preferred_link_setting.dpcd_source_device_specific_field_support = false; | |
| 6564 | − } else { | |
| 6565 | − DC_LOG_DC("Sink device does not support 00340h DPCD write. Skipping on purpose.\n"); | |
| 6566 | − } | |
| 6587 | + result_write_min_hblank = core_link_write_dpcd(link, | |
| 6588 | + DP_SOURCE_MINIMUM_HBLANK_SUPPORTED, (uint8_t *)(&hblank_size), | |
| 6589 | + sizeof(hblank_size)); | |
| 6567 | 6590 | } |
| 6568 | − | |
| 6569 | 6591 | DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, |
| 6570 | 6592 | WPP_BIT_FLAG_DC_DETECTION_DP_CAPS, |
| 6571 | 6593 | "result=%u link_index=%u enum dce_version=%d DPCD=0x%04X min_hblank=%u branch_dev_id=0x%x branch_dev_name='%c%c%c%c%c%c'", |
| @@ -7254,59 +7276,35 @@ void dp_retrain_link_dp_test(struct dc_link *link, · 682 unmodified lines | ||
| 7254 | 7276 | struct dc_link_settings *link_setting, |
| 7255 | 7277 | bool skip_video_pattern) |
| 7256 | 7278 | { |
| 7257 | − struct pipe_ctx *pipes = | |
| 7258 | − &link->dc->current_state->res_ctx.pipe_ctx[0]; | |
| 7279 | + struct pipe_ctx *pipe; | |
| 7259 | 7280 | unsigned int i; |
| 7260 | − bool do_fallback = false; | |
| 7261 | 7281 | |
| 7282 | + udelay(100); | |
| 7262 | 7283 | |
| 7263 | 7284 | for (i = 0; i < MAX_PIPES; i++) { |
| 7264 | − if (pipes[i].stream != NULL && | |
| 7265 | − !pipes[i].top_pipe && !pipes[i].prev_odm_pipe && | |
| 7266 | − pipes[i].stream->link != NULL && | |
| 7267 | − pipes[i].stream_res.stream_enc != NULL && | |
| 7268 | − pipes[i].stream->link == link) { | |
| 7269 | − udelay(100); | |
| 7270 | − | |
| 7271 | − pipes[i].stream_res.stream_enc->funcs->dp_blank(link, | |
| 7272 | − pipes[i].stream_res.stream_enc); | |
| 7273 | − | |
| 7274 | − /* disable any test pattern that might be active */ | |
| 7275 | − dp_set_hw_test_pattern(link, &pipes[i].link_res, | |
| 7276 | − DP_TEST_PATTERN_VIDEO_MODE, NULL, 0); | |
| 7277 | − | |
| 7278 | − dp_receiver_power_ctrl(link, false); | |
| 7279 | − | |
| 7280 | − link->dc->hwss.disable_stream(&pipes[i]); | |
| 7281 | − if ((&pipes[i])->stream_res.audio && !link->dc->debug.az_endpoint_mute_only) | |
| 7282 | − (&pipes[i])->stream_res.audio->funcs->az_disable((&pipes[i])->stream_res.audio); | |
| 7283 | − | |
| 7284 | − if (link->link_enc) | |
| 7285 | − link->link_enc->funcs->disable_output( | |
| 7286 | − link->link_enc, | |
| 7287 | − SIGNAL_TYPE_DISPLAY_PORT); | |
| 7288 | − | |
| 7289 | − /* Clear current link setting. */ | |
| 7290 | − memset(&link->cur_link_settings, 0, | |
| 7291 | − sizeof(link->cur_link_settings)); | |
| 7292 | − | |
| 7293 | − if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) | |
| 7294 | − do_fallback = true; | |
| 7295 | − | |
| 7296 | − perform_link_training_with_retries( | |
| 7297 | − link_setting, | |
| 7298 | − skip_video_pattern, | |
| 7299 | − LINK_TRAINING_ATTEMPTS, | |
| 7300 | − &pipes[i], | |
| 7301 | − SIGNAL_TYPE_DISPLAY_PORT, | |
| 7302 | − do_fallback); | |
| 7303 | − | |
| 7304 | − link->dc->hwss.enable_stream(&pipes[i]); | |
| 7305 | − | |
| 7306 | − link->dc->hwss.unblank_stream(&pipes[i], | |
| 7307 | − link_setting); | |
| 7285 | + pipe = &link->dc->current_state->res_ctx.pipe_ctx[i]; | |
| 7286 | + if (pipe->stream != NULL && | |
| 7287 | + pipe->stream->link == link && | |
| 7288 | + !pipe->stream->dpms_off && | |
| 7289 | + !pipe->top_pipe && !pipe->prev_odm_pipe) { | |
| 7290 | + core_link_disable_stream(pipe); | |
| 7291 | + pipe->link_config.dp_link_settings = *link_setting; | |
| 7292 | + update_dp_encoder_resources_for_test_harness( | |
| 7293 | + link->dc, | |
| 7294 | + pipe->stream->ctx->dc->current_state, | |
| 7295 | + pipe); | |
| 7296 | + } | |
| 7297 | + } | |
| 7308 | 7298 | |
| 7309 | − link->dc->hwss.enable_audio_stream(&pipes[i]); | |
| 7299 | + for (i = 0; i < MAX_PIPES; i++) { | |
| 7300 | + pipe = &link->dc->current_state->res_ctx.pipe_ctx[i]; | |
| 7301 | + if (pipe->stream != NULL && | |
| 7302 | + pipe->stream->link == link && | |
| 7303 | + !pipe->stream->dpms_off && | |
| 7304 | + !pipe->top_pipe && !pipe->prev_odm_pipe) { | |
| 7305 | + core_link_enable_stream( | |
| 7306 | + pipe->stream->ctx->dc->current_state, | |
| 7307 | + pipe); | |
| 7310 | 7308 | } |
| 7311 | 7309 | } |
| 7312 | 7310 | } |
| @@ -7496,7 +7494,6 @@ bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_u · 183 unmodified lines | ||
| 7496 | 7494 | dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false; |
| 7497 | 7495 | dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg; |
| 7498 | 7496 | |
| 7499 | − DC_LOG_DSC(" "); | |
| 7500 | 7497 | dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]); |
| 7501 | 7498 | memcpy(&stream->dsc_packed_pps[0], &dsc_packed_pps[0], sizeof(stream->dsc_packed_pps)); |
| 7502 | 7499 | if (dc_is_dp_signal(stream->signal)) { |
| @@ -3810,6 +3810,8 @@ void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc, · 3809 unmodified lines | ||
| 3810 | 3810 | int i; |
| 3811 | 3811 | struct pipe_ctx *pipe_ctx, *pipe_ctx_check; |
| 3812 | 3812 | |
| 3813 | + DC_LOGGER_INIT(dc->ctx->logger); | |
| 3814 | + | |
| 3813 | 3815 | pipe_ctx = &context->res_ctx.pipe_ctx[disabled_master_pipe_idx]; |
| 3814 | 3816 | if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx) != disabled_master_pipe_idx) || |
| 3815 | 3817 | !IS_PIPE_SYNCD_VALID(pipe_ctx)) |
| @@ -3820,9 +3822,16 @@ void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc, · 4 unmodified lines | ||
| 3820 | 3822 | pipe_ctx_check = &context->res_ctx.pipe_ctx[i]; |
| 3821 | 3823 | |
| 3822 | 3824 | if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx_check) == disabled_master_pipe_idx) && |
| 3823 | − IS_PIPE_SYNCD_VALID(pipe_ctx_check) && (i != disabled_master_pipe_idx)) | |
| 3824 | − DC_ERR("DC: Failure: pipe_idx[%d] syncd with disabled master pipe_idx[%d]\n", | |
| 3825 | − i, disabled_master_pipe_idx); | |
| 3825 | + IS_PIPE_SYNCD_VALID(pipe_ctx_check) && (i != disabled_master_pipe_idx)) { | |
| 3826 | + /* On dcn32, this error isn't fatal since hw supports odm transition in fast update*/ | |
| 3827 | + if (dc->ctx->dce_version == DCN_VERSION_3_2 || | |
| 3828 | + dc->ctx->dce_version == DCN_VERSION_3_21) | |
| 3829 | + DC_LOG_DEBUG("DC: pipe_idx[%d] syncd with disabled master pipe_idx[%d]\n", | |
| 3830 | + i, disabled_master_pipe_idx); | |
| 3831 | + else | |
| 3832 | + DC_ERR("DC: Failure: pipe_idx[%d] syncd with disabled master pipe_idx[%d]\n", | |
| 3833 | + i, disabled_master_pipe_idx); | |
| 3834 | + } | |
| 3826 | 3835 | } |
| 3827 | 3836 | } |
| 3828 | 3837 | |
| @@ -3981,3 +3990,42 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm( · 152 unmodified lines | ||
| 3981 | 3990 | |
| 3982 | 3991 | return true; |
| 3983 | 3992 | } |
| 3993 | + | |
| 3994 | +enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc, | |
| 3995 | + struct dc_state *context, | |
| 3996 | + struct pipe_ctx *pipe_ctx) | |
| 3997 | +{ | |
| 3998 | + if (dp_get_link_encoding_format(&pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) { | |
| 3999 | + if (pipe_ctx->stream_res.hpo_dp_stream_enc == NULL) { | |
| 4000 | + pipe_ctx->stream_res.hpo_dp_stream_enc = | |
| 4001 | + find_first_free_match_hpo_dp_stream_enc_for_link( | |
| 4002 | + &context->res_ctx, dc->res_pool, pipe_ctx->stream); | |
| 4003 | + | |
| 4004 | + if (!pipe_ctx->stream_res.hpo_dp_stream_enc) | |
| 4005 | + return DC_NO_STREAM_ENC_RESOURCE; | |
| 4006 | + | |
| 4007 | + update_hpo_dp_stream_engine_usage( | |
| 4008 | + &context->res_ctx, dc->res_pool, | |
| 4009 | + pipe_ctx->stream_res.hpo_dp_stream_enc, | |
| 4010 | + true); | |
| 4011 | + } | |
| 4012 | + | |
| 4013 | + if (pipe_ctx->link_res.hpo_dp_link_enc == NULL) { | |
| 4014 | + if (!add_hpo_dp_link_enc_to_ctx(&context->res_ctx, dc->res_pool, pipe_ctx, pipe_ctx->stream)) | |
| 4015 | + return DC_NO_LINK_ENC_RESOURCE; | |
| 4016 | + } | |
| 4017 | + } else { | |
| 4018 | + if (pipe_ctx->stream_res.hpo_dp_stream_enc) { | |
| 4019 | + update_hpo_dp_stream_engine_usage( | |
| 4020 | + &context->res_ctx, dc->res_pool, | |
| 4021 | + pipe_ctx->stream_res.hpo_dp_stream_enc, | |
| 4022 | + false); | |
| 4023 | + pipe_ctx->stream_res.hpo_dp_stream_enc = NULL; | |
| 4024 | + } | |
| 4025 | + if (pipe_ctx->link_res.hpo_dp_link_enc) | |
| 4026 | + remove_hpo_dp_link_enc_from_ctx(&context->res_ctx, pipe_ctx, pipe_ctx->stream); | |
| 4027 | + } | |
| 4028 | + | |
| 4029 | + return DC_OK; | |
| 4030 | +} | |
| 4031 | + | |
| @@ -65,6 +65,7 @@ void dc_stat_get_dmub_notification(const struct dc *dc, struct dmub_notification · 64 unmodified lines | ||
| 65 | 65 | /* For HPD/HPD RX, convert dpia port index into link index */ |
| 66 | 66 | if (notify->type == DMUB_NOTIFICATION_HPD || |
| 67 | 67 | notify->type == DMUB_NOTIFICATION_HPD_IRQ || |
| 68 | + notify->type == DMUB_NOTIFICATION_DPIA_NOTIFICATION || | |
| 68 | 69 | notify->type == DMUB_NOTIFICATION_SET_CONFIG_REPLY) { |
| 69 | 70 | notify->link_index = |
| 70 | 71 | get_link_index_from_dpia_port_index(dc, notify->link_index); |
| @@ -481,6 +481,7 @@ bool dc_stream_add_writeback(struct dc *dc, · 480 unmodified lines | ||
| 481 | 481 | } |
| 482 | 482 | |
| 483 | 483 | if (!isDrc) { |
| 484 | + ASSERT(stream->num_wb_info + 1 <= MAX_DWB_PIPES); | |
| 484 | 485 | stream->writeback_info[stream->num_wb_info++] = *wb_info; |
| 485 | 486 | } |
| 486 | 487 | |
| @@ -526,6 +527,11 @@ bool dc_stream_remove_writeback(struct dc *dc, · 39 unmodified lines | ||
| 526 | 527 | return false; |
| 527 | 528 | } |
| 528 | 529 | |
| 530 | + if (stream->num_wb_info > MAX_DWB_PIPES) { | |
| 531 | + dm_error("DC: num_wb_info is invalid!\n"); | |
| 532 | + return false; | |
| 533 | + } | |
| 534 | + | |
| 529 | 535 | // stream->writeback_info[dwb_pipe_inst].wb_enabled = false; |
| 530 | 536 | for (i = 0; i < stream->num_wb_info; i++) { |
| 531 | 537 | /*dynamic update*/ |
| @@ -540,7 +546,8 @@ bool dc_stream_remove_writeback(struct dc *dc, · 8 unmodified lines | ||
| 540 | 546 | if (stream->writeback_info[i].wb_enabled) { |
| 541 | 547 | if (j < i) |
| 542 | 548 | /* trim the array */ |
| 543 | − stream->writeback_info[j] = stream->writeback_info[i]; | |
| 549 | + memcpy(&stream->writeback_info[j], &stream->writeback_info[i], | |
| 550 | + sizeof(struct dc_writeback_info)); | |
| 544 | 551 | j++; |
| 545 | 552 | } |
| 546 | 553 | } |
| @@ -47,7 +47,7 @@ struct aux_payload; · 46 unmodified lines | ||
| 47 | 47 | struct set_config_cmd_payload; |
| 48 | 48 | struct dmub_notification; |
| 49 | 49 | |
| 50 | −#define DC_VER "3.2.215" | |
| 50 | +#define DC_VER "3.2.217" | |
| 51 | 51 | |
| 52 | 52 | #define MAX_SURFACES 3 |
| 53 | 53 | #define MAX_PLANES 6 |
| @@ -872,6 +872,7 @@ struct dc_debug_options { · 818 unmodified lines | ||
| 872 | 872 | enum lttpr_mode lttpr_mode_override; |
| 873 | 873 | unsigned int dsc_delay_factor_wa_x1000; |
| 874 | 874 | unsigned int min_prefetch_in_strobe_ns; |
| 875 | + bool disable_unbounded_requesting; | |
| 875 | 876 | }; |
| 876 | 877 | |
| 877 | 878 | struct gpu_info_soc_bounding_box_v1_0; |
| @@ -149,7 +149,6 @@ struct dc_link_settings { · 148 unmodified lines | ||
| 149 | 149 | enum dc_link_spread link_spread; |
| 150 | 150 | bool use_link_rate_set; |
| 151 | 151 | uint8_t link_rate_set; |
| 152 | − bool dpcd_source_device_specific_field_support; | |
| 153 | 152 | }; |
| 154 | 153 | |
| 155 | 154 | union dc_dp_ffe_preset { |
| @@ -926,6 +925,9 @@ struct dpcd_usb4_dp_tunneling_info { · 770 unmodified lines | ||
| 926 | 925 | #ifndef DP_128b_132b_TRAINING_AUX_RD_INTERVAL |
| 927 | 926 | #define DP_128b_132b_TRAINING_AUX_RD_INTERVAL 0x2216 |
| 928 | 927 | #endif |
| 928 | +#ifndef DP_LINK_SQUARE_PATTERN | |
| 929 | +#define DP_LINK_SQUARE_PATTERN 0x10F | |
| 930 | +#endif | |
| 929 | 931 | #ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX |
| 930 | 932 | #define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX 0x2217 |
| 931 | 933 | #endif |
| @@ -335,15 +335,18 @@ static inline bool dc_get_edp_link_panel_inst(const struct dc *dc, · 334 unmodified lines | ||
| 335 | 335 | unsigned int *inst_out) |
| 336 | 336 | { |
| 337 | 337 | struct dc_link *edp_links[MAX_NUM_EDP]; |
| 338 | − int edp_num; | |
| 338 | + int edp_num, i; | |
| 339 | 339 | |
| 340 | − if (link->connector_signal != SIGNAL_TYPE_EDP) | |
| 340 | + *inst_out = 0; | |
| 341 | + if (link->connector_signal != SIGNAL_TYPE_EDP || !link->local_sink) | |
| 341 | 342 | return false; |
| 342 | 343 | get_edp_links(dc, edp_links, &edp_num); |
| 343 | − if ((edp_num > 1) && (link->link_index > edp_links[0]->link_index)) | |
| 344 | − *inst_out = 1; | |
| 345 | − else | |
| 346 | − *inst_out = 0; | |
| 344 | + for (i = 0; i < edp_num; i++) { | |
| 345 | + if (link == edp_links[i]) | |
| 346 | + break; | |
| 347 | + if (edp_links[i]->local_sink) | |
| 348 | + (*inst_out)++; | |
| 349 | + } | |
| 347 | 350 | return true; |
| 348 | 351 | } |
| 349 | 352 | |
| @@ -543,9 +543,8 @@ bool dc_stream_get_crtc_position(struct dc *dc, · 542 unmodified lines | ||
| 543 | 543 | unsigned int *nom_v_pos); |
| 544 | 544 | |
| 545 | 545 | #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) |
| 546 | −bool dc_stream_forward_crc_window(struct dc *dc, | |
| 546 | +bool dc_stream_forward_crc_window(struct dc_stream_state *stream, | |
| 547 | 547 | struct rect *rect, |
| 548 | − struct dc_stream_state *stream, | |
| 549 | 548 | bool is_stop); |
| 550 | 549 | #endif |
| 551 | 550 | |
| @@ -1142,6 +1142,10 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) · 1141 unmodified lines | ||
| 1142 | 1142 | struct dc_link *link = stream->link; |
| 1143 | 1143 | struct dc *dc = pipe_ctx->stream->ctx->dc; |
| 1144 | 1144 | const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res); |
| 1145 | + struct dccg *dccg = dc->res_pool->dccg; | |
| 1146 | + struct timing_generator *tg = pipe_ctx->stream_res.tg; | |
| 1147 | + struct dtbclk_dto_params dto_params = {0}; | |
| 1148 | + int dp_hpo_inst; | |
| 1145 | 1149 | |
| 1146 | 1150 | if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) { |
| 1147 | 1151 | pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets( |
| @@ -1161,6 +1165,15 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) · 13 unmodified lines | ||
| 1161 | 1165 | |
| 1162 | 1166 | link_hwss->reset_stream_encoder(pipe_ctx); |
| 1163 | 1167 | |
| 1168 | + if (is_dp_128b_132b_signal(pipe_ctx)) { | |
| 1169 | + dto_params.otg_inst = tg->inst; | |
| 1170 | + dto_params.timing = &pipe_ctx->stream->timing; | |
| 1171 | + dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; | |
| 1172 | + dccg->funcs->set_dtbclk_dto(dccg, &dto_params); | |
| 1173 | + dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst); | |
| 1174 | + dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst); | |
| 1175 | + } | |
| 1176 | + | |
| 1164 | 1177 | if (is_dp_128b_132b_signal(pipe_ctx)) { |
| 1165 | 1178 | /* TODO: This looks like a bug to me as we are disabling HPO IO when |
| 1166 | 1179 | * we are just disabling a single HPO stream. Shouldn't we disable HPO |
| @@ -200,7 +200,6 @@ static void dsc2_set_config(struct display_stream_compressor *dsc, const struct · 199 unmodified lines | ||
| 200 | 200 | bool is_config_ok; |
| 201 | 201 | struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc); |
| 202 | 202 | |
| 203 | − DC_LOG_DSC(" "); | |
| 204 | 203 | DC_LOG_DSC("Setting DSC Config at DSC inst %d", dsc->inst); |
| 205 | 204 | dsc_config_log(dsc, dsc_cfg); |
| 206 | 205 | is_config_ok = dsc_prepare_config(dsc_cfg, &dsc20->reg_vals, dsc_optc_cfg); |
| @@ -582,6 +582,9 @@ void dcn20_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx) · 581 unmodified lines | ||
| 582 | 582 | if (pipe_ctx->stream_res.gsl_group != 0) |
| 583 | 583 | dcn20_setup_gsl_group_as_lock(dc, pipe_ctx, false); |
| 584 | 584 | |
| 585 | + if (hubp->funcs->hubp_update_mall_sel) | |
| 586 | + hubp->funcs->hubp_update_mall_sel(hubp, 0, false); | |
| 587 | + | |
| 585 | 588 | dc->hwss.set_flip_control_gsl(pipe_ctx, false); |
| 586 | 589 | |
| 587 | 590 | hubp->funcs->hubp_clk_cntl(hubp, false); |
| @@ -605,6 +608,9 @@ void dcn20_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx) · 17 unmodified lines | ||
| 605 | 608 | |
| 606 | 609 | void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx) |
| 607 | 610 | { |
| 611 | + bool is_phantom = pipe_ctx->plane_state && pipe_ctx->plane_state->is_phantom; | |
| 612 | + struct timing_generator *tg = is_phantom ? pipe_ctx->stream_res.tg : NULL; | |
| 613 | + | |
| 608 | 614 | DC_LOGGER_INIT(dc->ctx->logger); |
| 609 | 615 | |
| 610 | 616 | if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated) |
| @@ -612,6 +618,12 @@ void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx) · 1 unmodified line | ||
| 612 | 618 | |
| 613 | 619 | dcn20_plane_atomic_disable(dc, pipe_ctx); |
| 614 | 620 | |
| 621 | + /* Turn back off the phantom OTG after the phantom plane is fully disabled | |
| 622 | + */ | |
| 623 | + if (is_phantom) | |
| 624 | + if (tg && tg->funcs->disable_phantom_crtc) | |
| 625 | + tg->funcs->disable_phantom_crtc(tg); | |
| 626 | + | |
| 615 | 627 | DC_LOG_DC("Power down front end %d\n", |
| 616 | 628 | pipe_ctx->pipe_idx); |
| 617 | 629 | } |
| @@ -1803,6 +1815,18 @@ void dcn20_program_front_end_for_ctx( · 1185 unmodified lines | ||
| 1803 | 1815 | dcn20_detect_pipe_changes(&dc->current_state->res_ctx.pipe_ctx[i], |
| 1804 | 1816 | &context->res_ctx.pipe_ctx[i]); |
| 1805 | 1817 | |
| 1818 | + /* When disabling phantom pipes, turn on phantom OTG first (so we can get double | |
| 1819 | + * buffer updates properly) | |
| 1820 | + */ | |
| 1821 | + for (i = 0; i < dc->res_pool->pipe_count; i++) | |
| 1822 | + if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable | |
| 1823 | + && dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) { | |
| 1824 | + struct timing_generator *tg = dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg; | |
| 1825 | + | |
| 1826 | + if (tg->funcs->enable_crtc) | |
| 1827 | + tg->funcs->enable_crtc(tg); | |
| 1828 | + } | |
| 1829 | + | |
| 1806 | 1830 | /* OTG blank before disabling all front ends */ |
| 1807 | 1831 | for (i = 0; i < dc->res_pool->pipe_count; i++) |
| 1808 | 1832 | if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable |
| @@ -2615,6 +2639,37 @@ void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) · 806 unmodified lines | ||
| 2615 | 2639 | hubp->mpcc_id = mpcc_id; |
| 2616 | 2640 | } |
| 2617 | 2641 | |
| 2642 | +static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link) | |
| 2643 | +{ | |
| 2644 | + switch (link->link_enc->transmitter) { | |
| 2645 | + case TRANSMITTER_UNIPHY_A: | |
| 2646 | + return PHYD32CLKA; | |
| 2647 | + case TRANSMITTER_UNIPHY_B: | |
| 2648 | + return PHYD32CLKB; | |
| 2649 | + case TRANSMITTER_UNIPHY_C: | |
| 2650 | + return PHYD32CLKC; | |
| 2651 | + case TRANSMITTER_UNIPHY_D: | |
| 2652 | + return PHYD32CLKD; | |
| 2653 | + case TRANSMITTER_UNIPHY_E: | |
| 2654 | + return PHYD32CLKE; | |
| 2655 | + default: | |
| 2656 | + return PHYD32CLKA; | |
| 2657 | + } | |
| 2658 | +} | |
| 2659 | + | |
| 2660 | +static int get_odm_segment_count(struct pipe_ctx *pipe_ctx) | |
| 2661 | +{ | |
| 2662 | + struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe; | |
| 2663 | + int count = 1; | |
| 2664 | + | |
| 2665 | + while (odm_pipe != NULL) { | |
| 2666 | + count++; | |
| 2667 | + odm_pipe = odm_pipe->next_odm_pipe; | |
| 2668 | + } | |
| 2669 | + | |
| 2670 | + return count; | |
| 2671 | +} | |
| 2672 | + | |
| 2618 | 2673 | void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) |
| 2619 | 2674 | { |
| 2620 | 2675 | enum dc_lane_count lane_count = |
| @@ -2628,12 +2683,43 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) · 7 unmodified lines | ||
| 2628 | 2683 | struct timing_generator *tg = pipe_ctx->stream_res.tg; |
| 2629 | 2684 | const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res); |
| 2630 | 2685 | struct dc *dc = pipe_ctx->stream->ctx->dc; |
| 2686 | + struct dtbclk_dto_params dto_params = {0}; | |
| 2687 | + struct dccg *dccg = dc->res_pool->dccg; | |
| 2688 | + enum phyd32clk_clock_source phyd32clk; | |
| 2689 | + int dp_hpo_inst; | |
| 2690 | + struct dce_hwseq *hws = dc->hwseq; | |
| 2691 | + unsigned int k1_div = PIXEL_RATE_DIV_NA; | |
| 2692 | + unsigned int k2_div = PIXEL_RATE_DIV_NA; | |
| 2631 | 2693 | |
| 2632 | 2694 | if (is_dp_128b_132b_signal(pipe_ctx)) { |
| 2633 | 2695 | if (dc->hwseq->funcs.setup_hpo_hw_control) |
| 2634 | 2696 | dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, true); |
| 2635 | 2697 | } |
| 2636 | 2698 | |
| 2699 | + if (is_dp_128b_132b_signal(pipe_ctx)) { | |
| 2700 | + dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; | |
| 2701 | + dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, dp_hpo_inst); | |
| 2702 | + | |
| 2703 | + phyd32clk = get_phyd32clk_src(link); | |
| 2704 | + dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk); | |
| 2705 | + | |
| 2706 | + dto_params.otg_inst = tg->inst; | |
| 2707 | + dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10; | |
| 2708 | + dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx); | |
| 2709 | + dto_params.timing = &pipe_ctx->stream->timing; | |
| 2710 | + dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr); | |
| 2711 | + dccg->funcs->set_dtbclk_dto(dccg, &dto_params); | |
| 2712 | + } | |
| 2713 | + | |
| 2714 | + if (hws->funcs.calculate_dccg_k1_k2_values && dc->res_pool->dccg->funcs->set_pixel_rate_div) { | |
| 2715 | + hws->funcs.calculate_dccg_k1_k2_values(pipe_ctx, &k1_div, &k2_div); | |
| 2716 | + | |
| 2717 | + dc->res_pool->dccg->funcs->set_pixel_rate_div( | |
| 2718 | + dc->res_pool->dccg, | |
| 2719 | + pipe_ctx->stream_res.tg->inst, | |
| 2720 | + k1_div, k2_div); | |
| 2721 | + } | |
| 2722 | + | |
| 2637 | 2723 | link_hwss->setup_stream_encoder(pipe_ctx); |
| 2638 | 2724 | |
| 2639 | 2725 | if (pipe_ctx->plane_state && pipe_ctx->plane_state->flip_immediate != 1) { |
| @@ -1389,6 +1389,9 @@ enum dc_status dcn20_add_dsc_to_stream_resource(struct dc *dc, · 1388 unmodified lines | ||
| 1389 | 1389 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
| 1390 | 1390 | struct pipe_ctx *pipe_ctx = &dc_ctx->res_ctx.pipe_ctx[i]; |
| 1391 | 1391 | |
| 1392 | + if (pipe_ctx->top_pipe) | |
| 1393 | + continue; | |
| 1394 | + | |
| 1392 | 1395 | if (pipe_ctx->stream != dc_stream) |
| 1393 | 1396 | continue; |
| 1394 | 1397 | |
| @@ -1414,7 +1414,8 @@ static struct resource_funcs dcn301_res_pool_funcs = { · 1413 unmodified lines | ||
| 1414 | 1414 | .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link, |
| 1415 | 1415 | .acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut, |
| 1416 | 1416 | .release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut, |
| 1417 | − .update_bw_bounding_box = dcn301_update_bw_bounding_box | |
| 1417 | + .update_bw_bounding_box = dcn301_update_bw_bounding_box, | |
| 1418 | + .patch_unknown_plane_state = dcn20_patch_unknown_plane_state | |
| 1418 | 1419 | }; |
| 1419 | 1420 | |
| 1420 | 1421 | static bool dcn301_resource_construct( |
| @@ -242,7 +242,10 @@ void dcn31_hpo_dp_link_enc_set_link_test_pattern( · 241 unmodified lines | ||
| 242 | 242 | REG_UPDATE(DP_DPHY_SYM32_CONTROL, |
| 243 | 243 | MODE, DP2_TEST_PATTERN); |
| 244 | 244 | break; |
| 245 | − case DP_TEST_PATTERN_SQUARE_PULSE: | |
| 245 | + case DP_TEST_PATTERN_SQUARE: | |
| 246 | + case DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED: | |
| 247 | + case DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED: | |
| 248 | + case DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED: | |
| 246 | 249 | REG_SET(DP_DPHY_SYM32_TP_SQ_PULSE, 0, |
| 247 | 250 | TP_SQ_PULSE_WIDTH, tp_params->custom_pattern[0]); |
| 248 | 251 | |
| @@ -623,43 +623,3 @@ void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable) · 622 unmodified lines | ||
| 623 | 623 | if (hws->ctx->dc->debug.hpo_optimization) |
| 624 | 624 | REG_UPDATE(HPO_TOP_HW_CONTROL, HPO_IO_EN, !!enable); |
| 625 | 625 | } |
| 626 | −void dcn31_set_drr(struct pipe_ctx **pipe_ctx, | |
| 627 | − int num_pipes, struct dc_crtc_timing_adjust adjust) | |
| 628 | −{ | |
| 629 | − int i = 0; | |
| 630 | − struct drr_params params = {0}; | |
| 631 | − unsigned int event_triggers = 0x2;/*Bit[1]: OTG_TRIG_A*/ | |
| 632 | − unsigned int num_frames = 2; | |
| 633 | − params.vertical_total_max = adjust.v_total_max; | |
| 634 | − params.vertical_total_min = adjust.v_total_min; | |
| 635 | − params.vertical_total_mid = adjust.v_total_mid; | |
| 636 | − params.vertical_total_mid_frame_num = adjust.v_total_mid_frame_num; | |
| 637 | − for (i = 0; i < num_pipes; i++) { | |
| 638 | − if ((pipe_ctx[i]->stream_res.tg != NULL) && pipe_ctx[i]->stream_res.tg->funcs) { | |
| 639 | − if (pipe_ctx[i]->stream_res.tg->funcs->set_drr) | |
| 640 | − pipe_ctx[i]->stream_res.tg->funcs->set_drr( | |
| 641 | − pipe_ctx[i]->stream_res.tg, ¶ms); | |
| 642 | − if (adjust.v_total_max != 0 && adjust.v_total_min != 0) | |
| 643 | − if (pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control) | |
| 644 | − pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control( | |
| 645 | − pipe_ctx[i]->stream_res.tg, | |
| 646 | − event_triggers, num_frames); | |
| 647 | − } | |
| 648 | − } | |
| 649 | −} | |
| 650 | −void dcn31_set_static_screen_control(struct pipe_ctx **pipe_ctx, | |
| 651 | − int num_pipes, const struct dc_static_screen_params *params) | |
| 652 | −{ | |
| 653 | − unsigned int i; | |
| 654 | − unsigned int triggers = 0; | |
| 655 | − if (params->triggers.surface_update) | |
| 656 | − triggers |= 0x600;/*bit 9 and bit10 : 110 0000 0000*/ | |
| 657 | − if (params->triggers.cursor_update) | |
| 658 | − triggers |= 0x10;/*bit4*/ | |
| 659 | − if (params->triggers.force_trigger) | |
| 660 | − triggers |= 0x1; | |
| 661 | − for (i = 0; i < num_pipes; i++) | |
| 662 | − pipe_ctx[i]->stream_res.tg->funcs-> | |
| 663 | − set_static_screen_control(pipe_ctx[i]->stream_res.tg, | |
| 664 | − triggers, params->num_frames); | |
| 665 | −} | |
| @@ -56,8 +56,4 @@ bool dcn31_is_abm_supported(struct dc *dc, · 55 unmodified lines | ||
| 56 | 56 | void dcn31_init_pipes(struct dc *dc, struct dc_state *context); |
| 57 | 57 | void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable); |
| 58 | 58 | |
| 59 | −void dcn31_set_static_screen_control(struct pipe_ctx **pipe_ctx, | |
| 60 | − int num_pipes, const struct dc_static_screen_params *params); | |
| 61 | −void dcn31_set_drr(struct pipe_ctx **pipe_ctx, | |
| 62 | − int num_pipes, struct dc_crtc_timing_adjust adjust); | |
| 63 | 59 | #endif /* __DC_HWSS_DCN31_H__ */ |
| @@ -64,9 +64,9 @@ static const struct hw_sequencer_funcs dcn31_funcs = { · 63 unmodified lines | ||
| 64 | 64 | .prepare_bandwidth = dcn20_prepare_bandwidth, |
| 65 | 65 | .optimize_bandwidth = dcn20_optimize_bandwidth, |
| 66 | 66 | .update_bandwidth = dcn20_update_bandwidth, |
| 67 | − .set_drr = dcn31_set_drr, | |
| 67 | + .set_drr = dcn10_set_drr, | |
| 68 | 68 | .get_position = dcn10_get_position, |
| 69 | − .set_static_screen_control = dcn31_set_static_screen_control, | |
| 69 | + .set_static_screen_control = dcn10_set_static_screen_control, | |
| 70 | 70 | .setup_stereo = dcn10_setup_stereo, |
| 71 | 71 | .set_avmute = dcn30_set_avmute, |
| 72 | 72 | .log_hw_state = dcn10_log_hw_state, |
| @@ -40,7 +40,6 @@ · 39 unmodified lines | ||
| 40 | 40 | #define FN(reg_name, field_name) \ |
| 41 | 41 | optc1->tg_shift->field_name, optc1->tg_mask->field_name |
| 42 | 42 | |
| 43 | −#define STATIC_SCREEN_EVENT_MASK_DRR_DOUBLE_BUFFER_UPDATE_EN 0x2000 /*bit 13*/ | |
| 44 | 43 | static void optc31_set_odm_combine(struct timing_generator *optc, int *opp_id, int opp_cnt, |
| 45 | 44 | struct dc_crtc_timing *timing) |
| 46 | 45 | { |
| @@ -232,32 +231,6 @@ void optc3_init_odm(struct timing_generator *optc) · 185 unmodified lines | ||
| 232 | 231 | OPTC_MEM_SEL, 0); |
| 233 | 232 | optc1->opp_count = 1; |
| 234 | 233 | } |
| 235 | −void optc31_set_static_screen_control( | |
| 236 | − struct timing_generator *optc, | |
| 237 | − uint32_t event_triggers, | |
| 238 | − uint32_t num_frames) | |
| 239 | −{ | |
| 240 | − struct optc *optc1 = DCN10TG_FROM_TG(optc); | |
| 241 | − uint32_t framecount; | |
| 242 | − uint32_t events; | |
| 243 | − | |
| 244 | − if (num_frames > 0xFF) | |
| 245 | − num_frames = 0xFF; | |
| 246 | − REG_GET_2(OTG_STATIC_SCREEN_CONTROL, | |
| 247 | − OTG_STATIC_SCREEN_EVENT_MASK, &events, | |
| 248 | − OTG_STATIC_SCREEN_FRAME_COUNT, &framecount); | |
| 249 | − | |
| 250 | − if (events == event_triggers && num_frames == framecount) | |
| 251 | − return; | |
| 252 | − if ((event_triggers & STATIC_SCREEN_EVENT_MASK_DRR_DOUBLE_BUFFER_UPDATE_EN) | |
| 253 | − != 0) | |
| 254 | − event_triggers = event_triggers & | |
| 255 | − ~STATIC_SCREEN_EVENT_MASK_DRR_DOUBLE_BUFFER_UPDATE_EN; | |
| 256 | − | |
| 257 | − REG_UPDATE_2(OTG_STATIC_SCREEN_CONTROL, | |
| 258 | − OTG_STATIC_SCREEN_EVENT_MASK, event_triggers, | |
| 259 | − OTG_STATIC_SCREEN_FRAME_COUNT, num_frames); | |
| 260 | −} | |
| 261 | 234 | |
| 262 | 235 | static struct timing_generator_funcs dcn31_tg_funcs = { |
| 263 | 236 | .validate_timing = optc1_validate_timing, |
| @@ -293,7 +266,7 @@ static struct timing_generator_funcs dcn31_tg_funcs = { · 29 unmodified lines | ||
| 293 | 266 | .set_drr = optc31_set_drr, |
| 294 | 267 | .get_last_used_drr_vtotal = optc2_get_last_used_drr_vtotal, |
| 295 | 268 | .set_vtotal_min_max = optc1_set_vtotal_min_max, |
| 296 | − .set_static_screen_control = optc31_set_static_screen_control, | |
| 269 | + .set_static_screen_control = optc1_set_static_screen_control, | |
| 297 | 270 | .program_stereo = optc1_program_stereo, |
| 298 | 271 | .is_stereo_left_eye = optc1_is_stereo_left_eye, |
| 299 | 272 | .tg_init = optc3_tg_init, |
| @@ -263,8 +263,5 @@ bool optc31_immediate_disable_crtc(struct timing_generator *optc); · 262 unmodified lines | ||
| 263 | 263 | void optc31_set_drr(struct timing_generator *optc, const struct drr_params *params); |
| 264 | 264 | |
| 265 | 265 | void optc3_init_odm(struct timing_generator *optc); |
| 266 | −void optc31_set_static_screen_control( | |
| 267 | − struct timing_generator *optc, | |
| 268 | − uint32_t event_triggers, | |
| 269 | − uint32_t num_frames); | |
| 266 | + | |
| 270 | 267 | #endif /* __DC_OPTC_DCN31_H__ */ |
| @@ -278,10 +278,10 @@ static void enc314_stream_encoder_dp_blank( · 277 unmodified lines | ||
| 278 | 278 | struct dc_link *link, |
| 279 | 279 | struct stream_encoder *enc) |
| 280 | 280 | { |
| 281 | − /* New to DCN314 - disable the FIFO before VID stream disable. */ | |
| 282 | − enc314_disable_fifo(enc); | |
| 283 | − | |
| 284 | 281 | enc1_stream_encoder_dp_blank(link, enc); |
| 282 | + | |
| 283 | + /* Disable FIFO after the DP vid stream is disabled to avoid corruption. */ | |
| 284 | + enc314_disable_fifo(enc); | |
| 285 | 285 | } |
| 286 | 286 | |
| 287 | 287 | static void enc314_stream_encoder_dp_unblank( |
| @@ -66,9 +66,9 @@ static const struct hw_sequencer_funcs dcn314_funcs = { · 65 unmodified lines | ||
| 66 | 66 | .prepare_bandwidth = dcn20_prepare_bandwidth, |
| 67 | 67 | .optimize_bandwidth = dcn20_optimize_bandwidth, |
| 68 | 68 | .update_bandwidth = dcn20_update_bandwidth, |
| 69 | − .set_drr = dcn31_set_drr, | |
| 69 | + .set_drr = dcn10_set_drr, | |
| 70 | 70 | .get_position = dcn10_get_position, |
| 71 | − .set_static_screen_control = dcn31_set_static_screen_control, | |
| 71 | + .set_static_screen_control = dcn10_set_static_screen_control, | |
| 72 | 72 | .setup_stereo = dcn10_setup_stereo, |
| 73 | 73 | .set_avmute = dcn30_set_avmute, |
| 74 | 74 | .log_hw_state = dcn10_log_hw_state, |
| @@ -228,7 +228,7 @@ static struct timing_generator_funcs dcn314_tg_funcs = { · 227 unmodified lines | ||
| 228 | 228 | .set_drr = optc31_set_drr, |
| 229 | 229 | .get_last_used_drr_vtotal = optc2_get_last_used_drr_vtotal, |
| 230 | 230 | .set_vtotal_min_max = optc1_set_vtotal_min_max, |
| 231 | − .set_static_screen_control = optc31_set_static_screen_control, | |
| 231 | + .set_static_screen_control = optc1_set_static_screen_control, | |
| 232 | 232 | .program_stereo = optc1_program_stereo, |
| 233 | 233 | .is_stereo_left_eye = optc1_is_stereo_left_eye, |
| 234 | 234 | .tg_init = optc3_tg_init, |
| @@ -241,7 +241,6 @@ static struct timing_generator_funcs dcn314_tg_funcs = { · 6 unmodified lines | ||
| 241 | 241 | .set_dsc_config = optc3_set_dsc_config, |
| 242 | 242 | .get_dsc_status = optc2_get_dsc_status, |
| 243 | 243 | .set_dwb_source = NULL, |
| 244 | − .set_odm_combine = optc314_set_odm_combine, | |
| 245 | 244 | .get_optc_source = optc2_get_optc_source, |
| 246 | 245 | .set_out_mux = optc3_set_out_mux, |
| 247 | 246 | .set_drr_trigger_window = optc3_set_drr_trigger_window, |
| @@ -188,7 +188,8 @@ static bool dcn32_check_no_memory_request_for_cab(struct dc *dc) · 187 unmodified lines | ||
| 188 | 188 | |
| 189 | 189 | /* First, check no-memory-request case */ |
| 190 | 190 | for (i = 0; i < dc->current_state->stream_count; i++) { |
| 191 | − if (dc->current_state->stream_status[i].plane_count) | |
| 191 | + if ((dc->current_state->stream_status[i].plane_count) && | |
| 192 | + (dc->current_state->streams[i]->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED)) | |
| 192 | 193 | /* Fail eligibility on a visible stream */ |
| 193 | 194 | break; |
| 194 | 195 | } |
| @@ -1450,3 +1451,39 @@ void dcn32_update_dsc_pg(struct dc *dc, · 1255 unmodified lines | ||
| 1450 | 1451 | } |
| 1451 | 1452 | } |
| 1452 | 1453 | } |
| 1454 | + | |
| 1455 | +void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context) | |
| 1456 | +{ | |
| 1457 | + unsigned int i; | |
| 1458 | + | |
| 1459 | + for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 1460 | + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; | |
| 1461 | + struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; | |
| 1462 | + | |
| 1463 | + /* If an active, non-phantom pipe is being transitioned into a phantom | |
| 1464 | + * pipe, wait for the double buffer update to complete first before we do | |
| 1465 | + * ANY phantom pipe programming. | |
| 1466 | + */ | |
| 1467 | + if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM && | |
| 1468 | + old_pipe->stream && old_pipe->stream->mall_stream_config.type != SUBVP_PHANTOM) { | |
| 1469 | + old_pipe->stream_res.tg->funcs->wait_for_state( | |
| 1470 | + old_pipe->stream_res.tg, | |
| 1471 | + CRTC_STATE_VBLANK); | |
| 1472 | + old_pipe->stream_res.tg->funcs->wait_for_state( | |
| 1473 | + old_pipe->stream_res.tg, | |
| 1474 | + CRTC_STATE_VACTIVE); | |
| 1475 | + } | |
| 1476 | + } | |
| 1477 | + for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 1478 | + struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; | |
| 1479 | + | |
| 1480 | + if (new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) { | |
| 1481 | + // If old context or new context has phantom pipes, apply | |
| 1482 | + // the phantom timings now. We can't change the phantom | |
| 1483 | + // pipe configuration safely without driver acquiring | |
| 1484 | + // the DMCUB lock first. | |
| 1485 | + dc->hwss.apply_ctx_to_hw(dc, context); | |
| 1486 | + break; | |
| 1487 | + } | |
| 1488 | + } | |
| 1489 | +} | |
| @@ -102,4 +102,6 @@ void dcn32_update_dsc_pg(struct dc *dc, · 101 unmodified lines | ||
| 102 | 102 | struct dc_state *context, |
| 103 | 103 | bool safe_to_disable); |
| 104 | 104 | |
| 105 | +void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context); | |
| 106 | + | |
| 105 | 107 | #endif /* __DC_HWSS_DCN32_H__ */ |
| @@ -106,6 +106,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = { · 105 unmodified lines | ||
| 106 | 106 | .set_disp_pattern_generator = dcn30_set_disp_pattern_generator, |
| 107 | 107 | .get_dcc_en_bits = dcn10_get_dcc_en_bits, |
| 108 | 108 | .commit_subvp_config = dcn32_commit_subvp_config, |
| 109 | + .enable_phantom_streams = dcn32_enable_phantom_streams, | |
| 109 | 110 | .subvp_pipe_control_lock = dcn32_subvp_pipe_control_lock, |
| 110 | 111 | .update_visual_confirm_color = dcn20_update_visual_confirm_color, |
| 111 | 112 | .update_phantom_vp_position = dcn32_update_phantom_vp_position, |
| @@ -726,6 +726,7 @@ static const struct dc_debug_options debug_defaults_drv = { · 725 unmodified lines | ||
| 726 | 726 | .allow_sw_cursor_fallback = false, // Linux can't do SW cursor "fallback" |
| 727 | 727 | .alloc_extra_way_for_cursor = true, |
| 728 | 728 | .min_prefetch_in_strobe_ns = 60000, // 60us |
| 729 | + .disable_unbounded_requesting = false, | |
| 729 | 730 | }; |
| 730 | 731 | |
| 731 | 732 | static const struct dc_debug_options debug_defaults_diags = { |
| @@ -112,6 +112,7 @@ bool dcn32_subvp_in_use(struct dc *dc, · 111 unmodified lines | ||
| 112 | 112 | bool dcn32_mpo_in_use(struct dc_state *context); |
| 113 | 113 | |
| 114 | 114 | bool dcn32_any_surfaces_rotated(struct dc *dc, struct dc_state *context); |
| 115 | +bool dcn32_is_center_timing(struct pipe_ctx *pipe); | |
| 115 | 116 | |
| 116 | 117 | struct pipe_ctx *dcn32_acquire_idle_pipe_for_head_pipe_in_layer( |
| 117 | 118 | struct dc_state *state, |
| @@ -255,6 +255,19 @@ bool dcn32_any_surfaces_rotated(struct dc *dc, struct dc_state *context) · 254 unmodified lines | ||
| 255 | 255 | return false; |
| 256 | 256 | } |
| 257 | 257 | |
| 258 | +bool dcn32_is_center_timing(struct pipe_ctx *pipe) | |
| 259 | +{ | |
| 260 | + bool is_center_timing = false; | |
| 261 | + | |
| 262 | + if (pipe->stream) { | |
| 263 | + if (pipe->stream->timing.v_addressable != pipe->stream->dst.height || | |
| 264 | + pipe->stream->timing.v_addressable != pipe->stream->src.height) { | |
| 265 | + is_center_timing = true; | |
| 266 | + } | |
| 267 | + } | |
| 268 | + return is_center_timing; | |
| 269 | +} | |
| 270 | + | |
| 258 | 271 | /** |
| 259 | 272 | * ******************************************************************************************* |
| 260 | 273 | * dcn32_determine_det_override: Determine DET allocation for each pipe |
| @@ -357,6 +370,7 @@ void dcn32_set_det_allocations(struct dc *dc, struct dc_state *context, · 96 unmodified lines | ||
| 357 | 370 | int i, pipe_cnt; |
| 358 | 371 | struct resource_context *res_ctx = &context->res_ctx; |
| 359 | 372 | struct pipe_ctx *pipe; |
| 373 | + bool disable_unbounded_requesting = dc->debug.disable_z9_mpc || dc->debug.disable_unbounded_requesting; | |
| 360 | 374 | |
| 361 | 375 | for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { |
| 362 | 376 | |
| @@ -373,7 +387,7 @@ void dcn32_set_det_allocations(struct dc *dc, struct dc_state *context, · 10 unmodified lines | ||
| 373 | 387 | */ |
| 374 | 388 | if (pipe_cnt == 1) { |
| 375 | 389 | pipes[0].pipe.src.det_size_override = DCN3_2_MAX_DET_SIZE; |
| 376 | − if (pipe->plane_state && !dc->debug.disable_z9_mpc && pipe->plane_state->tiling_info.gfx9.swizzle != DC_SW_LINEAR) { | |
| 390 | + if (pipe->plane_state && !disable_unbounded_requesting && pipe->plane_state->tiling_info.gfx9.swizzle != DC_SW_LINEAR) { | |
| 377 | 391 | if (!is_dual_plane(pipe->plane_state->format)) { |
| 378 | 392 | pipes[0].pipe.src.det_size_override = DCN3_2_DEFAULT_DET_SIZE; |
| 379 | 393 | pipes[0].pipe.src.unbounded_req_mode = true; |
| @@ -724,6 +724,7 @@ static const struct dc_debug_options debug_defaults_drv = { · 723 unmodified lines | ||
| 724 | 724 | .allow_sw_cursor_fallback = false, // Linux can't do SW cursor "fallback" |
| 725 | 725 | .alloc_extra_way_for_cursor = true, |
| 726 | 726 | .min_prefetch_in_strobe_ns = 60000, // 60us |
| 727 | + .disable_unbounded_requesting = false, | |
| 727 | 728 | }; |
| 728 | 729 | |
| 729 | 730 | static const struct dc_debug_options debug_defaults_diags = { |
| @@ -691,7 +691,7 @@ static bool dcn32_assign_subvp_pipe(struct dc *dc, · 690 unmodified lines | ||
| 691 | 691 | * to combine this with SubVP can cause issues with the scheduling). |
| 692 | 692 | * - Not TMZ surface |
| 693 | 693 | */ |
| 694 | − if (pipe->plane_state && !pipe->top_pipe && | |
| 694 | + if (pipe->plane_state && !pipe->top_pipe && !dcn32_is_center_timing(pipe) && | |
| 695 | 695 | pipe->stream->mall_stream_config.type == SUBVP_NONE && refresh_rate < 120 && !pipe->plane_state->address.tmz_surface && |
| 696 | 696 | vba->ActiveDRAMClockChangeLatencyMarginPerState[vba->VoltageLevel][vba->maxMpcComb][vba->pipe_plane[pipe_idx]] <= 0) { |
| 697 | 697 | while (pipe) { |
| @@ -979,8 +979,11 @@ static bool subvp_vblank_schedulable(struct dc *dc, struct dc_state *context) · 281 unmodified lines | ||
| 979 | 979 | } |
| 980 | 980 | // Use ignore_msa_timing_param flag to identify as DRR |
| 981 | 981 | if (found && context->res_ctx.pipe_ctx[vblank_index].stream->ignore_msa_timing_param) { |
| 982 | − // SUBVP + DRR case | |
| 983 | − schedulable = subvp_drr_schedulable(dc, context, &context->res_ctx.pipe_ctx[vblank_index]); | |
| 982 | + // SUBVP + DRR case -- don't enable SubVP + DRR for HDMI VRR cases | |
| 983 | + if (context->res_ctx.pipe_ctx[vblank_index].stream->allow_freesync) | |
| 984 | + schedulable = subvp_drr_schedulable(dc, context, &context->res_ctx.pipe_ctx[vblank_index]); | |
| 985 | + else | |
| 986 | + schedulable = false; | |
| 984 | 987 | } else if (found) { |
| 985 | 988 | main_timing = &subvp_pipe->stream->timing; |
| 986 | 989 | phantom_timing = &subvp_pipe->stream->mall_stream_config.paired_stream->timing; |
| @@ -1169,6 +1172,16 @@ static void dcn32_full_validate_bw_helper(struct dc *dc, · 182 unmodified lines | ||
| 1169 | 1172 | pipes[0].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, *pipe_cnt, 0); |
| 1170 | 1173 | *vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, *pipe_cnt); |
| 1171 | 1174 | |
| 1175 | + /* Check that vlevel requested supports pstate or not | |
| 1176 | + * if not, select the lowest vlevel that supports it | |
| 1177 | + */ | |
| 1178 | + for (i = *vlevel; i < context->bw_ctx.dml.soc.num_states; i++) { | |
| 1179 | + if (vba->DRAMClockChangeSupport[i][vba->maxMpcComb] != dm_dram_clock_change_unsupported) { | |
| 1180 | + *vlevel = i; | |
| 1181 | + break; | |
| 1182 | + } | |
| 1183 | + } | |
| 1184 | + | |
| 1172 | 1185 | if (*vlevel < context->bw_ctx.dml.soc.num_states && |
| 1173 | 1186 | vba->DRAMClockChangeSupport[*vlevel][vba->maxMpcComb] != dm_dram_clock_change_unsupported |
| 1174 | 1187 | && subvp_validate_static_schedulability(dc, context, *vlevel)) { |
| @@ -1185,7 +1198,7 @@ static void dcn32_full_validate_bw_helper(struct dc *dc, · 10 unmodified lines | ||
| 1185 | 1198 | pipe->stream->mall_stream_config.type == SUBVP_NONE) { |
| 1186 | 1199 | non_subvp_pipes++; |
| 1187 | 1200 | // Use ignore_msa_timing_param flag to identify as DRR |
| 1188 | − if (pipe->stream->ignore_msa_timing_param) { | |
| 1201 | + if (pipe->stream->ignore_msa_timing_param && pipe->stream->allow_freesync) { | |
| 1189 | 1202 | drr_pipe_found = true; |
| 1190 | 1203 | drr_pipe_index = i; |
| 1191 | 1204 | } |
| @@ -1551,6 +1564,7 @@ bool dcn32_internal_validate_bw(struct dc *dc, · 359 unmodified lines | ||
| 1551 | 1564 | context->bw_ctx.dml.soc.allow_for_pstate_or_stutter_in_vblank_final = |
| 1552 | 1565 | dm_prefetch_support_fclk_and_stutter; |
| 1553 | 1566 | |
| 1567 | + context->bw_ctx.dml.validate_max_state = fast_validate; | |
| 1554 | 1568 | vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt); |
| 1555 | 1569 | |
| 1556 | 1570 | /* Last attempt with Prefetch mode 2 (dm_prefetch_support_stutter == 3) */ |
| @@ -1559,6 +1573,7 @@ bool dcn32_internal_validate_bw(struct dc *dc, · 2 unmodified lines | ||
| 1559 | 1573 | dm_prefetch_support_stutter; |
| 1560 | 1574 | vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt); |
| 1561 | 1575 | } |
| 1576 | + context->bw_ctx.dml.validate_max_state = false; | |
| 1562 | 1577 | |
| 1563 | 1578 | if (vlevel < context->bw_ctx.dml.soc.num_states) { |
| 1564 | 1579 | memset(split, 0, sizeof(split)); |
| @@ -1645,6 +1660,7 @@ bool dcn32_internal_validate_bw(struct dc *dc, · 80 unmodified lines | ||
| 1645 | 1660 | dcn20_release_dsc(&context->res_ctx, dc->res_pool, &pipe->stream_res.dsc); |
| 1646 | 1661 | memset(&pipe->plane_res, 0, sizeof(pipe->plane_res)); |
| 1647 | 1662 | memset(&pipe->stream_res, 0, sizeof(pipe->stream_res)); |
| 1663 | + memset(&pipe->link_res, 0, sizeof(pipe->link_res)); | |
| 1648 | 1664 | repopulate_pipes = true; |
| 1649 | 1665 | } else if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) { |
| 1650 | 1666 | struct pipe_ctx *top_pipe = pipe->top_pipe; |
| @@ -1660,6 +1676,7 @@ bool dcn32_internal_validate_bw(struct dc *dc, · 9 unmodified lines | ||
| 1660 | 1676 | pipe->stream = NULL; |
| 1661 | 1677 | memset(&pipe->plane_res, 0, sizeof(pipe->plane_res)); |
| 1662 | 1678 | memset(&pipe->stream_res, 0, sizeof(pipe->stream_res)); |
| 1679 | + memset(&pipe->link_res, 0, sizeof(pipe->link_res)); | |
| 1663 | 1680 | repopulate_pipes = true; |
| 1664 | 1681 | } else |
| 1665 | 1682 | ASSERT(0); /* Should never try to merge master pipe */ |
| @@ -1707,7 +1707,7 @@ static void mode_support_configuration(struct vba_vars_st *v, · 1706 unmodified lines | ||
| 1707 | 1707 | void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib) |
| 1708 | 1708 | { |
| 1709 | 1709 | struct vba_vars_st *v = &mode_lib->vba; |
| 1710 | − int i, j; | |
| 1710 | + int i, j, start_state; | |
| 1711 | 1711 | unsigned int k, m; |
| 1712 | 1712 | unsigned int MaximumMPCCombine; |
| 1713 | 1713 | unsigned int NumberOfNonCombinedSurfaceOfMaximumBandwidth; |
| @@ -1720,7 +1720,10 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 6 unmodified lines | ||
| 1720 | 1720 | #endif |
| 1721 | 1721 | |
| 1722 | 1722 | /*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/ |
| 1723 | − | |
| 1723 | + if (mode_lib->validate_max_state) | |
| 1724 | + start_state = v->soc.num_states - 1; | |
| 1725 | + else | |
| 1726 | + start_state = 0; | |
| 1724 | 1727 | /*Scale Ratio, taps Support Check*/ |
| 1725 | 1728 | |
| 1726 | 1729 | mode_lib->vba.ScaleRatioAndTapsSupport = true; |
| @@ -2009,7 +2012,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 282 unmodified lines | ||
| 2009 | 2012 | mode_lib->vba.MPCCombineMethodIncompatible = v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.MPCCombineMethodAsNeededForPStateChangeAndVoltage |
| 2010 | 2013 | && v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.MPCCombineMethodAsPossible; |
| 2011 | 2014 | |
| 2012 | − for (i = 0; i < v->soc.num_states; i++) { | |
| 2015 | + for (i = start_state; i < v->soc.num_states; i++) { | |
| 2013 | 2016 | for (j = 0; j < 2; j++) { |
| 2014 | 2017 | mode_lib->vba.TotalNumberOfActiveDPP[i][j] = 0; |
| 2015 | 2018 | mode_lib->vba.TotalAvailablePipesSupport[i][j] = true; |
| @@ -2286,7 +2289,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 270 unmodified lines | ||
| 2286 | 2289 | } |
| 2287 | 2290 | } |
| 2288 | 2291 | |
| 2289 | − for (i = 0; i < v->soc.num_states; ++i) { | |
| 2292 | + for (i = start_state; i < v->soc.num_states; ++i) { | |
| 2290 | 2293 | mode_lib->vba.ExceededMultistreamSlots[i] = false; |
| 2291 | 2294 | for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) { |
| 2292 | 2295 | if (mode_lib->vba.OutputMultistreamEn[k] == true && mode_lib->vba.OutputMultistreamId[k] == k) { |
| @@ -2386,7 +2389,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 93 unmodified lines | ||
| 2386 | 2389 | } |
| 2387 | 2390 | } |
| 2388 | 2391 | |
| 2389 | − for (i = 0; i < v->soc.num_states; ++i) { | |
| 2392 | + for (i = start_state; i < v->soc.num_states; ++i) { | |
| 2390 | 2393 | mode_lib->vba.DTBCLKRequiredMoreThanSupported[i] = false; |
| 2391 | 2394 | for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) { |
| 2392 | 2395 | if (mode_lib->vba.BlendingAndTiming[k] == k |
| @@ -2403,7 +2406,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 10 unmodified lines | ||
| 2403 | 2406 | } |
| 2404 | 2407 | } |
| 2405 | 2408 | |
| 2406 | − for (i = 0; i < v->soc.num_states; ++i) { | |
| 2409 | + for (i = start_state; i < v->soc.num_states; ++i) { | |
| 2407 | 2410 | mode_lib->vba.ODMCombine2To1SupportCheckOK[i] = true; |
| 2408 | 2411 | mode_lib->vba.ODMCombine4To1SupportCheckOK[i] = true; |
| 2409 | 2412 | for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) { |
| @@ -2421,7 +2424,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 11 unmodified lines | ||
| 2421 | 2424 | } |
| 2422 | 2425 | } |
| 2423 | 2426 | |
| 2424 | − for (i = 0; i < v->soc.num_states; i++) { | |
| 2427 | + for (i = start_state; i < v->soc.num_states; i++) { | |
| 2425 | 2428 | mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] = false; |
| 2426 | 2429 | for (k = 0; k <= mode_lib->vba.NumberOfActiveSurfaces - 1; k++) { |
| 2427 | 2430 | if (mode_lib->vba.BlendingAndTiming[k] == k) { |
| @@ -2458,7 +2461,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 30 unmodified lines | ||
| 2458 | 2461 | /* Check DSC Unit and Slices Support */ |
| 2459 | 2462 | v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.TotalDSCUnitsRequired = 0; |
| 2460 | 2463 | |
| 2461 | − for (i = 0; i < v->soc.num_states; ++i) { | |
| 2464 | + for (i = start_state; i < v->soc.num_states; ++i) { | |
| 2462 | 2465 | mode_lib->vba.NotEnoughDSCUnits[i] = false; |
| 2463 | 2466 | mode_lib->vba.NotEnoughDSCSlices[i] = false; |
| 2464 | 2467 | v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.TotalDSCUnitsRequired = 0; |
| @@ -2493,7 +2496,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 28 unmodified lines | ||
| 2493 | 2496 | } |
| 2494 | 2497 | |
| 2495 | 2498 | /*DSC Delay per state*/ |
| 2496 | − for (i = 0; i < v->soc.num_states; ++i) { | |
| 2499 | + for (i = start_state; i < v->soc.num_states; ++i) { | |
| 2497 | 2500 | for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) { |
| 2498 | 2501 | mode_lib->vba.DSCDelayPerState[i][k] = dml32_DSCDelayRequirement( |
| 2499 | 2502 | mode_lib->vba.RequiresDSC[i][k], mode_lib->vba.ODMCombineEnablePerState[i][k], |
| @@ -2520,7 +2523,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 20 unmodified lines | ||
| 2520 | 2523 | |
| 2521 | 2524 | //Calculate Swath, DET Configuration, DCFCLKDeepSleep |
| 2522 | 2525 | // |
| 2523 | − for (i = 0; i < (int) v->soc.num_states; ++i) { | |
| 2526 | + for (i = start_state; i < (int) v->soc.num_states; ++i) { | |
| 2524 | 2527 | for (j = 0; j <= 1; ++j) { |
| 2525 | 2528 | for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) { |
| 2526 | 2529 | mode_lib->vba.RequiredDPPCLKThisState[k] = mode_lib->vba.RequiredDPPCLK[i][j][k]; |
| @@ -2655,7 +2658,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 128 unmodified lines | ||
| 2655 | 2658 | mode_lib->vba.SurfaceSizeInMALL, |
| 2656 | 2659 | &mode_lib->vba.ExceededMALLSize); |
| 2657 | 2660 | |
| 2658 | − for (i = 0; i < v->soc.num_states; i++) { | |
| 2661 | + for (i = start_state; i < v->soc.num_states; i++) { | |
| 2659 | 2662 | for (j = 0; j < 2; j++) { |
| 2660 | 2663 | for (k = 0; k <= mode_lib->vba.NumberOfActiveSurfaces - 1; k++) { |
| 2661 | 2664 | mode_lib->vba.swath_width_luma_ub_this_state[k] = |
| @@ -2882,7 +2885,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 220 unmodified lines | ||
| 2882 | 2885 | } |
| 2883 | 2886 | |
| 2884 | 2887 | //Calculate Return BW |
| 2885 | − for (i = 0; i < (int) v->soc.num_states; ++i) { | |
| 2888 | + for (i = start_state; i < (int) v->soc.num_states; ++i) { | |
| 2886 | 2889 | for (j = 0; j <= 1; ++j) { |
| 2887 | 2890 | for (k = 0; k <= mode_lib->vba.NumberOfActiveSurfaces - 1; k++) { |
| 2888 | 2891 | if (mode_lib->vba.BlendingAndTiming[k] == k) { |
| @@ -2961,7 +2964,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 72 unmodified lines | ||
| 2961 | 2964 | &mode_lib->vba.MinPrefetchMode, |
| 2962 | 2965 | &mode_lib->vba.MaxPrefetchMode); |
| 2963 | 2966 | |
| 2964 | − for (i = 0; i < (int) v->soc.num_states; ++i) { | |
| 2967 | + for (i = start_state; i < (int) v->soc.num_states; ++i) { | |
| 2965 | 2968 | for (j = 0; j <= 1; ++j) |
| 2966 | 2969 | mode_lib->vba.DCFCLKState[i][j] = mode_lib->vba.DCFCLKPerState[i]; |
| 2967 | 2970 | } |
| @@ -3083,7 +3086,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 115 unmodified lines | ||
| 3083 | 3086 | mode_lib->vba.DCFCLKState); |
| 3084 | 3087 | } // UseMinimumRequiredDCFCLK == true |
| 3085 | 3088 | |
| 3086 | − for (i = 0; i < (int) v->soc.num_states; ++i) { | |
| 3089 | + for (i = start_state; i < (int) v->soc.num_states; ++i) { | |
| 3087 | 3090 | for (j = 0; j <= 1; ++j) { |
| 3088 | 3091 | mode_lib->vba.ReturnBWPerState[i][j] = dml32_get_return_bw_mbps(&mode_lib->vba.soc, i, |
| 3089 | 3092 | mode_lib->vba.HostVMEnable, mode_lib->vba.DCFCLKState[i][j], |
| @@ -3092,7 +3095,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 2 unmodified lines | ||
| 3092 | 3095 | } |
| 3093 | 3096 | |
| 3094 | 3097 | //Re-ordering Buffer Support Check |
| 3095 | − for (i = 0; i < (int) v->soc.num_states; ++i) { | |
| 3098 | + for (i = start_state; i < (int) v->soc.num_states; ++i) { | |
| 3096 | 3099 | for (j = 0; j <= 1; ++j) { |
| 3097 | 3100 | if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024 |
| 3098 | 3101 | / mode_lib->vba.ReturnBWPerState[i][j] |
| @@ -3114,7 +3117,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 15 unmodified lines | ||
| 3114 | 3117 | + mode_lib->vba.ReadBandwidthChroma[k]; |
| 3115 | 3118 | } |
| 3116 | 3119 | |
| 3117 | − for (i = 0; i < (int) v->soc.num_states; ++i) { | |
| 3120 | + for (i = start_state; i < (int) v->soc.num_states; ++i) { | |
| 3118 | 3121 | for (j = 0; j <= 1; ++j) { |
| 3119 | 3122 | mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i][j] = |
| 3120 | 3123 | dml_min3(mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKState[i][j] |
| @@ -3138,7 +3141,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 17 unmodified lines | ||
| 3138 | 3141 | |
| 3139 | 3142 | /* Prefetch Check */ |
| 3140 | 3143 | |
| 3141 | − for (i = 0; i < (int) v->soc.num_states; ++i) { | |
| 3144 | + for (i = start_state; i < (int) v->soc.num_states; ++i) { | |
| 3142 | 3145 | for (j = 0; j <= 1; ++j) { |
| 3143 | 3146 | |
| 3144 | 3147 | mode_lib->vba.TimeCalc = 24 / mode_lib->vba.ProjectedDCFCLKDeepSleep[i][j]; |
| @@ -6257,12 +6257,12 @@ bool dml32_CalculateDETSwathFillLatencyHiding(unsigned int NumberOfActiveSurface · 6256 unmodified lines | ||
| 6257 | 6257 | double SwathSizePerSurfaceC[DC__NUM_DPP__MAX]; |
| 6258 | 6258 | bool NotEnoughDETSwathFillLatencyHiding = false; |
| 6259 | 6259 | |
| 6260 | − /* calculate sum of single swath size for all pipes in bytes*/ | |
| 6260 | + /* calculate sum of single swath size for all pipes in bytes */ | |
| 6261 | 6261 | for (k = 0; k < NumberOfActiveSurfaces; k++) { |
| 6262 | − SwathSizePerSurfaceY[k] += SwathHeightY[k] * SwathWidthY[k] * BytePerPixelInDETY[k] * NumOfDPP[k]; | |
| 6262 | + SwathSizePerSurfaceY[k] = SwathHeightY[k] * SwathWidthY[k] * BytePerPixelInDETY[k] * NumOfDPP[k]; | |
| 6263 | 6263 | |
| 6264 | 6264 | if (SwathHeightC[k] != 0) |
| 6265 | − SwathSizePerSurfaceC[k] += SwathHeightC[k] * SwathWidthC[k] * BytePerPixelInDETC[k] * NumOfDPP[k]; | |
| 6265 | + SwathSizePerSurfaceC[k] = SwathHeightC[k] * SwathWidthC[k] * BytePerPixelInDETC[k] * NumOfDPP[k]; | |
| 6266 | 6266 | else |
| 6267 | 6267 | SwathSizePerSurfaceC[k] = 0; |
| 6268 | 6268 | |
| @@ -136,7 +136,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = { · 135 unmodified lines | ||
| 136 | 136 | .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, |
| 137 | 137 | .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, |
| 138 | 138 | .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, |
| 139 | − .pct_ideal_sdp_bw_after_urgent = 100.0, | |
| 139 | + .pct_ideal_sdp_bw_after_urgent = 90.0, | |
| 140 | 140 | .pct_ideal_fabric_bw_after_urgent = 67.0, |
| 141 | 141 | .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 20.0, |
| 142 | 142 | .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0, // N/A, for now keep as is until DML implemented |
| @@ -91,6 +91,7 @@ struct display_mode_lib { · 90 unmodified lines | ||
| 91 | 91 | struct dal_logger *logger; |
| 92 | 92 | struct dml_funcs funcs; |
| 93 | 93 | struct _vcs_dpi_display_e2e_pipe_params_st dml_pipe_state[6]; |
| 94 | + bool validate_max_state; | |
| 94 | 95 | }; |
| 95 | 96 | |
| 96 | 97 | void dml_init_instance(struct display_mode_lib *lib, |
| @@ -546,15 +546,6 @@ struct dc_state { · 545 unmodified lines | ||
| 546 | 546 | */ |
| 547 | 547 | struct resource_context res_ctx; |
| 548 | 548 | |
| 549 | − /** | |
| 550 | − * @bw_ctx: The output from bandwidth and watermark calculations and the DML | |
| 551 | − * | |
| 552 | − * Each context must have its own instance of VBA, and in order to | |
| 553 | − * initialize and obtain IP and SOC, the base DML instance from DC is | |
| 554 | − * initially copied into every context. | |
| 555 | − */ | |
| 556 | − struct bw_context bw_ctx; | |
| 557 | − | |
| 558 | 549 | /** |
| 559 | 550 | * @pp_display_cfg: PowerPlay clocks and settings |
| 560 | 551 | * Note: this is a big struct, do *not* put on stack! |
| @@ -569,6 +560,15 @@ struct dc_state { · 8 unmodified lines | ||
| 569 | 560 | |
| 570 | 561 | struct clk_mgr *clk_mgr; |
| 571 | 562 | |
| 563 | + /** | |
| 564 | + * @bw_ctx: The output from bandwidth and watermark calculations and the DML | |
| 565 | + * | |
| 566 | + * Each context must have its own instance of VBA, and in order to | |
| 567 | + * initialize and obtain IP and SOC, the base DML instance from DC is | |
| 568 | + * initially copied into every context. | |
| 569 | + */ | |
| 570 | + struct bw_context bw_ctx; | |
| 571 | + | |
| 572 | 572 | /** |
| 573 | 573 | * @refcount: refcount reference |
| 574 | 574 | * |
| @@ -266,6 +266,7 @@ struct hw_sequencer_funcs { · 265 unmodified lines | ||
| 266 | 266 | void (*apply_update_flags_for_phantom)(struct pipe_ctx *phantom_pipe); |
| 267 | 267 | |
| 268 | 268 | void (*commit_subvp_config)(struct dc *dc, struct dc_state *context); |
| 269 | + void (*enable_phantom_streams)(struct dc *dc, struct dc_state *context); | |
| 269 | 270 | void (*subvp_pipe_control_lock)(struct dc *dc, |
| 270 | 271 | struct dc_state *context, |
| 271 | 272 | bool lock, |
| @@ -236,4 +236,13 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm( · 235 unmodified lines | ||
| 236 | 236 | struct pipe_ctx *pri_pipe, |
| 237 | 237 | struct pipe_ctx *sec_pipe, |
| 238 | 238 | bool odm); |
| 239 | + | |
| 240 | +/* A test harness interface that modifies dp encoder resources in the given dc | |
| 241 | + * state and bypasses the need to revalidate. The interface assumes that the | |
| 242 | + * test harness interface is called with pre-validated link config stored in the | |
| 243 | + * pipe_ctx and updates dp encoder resources according to the link config. | |
| 244 | + */ | |
| 245 | +enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc, | |
| 246 | + struct dc_state *context, | |
| 247 | + struct pipe_ctx *pipe_ctx); | |
| 239 | 248 | #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */ |
| @@ -136,11 +136,6 @@ static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { · 135 unmodified lines | ||
| 136 | 136 | .ack = NULL |
| 137 | 137 | }; |
| 138 | 138 | |
| 139 | −static const struct irq_source_info_funcs dmub_outbox_irq_info_funcs = { | |
| 140 | − .set = NULL, | |
| 141 | − .ack = NULL | |
| 142 | −}; | |
| 143 | − | |
| 144 | 139 | #undef BASE_INNER |
| 145 | 140 | #define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg |
| 146 | 141 | |
| @@ -87,57 +87,20 @@ static void set_hpo_dp_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx, · 86 unmodified lines | ||
| 87 | 87 | hblank_min_symbol_width); |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | −static int get_odm_segment_count(struct pipe_ctx *pipe_ctx) | |
| 91 | −{ | |
| 92 | − struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe; | |
| 93 | − int count = 1; | |
| 94 | − | |
| 95 | − while (odm_pipe != NULL) { | |
| 96 | − count++; | |
| 97 | − odm_pipe = odm_pipe->next_odm_pipe; | |
| 98 | − } | |
| 99 | − | |
| 100 | − return count; | |
| 101 | −} | |
| 102 | − | |
| 103 | 90 | static void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx) |
| 104 | 91 | { |
| 105 | − struct dc *dc = pipe_ctx->stream->ctx->dc; | |
| 106 | 92 | struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc; |
| 107 | 93 | struct hpo_dp_link_encoder *link_enc = pipe_ctx->link_res.hpo_dp_link_enc; |
| 108 | − struct dccg *dccg = dc->res_pool->dccg; | |
| 109 | − struct timing_generator *tg = pipe_ctx->stream_res.tg; | |
| 110 | − struct dtbclk_dto_params dto_params = {0}; | |
| 111 | − enum phyd32clk_clock_source phyd32clk = get_phyd32clk_src(pipe_ctx->stream->link); | |
| 112 | 94 | |
| 113 | − dto_params.otg_inst = tg->inst; | |
| 114 | − dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10; | |
| 115 | − dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx); | |
| 116 | − dto_params.timing = &pipe_ctx->stream->timing; | |
| 117 | − dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr); | |
| 118 | − | |
| 119 | − dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, stream_enc->inst); | |
| 120 | − dccg->funcs->enable_symclk32_se(dccg, stream_enc->inst, phyd32clk); | |
| 121 | − dccg->funcs->set_dtbclk_dto(dccg, &dto_params); | |
| 122 | 95 | stream_enc->funcs->enable_stream(stream_enc); |
| 123 | 96 | stream_enc->funcs->map_stream_to_link(stream_enc, stream_enc->inst, link_enc->inst); |
| 124 | 97 | } |
| 125 | 98 | |
| 126 | 99 | static void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx) |
| 127 | 100 | { |
| 128 | − struct dc *dc = pipe_ctx->stream->ctx->dc; | |
| 129 | 101 | struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc; |
| 130 | − struct dccg *dccg = dc->res_pool->dccg; | |
| 131 | − struct timing_generator *tg = pipe_ctx->stream_res.tg; | |
| 132 | − struct dtbclk_dto_params dto_params = {0}; | |
| 133 | − | |
| 134 | − dto_params.otg_inst = tg->inst; | |
| 135 | − dto_params.timing = &pipe_ctx->stream->timing; | |
| 136 | 102 | |
| 137 | 103 | stream_enc->funcs->disable(stream_enc); |
| 138 | − dccg->funcs->set_dtbclk_dto(dccg, &dto_params); | |
| 139 | − dccg->funcs->disable_symclk32_se(dccg, stream_enc->inst); | |
| 140 | − dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, stream_enc->inst); | |
| 141 | 104 | } |
| 142 | 105 | |
| 143 | 106 | static void setup_hpo_dp_stream_attribute(struct pipe_ctx *pipe_ctx) |
| @@ -126,6 +126,7 @@ enum dmub_notification_type { · 125 unmodified lines | ||
| 126 | 126 | DMUB_NOTIFICATION_HPD, |
| 127 | 127 | DMUB_NOTIFICATION_HPD_IRQ, |
| 128 | 128 | DMUB_NOTIFICATION_SET_CONFIG_REPLY, |
| 129 | + DMUB_NOTIFICATION_DPIA_NOTIFICATION, | |
| 129 | 130 | DMUB_NOTIFICATION_MAX |
| 130 | 131 | }; |
| 131 | 132 | |
| @@ -453,6 +454,7 @@ struct dmub_srv { · 321 unmodified lines | ||
| 453 | 454 | * @pending_notification: Indicates there are other pending notifications |
| 454 | 455 | * @aux_reply: aux reply |
| 455 | 456 | * @hpd_status: hpd status |
| 457 | + * @bw_alloc_reply: BW Allocation reply from CM/DPIA | |
| 456 | 458 | */ |
| 457 | 459 | struct dmub_notification { |
| 458 | 460 | enum dmub_notification_type type; |
| @@ -463,6 +465,7 @@ struct dmub_notification { · 4 unmodified lines | ||
| 463 | 465 | struct aux_reply_data aux_reply; |
| 464 | 466 | enum dp_hpd_status hpd_status; |
| 465 | 467 | enum set_config_status sc_status; |
| 468 | + struct dpia_notification_reply_data bw_alloc_reply; | |
| 466 | 469 | }; |
| 467 | 470 | }; |
| 468 | 471 | |
| @@ -770,6 +770,7 @@ enum dmub_out_cmd_type { · 769 unmodified lines | ||
| 770 | 770 | * Command type used for SET_CONFIG Reply notification |
| 771 | 771 | */ |
| 772 | 772 | DMUB_OUT_CMD__SET_CONFIG_REPLY = 3, |
| 773 | + DMUB_OUT_CMD__DPIA_NOTIFICATION = 5 | |
| 773 | 774 | }; |
| 774 | 775 | |
| 775 | 776 | /* DMUB_CMD__DPIA command sub-types. */ |
| @@ -1516,6 +1517,84 @@ struct dp_hpd_data { · 740 unmodified lines | ||
| 1516 | 1517 | uint8_t pad; |
| 1517 | 1518 | }; |
| 1518 | 1519 | |
| 1520 | +/** | |
| 1521 | + * DPIA NOTIFICATION Response Type | |
| 1522 | + */ | |
| 1523 | +enum dpia_notify_bw_alloc_status { | |
| 1524 | + | |
| 1525 | + DPIA_BW_REQ_FAILED = 0, | |
| 1526 | + DPIA_BW_REQ_SUCCESS, | |
| 1527 | + DPIA_EST_BW_CHANGED, | |
| 1528 | + DPIA_BW_ALLOC_CAPS_CHANGED | |
| 1529 | +}; | |
| 1530 | + | |
| 1531 | +/* DMUB_OUT_CMD__DPIA_NOTIFY Reply command - OutBox Cmd */ | |
| 1532 | +/** | |
| 1533 | + * Data passed to driver from FW in a DMUB_OUT_CMD__DPIA_NOTIFY command. | |
| 1534 | + */ | |
| 1535 | +struct dpia_notification_reply_data { | |
| 1536 | + uint8_t allocated_bw; | |
| 1537 | + uint8_t estimated_bw; | |
| 1538 | +}; | |
| 1539 | + | |
| 1540 | +struct dpia_notification_common { | |
| 1541 | + bool shared; | |
| 1542 | +}; | |
| 1543 | + | |
| 1544 | +struct dpia_bw_allocation_notify_data { | |
| 1545 | + union { | |
| 1546 | + struct { | |
| 1547 | + uint16_t cm_bw_alloc_support: 1; /**< USB4 CM BW Allocation mode support */ | |
| 1548 | + uint16_t bw_request_failed: 1; /**< BW_Request_Failed */ | |
| 1549 | + uint16_t bw_request_succeeded: 1; /**< BW_Request_Succeeded */ | |
| 1550 | + uint16_t est_bw_changed: 1; /**< Estimated_BW changed */ | |
| 1551 | + uint16_t bw_alloc_cap_changed: 1; /**< BW_Allocation_Capabiity_Changed */ | |
| 1552 | + uint16_t reserved: 11; | |
| 1553 | + } bits; | |
| 1554 | + uint16_t flags; | |
| 1555 | + }; | |
| 1556 | + uint8_t cm_id; /**< CM ID */ | |
| 1557 | + uint8_t group_id; /**< Group ID */ | |
| 1558 | + uint8_t granularity; /**< BW Allocation Granularity */ | |
| 1559 | + uint8_t estimated_bw; /**< Estimated_BW */ | |
| 1560 | + uint8_t allocated_bw; /**< Allocated_BW */ | |
| 1561 | + uint8_t reserved; | |
| 1562 | +}; | |
| 1563 | + | |
| 1564 | +union dpia_notification_data { | |
| 1565 | + struct dpia_notification_common common_data; | |
| 1566 | + struct dpia_bw_allocation_notify_data dpia_bw_alloc; /**< Used for DPIA BW Allocation mode notification */ | |
| 1567 | +}; | |
| 1568 | + | |
| 1569 | +enum dmub_cmd_dpia_notification_type { | |
| 1570 | + DPIA_NOTIFY__BW_ALLOCATION = 0, | |
| 1571 | +}; | |
| 1572 | + | |
| 1573 | +struct dpia_notification_header { | |
| 1574 | + uint8_t instance; /**< DPIA Instance */ | |
| 1575 | + uint8_t reserved[3]; | |
| 1576 | + enum dmub_cmd_dpia_notification_type type; /**< DPIA notification type */ | |
| 1577 | +}; | |
| 1578 | + | |
| 1579 | +struct dpia_notification_payload { | |
| 1580 | + struct dpia_notification_header header; | |
| 1581 | + union dpia_notification_data data; /**< DPIA notification data */ | |
| 1582 | +}; | |
| 1583 | + | |
| 1584 | +/** | |
| 1585 | + * Definition of a DMUB_OUT_CMD__DPIA_NOTIFY command. | |
| 1586 | + */ | |
| 1587 | +struct dmub_rb_cmd_dpia_notification { | |
| 1588 | + /** | |
| 1589 | + * Command header. | |
| 1590 | + */ | |
| 1591 | + struct dmub_cmd_header header; /**< DPIA notification header */ | |
| 1592 | + /** | |
| 1593 | + * Data passed to driver from FW in a DMUB_OUT_CMD__DPIA_NOTIFY command. | |
| 1594 | + */ | |
| 1595 | + struct dpia_notification_payload payload; /**< DPIA notification payload */ | |
| 1596 | +}; | |
| 1597 | + | |
| 1519 | 1598 | /** |
| 1520 | 1599 | * Definition of a DMUB_OUT_CMD__DP_HPD_NOTIFY command. |
| 1521 | 1600 | */ |
| @@ -3422,6 +3501,10 @@ union dmub_rb_out_cmd { · 1900 unmodified lines | ||
| 3422 | 3501 | * SET_CONFIG reply command. |
| 3423 | 3502 | */ |
| 3424 | 3503 | struct dmub_rb_cmd_dp_set_config_reply set_config_reply; |
| 3504 | + /** | |
| 3505 | + * BW ALLOCATION notification command. | |
| 3506 | + */ | |
| 3507 | + struct dmub_rb_cmd_dpia_notification dpia_notify; | |
| 3425 | 3508 | }; |
| 3426 | 3509 | #pragma pack(pop) |
| 3427 | 3510 | |
| @@ -92,6 +92,27 @@ enum dmub_status dmub_srv_stat_get_notification(struct dmub_srv *dmub, · 91 unmodified lines | ||
| 92 | 92 | notify->link_index = cmd.set_config_reply.set_config_reply_control.instance; |
| 93 | 93 | notify->sc_status = cmd.set_config_reply.set_config_reply_control.status; |
| 94 | 94 | break; |
| 95 | + case DMUB_OUT_CMD__DPIA_NOTIFICATION: | |
| 96 | + notify->type = DMUB_NOTIFICATION_DPIA_NOTIFICATION; | |
| 97 | + notify->link_index = cmd.dpia_notify.payload.header.instance; | |
| 98 | + | |
| 99 | + if (cmd.dpia_notify.payload.header.type == DPIA_NOTIFY__BW_ALLOCATION) { | |
| 100 | + | |
| 101 | + if (cmd.dpia_notify.payload.data.dpia_bw_alloc.bits.bw_request_failed) { | |
| 102 | + notify->result = DPIA_BW_REQ_FAILED; | |
| 103 | + } else if (cmd.dpia_notify.payload.data.dpia_bw_alloc.bits.bw_request_succeeded) { | |
| 104 | + notify->result = DPIA_BW_REQ_SUCCESS; | |
| 105 | + notify->bw_alloc_reply.allocated_bw = | |
| 106 | + cmd.dpia_notify.payload.data.dpia_bw_alloc.allocated_bw; | |
| 107 | + } else if (cmd.dpia_notify.payload.data.dpia_bw_alloc.bits.est_bw_changed) { | |
| 108 | + notify->result = DPIA_EST_BW_CHANGED; | |
| 109 | + notify->bw_alloc_reply.estimated_bw = | |
| 110 | + cmd.dpia_notify.payload.data.dpia_bw_alloc.estimated_bw; | |
| 111 | + } else if (cmd.dpia_notify.payload.data.dpia_bw_alloc.bits.bw_alloc_cap_changed) { | |
| 112 | + notify->result = DPIA_BW_ALLOC_CAPS_CHANGED; | |
| 113 | + } | |
| 114 | + } | |
| 115 | + break; | |
| 95 | 116 | default: |
| 96 | 117 | notify->type = DMUB_NOTIFICATION_NO_DATA; |
| 97 | 118 | break; |
| @@ -88,7 +88,10 @@ enum dpcd_phy_test_patterns { · 87 unmodified lines | ||
| 88 | 88 | PHY_TEST_PATTERN_PRBS23 = 0x30, |
| 89 | 89 | PHY_TEST_PATTERN_PRBS31 = 0x38, |
| 90 | 90 | PHY_TEST_PATTERN_264BIT_CUSTOM = 0x40, |
| 91 | − PHY_TEST_PATTERN_SQUARE_PULSE = 0x48, | |
| 91 | + PHY_TEST_PATTERN_SQUARE = 0x48, | |
| 92 | + PHY_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED = 0x49, | |
| 93 | + PHY_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED = 0x4A, | |
| 94 | + PHY_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED = 0x4B, | |
| 92 | 95 | }; |
| 93 | 96 | |
| 94 | 97 | enum dpcd_test_dyn_range { |
| @@ -165,7 +165,12 @@ enum dp_test_pattern { · 164 unmodified lines | ||
| 165 | 165 | DP_TEST_PATTERN_PRBS23, |
| 166 | 166 | DP_TEST_PATTERN_PRBS31, |
| 167 | 167 | DP_TEST_PATTERN_264BIT_CUSTOM, |
| 168 | − DP_TEST_PATTERN_SQUARE_PULSE, | |
| 168 | + DP_TEST_PATTERN_SQUARE_BEGIN, | |
| 169 | + DP_TEST_PATTERN_SQUARE = DP_TEST_PATTERN_SQUARE_BEGIN, | |
| 170 | + DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED, | |
| 171 | + DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED, | |
| 172 | + DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED, | |
| 173 | + DP_TEST_PATTERN_SQUARE_END = DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED, | |
| 169 | 174 | |
| 170 | 175 | /* Link Training Patterns */ |
| 171 | 176 | DP_TEST_PATTERN_TRAINING_PATTERN1, |
| @@ -0,0 +1,30 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2022 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included | |
| 12 | + * in all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 15 | + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |
| 18 | + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
| 19 | + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| 20 | + */ | |
| 21 | + | |
| 22 | +#ifndef _df_4_3_OFFSET_HEADER | |
| 23 | +#define _df_4_3_OFFSET_HEADER | |
| 24 | + | |
| 25 | +#define regDF_CS_UMC_AON0_HardwareAssertMaskLow 0x0e3e | |
| 26 | +#define regDF_CS_UMC_AON0_HardwareAssertMaskLow_BASE_IDX 4 | |
| 27 | +#define regDF_NCS_PG0_HardwareAssertMaskHigh 0x0e3f | |
| 28 | +#define regDF_NCS_PG0_HardwareAssertMaskHigh_BASE_IDX 4 | |
| 29 | + | |
| 30 | +#endif | |
| @@ -0,0 +1,157 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2022 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included | |
| 12 | + * in all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 15 | + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |
| 18 | + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
| 19 | + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| 20 | + */ | |
| 21 | + | |
| 22 | +#ifndef _df_4_3_SH_MASK_HEADER | |
| 23 | +#define _df_4_3_SH_MASK_HEADER | |
| 24 | + | |
| 25 | +//DF_CS_UMC_AON0_HardwareAssertMaskLow | |
| 26 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk0__SHIFT 0x0 | |
| 27 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk1__SHIFT 0x1 | |
| 28 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk2__SHIFT 0x2 | |
| 29 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk3__SHIFT 0x3 | |
| 30 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk4__SHIFT 0x4 | |
| 31 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk5__SHIFT 0x5 | |
| 32 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk6__SHIFT 0x6 | |
| 33 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk7__SHIFT 0x7 | |
| 34 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk8__SHIFT 0x8 | |
| 35 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk9__SHIFT 0x9 | |
| 36 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk10__SHIFT 0xa | |
| 37 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk11__SHIFT 0xb | |
| 38 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk12__SHIFT 0xc | |
| 39 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk13__SHIFT 0xd | |
| 40 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk14__SHIFT 0xe | |
| 41 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk15__SHIFT 0xf | |
| 42 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk16__SHIFT 0x10 | |
| 43 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk17__SHIFT 0x11 | |
| 44 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk18__SHIFT 0x12 | |
| 45 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk19__SHIFT 0x13 | |
| 46 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk20__SHIFT 0x14 | |
| 47 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk21__SHIFT 0x15 | |
| 48 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk22__SHIFT 0x16 | |
| 49 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk23__SHIFT 0x17 | |
| 50 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk24__SHIFT 0x18 | |
| 51 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk25__SHIFT 0x19 | |
| 52 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk26__SHIFT 0x1a | |
| 53 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk27__SHIFT 0x1b | |
| 54 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk28__SHIFT 0x1c | |
| 55 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk29__SHIFT 0x1d | |
| 56 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk30__SHIFT 0x1e | |
| 57 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk31__SHIFT 0x1f | |
| 58 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk0_MASK 0x00000001L | |
| 59 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk1_MASK 0x00000002L | |
| 60 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk2_MASK 0x00000004L | |
| 61 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk3_MASK 0x00000008L | |
| 62 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk4_MASK 0x00000010L | |
| 63 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk5_MASK 0x00000020L | |
| 64 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk6_MASK 0x00000040L | |
| 65 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk7_MASK 0x00000080L | |
| 66 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk8_MASK 0x00000100L | |
| 67 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk9_MASK 0x00000200L | |
| 68 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk10_MASK 0x00000400L | |
| 69 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk11_MASK 0x00000800L | |
| 70 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk12_MASK 0x00001000L | |
| 71 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk13_MASK 0x00002000L | |
| 72 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk14_MASK 0x00004000L | |
| 73 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk15_MASK 0x00008000L | |
| 74 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk16_MASK 0x00010000L | |
| 75 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk17_MASK 0x00020000L | |
| 76 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk18_MASK 0x00040000L | |
| 77 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk19_MASK 0x00080000L | |
| 78 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk20_MASK 0x00100000L | |
| 79 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk21_MASK 0x00200000L | |
| 80 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk22_MASK 0x00400000L | |
| 81 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk23_MASK 0x00800000L | |
| 82 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk24_MASK 0x01000000L | |
| 83 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk25_MASK 0x02000000L | |
| 84 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk26_MASK 0x04000000L | |
| 85 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk27_MASK 0x08000000L | |
| 86 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk28_MASK 0x10000000L | |
| 87 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk29_MASK 0x20000000L | |
| 88 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk30_MASK 0x40000000L | |
| 89 | +#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk31_MASK 0x80000000L | |
| 90 | + | |
| 91 | +//DF_NCS_PG0_HardwareAssertMaskHigh | |
| 92 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk0__SHIFT 0x0 | |
| 93 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk1__SHIFT 0x1 | |
| 94 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk2__SHIFT 0x2 | |
| 95 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk3__SHIFT 0x3 | |
| 96 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk4__SHIFT 0x4 | |
| 97 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk5__SHIFT 0x5 | |
| 98 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk6__SHIFT 0x6 | |
| 99 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk7__SHIFT 0x7 | |
| 100 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk8__SHIFT 0x8 | |
| 101 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk9__SHIFT 0x9 | |
| 102 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk10__SHIFT 0xa | |
| 103 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk11__SHIFT 0xb | |
| 104 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk12__SHIFT 0xc | |
| 105 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk13__SHIFT 0xd | |
| 106 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk14__SHIFT 0xe | |
| 107 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk15__SHIFT 0xf | |
| 108 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk16__SHIFT 0x10 | |
| 109 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk17__SHIFT 0x11 | |
| 110 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk18__SHIFT 0x12 | |
| 111 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk19__SHIFT 0x13 | |
| 112 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk20__SHIFT 0x14 | |
| 113 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk21__SHIFT 0x15 | |
| 114 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk22__SHIFT 0x16 | |
| 115 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk23__SHIFT 0x17 | |
| 116 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk24__SHIFT 0x18 | |
| 117 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk25__SHIFT 0x19 | |
| 118 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk26__SHIFT 0x1a | |
| 119 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk27__SHIFT 0x1b | |
| 120 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk28__SHIFT 0x1c | |
| 121 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk29__SHIFT 0x1d | |
| 122 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk30__SHIFT 0x1e | |
| 123 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk31__SHIFT 0x1f | |
| 124 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk0_MASK 0x00000001L | |
| 125 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk1_MASK 0x00000002L | |
| 126 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk2_MASK 0x00000004L | |
| 127 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk3_MASK 0x00000008L | |
| 128 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk4_MASK 0x00000010L | |
| 129 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk5_MASK 0x00000020L | |
| 130 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk6_MASK 0x00000040L | |
| 131 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk7_MASK 0x00000080L | |
| 132 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk8_MASK 0x00000100L | |
| 133 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk9_MASK 0x00000200L | |
| 134 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk10_MASK 0x00000400L | |
| 135 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk11_MASK 0x00000800L | |
| 136 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk12_MASK 0x00001000L | |
| 137 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk13_MASK 0x00002000L | |
| 138 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk14_MASK 0x00004000L | |
| 139 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk15_MASK 0x00008000L | |
| 140 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk16_MASK 0x00010000L | |
| 141 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk17_MASK 0x00020000L | |
| 142 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk18_MASK 0x00040000L | |
| 143 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk19_MASK 0x00080000L | |
| 144 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk20_MASK 0x00100000L | |
| 145 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk21_MASK 0x00200000L | |
| 146 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk22_MASK 0x00400000L | |
| 147 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk23_MASK 0x00800000L | |
| 148 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk24_MASK 0x01000000L | |
| 149 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk25_MASK 0x02000000L | |
| 150 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk26_MASK 0x04000000L | |
| 151 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk27_MASK 0x08000000L | |
| 152 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk28_MASK 0x10000000L | |
| 153 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk29_MASK 0x20000000L | |
| 154 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk30_MASK 0x40000000L | |
| 155 | +#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk31_MASK 0x80000000L | |
| 156 | + | |
| 157 | +#endif | |
| @@ -139,6 +139,8 @@ enum amd_pp_sensors { · 138 unmodified lines | ||
| 139 | 139 | AMDGPU_PP_SENSOR_MIN_FAN_RPM, |
| 140 | 140 | AMDGPU_PP_SENSOR_MAX_FAN_RPM, |
| 141 | 141 | AMDGPU_PP_SENSOR_VCN_POWER_STATE, |
| 142 | + AMDGPU_PP_SENSOR_PEAK_PSTATE_SCLK, | |
| 143 | + AMDGPU_PP_SENSOR_PEAK_PSTATE_MCLK, | |
| 142 | 144 | }; |
| 143 | 145 | |
| 144 | 146 | enum amd_pp_task { |
| @@ -769,10 +769,16 @@ static int pp_dpm_read_sensor(void *handle, int idx, · 768 unmodified lines | ||
| 769 | 769 | |
| 770 | 770 | switch (idx) { |
| 771 | 771 | case AMDGPU_PP_SENSOR_STABLE_PSTATE_SCLK: |
| 772 | − *((uint32_t *)value) = hwmgr->pstate_sclk; | |
| 772 | + *((uint32_t *)value) = hwmgr->pstate_sclk * 100; | |
| 773 | 773 | return 0; |
| 774 | 774 | case AMDGPU_PP_SENSOR_STABLE_PSTATE_MCLK: |
| 775 | − *((uint32_t *)value) = hwmgr->pstate_mclk; | |
| 775 | + *((uint32_t *)value) = hwmgr->pstate_mclk * 100; | |
| 776 | + return 0; | |
| 777 | + case AMDGPU_PP_SENSOR_PEAK_PSTATE_SCLK: | |
| 778 | + *((uint32_t *)value) = hwmgr->pstate_sclk_peak * 100; | |
| 779 | + return 0; | |
| 780 | + case AMDGPU_PP_SENSOR_PEAK_PSTATE_MCLK: | |
| 781 | + *((uint32_t *)value) = hwmgr->pstate_mclk_peak * 100; | |
| 776 | 782 | return 0; |
| 777 | 783 | case AMDGPU_PP_SENSOR_MIN_FAN_RPM: |
| 778 | 784 | *((uint32_t *)value) = hwmgr->thermal_controller.fanInfo.ulMinRPM; |
| @@ -375,6 +375,17 @@ static int smu10_enable_gfx_off(struct pp_hwmgr *hwmgr) · 374 unmodified lines | ||
| 375 | 375 | return 0; |
| 376 | 376 | } |
| 377 | 377 | |
| 378 | +static void smu10_populate_umdpstate_clocks(struct pp_hwmgr *hwmgr) | |
| 379 | +{ | |
| 380 | + hwmgr->pstate_sclk = SMU10_UMD_PSTATE_GFXCLK; | |
| 381 | + hwmgr->pstate_mclk = SMU10_UMD_PSTATE_FCLK; | |
| 382 | + | |
| 383 | + smum_send_msg_to_smc(hwmgr, | |
| 384 | + PPSMC_MSG_GetMaxGfxclkFrequency, | |
| 385 | + &hwmgr->pstate_sclk_peak); | |
| 386 | + hwmgr->pstate_mclk_peak = SMU10_UMD_PSTATE_PEAK_FCLK; | |
| 387 | +} | |
| 388 | + | |
| 378 | 389 | static int smu10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) |
| 379 | 390 | { |
| 380 | 391 | struct amdgpu_device *adev = hwmgr->adev; |
| @@ -398,6 +409,8 @@ static int smu10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) · 17 unmodified lines | ||
| 398 | 409 | return ret; |
| 399 | 410 | } |
| 400 | 411 | |
| 412 | + smu10_populate_umdpstate_clocks(hwmgr); | |
| 413 | + | |
| 401 | 414 | return 0; |
| 402 | 415 | } |
| 403 | 416 | |
| @@ -574,9 +587,6 @@ static int smu10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) · 170 unmodified lines | ||
| 574 | 587 | |
| 575 | 588 | hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50; |
| 576 | 589 | |
| 577 | − hwmgr->pstate_sclk = SMU10_UMD_PSTATE_GFXCLK * 100; | |
| 578 | − hwmgr->pstate_mclk = SMU10_UMD_PSTATE_FCLK * 100; | |
| 579 | − | |
| 580 | 590 | /* enable the pp_od_clk_voltage sysfs file */ |
| 581 | 591 | hwmgr->od_enabled = 1; |
| 582 | 592 | /* disabled fine grain tuning function by default */ |
| @@ -1501,6 +1501,65 @@ static int smu7_populate_edc_leakage_registers(struct pp_hwmgr *hwmgr) · 1500 unmodified lines | ||
| 1501 | 1501 | return ret; |
| 1502 | 1502 | } |
| 1503 | 1503 | |
| 1504 | +static void smu7_populate_umdpstate_clocks(struct pp_hwmgr *hwmgr) | |
| 1505 | +{ | |
| 1506 | + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); | |
| 1507 | + struct smu7_dpm_table *golden_dpm_table = &data->golden_dpm_table; | |
| 1508 | + struct phm_clock_voltage_dependency_table *vddc_dependency_on_sclk = | |
| 1509 | + hwmgr->dyn_state.vddc_dependency_on_sclk; | |
| 1510 | + struct phm_ppt_v1_information *table_info = | |
| 1511 | + (struct phm_ppt_v1_information *)(hwmgr->pptable); | |
| 1512 | + struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_sclk = | |
| 1513 | + table_info->vdd_dep_on_sclk; | |
| 1514 | + int32_t tmp_sclk, count, percentage; | |
| 1515 | + | |
| 1516 | + if (golden_dpm_table->mclk_table.count == 1) { | |
| 1517 | + percentage = 70; | |
| 1518 | + hwmgr->pstate_mclk = golden_dpm_table->mclk_table.dpm_levels[0].value; | |
| 1519 | + } else { | |
| 1520 | + percentage = 100 * golden_dpm_table->sclk_table.dpm_levels[golden_dpm_table->sclk_table.count - 1].value / | |
| 1521 | + golden_dpm_table->mclk_table.dpm_levels[golden_dpm_table->mclk_table.count - 1].value; | |
| 1522 | + hwmgr->pstate_mclk = golden_dpm_table->mclk_table.dpm_levels[golden_dpm_table->mclk_table.count - 2].value; | |
| 1523 | + } | |
| 1524 | + | |
| 1525 | + tmp_sclk = hwmgr->pstate_mclk * percentage / 100; | |
| 1526 | + | |
| 1527 | + if (hwmgr->pp_table_version == PP_TABLE_V0) { | |
| 1528 | + for (count = vddc_dependency_on_sclk->count - 1; count >= 0; count--) { | |
| 1529 | + if (tmp_sclk >= vddc_dependency_on_sclk->entries[count].clk) { | |
| 1530 | + hwmgr->pstate_sclk = vddc_dependency_on_sclk->entries[count].clk; | |
| 1531 | + break; | |
| 1532 | + } | |
| 1533 | + } | |
| 1534 | + if (count < 0) | |
| 1535 | + hwmgr->pstate_sclk = vddc_dependency_on_sclk->entries[0].clk; | |
| 1536 | + | |
| 1537 | + hwmgr->pstate_sclk_peak = | |
| 1538 | + vddc_dependency_on_sclk->entries[vddc_dependency_on_sclk->count - 1].clk; | |
| 1539 | + } else if (hwmgr->pp_table_version == PP_TABLE_V1) { | |
| 1540 | + for (count = vdd_dep_on_sclk->count - 1; count >= 0; count--) { | |
| 1541 | + if (tmp_sclk >= vdd_dep_on_sclk->entries[count].clk) { | |
| 1542 | + hwmgr->pstate_sclk = vdd_dep_on_sclk->entries[count].clk; | |
| 1543 | + break; | |
| 1544 | + } | |
| 1545 | + } | |
| 1546 | + if (count < 0) | |
| 1547 | + hwmgr->pstate_sclk = vdd_dep_on_sclk->entries[0].clk; | |
| 1548 | + | |
| 1549 | + hwmgr->pstate_sclk_peak = | |
| 1550 | + vdd_dep_on_sclk->entries[vdd_dep_on_sclk->count - 1].clk; | |
| 1551 | + } | |
| 1552 | + | |
| 1553 | + hwmgr->pstate_mclk_peak = | |
| 1554 | + golden_dpm_table->mclk_table.dpm_levels[golden_dpm_table->mclk_table.count - 1].value; | |
| 1555 | + | |
| 1556 | + /* make sure the output is in Mhz */ | |
| 1557 | + hwmgr->pstate_sclk /= 100; | |
| 1558 | + hwmgr->pstate_mclk /= 100; | |
| 1559 | + hwmgr->pstate_sclk_peak /= 100; | |
| 1560 | + hwmgr->pstate_mclk_peak /= 100; | |
| 1561 | +} | |
| 1562 | + | |
| 1504 | 1563 | static int smu7_enable_dpm_tasks(struct pp_hwmgr *hwmgr) |
| 1505 | 1564 | { |
| 1506 | 1565 | int tmp_result = 0; |
| @@ -1625,6 +1684,8 @@ static int smu7_enable_dpm_tasks(struct pp_hwmgr *hwmgr) · 118 unmodified lines | ||
| 1625 | 1684 | PP_ASSERT_WITH_CODE((0 == tmp_result), |
| 1626 | 1685 | "pcie performance request failed!", result = tmp_result); |
| 1627 | 1686 | |
| 1687 | + smu7_populate_umdpstate_clocks(hwmgr); | |
| 1688 | + | |
| 1628 | 1689 | return 0; |
| 1629 | 1690 | } |
| 1630 | 1691 | |
| @@ -3143,15 +3204,12 @@ static int smu7_get_profiling_clk(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_le · 1512 unmodified lines | ||
| 3143 | 3204 | for (count = hwmgr->dyn_state.vddc_dependency_on_sclk->count-1; |
| 3144 | 3205 | count >= 0; count--) { |
| 3145 | 3206 | if (tmp_sclk >= hwmgr->dyn_state.vddc_dependency_on_sclk->entries[count].clk) { |
| 3146 | − tmp_sclk = hwmgr->dyn_state.vddc_dependency_on_sclk->entries[count].clk; | |
| 3147 | 3207 | *sclk_mask = count; |
| 3148 | 3208 | break; |
| 3149 | 3209 | } |
| 3150 | 3210 | } |
| 3151 | − if (count < 0 || level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) { | |
| 3211 | + if (count < 0 || level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) | |
| 3152 | 3212 | *sclk_mask = 0; |
| 3153 | − tmp_sclk = hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].clk; | |
| 3154 | − } | |
| 3155 | 3213 | |
| 3156 | 3214 | if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) |
| 3157 | 3215 | *sclk_mask = hwmgr->dyn_state.vddc_dependency_on_sclk->count-1; |
| @@ -3161,15 +3219,12 @@ static int smu7_get_profiling_clk(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_le · 3 unmodified lines | ||
| 3161 | 3219 | |
| 3162 | 3220 | for (count = table_info->vdd_dep_on_sclk->count-1; count >= 0; count--) { |
| 3163 | 3221 | if (tmp_sclk >= table_info->vdd_dep_on_sclk->entries[count].clk) { |
| 3164 | − tmp_sclk = table_info->vdd_dep_on_sclk->entries[count].clk; | |
| 3165 | 3222 | *sclk_mask = count; |
| 3166 | 3223 | break; |
| 3167 | 3224 | } |
| 3168 | 3225 | } |
| 3169 | − if (count < 0 || level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) { | |
| 3226 | + if (count < 0 || level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) | |
| 3170 | 3227 | *sclk_mask = 0; |
| 3171 | − tmp_sclk = table_info->vdd_dep_on_sclk->entries[0].clk; | |
| 3172 | − } | |
| 3173 | 3228 | |
| 3174 | 3229 | if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) |
| 3175 | 3230 | *sclk_mask = table_info->vdd_dep_on_sclk->count - 1; |
| @@ -3181,8 +3236,6 @@ static int smu7_get_profiling_clk(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_le · 5 unmodified lines | ||
| 3181 | 3236 | *mclk_mask = golden_dpm_table->mclk_table.count - 1; |
| 3182 | 3237 | |
| 3183 | 3238 | *pcie_mask = data->dpm_table.pcie_speed_table.count - 1; |
| 3184 | − hwmgr->pstate_sclk = tmp_sclk; | |
| 3185 | − hwmgr->pstate_mclk = tmp_mclk; | |
| 3186 | 3239 | |
| 3187 | 3240 | return 0; |
| 3188 | 3241 | } |
| @@ -3195,9 +3248,6 @@ static int smu7_force_dpm_level(struct pp_hwmgr *hwmgr, · 6 unmodified lines | ||
| 3195 | 3248 | uint32_t mclk_mask = 0; |
| 3196 | 3249 | uint32_t pcie_mask = 0; |
| 3197 | 3250 | |
| 3198 | − if (hwmgr->pstate_sclk == 0) | |
| 3199 | − smu7_get_profiling_clk(hwmgr, level, &sclk_mask, &mclk_mask, &pcie_mask); | |
| 3200 | − | |
| 3201 | 3251 | switch (level) { |
| 3202 | 3252 | case AMD_DPM_FORCED_LEVEL_HIGH: |
| 3203 | 3253 | ret = smu7_force_dpm_highest(hwmgr); |
| @@ -1016,6 +1016,18 @@ static void smu8_reset_acp_boot_level(struct pp_hwmgr *hwmgr) · 1015 unmodified lines | ||
| 1016 | 1016 | data->acp_boot_level = 0xff; |
| 1017 | 1017 | } |
| 1018 | 1018 | |
| 1019 | +static void smu8_populate_umdpstate_clocks(struct pp_hwmgr *hwmgr) | |
| 1020 | +{ | |
| 1021 | + struct phm_clock_voltage_dependency_table *table = | |
| 1022 | + hwmgr->dyn_state.vddc_dependency_on_sclk; | |
| 1023 | + | |
| 1024 | + hwmgr->pstate_sclk = table->entries[0].clk / 100; | |
| 1025 | + hwmgr->pstate_mclk = 0; | |
| 1026 | + | |
| 1027 | + hwmgr->pstate_sclk_peak = table->entries[table->count - 1].clk / 100; | |
| 1028 | + hwmgr->pstate_mclk_peak = 0; | |
| 1029 | +} | |
| 1030 | + | |
| 1019 | 1031 | static int smu8_enable_dpm_tasks(struct pp_hwmgr *hwmgr) |
| 1020 | 1032 | { |
| 1021 | 1033 | smu8_program_voting_clients(hwmgr); |
| @@ -1024,6 +1036,8 @@ static int smu8_enable_dpm_tasks(struct pp_hwmgr *hwmgr) · 2 unmodified lines | ||
| 1024 | 1036 | smu8_program_bootup_state(hwmgr); |
| 1025 | 1037 | smu8_reset_acp_boot_level(hwmgr); |
| 1026 | 1038 | |
| 1039 | + smu8_populate_umdpstate_clocks(hwmgr); | |
| 1040 | + | |
| 1027 | 1041 | return 0; |
| 1028 | 1042 | } |
| 1029 | 1043 | |
| @@ -1167,8 +1181,6 @@ static int smu8_phm_unforce_dpm_levels(struct pp_hwmgr *hwmgr) · 137 unmodified lines | ||
| 1167 | 1181 | |
| 1168 | 1182 | data->sclk_dpm.soft_min_clk = table->entries[0].clk; |
| 1169 | 1183 | data->sclk_dpm.hard_min_clk = table->entries[0].clk; |
| 1170 | − hwmgr->pstate_sclk = table->entries[0].clk; | |
| 1171 | − hwmgr->pstate_mclk = 0; | |
| 1172 | 1184 | |
| 1173 | 1185 | level = smu8_get_max_sclk_level(hwmgr) - 1; |
| 1174 | 1186 | |
| @@ -3008,6 +3008,30 @@ static int vega10_enable_disable_PCC_limit_feature(struct pp_hwmgr *hwmgr, bool · 3007 unmodified lines | ||
| 3008 | 3008 | return 0; |
| 3009 | 3009 | } |
| 3010 | 3010 | |
| 3011 | +static void vega10_populate_umdpstate_clocks(struct pp_hwmgr *hwmgr) | |
| 3012 | +{ | |
| 3013 | + struct phm_ppt_v2_information *table_info = | |
| 3014 | + (struct phm_ppt_v2_information *)(hwmgr->pptable); | |
| 3015 | + | |
| 3016 | + if (table_info->vdd_dep_on_sclk->count > VEGA10_UMD_PSTATE_GFXCLK_LEVEL && | |
| 3017 | + table_info->vdd_dep_on_mclk->count > VEGA10_UMD_PSTATE_MCLK_LEVEL) { | |
| 3018 | + hwmgr->pstate_sclk = table_info->vdd_dep_on_sclk->entries[VEGA10_UMD_PSTATE_GFXCLK_LEVEL].clk; | |
| 3019 | + hwmgr->pstate_mclk = table_info->vdd_dep_on_mclk->entries[VEGA10_UMD_PSTATE_MCLK_LEVEL].clk; | |
| 3020 | + } else { | |
| 3021 | + hwmgr->pstate_sclk = table_info->vdd_dep_on_sclk->entries[0].clk; | |
| 3022 | + hwmgr->pstate_mclk = table_info->vdd_dep_on_mclk->entries[0].clk; | |
| 3023 | + } | |
| 3024 | + | |
| 3025 | + hwmgr->pstate_sclk_peak = table_info->vdd_dep_on_sclk->entries[table_info->vdd_dep_on_sclk->count - 1].clk; | |
| 3026 | + hwmgr->pstate_mclk_peak = table_info->vdd_dep_on_mclk->entries[table_info->vdd_dep_on_mclk->count - 1].clk; | |
| 3027 | + | |
| 3028 | + /* make sure the output is in Mhz */ | |
| 3029 | + hwmgr->pstate_sclk /= 100; | |
| 3030 | + hwmgr->pstate_mclk /= 100; | |
| 3031 | + hwmgr->pstate_sclk_peak /= 100; | |
| 3032 | + hwmgr->pstate_mclk_peak /= 100; | |
| 3033 | +} | |
| 3034 | + | |
| 3011 | 3035 | static int vega10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) |
| 3012 | 3036 | { |
| 3013 | 3037 | struct vega10_hwmgr *data = hwmgr->backend; |
| @@ -3082,6 +3106,8 @@ static int vega10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) · 68 unmodified lines | ||
| 3082 | 3106 | result = tmp_result); |
| 3083 | 3107 | } |
| 3084 | 3108 | |
| 3109 | + vega10_populate_umdpstate_clocks(hwmgr); | |
| 3110 | + | |
| 3085 | 3111 | return result; |
| 3086 | 3112 | } |
| 3087 | 3113 | |
| @@ -4169,8 +4195,6 @@ static int vega10_get_profiling_clk_mask(struct pp_hwmgr *hwmgr, enum amd_dpm_fo · 1081 unmodified lines | ||
| 4169 | 4195 | *sclk_mask = VEGA10_UMD_PSTATE_GFXCLK_LEVEL; |
| 4170 | 4196 | *soc_mask = VEGA10_UMD_PSTATE_SOCCLK_LEVEL; |
| 4171 | 4197 | *mclk_mask = VEGA10_UMD_PSTATE_MCLK_LEVEL; |
| 4172 | − hwmgr->pstate_sclk = table_info->vdd_dep_on_sclk->entries[VEGA10_UMD_PSTATE_GFXCLK_LEVEL].clk; | |
| 4173 | − hwmgr->pstate_mclk = table_info->vdd_dep_on_mclk->entries[VEGA10_UMD_PSTATE_MCLK_LEVEL].clk; | |
| 4174 | 4198 | } |
| 4175 | 4199 | |
| 4176 | 4200 | if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) { |
| @@ -4281,9 +4305,6 @@ static int vega10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 104 unmodified lines | ||
| 4281 | 4305 | uint32_t mclk_mask = 0; |
| 4282 | 4306 | uint32_t soc_mask = 0; |
| 4283 | 4307 | |
| 4284 | − if (hwmgr->pstate_sclk == 0) | |
| 4285 | − vega10_get_profiling_clk_mask(hwmgr, level, &sclk_mask, &mclk_mask, &soc_mask); | |
| 4286 | − | |
| 4287 | 4308 | switch (level) { |
| 4288 | 4309 | case AMD_DPM_FORCED_LEVEL_HIGH: |
| 4289 | 4310 | ret = vega10_force_dpm_highest(hwmgr); |
| @@ -1026,6 +1026,25 @@ static int vega12_get_all_clock_ranges(struct pp_hwmgr *hwmgr) · 1025 unmodified lines | ||
| 1026 | 1026 | return 0; |
| 1027 | 1027 | } |
| 1028 | 1028 | |
| 1029 | +static void vega12_populate_umdpstate_clocks(struct pp_hwmgr *hwmgr) | |
| 1030 | +{ | |
| 1031 | + struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); | |
| 1032 | + struct vega12_single_dpm_table *gfx_dpm_table = &(data->dpm_table.gfx_table); | |
| 1033 | + struct vega12_single_dpm_table *mem_dpm_table = &(data->dpm_table.mem_table); | |
| 1034 | + | |
| 1035 | + if (gfx_dpm_table->count > VEGA12_UMD_PSTATE_GFXCLK_LEVEL && | |
| 1036 | + mem_dpm_table->count > VEGA12_UMD_PSTATE_MCLK_LEVEL) { | |
| 1037 | + hwmgr->pstate_sclk = gfx_dpm_table->dpm_levels[VEGA12_UMD_PSTATE_GFXCLK_LEVEL].value; | |
| 1038 | + hwmgr->pstate_mclk = mem_dpm_table->dpm_levels[VEGA12_UMD_PSTATE_MCLK_LEVEL].value; | |
| 1039 | + } else { | |
| 1040 | + hwmgr->pstate_sclk = gfx_dpm_table->dpm_levels[0].value; | |
| 1041 | + hwmgr->pstate_mclk = mem_dpm_table->dpm_levels[0].value; | |
| 1042 | + } | |
| 1043 | + | |
| 1044 | + hwmgr->pstate_sclk_peak = gfx_dpm_table->dpm_levels[gfx_dpm_table->count].value; | |
| 1045 | + hwmgr->pstate_mclk_peak = mem_dpm_table->dpm_levels[mem_dpm_table->count].value; | |
| 1046 | +} | |
| 1047 | + | |
| 1029 | 1048 | static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr) |
| 1030 | 1049 | { |
| 1031 | 1050 | int tmp_result, result = 0; |
| @@ -1077,6 +1096,9 @@ static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr) · 45 unmodified lines | ||
| 1077 | 1096 | PP_ASSERT_WITH_CODE(!result, |
| 1078 | 1097 | "Failed to setup default DPM tables!", |
| 1079 | 1098 | return result); |
| 1099 | + | |
| 1100 | + vega12_populate_umdpstate_clocks(hwmgr); | |
| 1101 | + | |
| 1080 | 1102 | return result; |
| 1081 | 1103 | } |
| 1082 | 1104 | |
| @@ -1555,26 +1555,23 @@ static int vega20_set_mclk_od( · 1554 unmodified lines | ||
| 1555 | 1555 | return 0; |
| 1556 | 1556 | } |
| 1557 | 1557 | |
| 1558 | −static int vega20_populate_umdpstate_clocks( | |
| 1559 | − struct pp_hwmgr *hwmgr) | |
| 1558 | +static void vega20_populate_umdpstate_clocks(struct pp_hwmgr *hwmgr) | |
| 1560 | 1559 | { |
| 1561 | 1560 | struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); |
| 1562 | 1561 | struct vega20_single_dpm_table *gfx_table = &(data->dpm_table.gfx_table); |
| 1563 | 1562 | struct vega20_single_dpm_table *mem_table = &(data->dpm_table.mem_table); |
| 1564 | 1563 | |
| 1565 | − hwmgr->pstate_sclk = gfx_table->dpm_levels[0].value; | |
| 1566 | − hwmgr->pstate_mclk = mem_table->dpm_levels[0].value; | |
| 1567 | − | |
| 1568 | 1564 | if (gfx_table->count > VEGA20_UMD_PSTATE_GFXCLK_LEVEL && |
| 1569 | 1565 | mem_table->count > VEGA20_UMD_PSTATE_MCLK_LEVEL) { |
| 1570 | 1566 | hwmgr->pstate_sclk = gfx_table->dpm_levels[VEGA20_UMD_PSTATE_GFXCLK_LEVEL].value; |
| 1571 | 1567 | hwmgr->pstate_mclk = mem_table->dpm_levels[VEGA20_UMD_PSTATE_MCLK_LEVEL].value; |
| 1568 | + } else { | |
| 1569 | + hwmgr->pstate_sclk = gfx_table->dpm_levels[0].value; | |
| 1570 | + hwmgr->pstate_mclk = mem_table->dpm_levels[0].value; | |
| 1572 | 1571 | } |
| 1573 | 1572 | |
| 1574 | − hwmgr->pstate_sclk = hwmgr->pstate_sclk * 100; | |
| 1575 | − hwmgr->pstate_mclk = hwmgr->pstate_mclk * 100; | |
| 1576 | − | |
| 1577 | − return 0; | |
| 1573 | + hwmgr->pstate_sclk_peak = gfx_table->dpm_levels[gfx_table->count - 1].value; | |
| 1574 | + hwmgr->pstate_mclk_peak = mem_table->dpm_levels[mem_table->count - 1].value; | |
| 1578 | 1575 | } |
| 1579 | 1576 | |
| 1580 | 1577 | static int vega20_get_max_sustainable_clock(struct pp_hwmgr *hwmgr, |
| @@ -1753,10 +1750,7 @@ static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr) · 172 unmodified lines | ||
| 1753 | 1750 | "[EnableDPMTasks] Failed to initialize odn settings!", |
| 1754 | 1751 | return result); |
| 1755 | 1752 | |
| 1756 | − result = vega20_populate_umdpstate_clocks(hwmgr); | |
| 1757 | − PP_ASSERT_WITH_CODE(!result, | |
| 1758 | − "[EnableDPMTasks] Failed to populate umdpstate clocks!", | |
| 1759 | − return result); | |
| 1753 | + vega20_populate_umdpstate_clocks(hwmgr); | |
| 1760 | 1754 | |
| 1761 | 1755 | result = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetPptLimit, |
| 1762 | 1756 | POWER_SOURCE_AC << 16, &hwmgr->default_power_limit); |
| @@ -809,6 +809,8 @@ struct pp_hwmgr { · 808 unmodified lines | ||
| 809 | 809 | uint32_t workload_prority[Workload_Policy_Max]; |
| 810 | 810 | uint32_t workload_setting[Workload_Policy_Max]; |
| 811 | 811 | bool gfxoff_state_changed_by_workload; |
| 812 | + uint32_t pstate_sclk_peak; | |
| 813 | + uint32_t pstate_mclk_peak; | |
| 812 | 814 | }; |
| 813 | 815 | |
| 814 | 816 | int hwmgr_early_init(struct pp_hwmgr *hwmgr); |
| @@ -250,9 +250,8 @@ static int smu10_smu_init(struct pp_hwmgr *hwmgr) · 249 unmodified lines | ||
| 250 | 250 | |
| 251 | 251 | /* allocate space for watermarks table */ |
| 252 | 252 | r = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev, |
| 253 | − sizeof(Watermarks_t), | |
| 254 | − PAGE_SIZE, | |
| 255 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 253 | + sizeof(Watermarks_t), PAGE_SIZE, | |
| 254 | + AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT, | |
| 256 | 255 | &priv->smu_tables.entry[SMU10_WMTABLE].handle, |
| 257 | 256 | &priv->smu_tables.entry[SMU10_WMTABLE].mc_addr, |
| 258 | 257 | &priv->smu_tables.entry[SMU10_WMTABLE].table); |
| @@ -266,9 +265,8 @@ static int smu10_smu_init(struct pp_hwmgr *hwmgr) · 7 unmodified lines | ||
| 266 | 265 | |
| 267 | 266 | /* allocate space for watermarks table */ |
| 268 | 267 | r = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev, |
| 269 | − sizeof(DpmClocks_t), | |
| 270 | − PAGE_SIZE, | |
| 271 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 268 | + sizeof(DpmClocks_t), PAGE_SIZE, | |
| 269 | + AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT, | |
| 272 | 270 | &priv->smu_tables.entry[SMU10_CLOCKTABLE].handle, |
| 273 | 271 | &priv->smu_tables.entry[SMU10_CLOCKTABLE].mc_addr, |
| 274 | 272 | &priv->smu_tables.entry[SMU10_CLOCKTABLE].table); |
| @@ -2473,6 +2473,14 @@ static int smu_read_sensor(void *handle, · 2472 unmodified lines | ||
| 2473 | 2473 | *((uint32_t *)data) = pstate_table->uclk_pstate.standard * 100; |
| 2474 | 2474 | *size = 4; |
| 2475 | 2475 | break; |
| 2476 | + case AMDGPU_PP_SENSOR_PEAK_PSTATE_SCLK: | |
| 2477 | + *((uint32_t *)data) = pstate_table->gfxclk_pstate.peak * 100; | |
| 2478 | + *size = 4; | |
| 2479 | + break; | |
| 2480 | + case AMDGPU_PP_SENSOR_PEAK_PSTATE_MCLK: | |
| 2481 | + *((uint32_t *)data) = pstate_table->uclk_pstate.peak * 100; | |
| 2482 | + *size = 4; | |
| 2483 | + break; | |
| 2476 | 2484 | case AMDGPU_PP_SENSOR_ENABLED_SMC_FEATURES_MASK: |
| 2477 | 2485 | ret = smu_feature_get_enabled_mask(smu, (uint64_t *)data); |
| 2478 | 2486 | *size = 8; |
| @@ -244,11 +244,6 @@ int smu_v13_0_set_single_dpm_table(struct smu_context *smu, · 243 unmodified lines | ||
| 244 | 244 | enum smu_clk_type clk_type, |
| 245 | 245 | struct smu_13_0_dpm_table *single_dpm_table); |
| 246 | 246 | |
| 247 | −int smu_v13_0_get_dpm_level_range(struct smu_context *smu, | |
| 248 | − enum smu_clk_type clk_type, | |
| 249 | − uint32_t *min_value, | |
| 250 | − uint32_t *max_value); | |
| 251 | − | |
| 252 | 247 | int smu_v13_0_get_current_pcie_link_width_level(struct smu_context *smu); |
| 253 | 248 | |
| 254 | 249 | int smu_v13_0_get_current_pcie_link_width(struct smu_context *smu); |
| @@ -1261,7 +1261,8 @@ int smu_v13_0_set_fan_speed_rpm(struct smu_context *smu, · 1260 unmodified lines | ||
| 1261 | 1261 | uint32_t speed) |
| 1262 | 1262 | { |
| 1263 | 1263 | struct amdgpu_device *adev = smu->adev; |
| 1264 | − uint32_t tach_period, crystal_clock_freq; | |
| 1264 | + uint32_t crystal_clock_freq = 2500; | |
| 1265 | + uint32_t tach_period; | |
| 1265 | 1266 | int ret; |
| 1266 | 1267 | |
| 1267 | 1268 | if (!speed) |
| @@ -1271,7 +1272,6 @@ int smu_v13_0_set_fan_speed_rpm(struct smu_context *smu, · 3 unmodified lines | ||
| 1271 | 1272 | if (ret) |
| 1272 | 1273 | return ret; |
| 1273 | 1274 | |
| 1274 | − crystal_clock_freq = amdgpu_asic_get_xclk(adev); | |
| 1275 | 1275 | tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed); |
| 1276 | 1276 | WREG32_SOC15(THM, 0, regCG_TACH_CTRL, |
| 1277 | 1277 | REG_SET_FIELD(RREG32_SOC15(THM, 0, regCG_TACH_CTRL), |
| @@ -2064,45 +2064,6 @@ int smu_v13_0_set_single_dpm_table(struct smu_context *smu, · 786 unmodified lines | ||
| 2064 | 2064 | return 0; |
| 2065 | 2065 | } |
| 2066 | 2066 | |
| 2067 | −int smu_v13_0_get_dpm_level_range(struct smu_context *smu, | |
| 2068 | − enum smu_clk_type clk_type, | |
| 2069 | − uint32_t *min_value, | |
| 2070 | − uint32_t *max_value) | |
| 2071 | −{ | |
| 2072 | − uint32_t level_count = 0; | |
| 2073 | − int ret = 0; | |
| 2074 | − | |
| 2075 | − if (!min_value && !max_value) | |
| 2076 | − return -EINVAL; | |
| 2077 | − | |
| 2078 | − if (min_value) { | |
| 2079 | − /* by default, level 0 clock value as min value */ | |
| 2080 | − ret = smu_v13_0_get_dpm_freq_by_index(smu, | |
| 2081 | − clk_type, | |
| 2082 | − 0, | |
| 2083 | − min_value); | |
| 2084 | − if (ret) | |
| 2085 | − return ret; | |
| 2086 | − } | |
| 2087 | − | |
| 2088 | − if (max_value) { | |
| 2089 | − ret = smu_v13_0_get_dpm_level_count(smu, | |
| 2090 | − clk_type, | |
| 2091 | − &level_count); | |
| 2092 | − if (ret) | |
| 2093 | − return ret; | |
| 2094 | − | |
| 2095 | − ret = smu_v13_0_get_dpm_freq_by_index(smu, | |
| 2096 | − clk_type, | |
| 2097 | − level_count - 1, | |
| 2098 | − max_value); | |
| 2099 | − if (ret) | |
| 2100 | − return ret; | |
| 2101 | − } | |
| 2102 | − | |
| 2103 | − return ret; | |
| 2104 | −} | |
| 2105 | − | |
| 2106 | 2067 | int smu_v13_0_get_current_pcie_link_width_level(struct smu_context *smu) |
| 2107 | 2068 | { |
| 2108 | 2069 | struct amdgpu_device *adev = smu->adev; |
| @@ -213,6 +213,7 @@ static struct cmn2asic_mapping smu_v13_0_0_feature_mask_map[SMU_FEATURE_COUNT] = · 212 unmodified lines | ||
| 213 | 213 | FEA_MAP(SOC_PCC), |
| 214 | 214 | [SMU_FEATURE_DPM_VCLK_BIT] = {1, FEATURE_MM_DPM_BIT}, |
| 215 | 215 | [SMU_FEATURE_DPM_DCLK_BIT] = {1, FEATURE_MM_DPM_BIT}, |
| 216 | + [SMU_FEATURE_PPT_BIT] = {1, FEATURE_THROTTLERS_BIT}, | |
| 216 | 217 | }; |
| 217 | 218 | |
| 218 | 219 | static struct cmn2asic_mapping smu_v13_0_0_table_map[SMU_TABLE_COUNT] = { |
| @@ -240,6 +241,7 @@ static struct cmn2asic_mapping smu_v13_0_0_workload_map[PP_SMC_POWER_PROFILE_COU · 21 unmodified lines | ||
| 240 | 241 | WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR, WORKLOAD_PPLIB_VR_BIT), |
| 241 | 242 | WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE, WORKLOAD_PPLIB_COMPUTE_BIT), |
| 242 | 243 | WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT), |
| 244 | + WORKLOAD_MAP(PP_SMC_POWER_PROFILE_WINDOW3D, WORKLOAD_PPLIB_WINDOW_3D_BIT), | |
| 243 | 245 | }; |
| 244 | 246 | |
| 245 | 247 | static const uint8_t smu_v13_0_0_throttler_map[] = { |
| @@ -1555,7 +1557,7 @@ static int smu_v13_0_0_get_power_profile_mode(struct smu_context *smu, · 1309 unmodified lines | ||
| 1555 | 1557 | title[0], title[1], title[2], title[3], title[4], title[5], |
| 1556 | 1558 | title[6], title[7], title[8], title[9]); |
| 1557 | 1559 | |
| 1558 | − for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) { | |
| 1560 | + for (i = 0; i < PP_SMC_POWER_PROFILE_COUNT; i++) { | |
| 1559 | 1561 | /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ |
| 1560 | 1562 | workload_type = smu_cmn_to_asic_specific_index(smu, |
| 1561 | 1563 | CMN2ASIC_MAPPING_WORKLOAD, |
| @@ -1617,7 +1619,7 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, · 55 unmodified lines | ||
| 1617 | 1619 | |
| 1618 | 1620 | smu->power_profile_mode = input[size]; |
| 1619 | 1621 | |
| 1620 | − if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) { | |
| 1622 | + if (smu->power_profile_mode >= PP_SMC_POWER_PROFILE_COUNT) { | |
| 1621 | 1623 | dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode); |
| 1622 | 1624 | return -EINVAL; |
| 1623 | 1625 | } |
| @@ -192,6 +192,7 @@ static struct cmn2asic_mapping smu_v13_0_7_feature_mask_map[SMU_FEATURE_COUNT] = · 191 unmodified lines | ||
| 192 | 192 | FEA_MAP(SOC_PCC), |
| 193 | 193 | [SMU_FEATURE_DPM_VCLK_BIT] = {1, FEATURE_MM_DPM_BIT}, |
| 194 | 194 | [SMU_FEATURE_DPM_DCLK_BIT] = {1, FEATURE_MM_DPM_BIT}, |
| 195 | + [SMU_FEATURE_PPT_BIT] = {1, FEATURE_THROTTLERS_BIT}, | |
| 195 | 196 | }; |
| 196 | 197 | |
| 197 | 198 | static struct cmn2asic_mapping smu_v13_0_7_table_map[SMU_TABLE_COUNT] = { |
| @@ -4020,7 +4020,7 @@ typedef struct _ATOM_DISPLAY_OBJECT_PATH · 4019 unmodified lines | ||
| 4020 | 4020 | USHORT usSize; //the size of ATOM_DISPLAY_OBJECT_PATH |
| 4021 | 4021 | USHORT usConnObjectId; //Connector Object ID |
| 4022 | 4022 | USHORT usGPUObjectId; //GPU ID |
| 4023 | − USHORT usGraphicObjIds[1]; //1st Encoder Obj source from GPU to last Graphic Obj destinate to connector. | |
| 4023 | + USHORT usGraphicObjIds[]; //1st Encoder Obj source from GPU to last Graphic Obj destinate to connector. | |
| 4024 | 4024 | }ATOM_DISPLAY_OBJECT_PATH; |
| 4025 | 4025 | |
| 4026 | 4026 | typedef struct _ATOM_DISPLAY_EXTERNAL_OBJECT_PATH |
| @@ -4037,7 +4037,7 @@ typedef struct _ATOM_DISPLAY_OBJECT_PATH_TABLE · 10 unmodified lines | ||
| 4037 | 4037 | UCHAR ucNumOfDispPath; |
| 4038 | 4038 | UCHAR ucVersion; |
| 4039 | 4039 | UCHAR ucPadding[2]; |
| 4040 | − ATOM_DISPLAY_OBJECT_PATH asDispPath[1]; | |
| 4040 | + ATOM_DISPLAY_OBJECT_PATH asDispPath[]; | |
| 4041 | 4041 | }ATOM_DISPLAY_OBJECT_PATH_TABLE; |
| 4042 | 4042 | |
| 4043 | 4043 | |
| @@ -4053,7 +4053,7 @@ typedef struct _ATOM_OBJECT_TABLE //Above 4 object table · 9 unmodified lines | ||
| 4053 | 4053 | { |
| 4054 | 4054 | UCHAR ucNumberOfObjects; |
| 4055 | 4055 | UCHAR ucPadding[3]; |
| 4056 | − ATOM_OBJECT asObjects[1]; | |
| 4056 | + ATOM_OBJECT asObjects[]; | |
| 4057 | 4057 | }ATOM_OBJECT_TABLE; |
| 4058 | 4058 | |
| 4059 | 4059 | typedef struct _ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT //usSrcDstTableOffset pointing to this structure |
| @@ -4615,7 +4615,7 @@ typedef struct _ATOM_GPIO_VOLTAGE_OBJECT_V3 · 555 unmodified lines | ||
| 4615 | 4615 | UCHAR ucPhaseDelay; // phase delay in unit of micro second |
| 4616 | 4616 | UCHAR ucReserved; |
| 4617 | 4617 | ULONG ulGpioMaskVal; // GPIO Mask value |
| 4618 | − VOLTAGE_LUT_ENTRY_V2 asVolGpioLut[1]; | |
| 4618 | + VOLTAGE_LUT_ENTRY_V2 asVolGpioLut[]; | |
| 4619 | 4619 | }ATOM_GPIO_VOLTAGE_OBJECT_V3; |
| 4620 | 4620 | |
| 4621 | 4621 | typedef struct _ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 |
| @@ -7964,7 +7964,7 @@ typedef struct { · 3342 unmodified lines | ||
| 7964 | 7964 | |
| 7965 | 7965 | typedef struct { |
| 7966 | 7966 | VFCT_IMAGE_HEADER VbiosHeader; |
| 7967 | − UCHAR VbiosContent[1]; | |
| 7967 | + UCHAR VbiosContent[]; | |
| 7968 | 7968 | }GOP_VBIOS_CONTENT; |
| 7969 | 7969 | |
| 7970 | 7970 | typedef struct { |
| @@ -603,6 +603,7 @@ · 602 unmodified lines | ||
| 603 | 603 | |
| 604 | 604 | #define DP_DOWNSPREAD_CTRL 0x107 |
| 605 | 605 | # define DP_SPREAD_AMP_0_5 (1 << 4) |
| 606 | +# define DP_FIXED_VTOTAL_AS_SDP_EN_IN_PR_ACTIVE (1 << 6) | |
| 606 | 607 | # define DP_MSA_TIMING_PAR_IGNORE_EN (1 << 7) /* eDP */ |
| 607 | 608 | |
| 608 | 609 | #define DP_MAIN_LINK_CHANNEL_CODING_SET 0x108 |
| @@ -1105,6 +1106,11 @@ · 496 unmodified lines | ||
| 1105 | 1106 | # define DP_VSC_EXT_CEA_SDP_SUPPORTED (1 << 6) /* DP 1.4 */ |
| 1106 | 1107 | # define DP_VSC_EXT_CEA_SDP_CHAINING_SUPPORTED (1 << 7) /* DP 1.4 */ |
| 1107 | 1108 | |
| 1109 | +#define DP_DPRX_FEATURE_ENUMERATION_LIST_CONT_1 0x2214 /* 2.0 E11 */ | |
| 1110 | +# define DP_ADAPTIVE_SYNC_SDP_SUPPORTED (1 << 0) | |
| 1111 | +# define DP_AS_SDP_FIRST_HALF_LINE_OR_3840_PIXEL_CYCLE_WINDOW_NOT_SUPPORTED (1 << 1) | |
| 1112 | +# define DP_VSC_EXT_SDP_FRAMEWORK_VERSION_1_SUPPORTED (1 << 4) | |
| 1113 | + | |
| 1108 | 1114 | #define DP_128B132B_SUPPORTED_LINK_RATES 0x2215 /* 2.0 */ |
| 1109 | 1115 | # define DP_UHBR10 (1 << 0) |
| 1110 | 1116 | # define DP_UHBR20 (1 << 1) |
| @@ -832,6 +832,10 @@ struct drm_amdgpu_cs_chunk_data { · 831 unmodified lines | ||
| 832 | 832 | #define AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_SCLK 0x8 |
| 833 | 833 | /* Subquery id: Query GPU stable pstate memory clock */ |
| 834 | 834 | #define AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_MCLK 0x9 |
| 835 | + /* Subquery id: Query GPU peak pstate shader clock */ | |
| 836 | + #define AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_SCLK 0xa | |
| 837 | + /* Subquery id: Query GPU peak pstate memory clock */ | |
| 838 | + #define AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_MCLK 0xb | |
| 835 | 839 | /* Number of VRAM page faults on CPU access. */ |
| 836 | 840 | #define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS 0x1E |
| 837 | 841 | #define AMDGPU_INFO_VRAM_LOST_COUNTER 0x1F |
| @@ -1107,6 +1111,8 @@ struct drm_amdgpu_info_device { · 269 unmodified lines | ||
| 1107 | 1111 | __u32 pa_sc_tile_steering_override; |
| 1108 | 1112 | /* disabled TCCs */ |
| 1109 | 1113 | __u64 tcc_disabled_mask; |
| 1114 | + __u64 min_engine_clock; | |
| 1115 | + __u64 min_memory_clock; | |
| 1110 | 1116 | }; |
| 1111 | 1117 | |
| 1112 | 1118 | struct drm_amdgpu_info_hw_ip { |