From 39934d3ed5725c5e3570ed1b67f612f1ea60ce03 Mon Sep 17 00:00:00 2001 From: Vitaly Prosyak Date: Fri, 20 Jan 2023 13:19:50 -0500 Subject: [PATCH 01/36] Revert "drm/amdgpu: TA unload messages are not actually sent to psp when amdgpu is uninstalled" This reverts commit fac53471d0ea9693d314aa2df08d62b2e7e3a0f8. The following change: move the drm_dev_unplug call after amdgpu_driver_unload_kms in amdgpu_pci_remove. The reason is the following: amdgpu_pci_remove calls drm_dev_unregister and it should be called first to ensure userspace can't access the device instance anymore. If we call drm_dev_unplug after amdgpu_driver_unload_kms then we observe IGT PCI software unplug test failure (kernel hung) for all ASICs. This is how this regression was found. After this revert, the following commands do work not, but it would be fixed in the next commit: - sudo modprobe -r amdgpu - sudo modprobe amdgpu Signed-off-by: Vitaly Prosyak Reviewed-by Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 5bee3ff62344..d376faad7696 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4031,7 +4031,8 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) amdgpu_gart_dummy_page_fini(adev); - amdgpu_device_unmap_mmio(adev); + if (drm_dev_is_unplugged(adev_to_drm(adev))) + amdgpu_device_unmap_mmio(adev); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 7bb12a76631f..1bf31707e4f7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -2227,6 +2227,8 @@ amdgpu_pci_remove(struct pci_dev *pdev) struct drm_device *dev = pci_get_drvdata(pdev); struct amdgpu_device *adev = drm_to_adev(dev); + drm_dev_unplug(dev); + if (adev->pm.rpm_mode != AMDGPU_RUNPM_NONE) { pm_runtime_get_sync(dev->dev); pm_runtime_forbid(dev->dev); @@ -2266,8 +2268,6 @@ amdgpu_pci_remove(struct pci_dev *pdev) amdgpu_driver_unload_kms(dev); - drm_dev_unplug(dev); - /* * Flush any in flight DMA operations from device. * Clear the Bus Master Enable bit and then wait on the PCIe Device From cf488dcd0ab75d01bb09edd529aa6381c5ebec68 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 25 Jan 2023 12:22:40 -0600 Subject: [PATCH 02/36] drm/amd: Allow s0ix without BIOS support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We guard the suspend entry code from running unless we have proper BIOS support for either S3 mode or s0ix mode. If a user's system doesn't support either of these modes the kernel still does offer s2idle in `/sys/power/mem_sleep` so there is an expectation from users that it works even if the power consumption remains very high. Rafael Ávila de Espíndola reports that a system of his has a non-functional graphics stack after resuming. That system doesn't support S3 and the FADT doesn't indicate support for low power idle. Through some experimentation it was concluded that even without the hardware s0i3 support provided by the amd_pmc driver the power consumption over suspend is decreased by running amdgpu's s0ix suspend routine. The numbers over suspend showed: * No patch: 9.2W * Skip amdgpu suspend entirely: 10.5W * Run amdgpu s0ix routine: 7.7W As this does improve the power, remove some of the guard rails in `amdgpu_acpi.c` for only running s0ix suspend routines in the right circumstances. However if this turns out to cause regressions for anyone, we should revert this change and instead opt for skipping suspend/resume routines entirely or try to fix the underlying behavior that makes graphics fail after resume without underlying platform support. Reported-by: Rafael Ávila de Espíndola Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2364 Acked-by: Alex Deucher Signed-off-by: Mario Limonciello Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c index f29c1d0ad4c1..458362e4ea01 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c @@ -1079,20 +1079,16 @@ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) * S0ix even though the system is suspending to idle, so return false * in that case. */ - if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) { + if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) dev_warn_once(adev->dev, "Power consumption will be higher as BIOS has not been configured for suspend-to-idle.\n" "To use suspend-to-idle change the sleep mode in BIOS setup.\n"); - return false; - } #if !IS_ENABLED(CONFIG_AMD_PMC) dev_warn_once(adev->dev, "Power consumption will be higher as the kernel has not been compiled with CONFIG_AMD_PMC.\n"); - return false; -#else - return true; #endif /* CONFIG_AMD_PMC */ + return true; } #endif /* CONFIG_SUSPEND */ From 634d0aa54e3eb507744a6350705fe454c7cf78b9 Mon Sep 17 00:00:00 2001 From: Graham Sider Date: Mon, 16 Jan 2023 10:43:11 -0500 Subject: [PATCH 03/36] drm/amdgpu: update wave data type to 3 for gfx11 SQ_WAVE_INST_DW0 isn't present on gfx11 compared to gfx10, so update wave data type to signify a difference. Signed-off-by: Graham Sider Reviewed-by: Mukul Joshi Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index c621b2ad7ba3..8ad8a0bffcac 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -754,8 +754,8 @@ static void gfx_v11_0_read_wave_data(struct amdgpu_device *adev, uint32_t simd, * zero here */ WARN_ON(simd != 0); - /* type 2 wave data */ - dst[(*no_fields)++] = 2; + /* type 3 wave data */ + dst[(*no_fields)++] = 3; dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_STATUS); dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_PC_LO); dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_PC_HI); From 5b49da02ddbe1b9082cfc9be1cd848375da178ea Mon Sep 17 00:00:00 2001 From: Sung Joon Kim Date: Thu, 12 Jan 2023 10:38:10 -0500 Subject: [PATCH 04/36] drm/amd/display: Enable Freesync over PCon [why] Enable Freesync over PCon on Linux environment. [how] Adding Freesync over PCon support in amdgpu_dm - Read DPCD for Freesync over PCon capabilitiy - Add whitelist for compatible branch devices Reviewed-by: Chao-kai Wang Acked-by: Alex Hung Signed-off-by: Sung Joon Kim Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 45 ++++++++++++- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 67 ++++++++++--------- .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 33 +++++++++ drivers/gpu/drm/amd/display/dc/dm_helpers.h | 1 + .../amd/display/include/ddc_service_types.h | 1 + .../amd/display/modules/inc/mod_info_packet.h | 4 +- .../display/modules/info_packet/info_packet.c | 4 +- 7 files changed, 118 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index e1d63826927a..9846bd6e0456 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -106,7 +106,6 @@ #include "modules/inc/mod_freesync.h" #include "modules/power/power_helpers.h" -#include "modules/inc/mod_info_packet.h" #define FIRMWARE_RENOIR_DMUB "amdgpu/renoir_dmcub.bin" MODULE_FIRMWARE(FIRMWARE_RENOIR_DMUB); @@ -7113,6 +7112,9 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, aconnector->base.dpms = DRM_MODE_DPMS_OFF; aconnector->hpd.hpd = AMDGPU_HPD_NONE; /* not used */ aconnector->audio_inst = -1; + aconnector->pack_sdp_v1_3 = false; + aconnector->as_type = ADAPTIVE_SYNC_TYPE_NONE; + memset(&aconnector->vsdb_info, 0, sizeof(aconnector->vsdb_info)); mutex_init(&aconnector->hpd_lock); /* @@ -7603,6 +7605,8 @@ static void update_freesync_state_on_stream( struct amdgpu_crtc *acrtc = to_amdgpu_crtc(new_crtc_state->base.crtc); unsigned long flags; bool pack_sdp_v1_3 = false; + struct amdgpu_dm_connector *aconn; + enum vrr_packet_type packet_type = PACKET_TYPE_VRR; if (!new_stream) return; @@ -7638,11 +7642,27 @@ static void update_freesync_state_on_stream( } } + aconn = (struct amdgpu_dm_connector *)new_stream->dm_stream_context; + + if (aconn && aconn->as_type == FREESYNC_TYPE_PCON_IN_WHITELIST) { + pack_sdp_v1_3 = aconn->pack_sdp_v1_3; + + if (aconn->vsdb_info.amd_vsdb_version == 1) + packet_type = PACKET_TYPE_FS_V1; + else if (aconn->vsdb_info.amd_vsdb_version == 2) + packet_type = PACKET_TYPE_FS_V2; + else if (aconn->vsdb_info.amd_vsdb_version == 3) + packet_type = PACKET_TYPE_FS_V3; + + mod_build_adaptive_sync_infopacket(new_stream, aconn->as_type, NULL, + &new_stream->adaptive_sync_infopacket); + } + mod_freesync_build_vrr_infopacket( dm->freesync_module, new_stream, &vrr_params, - PACKET_TYPE_VRR, + packet_type, TRANSFER_FUNC_UNKNOWN, &vrr_infopacket, pack_sdp_v1_3); @@ -10311,6 +10331,7 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector, struct amdgpu_device *adev = drm_to_adev(dev); struct amdgpu_hdmi_vsdb_info vsdb_info = {0}; bool freesync_capable = false; + enum adaptive_sync_type as_type = ADAPTIVE_SYNC_TYPE_NONE; if (!connector->state) { DRM_ERROR("%s - Connector has no state", __func__); @@ -10403,6 +10424,26 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector, } } + as_type = dm_get_adaptive_sync_support_type(amdgpu_dm_connector->dc_link); + + if (as_type == FREESYNC_TYPE_PCON_IN_WHITELIST) { + i = parse_hdmi_amd_vsdb(amdgpu_dm_connector, edid, &vsdb_info); + if (i >= 0 && vsdb_info.freesync_supported && vsdb_info.amd_vsdb_version > 0) { + + amdgpu_dm_connector->pack_sdp_v1_3 = true; + amdgpu_dm_connector->as_type = as_type; + amdgpu_dm_connector->vsdb_info = vsdb_info; + + amdgpu_dm_connector->min_vfreq = vsdb_info.min_refresh_rate_hz; + amdgpu_dm_connector->max_vfreq = vsdb_info.max_refresh_rate_hz; + if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10) + freesync_capable = true; + + connector->display_info.monitor_range.min_vfreq = vsdb_info.min_refresh_rate_hz; + connector->display_info.monitor_range.max_vfreq = vsdb_info.max_refresh_rate_hz; + } + } + update: if (dm_con_state) dm_con_state->freesync_capable = freesync_capable; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index d89f2eaf9117..ed5cbe9da40c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -59,6 +59,7 @@ #include "irq_types.h" #include "signal_types.h" #include "amdgpu_dm_crc.h" +#include "mod_info_packet.h" struct aux_payload; struct set_config_cmd_payload; enum aux_return_code_type; @@ -577,6 +578,36 @@ enum mst_progress_status { MST_CLEAR_ALLOCATED_PAYLOAD = BIT(3), }; +/** + * struct amdgpu_hdmi_vsdb_info - Keep track of the VSDB info + * + * AMDGPU supports FreeSync over HDMI by using the VSDB section, and this + * struct is useful to keep track of the display-specific information about + * FreeSync. + */ +struct amdgpu_hdmi_vsdb_info { + /** + * @amd_vsdb_version: Vendor Specific Data Block Version, should be + * used to determine which Vendor Specific InfoFrame (VSIF) to send. + */ + unsigned int amd_vsdb_version; + + /** + * @freesync_supported: FreeSync Supported. + */ + bool freesync_supported; + + /** + * @min_refresh_rate_hz: FreeSync Minimum Refresh Rate in Hz. + */ + unsigned int min_refresh_rate_hz; + + /** + * @max_refresh_rate_hz: FreeSync Maximum Refresh Rate in Hz + */ + unsigned int max_refresh_rate_hz; +}; + struct amdgpu_dm_connector { struct drm_connector base; @@ -649,6 +680,11 @@ struct amdgpu_dm_connector { /* Automated testing */ bool timing_changed; struct dc_crtc_timing *timing_requested; + + /* Adaptive Sync */ + bool pack_sdp_v1_3; + enum adaptive_sync_type as_type; + struct amdgpu_hdmi_vsdb_info vsdb_info; }; static inline void amdgpu_dm_set_mst_status(uint8_t *status, @@ -719,37 +755,6 @@ struct dm_connector_state { uint64_t pbn; }; -/** - * struct amdgpu_hdmi_vsdb_info - Keep track of the VSDB info - * - * AMDGPU supports FreeSync over HDMI by using the VSDB section, and this - * struct is useful to keep track of the display-specific information about - * FreeSync. - */ -struct amdgpu_hdmi_vsdb_info { - /** - * @amd_vsdb_version: Vendor Specific Data Block Version, should be - * used to determine which Vendor Specific InfoFrame (VSIF) to send. - */ - unsigned int amd_vsdb_version; - - /** - * @freesync_supported: FreeSync Supported. - */ - bool freesync_supported; - - /** - * @min_refresh_rate_hz: FreeSync Minimum Refresh Rate in Hz. - */ - unsigned int min_refresh_rate_hz; - - /** - * @max_refresh_rate_hz: FreeSync Maximum Refresh Rate in Hz - */ - unsigned int max_refresh_rate_hz; -}; - - #define to_dm_connector_state(x)\ container_of((x), struct dm_connector_state, base) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index a50319fc42b1..5c733d445fe9 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -1133,3 +1133,36 @@ void dm_helpers_dp_mst_update_branch_bandwidth( // TODO } +static bool dm_is_freesync_pcon_whitelist(const uint32_t branch_dev_id) +{ + bool ret_val = false; + + switch (branch_dev_id) { + case DP_BRANCH_DEVICE_ID_0060AD: + ret_val = true; + break; + default: + break; + } + + return ret_val; +} + +enum adaptive_sync_type dm_get_adaptive_sync_support_type(struct dc_link *link) +{ + struct dpcd_caps *dpcd_caps = &link->dpcd_caps; + enum adaptive_sync_type as_type = ADAPTIVE_SYNC_TYPE_NONE; + + switch (dpcd_caps->dongle_type) { + case DISPLAY_DONGLE_DP_HDMI_CONVERTER: + if (dpcd_caps->adaptive_sync_caps.dp_adap_sync_caps.bits.ADAPTIVE_SYNC_SDP_SUPPORT == true && + dpcd_caps->allow_invalid_MSA_timing_param == true && + dm_is_freesync_pcon_whitelist(dpcd_caps->branch_dev_id)) + as_type = FREESYNC_TYPE_PCON_IN_WHITELIST; + break; + default: + break; + } + + return as_type; +} diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h index c624c768cc3d..7ce9a5b6c33b 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h +++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h @@ -199,6 +199,7 @@ int dm_helpers_dmub_set_config_sync(struct dc_context *ctx, const struct dc_link *link, struct set_config_cmd_payload *payload, enum set_config_status *operation_result); +enum adaptive_sync_type dm_get_adaptive_sync_support_type(struct dc_link *link); enum dc_edid_status dm_helpers_get_sbios_edid(struct dc_link *link, struct dc_edid *edid); diff --git a/drivers/gpu/drm/amd/display/include/ddc_service_types.h b/drivers/gpu/drm/amd/display/include/ddc_service_types.h index 3610f71891a3..31a12ce79a8e 100644 --- a/drivers/gpu/drm/amd/display/include/ddc_service_types.h +++ b/drivers/gpu/drm/amd/display/include/ddc_service_types.h @@ -35,6 +35,7 @@ #define DP_BRANCH_DEVICE_ID_00E04C 0x00E04C #define DP_BRANCH_DEVICE_ID_006037 0x006037 #define DP_BRANCH_DEVICE_ID_001CF8 0x001CF8 +#define DP_BRANCH_DEVICE_ID_0060AD 0x0060AD #define DP_BRANCH_HW_REV_10 0x10 #define DP_BRANCH_HW_REV_20 0x20 diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h index 91fe039c0c95..66dc9a19aebe 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h @@ -44,8 +44,8 @@ void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream, enum adaptive_sync_type { ADAPTIVE_SYNC_TYPE_NONE = 0, ADAPTIVE_SYNC_TYPE_DP = 1, - ADAPTIVE_SYNC_TYPE_PCON_IN_WHITELIST = 2, - ADAPTIVE_SYNC_TYPE_PCON_NOT_IN_WHITELIST = 3, + FREESYNC_TYPE_PCON_IN_WHITELIST = 2, + FREESYNC_TYPE_PCON_NOT_IN_WHITELIST = 3, ADAPTIVE_SYNC_TYPE_EDP = 4, }; diff --git a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c index a8a31d0a7a7f..ec64f19e1786 100644 --- a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c +++ b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c @@ -533,11 +533,11 @@ void mod_build_adaptive_sync_infopacket(const struct dc_stream_state *stream, if (stream != NULL) mod_build_adaptive_sync_infopacket_v2(stream, param, info_packet); break; - case ADAPTIVE_SYNC_TYPE_PCON_IN_WHITELIST: + case FREESYNC_TYPE_PCON_IN_WHITELIST: mod_build_adaptive_sync_infopacket_v1(info_packet); break; case ADAPTIVE_SYNC_TYPE_NONE: - case ADAPTIVE_SYNC_TYPE_PCON_NOT_IN_WHITELIST: + case FREESYNC_TYPE_PCON_NOT_IN_WHITELIST: default: break; } From 0a31efb4d606884d1ed17d5df64e9d02f50a0713 Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Fri, 13 Jan 2023 16:07:10 -0500 Subject: [PATCH 05/36] drm/amd/display: add rc_params_override option in dc_dsc_config [why] Current RC params are based on VESA recommended configurations. Some DSC sink may prefer non standard rc params values due to hardware limitations. To support those DSC sink we will allow DM to optionally pass rc_params_ovrd in dc_dsc_config so DC will override the default VESA recommended configurations. Reviewed-by: Martin Leung Acked-by: Alex Hung Signed-off-by: Wenjing Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 24 +++++++++++++ .../gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c | 36 ++++++++++++++++++- .../gpu/drm/amd/display/dc/dsc/dscc_types.h | 5 ++- .../gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c | 10 +++--- 4 files changed, 68 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h index 848db8676adf..cc3d6fb39364 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -797,6 +797,29 @@ enum dc_timing_3d_format { TIMING_3D_FORMAT_MAX, }; +#define DC_DSC_QP_SET_SIZE 15 +#define DC_DSC_RC_BUF_THRESH_SIZE 14 +struct dc_dsc_rc_params_override { + int32_t rc_model_size; + int32_t rc_buf_thresh[DC_DSC_RC_BUF_THRESH_SIZE]; + int32_t rc_minqp[DC_DSC_QP_SET_SIZE]; + int32_t rc_maxqp[DC_DSC_QP_SET_SIZE]; + int32_t rc_offset[DC_DSC_QP_SET_SIZE]; + + int32_t rc_tgt_offset_hi; + int32_t rc_tgt_offset_lo; + int32_t rc_edge_factor; + int32_t rc_quant_incr_limit0; + int32_t rc_quant_incr_limit1; + + int32_t initial_fullness_offset; + int32_t initial_delay; + + int32_t flatness_min_qp; + int32_t flatness_max_qp; + int32_t flatness_det_thresh; +}; + struct dc_dsc_config { uint32_t num_slices_h; /* Number of DSC slices - horizontal */ uint32_t num_slices_v; /* Number of DSC slices - vertical */ @@ -811,6 +834,7 @@ struct dc_dsc_config { #endif bool is_dp; /* indicate if DSC is applied based on DP's capability */ uint32_t mst_pbn; /* pbn of display on dsc mst hub */ + const struct dc_dsc_rc_params_override *rc_params_ovrd; /* DM owned memory. If not NULL, apply custom dsc rc params */ }; /** diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c index c08c01e05dcf..42344aec60d6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c @@ -28,6 +28,7 @@ #include "reg_helper.h" #include "dcn20_dsc.h" #include "dsc/dscc_types.h" +#include "dsc/rc_calc.h" static void dsc_log_pps(struct display_stream_compressor *dsc, struct drm_dsc_config *pps); static bool dsc_prepare_config(const struct dsc_config *dsc_cfg, struct dsc_reg_values *dsc_reg_vals, @@ -344,10 +345,38 @@ static void dsc_log_pps(struct display_stream_compressor *dsc, struct drm_dsc_co } } +static void dsc_override_rc_params(struct rc_params *rc, const struct dc_dsc_rc_params_override *override) +{ + uint8_t i; + + rc->rc_model_size = override->rc_model_size; + for (i = 0; i < DC_DSC_RC_BUF_THRESH_SIZE; i++) + rc->rc_buf_thresh[i] = override->rc_buf_thresh[i]; + for (i = 0; i < DC_DSC_QP_SET_SIZE; i++) { + rc->qp_min[i] = override->rc_minqp[i]; + rc->qp_max[i] = override->rc_maxqp[i]; + rc->ofs[i] = override->rc_offset[i]; + } + + rc->rc_tgt_offset_hi = override->rc_tgt_offset_hi; + rc->rc_tgt_offset_lo = override->rc_tgt_offset_lo; + rc->rc_edge_factor = override->rc_edge_factor; + rc->rc_quant_incr_limit0 = override->rc_quant_incr_limit0; + rc->rc_quant_incr_limit1 = override->rc_quant_incr_limit1; + + rc->initial_fullness_offset = override->initial_fullness_offset; + rc->initial_xmit_delay = override->initial_delay; + + rc->flatness_min_qp = override->flatness_min_qp; + rc->flatness_max_qp = override->flatness_max_qp; + rc->flatness_det_thresh = override->flatness_det_thresh; +} + static bool dsc_prepare_config(const struct dsc_config *dsc_cfg, struct dsc_reg_values *dsc_reg_vals, struct dsc_optc_config *dsc_optc_cfg) { struct dsc_parameters dsc_params; + struct rc_params rc; /* Validate input parameters */ ASSERT(dsc_cfg->dc_dsc_cfg.num_slices_h); @@ -412,7 +441,12 @@ static bool dsc_prepare_config(const struct dsc_config *dsc_cfg, struct dsc_reg_ dsc_reg_vals->pps.native_420 = (dsc_reg_vals->pixel_format == DSC_PIXFMT_NATIVE_YCBCR420); dsc_reg_vals->pps.simple_422 = (dsc_reg_vals->pixel_format == DSC_PIXFMT_SIMPLE_YCBCR422); - if (dscc_compute_dsc_parameters(&dsc_reg_vals->pps, &dsc_params)) { + calc_rc_params(&rc, &dsc_reg_vals->pps); + + if (dsc_cfg->dc_dsc_cfg.rc_params_ovrd) + dsc_override_rc_params(&rc, dsc_cfg->dc_dsc_cfg.rc_params_ovrd); + + if (dscc_compute_dsc_parameters(&dsc_reg_vals->pps, &rc, &dsc_params)) { dm_output_to_console("%s: DSC config failed\n", __func__); return false; } diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dscc_types.h b/drivers/gpu/drm/amd/display/dc/dsc/dscc_types.h index ad80bde9bc0f..31574940ccc7 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dscc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dsc/dscc_types.h @@ -46,7 +46,10 @@ struct dsc_parameters { uint32_t rc_buffer_model_size; }; -int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, struct dsc_parameters *dsc_params); +struct rc_params; +int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, + const struct rc_params *rc, + struct dsc_parameters *dsc_params); #endif diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c index f0aea988fef0..36d6c1646a51 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c @@ -95,19 +95,19 @@ static void copy_rc_to_cfg(struct drm_dsc_config *dsc_cfg, const struct rc_param dsc_cfg->rc_buf_thresh[i] = rc->rc_buf_thresh[i]; } -int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, struct dsc_parameters *dsc_params) +int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, + const struct rc_params *rc, + struct dsc_parameters *dsc_params) { int ret; - struct rc_params rc; struct drm_dsc_config dsc_cfg; unsigned long long tmp; - calc_rc_params(&rc, pps); dsc_params->pps = *pps; - dsc_params->pps.initial_scale_value = 8 * rc.rc_model_size / (rc.rc_model_size - rc.initial_fullness_offset); + dsc_params->pps.initial_scale_value = 8 * rc->rc_model_size / (rc->rc_model_size - rc->initial_fullness_offset); copy_pps_fields(&dsc_cfg, &dsc_params->pps); - copy_rc_to_cfg(&dsc_cfg, &rc); + copy_rc_to_cfg(&dsc_cfg, rc); dsc_cfg.mux_word_size = dsc_params->pps.bits_per_component <= 10 ? 48 : 64; From 918d5166439078364453f2eb5b4d8e75095a510e Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Tue, 17 Jan 2023 03:47:13 -0500 Subject: [PATCH 06/36] drm/amd/display: fix MALL size hardcoded for DCN321 [Why] MALL size available can vary for different SKUs MALL size was still hardcoded for DCN321 [How] Remove hardcoding MALL size for DCN321 Reviewed-by: Alvin Lee Acked-by: Alex Hung Signed-off-by: Samson Tam Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c index fd57e0167737..55f918b44077 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c @@ -1714,7 +1714,6 @@ static bool dcn321_resource_construct( dc->caps.mall_size_per_mem_channel * 1024 * 1024; dc->caps.mall_size_total = dc->caps.max_cab_allocation_bytes; - dc->caps.max_cab_allocation_bytes = 33554432; // 32MB = 1024 * 1024 * 32 dc->caps.subvp_fw_processing_delay_us = 15; dc->caps.subvp_drr_max_vblank_margin_us = 40; dc->caps.subvp_prefetch_end_to_mall_start_us = 15; From e3834491b92a10d97f0cc0029e276d1938469bfe Mon Sep 17 00:00:00 2001 From: Fangzhi Zuo Date: Mon, 16 Jan 2023 16:29:26 -0500 Subject: [PATCH 07/36] drm/amd/display: Add Debug Log for MST and PCON Add log for MST/PCON specific use case: 1. If DP1.2 hub where gives reduced link bw and no dsc support. 2. If less than 4-lane configuration where gives reduced bw. 3. If FRL PCON enabled for asic. 4. Track MST sink count. Reviewed-by: Hersen Wu Acked-by: Alex Hung Signed-off-by: Fangzhi Zuo Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +++ .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 12 +++++++++++- .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 12 ++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 9846bd6e0456..ffbbd50a61d1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1622,6 +1622,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) /* TODO: Remove after DP2 receiver gets proper support of Cable ID feature */ adev->dm.dc->debug.ignore_cable_id = true; + if (adev->dm.dc->caps.dp_hdmi21_pcon_support) + DRM_INFO("DP-HDMI FRL PCON supported\n"); + r = dm_dmub_hw_init(adev); if (r) { DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 5c733d445fe9..c6794196a11d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -403,6 +403,7 @@ bool dm_helpers_dp_mst_start_top_mgr( bool boot) { struct amdgpu_dm_connector *aconnector = link->priv; + int ret; if (!aconnector) { DRM_ERROR("Failed to find connector for link!"); @@ -418,7 +419,16 @@ bool dm_helpers_dp_mst_start_top_mgr( DRM_INFO("DM_MST: starting TM on aconnector: %p [id: %d]\n", aconnector, aconnector->base.base.id); - return (drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true) == 0); + ret = drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true); + if (ret < 0) { + DRM_ERROR("DM_MST: Failed to set the device into MST mode!"); + return false; + } + + DRM_INFO("DM_MST: DP%x, %d-lane link detected\n", aconnector->mst_mgr.dpcd[0], + aconnector->mst_mgr.dpcd[2] & DP_MAX_LANE_COUNT_MASK); + + return true; } bool dm_helpers_dp_mst_stop_top_mgr( diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 0bff2cc20b02..33f53cae939d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -177,6 +177,9 @@ amdgpu_dm_mst_connector_early_unregister(struct drm_connector *connector) if (dc_link->sink_count) dc_link_remove_remote_sink(dc_link, dc_sink); + DC_LOG_MST("DM_MST: remove remote sink 0x%p, %d remaining\n", + dc_sink, dc_link->sink_count); + dc_sink_release(dc_sink); aconnector->dc_sink = NULL; aconnector->edid = NULL; @@ -308,6 +311,9 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) return 0; } + DC_LOG_MST("DM_MST: add remote sink 0x%p, %d remaining\n", + dc_sink, aconnector->dc_link->sink_count); + dc_sink->priv = aconnector; aconnector->dc_sink = dc_sink; } @@ -341,6 +347,9 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) return 0; } + DC_LOG_MST("DM_MST: add remote sink 0x%p, %d remaining\n", + dc_sink, aconnector->dc_link->sink_count); + dc_sink->priv = aconnector; /* dc_link_add_remote_sink returns a new reference */ aconnector->dc_sink = dc_sink; @@ -458,6 +467,9 @@ dm_dp_mst_detect(struct drm_connector *connector, if (aconnector->dc_link->sink_count) dc_link_remove_remote_sink(aconnector->dc_link, aconnector->dc_sink); + DC_LOG_MST("DM_MST: remove remote sink 0x%p, %d remaining\n", + aconnector->dc_link, aconnector->dc_link->sink_count); + dc_sink_release(aconnector->dc_sink); aconnector->dc_sink = NULL; aconnector->edid = NULL; From 73dd4ca4b5a01235607231839bd351bbef75a1d2 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Mon, 16 Jan 2023 09:49:32 -0500 Subject: [PATCH 08/36] drm/amd/display: Fix Z8 support configurations [Why] It's not supported in multi-display, but it is supported in 2nd eDP screen only. [How] Remove multi display support, restrict number of planes for all z-states support, but still allow Z8 if we're not using PWRSEQ0. Reviewed-by: Charlene Liu Acked-by: Alex Hung Signed-off-by: Nicholas Kazlauskas Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c index 197df404761a..d3ba65efe1d2 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c @@ -949,7 +949,6 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struc int plane_count; int i; unsigned int optimized_min_dst_y_next_start_us; - bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > 1000.0; plane_count = 0; optimized_min_dst_y_next_start_us = 0; @@ -974,6 +973,8 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struc else if (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) { struct dc_link *link = context->streams[0]->sink->link; struct dc_stream_status *stream_status = &context->stream_status[0]; + bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > 1000.0; + bool is_pwrseq0 = link->link_index == 0; if (dc_extended_blank_supported(dc)) { for (i = 0; i < dc->res_pool->pipe_count; i++) { @@ -986,18 +987,17 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struc } } } - /* zstate only supported on PWRSEQ0 and when there's <2 planes*/ - if (link->link_index != 0 || stream_status->plane_count > 1) + + /* Don't support multi-plane configurations */ + if (stream_status->plane_count > 1) return DCN_ZSTATE_SUPPORT_DISALLOW; - if (context->bw_ctx.dml.vba.StutterPeriod > 5000.0 || optimized_min_dst_y_next_start_us > 5000) + if (is_pwrseq0 && (context->bw_ctx.dml.vba.StutterPeriod > 5000.0 || optimized_min_dst_y_next_start_us > 5000)) return DCN_ZSTATE_SUPPORT_ALLOW; - else if (link->psr_settings.psr_version == DC_PSR_VERSION_1 && !link->panel_config.psr.disable_psr) + else if (is_pwrseq0 && link->psr_settings.psr_version == DC_PSR_VERSION_1 && !link->panel_config.psr.disable_psr) return allow_z8 ? DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY : DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY; else return allow_z8 ? DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY : DCN_ZSTATE_SUPPORT_DISALLOW; - } else if (allow_z8) { - return DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY; } else { return DCN_ZSTATE_SUPPORT_DISALLOW; } From f5df7725e38853b5b07b7ab41017916f1e5b4e57 Mon Sep 17 00:00:00 2001 From: Daniel Miess Date: Tue, 17 Jan 2023 15:23:06 -0500 Subject: [PATCH 09/36] drm/amd/display: Correct bw_params population [Why] Underflow observed during P010 video playback on dcn314 due to incorrectly populated bw_params [How] Populate fclk, memclk and voltage in bw_params with values from max pstate rather than min pstate Reviewed-by: Nicholas Kazlauskas Acked-by: Alex Hung Signed-off-by: Daniel Miess Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../dc/clk_mgr/dcn314/dcn314_clk_mgr.c | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c index 89df7244b272..f5276bacfa4e 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c @@ -572,10 +572,11 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl { struct clk_bw_params *bw_params = clk_mgr->base.bw_params; struct clk_limit_table_entry def_max = bw_params->clk_table.entries[bw_params->clk_table.num_entries - 1]; - uint32_t max_pstate = 0, max_fclk = 0, min_pstate = 0, max_dispclk = 0, max_dppclk = 0; + uint32_t max_pstate = 0, max_fclk = 0, max_dispclk = 0, max_dppclk = 0; + uint32_t min_pstate = 0, min_fclk = clock_table->DfPstateTable[0].FClk; int i; - /* Find highest valid fclk pstate */ + /* Find highest and lowest valid fclk pstate */ for (i = 0; i < clock_table->NumDfPstatesEnabled; i++) { if (is_valid_clock_value(clock_table->DfPstateTable[i].FClk) && clock_table->DfPstateTable[i].FClk > max_fclk) { @@ -584,6 +585,14 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl } } + for (i = 0; i < clock_table->NumDfPstatesEnabled; i++) { + if (is_valid_clock_value(clock_table->DfPstateTable[i].FClk) && + clock_table->DfPstateTable[i].FClk < min_fclk) { + min_fclk = clock_table->DfPstateTable[i].FClk; + min_pstate = i; + } + } + /* We expect the table to contain at least one valid fclk entry. */ ASSERT(is_valid_clock_value(max_fclk)); @@ -599,15 +608,17 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl /* Base the clock table on dcfclk, need at least one entry regardless of pmfw table */ for (i = 0; i < clock_table->NumDcfClkLevelsEnabled; i++) { - uint32_t min_fclk = clock_table->DfPstateTable[0].FClk; + uint32_t max_level_fclk = clock_table->DfPstateTable[0].FClk; + uint32_t max_level_pstate = 0; int j; + /* Look for the maximum supported FCLK for the current voltage. */ for (j = 1; j < clock_table->NumDfPstatesEnabled; j++) { if (is_valid_clock_value(clock_table->DfPstateTable[j].FClk) && - clock_table->DfPstateTable[j].FClk < min_fclk && + clock_table->DfPstateTable[j].FClk > max_level_fclk && clock_table->DfPstateTable[j].Voltage <= clock_table->SocVoltage[i]) { - min_fclk = clock_table->DfPstateTable[j].FClk; - min_pstate = j; + max_level_fclk = clock_table->DfPstateTable[j].FClk; + max_level_pstate = j; } } @@ -621,15 +632,15 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl bw_params->clk_table.entries[i].dtbclk_mhz = bw_params->clk_table.entries[j].dtbclk_mhz; /* Now update clocks we do read */ - bw_params->clk_table.entries[i].fclk_mhz = min_fclk; - bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[min_pstate].MemClk; - bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[min_pstate].Voltage; + bw_params->clk_table.entries[i].fclk_mhz = max_level_fclk; + bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[max_level_pstate].MemClk; + bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[max_level_pstate].Voltage; bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[i]; bw_params->clk_table.entries[i].socclk_mhz = clock_table->SocClocks[i]; bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk; bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk; bw_params->clk_table.entries[i].wck_ratio = convert_wck_ratio( - clock_table->DfPstateTable[min_pstate].WckRatio); + clock_table->DfPstateTable[max_level_pstate].WckRatio); } /* Make sure to include at least one entry at highest pstate */ From 1715339b45c46f4b588d940f50cc91ef0f10d4a1 Mon Sep 17 00:00:00 2001 From: Daniel Miess Date: Tue, 17 Jan 2023 15:34:35 -0500 Subject: [PATCH 10/36] drm/amd/display: Add missing brackets in calculation [Why] Brackets missing in the calculation for MIN_DST_Y_NEXT_START [How] Add missing brackets for this calculation Reviewed-by: Nicholas Kazlauskas Acked-by: Alex Hung Signed-off-by: Daniel Miess Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c index 950669f2c10d..cb7c0c878423 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c @@ -3183,7 +3183,7 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman } else { v->MIN_DST_Y_NEXT_START[k] = v->VTotal[k] - v->VFrontPorch[k] + v->VTotal[k] - v->VActive[k] - v->VStartup[k]; } - v->MIN_DST_Y_NEXT_START[k] += dml_floor(4.0 * v->TSetup[k] / (double)v->HTotal[k] / v->PixelClock[k], 1.0) / 4.0; + v->MIN_DST_Y_NEXT_START[k] += dml_floor(4.0 * v->TSetup[k] / ((double)v->HTotal[k] / v->PixelClock[k]), 1.0) / 4.0; if (((v->VUpdateOffsetPix[k] + v->VUpdateWidthPix[k] + v->VReadyOffsetPix[k]) / v->HTotal[k]) <= (isInterlaceTiming ? dml_floor((v->VTotal[k] - v->VActive[k] - v->VFrontPorch[k] - v->VStartup[k]) / 2.0, 1.0) : From 32e3da4310bb1c55b076ed477dea6ddf5a965e69 Mon Sep 17 00:00:00 2001 From: Leon Huang Date: Tue, 17 Jan 2023 14:17:40 +0800 Subject: [PATCH 11/36] drm/amd/display: Fix only one ABM pipe enabled under ODM combined case [Why] ABM set pipe before updating ODM status, it leads to incorrect ABM pipe setting when enabling ODM combine. [How] Call ABM set pipe flow after ODM status update in program pipe sequence. Reviewed-by: Chun-Liang Chang Reviewed-by: Nicholas Kazlauskas Acked-by: Alex Hung Signed-off-by: Leon Huang Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index 916dceecd3de..cb8edb14603a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1777,6 +1777,15 @@ static void dcn20_program_pipe( &pipe_ctx->stream->bit_depth_params, &pipe_ctx->stream->clamping); } + + /* Set ABM pipe after other pipe configurations done */ + if (pipe_ctx->plane_state->visible) { + if (pipe_ctx->stream_res.abm) { + dc->hwss.set_pipe(pipe_ctx); + pipe_ctx->stream_res.abm->funcs->set_abm_level(pipe_ctx->stream_res.abm, + pipe_ctx->stream->abm_level); + } + } } void dcn20_program_front_end_for_ctx( From 972243f973eb0821084e5833d5f7f4ed025f42da Mon Sep 17 00:00:00 2001 From: Vladimir Stempen Date: Tue, 17 Jan 2023 14:14:42 -0500 Subject: [PATCH 12/36] drm/amd/display: fix FCLK pstate change underflow [Why] Currently we set FCLK p-state change watermark calculated based on dummy p-state latency when UCLK p-state is not supported [How] Calculate FCLK p-state change watermark based on on FCLK pstate change latency in case UCLK p-state is not supported Reviewed-by: Nevenko Stupar Acked-by: Alex Hung Signed-off-by: Vladimir Stempen Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c index 0dc1a03999b6..28e9f3644bf4 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c @@ -2126,6 +2126,10 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, */ context->bw_ctx.bw.dcn.watermarks.a = context->bw_ctx.bw.dcn.watermarks.c; context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 0; + /* Calculate FCLK p-state change watermark based on FCLK pstate change latency in case + * UCLK p-state is not supported, to avoid underflow in case FCLK pstate is supported + */ + context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.fclk_pstate_change_ns = get_fclk_watermark(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; } else { /* Set A: * All clocks min. From ed9ca86b8c434f8f24355278f020a86bd445034f Mon Sep 17 00:00:00 2001 From: Daniel Miess Date: Tue, 17 Jan 2023 15:45:30 -0500 Subject: [PATCH 13/36] drm/amd/display: Adjust downscaling limits for dcn314 [Why] Lower max_downscale_ratio and ARGB888 downscale factor to prevent cases where underflow may occur on dcn314 [How] Set max_downscale_ratio to 400 and ARGB downscale factor to 250 for dcn314 Reviewed-by: Nicholas Kazlauskas Acked-by: Alex Hung Signed-off-by: Daniel Miess Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c index f9ea1e86707f..79850a68f62a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c @@ -874,8 +874,9 @@ static const struct dc_plane_cap plane_cap = { }, // 6:1 downscaling ratio: 1000/6 = 166.666 + // 4:1 downscaling ratio for ARGB888 to prevent underflow during P010 playback: 1000/4 = 250 .max_downscale_factor = { - .argb8888 = 167, + .argb8888 = 250, .nv12 = 167, .fp16 = 167 }, @@ -1763,7 +1764,7 @@ static bool dcn314_resource_construct( pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; pool->base.pipe_count = pool->base.res_cap->num_timing_generator; pool->base.mpcc_count = pool->base.res_cap->num_timing_generator; - dc->caps.max_downscale_ratio = 600; + dc->caps.max_downscale_ratio = 400; dc->caps.i2c_speed_in_khz = 100; dc->caps.i2c_speed_in_khz_hdcp = 100; dc->caps.max_cursor_size = 256; From b07bb766b6d54fb280ff257e5a6d1c3b418832f9 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Thu, 19 Jan 2023 09:31:28 -0500 Subject: [PATCH 14/36] drm/amd/display: Revert "avoid disable otg when dig was disabled" This reverts commit 7cf5ceb30d4d527d763ae78c5405e3faca1fb8b1. Acked-by: Alex Hung Signed-off-by: Aric Cyr Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 26 +++++-------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c index 8c368bcc8e7e..43d1f38b94ce 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c @@ -87,16 +87,6 @@ static int dcn315_get_active_display_cnt_wa( return display_count; } -bool should_disable_otg(struct pipe_ctx *pipe) -{ - bool ret = true; - - if (pipe->stream->link->link_enc && pipe->stream->link->link_enc->funcs->is_dig_enabled && - pipe->stream->link->link_enc->funcs->is_dig_enabled(pipe->stream->link->link_enc)) - ret = false; - return ret; -} - static void dcn315_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable) { struct dc *dc = clk_mgr_base->ctx->dc; @@ -108,16 +98,12 @@ static void dcn315_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state if (pipe->top_pipe || pipe->prev_odm_pipe) continue; if (pipe->stream && (pipe->stream->dpms_off || pipe->plane_state == NULL || - dc_is_virtual_signal(pipe->stream->signal))) { - - /* This w/a should not trigger when we have a dig active */ - if (should_disable_otg(pipe)) { - if (disable) { - pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg); - reset_sync_context_for_pipe(dc, context, i); - } else - pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg); - } + dc_is_virtual_signal(pipe->stream->signal))) { + if (disable) { + pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg); + reset_sync_context_for_pipe(dc, context, i); + } else + pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg); } } } From 0c2bfcc338ebd920cb0f4ddcfe6ad8f07e0064b0 Mon Sep 17 00:00:00 2001 From: Mustapha Ghaddar Date: Wed, 18 Jan 2023 11:46:37 -0500 Subject: [PATCH 15/36] drm/amd/display: Add Function declaration in dc_link [WHY] Housekeeping cleaning and adding declaration for function to be called from DM layer [HOW] Adding public functions to dc_link.h Reviewed-by: Jun Lei Acked-by: Alex Hung Signed-off-by: Mustapha Ghaddar Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_link.h | 27 +++++++++++++++++++ .../dc/link/protocols/link_dp_dpia_bw.h | 24 ----------------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index 1927eacbfa71..85b57848f5cb 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -627,4 +627,31 @@ struct fixed31_32 calculate_sst_avg_time_slots_per_mtp( void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable); void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode); +/* + * USB4 DPIA BW ALLOCATION PUBLIC FUNCTIONS + */ +/* + * Send a request from DP-Tx requesting to allocate BW remotely after + * allocating it locally. This will get processed by CM and a CB function + * will be called. + * + * @link: pointer to the dc_link struct instance + * @req_bw: The requested bw in Kbyte to allocated + * + * return: none + */ +void dc_link_set_usb4_req_bw_req(struct dc_link *link, int req_bw); + +/* + * CB function for when the status of the Req above is complete. We will + * find out the result of allocating on CM and update structs accordingly + * + * @link: pointer to the dc_link struct instance + * @bw: Allocated or Estimated BW depending on the result + * @result: Response type + * + * return: none + */ +void dc_link_get_usb4_req_bw_resp(struct dc_link *link, uint8_t bw, uint8_t result); + #endif /* DC_LINK_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h index 58eb7b581093..832a6dd2c5fa 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h @@ -44,30 +44,6 @@ enum bw_type { */ bool set_dptx_usb4_bw_alloc_support(struct dc_link *link); -/* - * Send a request from DP-Tx requesting to allocate BW remotely after - * allocating it locally. This will get processed by CM and a CB function - * will be called. - * - * @link: pointer to the dc_link struct instance - * @req_bw: The requested bw in Kbyte to allocated - * - * return: none - */ -void set_usb4_req_bw_req(struct dc_link *link, int req_bw); - -/* - * CB function for when the status of the Req above is complete. We will - * find out the result of allocating on CM and update structs accordingly - * - * @link: pointer to the dc_link struct instance - * @bw: Allocated or Estimated BW depending on the result - * @result: Response type - * - * return: none - */ -void get_usb4_req_bw_resp(struct dc_link *link, uint8_t bw, uint8_t result); - /* * Return the response_ready flag from dc_link struct * From cf76ce68c214b78bf151e84abaa0a2704fd38574 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 19 Jan 2023 17:09:54 -0500 Subject: [PATCH 16/36] drm/amd/display: Unassign does_plane_fit_in_mall function from dcn3.2 [Why] The hwss function does_plane_fit_in_mall not applicable to dcn3.2 asics. Using it with dcn3.2 can result in undefined behaviour. [How] Assign the function pointer to NULL. Reviewed-by: Alvin Lee Acked-by: Alex Hung Signed-off-by: George Shen Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c index 330d7cbc7398..a02918eaa2c1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c @@ -94,7 +94,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = { .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, .calc_vupdate_position = dcn10_calc_vupdate_position, .apply_idle_power_optimizations = dcn32_apply_idle_power_optimizations, - .does_plane_fit_in_mall = dcn30_does_plane_fit_in_mall, + .does_plane_fit_in_mall = NULL, .set_backlight_level = dcn21_set_backlight_level, .set_abm_immediate_disable = dcn21_set_abm_immediate_disable, .hardware_release = dcn30_hardware_release, From 4b0b4c17f5f6d4df40f2f79068909236858d61e0 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Fri, 20 Jan 2023 11:14:30 -0500 Subject: [PATCH 17/36] drm/amd/display: Reset DMUB mailbox SW state after HW reset [Why] Otherwise we can be out of sync with what's in the hardware, leading to us rerunning every command that's presently in the ringbuffer. [How] Reset software state for the mailboxes in hw_reset callback. This is already done as part of the mailbox init in hw_init, but we do need to remember to reset the last cached wptr value as well here. Reviewed-by: Hansen Dsouza Acked-by: Alex Hung Signed-off-by: Nicholas Kazlauskas Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index 4a122925c3ae..92c18bfb98b3 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -532,6 +532,9 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, if (dmub->hw_funcs.reset) dmub->hw_funcs.reset(dmub); + /* reset the cache of the last wptr as well now that hw is reset */ + dmub->inbox1_last_wptr = 0; + cw0.offset.quad_part = inst_fb->gpu_addr; cw0.region.base = DMUB_CW0_BASE; cw0.region.top = cw0.region.base + inst_fb->size - 1; @@ -649,6 +652,15 @@ enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub) if (dmub->hw_funcs.reset) dmub->hw_funcs.reset(dmub); + /* mailboxes have been reset in hw, so reset the sw state as well */ + dmub->inbox1_last_wptr = 0; + dmub->inbox1_rb.wrpt = 0; + dmub->inbox1_rb.rptr = 0; + dmub->outbox0_rb.wrpt = 0; + dmub->outbox0_rb.rptr = 0; + dmub->outbox1_rb.wrpt = 0; + dmub->outbox1_rb.rptr = 0; + dmub->hw_init = false; return DMUB_STATUS_OK; From e322843e5e33e72ff218d661f3d15ff9c9f2f1b5 Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Tue, 17 Jan 2023 10:58:34 -0500 Subject: [PATCH 18/36] drm/amd/display: fix linux dp link lost handled only one time [Why] linux amdgpu defer handle link lost irq. dm add handle request to irq work queue for the first irq of link lost. if link training fails for link lost handle, link will not be enabled anymore. [How] allow adding handle request of link lost to work queue before running dp link training for link lost. Signed-off-by: Hersen Wu Acked-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 ++++++++++++++++--- drivers/gpu/drm/amd/display/dc/dc_link.h | 3 +++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index ffbbd50a61d1..f4451fa6f781 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1301,10 +1301,28 @@ static void dm_handle_hpd_rx_offload_work(struct work_struct *work) else if ((dc_link->connector_signal != SIGNAL_TYPE_EDP) && dc_link_check_link_loss_status(dc_link, &offload_work->data) && dc_link_dp_allow_hpd_rx_irq(dc_link)) { - dc_link_dp_handle_link_loss(dc_link); + /* offload_work->data is from handle_hpd_rx_irq-> + * schedule_hpd_rx_offload_work.this is defer handle + * for hpd short pulse. upon here, link status may be + * changed, need get latest link status from dpcd + * registers. if link status is good, skip run link + * training again. + */ + union hpd_irq_data irq_data; + + memset(&irq_data, 0, sizeof(irq_data)); + + /* before dc_link_dp_handle_link_loss, allow new link lost handle + * request be added to work queue if link lost at end of dc_link_ + * dp_handle_link_loss + */ spin_lock_irqsave(&offload_work->offload_wq->offload_lock, flags); offload_work->offload_wq->is_handling_link_loss = false; spin_unlock_irqrestore(&offload_work->offload_wq->offload_lock, flags); + + if ((dp_read_hpd_rx_irq_data(dc_link, &irq_data) == DC_OK) && + dc_link_check_link_loss_status(dc_link, &irq_data)) + dc_link_dp_handle_link_loss(dc_link); } mutex_unlock(&adev->dm.dc_lock); @@ -3237,7 +3255,7 @@ static void handle_hpd_rx_irq(void *param) union hpd_irq_data hpd_irq_data; bool link_loss = false; bool has_left_work = false; - int idx = aconnector->base.index; + int idx = dc_link->link_index; struct hpd_rx_irq_offload_work_queue *offload_wq = &adev->dm.hpd_rx_offload_wq[idx]; memset(&hpd_irq_data, 0, sizeof(hpd_irq_data)); @@ -3379,7 +3397,7 @@ static void register_hpd_handlers(struct amdgpu_device *adev) (void *) aconnector); if (adev->dm.hpd_rx_offload_wq) - adev->dm.hpd_rx_offload_wq[connector->index].aconnector = + adev->dm.hpd_rx_offload_wq[dc_link->link_index].aconnector = aconnector; } } diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index 85b57848f5cb..64d5d9b28ca6 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -433,6 +433,9 @@ void dc_link_dp_handle_link_loss(struct dc_link *link); bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link); bool dc_link_check_link_loss_status(struct dc_link *link, union hpd_irq_data *hpd_irq_dpcd_data); +enum dc_status dp_read_hpd_rx_irq_data( + struct dc_link *link, + union hpd_irq_data *irq_data); struct dc_sink_init_data; struct dc_sink *dc_link_add_remote_sink( From 504f9ba8e02b2fb4496f6bccfa331b10fd34d14a Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Sun, 22 Jan 2023 16:42:45 -0500 Subject: [PATCH 19/36] drm/amd/display: 3.2.221 This version brings along following fixes: - fix linux dp link lost handled only one time - Reset DMUB mailbox SW state after HW reset - Unassign does_plane_fit_in_mall function from dcn3.2 - Add Function delaration in dc_link - Fix crash when connecting 2 displays with video playback - Adjust downscaling limits for dcn314 - fix FCLK pstate change underflow - Fix only one ABM pipe enabled under ODM combined case - Add missing brackets in calculation - Correct bw_params population - Fix Z8 support configurations - Add Debug Log for MST and PCON - fix MALL size hardcoded for DCN321 - add rc_params_override option in dc_dsc_config - Enable Freesync over PCon Acked-by: Alex Hung Signed-off-by: Aric Cyr Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 42ce45306483..2e23fd8b4e9f 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -47,7 +47,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.220" +#define DC_VER "3.2.221" #define MAX_SURFACES 3 #define MAX_PLANES 6 From 402ed4f1e23d63c9cd11789c500b86d35d4f5bc3 Mon Sep 17 00:00:00 2001 From: Tim Huang Date: Sat, 21 Jan 2023 10:35:04 +0800 Subject: [PATCH 20/36] drm/amd/pm: drop unneeded dpm features disablement for SMU 13.0.4/11 PMFW will handle the features disablement properly for gpu reset case, driver involvement may cause some unexpected issues. Cc: stable@vger.kernel.org # 6.1 Signed-off-by: Tim Huang Reviewed-by: Yifan Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index ec52830dde24..8bae3fe869cd 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -1497,6 +1497,20 @@ static int smu_disable_dpms(struct smu_context *smu) } } + /* + * For SMU 13.0.4/11, PMFW will handle the features disablement properly + * for gpu reset case. Driver involvement is unnecessary. + */ + if (amdgpu_in_reset(adev)) { + switch (adev->ip_versions[MP1_HWIP][0]) { + case IP_VERSION(13, 0, 4): + case IP_VERSION(13, 0, 11): + return 0; + default: + break; + } + } + /* * For gpu reset, runpm and hibernation through BACO, * BACO feature has to be kept enabled. From 20e6220b4154a57a9d26873b137070cddd301b38 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Sat, 28 Jan 2023 14:24:34 +0800 Subject: [PATCH 21/36] drm/amdgpu: enable HDP SD for gfx 11.0.3 Enable HDP clock gating control for gfx 11.0.3. Signed-off-by: Evan Quan Reviewed-by: Feifei Xu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/soc21.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c index e03cf7f766c5..477be4b62bc3 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc21.c +++ b/drivers/gpu/drm/amd/amdgpu/soc21.c @@ -676,7 +676,8 @@ static int soc21_common_early_init(void *handle) AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | AMD_CG_SUPPORT_REPEATER_FGCG | - AMD_CG_SUPPORT_GFX_MGCG; + AMD_CG_SUPPORT_GFX_MGCG | + AMD_CG_SUPPORT_HDP_SD; adev->pg_flags = AMD_PG_SUPPORT_VCN | AMD_PG_SUPPORT_VCN_DPG | AMD_PG_SUPPORT_JPEG; From 4ce11e833319c2794905c51be7ab00b12f25b264 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 30 Jan 2023 10:16:06 -0600 Subject: [PATCH 22/36] drm/amd: Fix initialization for nbio 4.3.0 A mistake has been made on some boards with NBIO 4.3.0 where some NBIO registers aren't properly set by the hardware. Ensure that they're set during initialization. Cc: Natikar Basavaraj Tested-by: Satyanarayana ReddyTVN Tested-by: Rutvij Gajjar Signed-off-by: Mario Limonciello Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c b/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c index 15eb3658d70e..09fdcd20cb91 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c @@ -337,7 +337,13 @@ const struct nbio_hdp_flush_reg nbio_v4_3_hdp_flush_reg = { static void nbio_v4_3_init_registers(struct amdgpu_device *adev) { - return; + if (adev->ip_versions[NBIO_HWIP][0] == IP_VERSION(4, 3, 0)) { + uint32_t data; + + data = RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF2_STRAP2); + data &= ~RCC_DEV0_EPF2_STRAP2__STRAP_NO_SOFT_RESET_DEV0_F2_MASK; + WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF2_STRAP2, data); + } } static u32 nbio_v4_3_get_rom_offset(struct amdgpu_device *adev) From 2f68c414981a10af42a90522ef831d59c0923ce1 Mon Sep 17 00:00:00 2001 From: Yiqing Yao Date: Tue, 31 Jan 2023 16:02:47 +0800 Subject: [PATCH 23/36] drm/amdgpu: Enable vclk dclk node for gc11.0.3 These sysfs nodes are tested supported, so enable them. Signed-off-by: Yiqing Yao Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 76b9ec64ca50..bd060697d982 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -2007,14 +2007,16 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ gc_ver == IP_VERSION(10, 3, 0) || gc_ver == IP_VERSION(10, 1, 2) || gc_ver == IP_VERSION(11, 0, 0) || - gc_ver == IP_VERSION(11, 0, 2))) + gc_ver == IP_VERSION(11, 0, 2) || + gc_ver == IP_VERSION(11, 0, 3))) *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_dpm_dclk)) { if (!(gc_ver == IP_VERSION(10, 3, 1) || gc_ver == IP_VERSION(10, 3, 0) || gc_ver == IP_VERSION(10, 1, 2) || gc_ver == IP_VERSION(11, 0, 0) || - gc_ver == IP_VERSION(11, 0, 2))) + gc_ver == IP_VERSION(11, 0, 2) || + gc_ver == IP_VERSION(11, 0, 3))) *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_power_profile_mode)) { if (amdgpu_dpm_get_power_profile_mode(adev, NULL) == -EOPNOTSUPP) From 44900af0401fd2a2f76f5e65d42a252665bb7bdb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 25 Jan 2023 14:35:16 -0500 Subject: [PATCH 24/36] drm/amd/display: Properly handle additional cases where DCN is not supported There could be boards with DCN listed in IP discovery, but no display hardware actually wired up. In this case the vbios display table will not be populated. Detect this case and skip loading DM when we detect it. v2: Mark DCN as harvested as well so other display checks elsewhere in the driver are handled properly. Cc: Aurabindo Pillai Reviewed-by: Aurabindo Pillai Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index f4451fa6f781..39bc8fd33cce 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4592,6 +4592,17 @@ static int dm_init_microcode(struct amdgpu_device *adev) static int dm_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + struct amdgpu_mode_info *mode_info = &adev->mode_info; + struct atom_context *ctx = mode_info->atom_context; + int index = GetIndexIntoMasterTable(DATA, Object_Header); + u16 data_offset; + + /* if there is no object header, skip DM */ + if (!amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { + adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK; + dev_info(adev->dev, "No object header, skipping DM\n"); + return -ENOENT; + } switch (adev->asic_type) { #if defined(CONFIG_DRM_AMD_DC_SI) From a2f42b5efe6e49b7447e54706925c7016d77388f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Sun, 29 Jan 2023 16:17:52 +0100 Subject: [PATCH 25/36] drm/amdgpu: Fix a typo ("boradcast") MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spell it as "broadcast". Signed-off-by: Jonathan Neuschäfer Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/df_v1_7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/df_v1_7.c b/drivers/gpu/drm/amd/amdgpu/df_v1_7.c index b991609f46c1..5dfab80ffff2 100644 --- a/drivers/gpu/drm/amd/amdgpu/df_v1_7.c +++ b/drivers/gpu/drm/amd/amdgpu/df_v1_7.c @@ -94,7 +94,7 @@ static void df_v1_7_update_medium_grain_clock_gating(struct amdgpu_device *adev, WREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater, tmp); } - /* Exit boradcast mode */ + /* Exit broadcast mode */ adev->df.funcs->enable_broadcast_mode(adev, false); } From 65a4cfb45e0e29a10fb35655f2375e1fc2f13c65 Mon Sep 17 00:00:00 2001 From: ye xingchen Date: Sat, 28 Jan 2023 09:39:08 +0800 Subject: [PATCH 26/36] drm/amdgpu/display: remove duplicate include header in files opp.h is included more than once. Signed-off-by: ye xingchen Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 6475664baa8a..1a2ab934b4bd 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -46,7 +46,6 @@ #include "dpcd_defs.h" #include "dmcu.h" #include "dsc.h" -#include "opp.h" #include "hw/clk_mgr.h" #include "dce/dmub_psr.h" #include "dmub/dmub_srv.h" From 67cdd3a5cc03591a98a303e5e2086a470650967f Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Thu, 26 Jan 2023 17:38:23 -0800 Subject: [PATCH 27/36] drm/amd/display: reduce else-if to else in dcn10_blank_pixel_data() checkpatch reports drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c:2902:13: style: Expression is always true because 'else if' condition is opposite to previous condition at line 2895. [multiCondition] } else if (blank) { ^ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c:2895:6: note: first condition if (!blank) { ^ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c:2902:13: note: else if condition is opposite to first condition } else if (blank) { It is not necessary to explicitly the check != condition, an else is simplier. Fixes: aa5a57773042 ("drm/amd/display: Vari-bright looks disabled near end of MM14") Signed-off-by: Tom Rix Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index bb155734ac93..f735ae5e045f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2899,7 +2899,7 @@ void dcn10_blank_pixel_data( dc->hwss.set_pipe(pipe_ctx); stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level); } - } else if (blank) { + } else { dc->hwss.set_abm_immediate_disable(pipe_ctx); if (stream_res->tg->funcs->set_blank) { stream_res->tg->funcs->wait_for_state(stream_res->tg, CRTC_STATE_VBLANK); From 1c6d24b8be0cbe8e9a573d069c16fe8a56af6a4f Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Thu, 26 Jan 2023 12:49:35 -0800 Subject: [PATCH 28/36] drm/amd/display: reduce else-if to else in dcn32_calculate_dlg_params() cppcheck reports drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c:1403:76: style: Expression is always true because 'else if' condition is opposite to previous condition at line 1396. [multiCondition] } else if (context->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) { ^ drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c:1396:69: note: first condition if (context->res_ctx.pipe_ctx[i].stream->mall_stream_config.type != SUBVP_PHANTOM) { ^ drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c:1403:76: note: else if condition is opposite to first condition } else if (context->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) { It is not necessary to explicitly the check != condition, an else is simplier. Fixes: 238debcaebe4 ("drm/amd/display: Use DML for MALL SS and Subvp allocation calculations") Signed-off-by: Tom Rix Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c index 28e9f3644bf4..27b62ef4f62d 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c @@ -1400,7 +1400,7 @@ static void dcn32_calculate_dlg_params(struct dc *dc, struct dc_state *context, /* SS PSR On: all active surfaces part of streams not supporting PSR stored in MALL */ context->bw_ctx.bw.dcn.mall_ss_psr_active_size_bytes += context->res_ctx.pipe_ctx[i].surface_size_in_mall_bytes; } - } else if (context->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) { + } else { /* SUBVP: phantom surfaces only stored in MALL */ context->bw_ctx.bw.dcn.mall_subvp_size_bytes += context->res_ctx.pipe_ctx[i].surface_size_in_mall_bytes; } From febb414745d98f0a6f14d7fd53f1965a455e19d5 Mon Sep 17 00:00:00 2001 From: "Guilherme G. Piccoli" Date: Mon, 30 Jan 2023 16:56:07 -0300 Subject: [PATCH 29/36] drm/amd/display: Trivial swizzle-related code clean-ups This is a very trivial code clean-up related to commit 5468c36d6285 ("drm/amd/display: Filter Invalid 420 Modes for HDMI TMDS"). This commit added a validation on driver probe to prevent invalid TMDS modes, but one of the fake properties (swizzle) ended-up causing a warning on driver probe; was reported here: https://gitlab.freedesktop.org/drm/amd/-/issues/2264. It was fixed by commit a1cbe6916f44 ("drm/amd/display: patch cases with unknown plane state to prevent warning"), but the validation code had a double variable assignment, which we hereby remove. Also, the fix relies in the dcn2{0,1}patch_unknown_plane_state() callbacks, so while at it we took the opportunity to perform a small code clean-up in such routines. Cc: Aurabindo Pillai Cc: Daniel Wheeler Cc: Fangzhi Zuo Cc: Harry Wentland Cc: Leo Li Cc: Mark Broadworth Cc: Melissa Wen Cc: Rodrigo Siqueira Cc: Sung Joon Kim Cc: Swapnil Patel Reviewed-by: Harry Wentland Signed-off-by: Guilherme G. Piccoli Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 - drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 8 ++------ drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 6 ++---- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 39bc8fd33cce..2096ad00a2de 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6365,7 +6365,6 @@ static enum dc_status dm_validate_stream_and_context(struct dc *dc, dc_plane_state->plane_size.surface_size.width = stream->src.width; dc_plane_state->plane_size.chroma_size.height = stream->src.height; dc_plane_state->plane_size.chroma_size.width = stream->src.width; - dc_plane_state->tiling_info.gfx9.swizzle = DC_SW_UNKNOWN; dc_plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB8888; dc_plane_state->tiling_info.gfx9.swizzle = DC_SW_UNKNOWN; dc_plane_state->rotation = ROTATION_ANGLE_0; diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 531f405d2554..3af24ef9cb2d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -2225,14 +2225,10 @@ enum dc_status dcn20_patch_unknown_plane_state(struct dc_plane_state *plane_stat enum surface_pixel_format surf_pix_format = plane_state->format; unsigned int bpp = resource_pixel_format_to_bpp(surf_pix_format); - enum swizzle_mode_values swizzle = DC_SW_LINEAR; - + plane_state->tiling_info.gfx9.swizzle = DC_SW_64KB_S; if (bpp == 64) - swizzle = DC_SW_64KB_D; - else - swizzle = DC_SW_64KB_S; + plane_state->tiling_info.gfx9.swizzle = DC_SW_64KB_D; - plane_state->tiling_info.gfx9.swizzle = swizzle; return DC_OK; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c index fbcf0afeae0d..8f9244fe5c86 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -1393,15 +1393,13 @@ static uint32_t read_pipe_fuses(struct dc_context *ctx) static enum dc_status dcn21_patch_unknown_plane_state(struct dc_plane_state *plane_state) { - enum dc_status result = DC_OK; - if (plane_state->ctx->dc->debug.disable_dcc == DCC_ENABLE) { plane_state->dcc.enable = 1; /* align to our worst case block width */ plane_state->dcc.meta_pitch = ((plane_state->src_rect.width + 1023) / 1024) * 1024; } - result = dcn20_patch_unknown_plane_state(plane_state); - return result; + + return dcn20_patch_unknown_plane_state(plane_state); } static const struct resource_funcs dcn21_res_pool_funcs = { From 11cc4652e99f5529a9785b64f78fe005d8782b47 Mon Sep 17 00:00:00 2001 From: Vitaly Prosyak Date: Fri, 20 Jan 2023 14:03:45 -0500 Subject: [PATCH 30/36] drm/amdgpu: always sending PSP messages LOAD_ASD and UNLOAD_TA We allow sending PSP messages LOAD_ASD and UNLOAD_TA without acquiring a lock in drm_dev_enter during driver unload because we must call drm_dev_unplug as the beginning of unload driver sequence. Added WARNING if other PSP messages are sent without a lock. After this commit, the following commands would work -sudo modprobe -r amdgpu -sudo modprobe amdgpu Signed-off-by: Vitaly Prosyak Reviewed-by Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index a8391f269cd0..40929f34447c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -606,12 +606,21 @@ psp_cmd_submit_buf(struct psp_context *psp, int timeout = 20000; bool ras_intr = false; bool skip_unsupport = false; + bool dev_entered; if (psp->adev->no_hw_access) return 0; - if (!drm_dev_enter(adev_to_drm(psp->adev), &idx)) - return 0; + dev_entered = drm_dev_enter(adev_to_drm(psp->adev), &idx); + /* + * We allow sending PSP messages LOAD_ASD and UNLOAD_TA without acquiring + * a lock in drm_dev_enter during driver unload because we must call + * drm_dev_unplug as the beginning of unload driver sequence . It is very + * crucial that userspace can't access device instances anymore. + */ + if (!dev_entered) + WARN_ON(psp->cmd_buf_mem->cmd_id != GFX_CMD_ID_LOAD_ASD && + psp->cmd_buf_mem->cmd_id != GFX_CMD_ID_UNLOAD_TA); memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE); @@ -676,7 +685,8 @@ psp_cmd_submit_buf(struct psp_context *psp, } exit: - drm_dev_exit(idx); + if (dev_entered) + drm_dev_exit(idx); return ret; } From 72fef4980ddf20792fa095f88b008d896313c2b1 Mon Sep 17 00:00:00 2001 From: Yifan Zha Date: Tue, 31 Jan 2023 15:31:27 +0800 Subject: [PATCH 31/36] drm/amdgpu: Remove writing GRBM_GFX_CNTL in RLCG interface under SRIOV [Why] Accessing GRBM_GFX_CNTL in full access time has risk when VF is doing MMIO attacking. Therefore, VF writing GRBM_GFX_CNTL are blocked by L1 Policy. For RLCG interface, RLCG use SCRATCH_REG2 which is copied from GRBM_GFX_CNTL. [How] Remove writing GRBM_GFX_CNTL in amdgpu_virt_rlcg_reg_rw. v2: Remove directly writing GRBM_GFX_INDEX in amdgpu_virt_rlcg_reg_rw as RLCG interface no need to use it. Signed-off-by: Yifan Zha Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index f39391e03d46..ca5a1d026f5a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -983,11 +983,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v if (offset == reg_access_ctrl->grbm_cntl) { /* if the target reg offset is grbm_cntl, write to scratch_reg2 */ writel(v, scratch_reg2); - writel(v, ((void __iomem *)adev->rmmio) + (offset * 4)); } else if (offset == reg_access_ctrl->grbm_idx) { /* if the target reg offset is grbm_idx, write to scratch_reg3 */ writel(v, scratch_reg3); - writel(v, ((void __iomem *)adev->rmmio) + (offset * 4)); } else { /* * SCRATCH_REG0 = read/write value From 2404f9b0ea0153c3fddb0c4d7a43869dc8608f6f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 26 Jan 2023 10:15:37 -0500 Subject: [PATCH 32/36] drm/amd/display: disable S/G display on DCN 2.1.0 Causes flickering or white screens in some configurations. Disable it for now until we can fix the issue. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2352 Cc: roman.li@amd.com Cc: yifan1.zhang@amd.com Reviewed-by: Yifan Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 2096ad00a2de..037af1997b27 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1552,7 +1552,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) (adev->apu_flags & AMD_APU_IS_PICASSO)) init_data.flags.gpu_vm_support = true; break; - case IP_VERSION(2, 1, 0): case IP_VERSION(3, 0, 1): case IP_VERSION(3, 1, 2): case IP_VERSION(3, 1, 3): From f081cd4ca2658752a8c0e2353d50aec80d07c65f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 25 Jan 2023 09:57:27 -0500 Subject: [PATCH 33/36] drm/amd/display: disable S/G display on DCN 3.1.2/3 Causes flickering or white screens in some configurations. Disable it for now until we can fix the issue. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2352 Cc: roman.li@amd.com Cc: yifan1.zhang@amd.com Reviewed-by: Yifan Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 037af1997b27..c40cbfb758b5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1553,8 +1553,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) init_data.flags.gpu_vm_support = true; break; case IP_VERSION(3, 0, 1): - case IP_VERSION(3, 1, 2): - case IP_VERSION(3, 1, 3): case IP_VERSION(3, 1, 6): init_data.flags.gpu_vm_support = true; break; From 0294868fd803b48dc354f7cd7ef7ba26a60e5a9b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 31 Jan 2023 09:56:46 -0500 Subject: [PATCH 34/36] drm/amd/display: properly handling AGP aperture in vm setup Take into account whether or not the AGP aperture is enabled or not when calculating the system aperture. Fixes white screens with DCN 3.1.4. Based on a patch from Yifan Zhang Cc: Yifan Zhang Acked-by: Harry Wentland Reviewed-by: Yifan Zhang Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index c40cbfb758b5..7cfc089084ed 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1185,24 +1185,38 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_ memset(pa_config, 0, sizeof(*pa_config)); - logical_addr_low = min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18; - pt_base = amdgpu_gmc_pd_addr(adev->gart.bo); - - if (adev->apu_flags & AMD_APU_IS_RAVEN2) - /* - * Raven2 has a HW issue that it is unable to use the vram which - * is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. So here is the - * workaround that increase system aperture high address (add 1) - * to get rid of the VM fault and hardware hang. - */ - logical_addr_high = max((adev->gmc.fb_end >> 18) + 0x1, adev->gmc.agp_end >> 18); - else - logical_addr_high = max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18; - agp_base = 0; agp_bot = adev->gmc.agp_start >> 24; agp_top = adev->gmc.agp_end >> 24; + /* AGP aperture is disabled */ + if (agp_bot == agp_top) { + logical_addr_low = adev->gmc.vram_start >> 18; + if (adev->apu_flags & AMD_APU_IS_RAVEN2) + /* + * Raven2 has a HW issue that it is unable to use the vram which + * is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. So here is the + * workaround that increase system aperture high address (add 1) + * to get rid of the VM fault and hardware hang. + */ + logical_addr_high = (adev->gmc.fb_end >> 18) + 0x1; + else + logical_addr_high = adev->gmc.vram_end >> 18; + } else { + logical_addr_low = min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18; + if (adev->apu_flags & AMD_APU_IS_RAVEN2) + /* + * Raven2 has a HW issue that it is unable to use the vram which + * is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. So here is the + * workaround that increase system aperture high address (add 1) + * to get rid of the VM fault and hardware hang. + */ + logical_addr_high = max((adev->gmc.fb_end >> 18) + 0x1, adev->gmc.agp_end >> 18); + else + logical_addr_high = max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18; + } + + pt_base = amdgpu_gmc_pd_addr(adev->gart.bo); page_table_start.high_part = (u32)(adev->gmc.gart_start >> 44) & 0xF; page_table_start.low_part = (u32)(adev->gmc.gart_start >> 12); From c6eafee038ed4a9ed91a6a21562f65c2ee31867c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 31 Jan 2023 10:03:40 -0500 Subject: [PATCH 35/36] Revert "Revert "drm/amdgpu/gmc11: enable AGP aperture"" This reverts commit 1a65327a84db5b9081a51ccb1c562083f59bfcec. This should be resolved so we can re-enable this. Also, the AGP apeture was bring programmed to 0 on MMHUB 3.0.1 since agp_start and end were not being set. Acked-by: Harry Wentland Reviewed-by: Yifan Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfxhub_v3_0.c | 7 ++++--- drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 1 + drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c | 7 ++++--- drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c | 6 +++--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v3_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v3_0.c index fa42d1907dfa..7c069010ca9a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v3_0.c @@ -151,10 +151,11 @@ static void gfxhub_v3_0_init_system_aperture_regs(struct amdgpu_device *adev) { uint64_t value; - /* Disable AGP. */ + /* Program the AGP BAR */ WREG32_SOC15(GC, 0, regGCMC_VM_AGP_BASE, 0); - WREG32_SOC15(GC, 0, regGCMC_VM_AGP_TOP, 0); - WREG32_SOC15(GC, 0, regGCMC_VM_AGP_BOT, 0x00FFFFFF); + WREG32_SOC15(GC, 0, regGCMC_VM_AGP_BOT, adev->gmc.agp_start >> 24); + WREG32_SOC15(GC, 0, regGCMC_VM_AGP_TOP, adev->gmc.agp_end >> 24); + /* Program the system aperture low logical page number. */ WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_LOW_ADDR, diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c index 5e0018fe7e7d..0a31a341aa43 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c @@ -673,6 +673,7 @@ static void gmc_v11_0_vram_gtt_location(struct amdgpu_device *adev, amdgpu_gmc_vram_location(adev, &adev->gmc, base); amdgpu_gmc_gart_location(adev, mc); + amdgpu_gmc_agp_location(adev, mc); /* base offset of vram pages */ if (amdgpu_sriov_vf(adev)) diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c index ae9cd1a4cfee..923fc09bc8fc 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c @@ -177,10 +177,11 @@ static void mmhub_v3_0_init_system_aperture_regs(struct amdgpu_device *adev) * these regs, and they will be programed at host. * so skip programing these regs. */ - /* Disable AGP. */ + /* Program the AGP BAR */ WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0); - WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, 0); - WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, 0x00FFFFFF); + WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, adev->gmc.agp_start >> 24); + WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, adev->gmc.agp_end >> 24); + /* Program the system aperture low logical page number. */ WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_LOW_ADDR, adev->gmc.vram_start >> 18); diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c index c30e40e52fb2..51580302ec42 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c @@ -162,10 +162,10 @@ static void mmhub_v3_0_2_init_system_aperture_regs(struct amdgpu_device *adev) uint64_t value; uint32_t tmp; - /* Disable AGP. */ + /* Program the AGP BAR */ WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0); - WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, 0); - WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, 0x00FFFFFF); + WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, adev->gmc.agp_start >> 24); + WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, adev->gmc.agp_end >> 24); if (!amdgpu_sriov_vf(adev)) { /* From 69ed0c5d44d72051b13e65384e9d9354c45d5e14 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 31 Jan 2023 13:10:55 -0500 Subject: [PATCH 36/36] Revert "drm/amd/display: disable S/G display on DCN 3.1.4" This reverts commit 9aa15370819294beb7eb67c9dcbf654d79ff8790. This is fixed now so we can re-enable S/G display on DCN 3.1.4. Reviewed-by: Yifan Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 7cfc089084ed..f26beb0e0e1d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1567,6 +1567,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) init_data.flags.gpu_vm_support = true; break; case IP_VERSION(3, 0, 1): + case IP_VERSION(3, 1, 4): case IP_VERSION(3, 1, 6): init_data.flags.gpu_vm_support = true; break;