From 5d9be22d0b6013b14216d313ea62573b77c8c915 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 25 Jul 2023 12:26:29 +0200 Subject: [PATCH] 6.1-stable patches added patches: drm-amd-display-add-polling-method-to-handle-mst-reply-packet.patch drm-amd-display-clean-up-errors-warnings-in-amdgpu_dm.c.patch drm-amd-display-fix-linux-dp-link-lost-handled-only-one-time.patch drm-amd-display-fix-some-coding-style-issues.patch drm-amd-display-force-connector-state-when-bpc-changes-during-compliance.patch drm-amd-display-use-max_dsc_bpp-in-amdgpu_dm.patch drm-dp_mst-clear-msg_rdy-flag-before-sending-new-message.patch --- ...ng-method-to-handle-mst-reply-packet.patch | 365 +++++++++++++ ...an-up-errors-warnings-in-amdgpu_dm.c.patch | 517 ++++++++++++++++++ ...x-dp-link-lost-handled-only-one-time.patch | 111 ++++ ...display-fix-some-coding-style-issues.patch | 359 ++++++++++++ ...e-when-bpc-changes-during-compliance.patch | 484 ++++++++++++++++ ...display-use-max_dsc_bpp-in-amdgpu_dm.patch | 86 +++ ..._rdy-flag-before-sending-new-message.patch | 286 ++++++++++ queue-6.1/series | 7 + 8 files changed, 2215 insertions(+) create mode 100644 queue-6.1/drm-amd-display-add-polling-method-to-handle-mst-reply-packet.patch create mode 100644 queue-6.1/drm-amd-display-clean-up-errors-warnings-in-amdgpu_dm.c.patch create mode 100644 queue-6.1/drm-amd-display-fix-linux-dp-link-lost-handled-only-one-time.patch create mode 100644 queue-6.1/drm-amd-display-fix-some-coding-style-issues.patch create mode 100644 queue-6.1/drm-amd-display-force-connector-state-when-bpc-changes-during-compliance.patch create mode 100644 queue-6.1/drm-amd-display-use-max_dsc_bpp-in-amdgpu_dm.patch create mode 100644 queue-6.1/drm-dp_mst-clear-msg_rdy-flag-before-sending-new-message.patch diff --git a/queue-6.1/drm-amd-display-add-polling-method-to-handle-mst-reply-packet.patch b/queue-6.1/drm-amd-display-add-polling-method-to-handle-mst-reply-packet.patch new file mode 100644 index 00000000000..a907dccc848 --- /dev/null +++ b/queue-6.1/drm-amd-display-add-polling-method-to-handle-mst-reply-packet.patch @@ -0,0 +1,365 @@ +From stable-owner@vger.kernel.org Tue Jul 25 00:26:58 2023 +From: Mario Limonciello +Date: Mon, 24 Jul 2023 17:26:38 -0500 +Subject: drm/amd/display: Add polling method to handle MST reply packet +To: +Cc: Mario Limonciello +Message-ID: <20230724222638.1477-8-mario.limonciello@amd.com> + +From: Wayne Lin + +commit 4f6d9e38c4d244ad106eb9ebd8c0e1215e866f35 upstream. + +[Why] +Specific TBT4 dock doesn't send out short HPD to notify source +that IRQ event DOWN_REP_MSG_RDY is set. Which violates the spec +and cause source can't send out streams to mst sinks. + +[How] +To cover this misbehavior, add an additional polling method to detect +DOWN_REP_MSG_RDY is set. HPD driven handling method is still kept. +Just hook up our handler to drm mgr->cbs->poll_hpd_irq(). + +Cc: Mario Limonciello +Cc: Alex Deucher +Cc: stable@vger.kernel.org +Reviewed-by: Jerry Zuo +Acked-by: Alan Liu +Signed-off-by: Wayne Lin +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Mario Limonciello +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 117 +++--------- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 7 + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 110 +++++++++++ + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h | 11 + + 4 files changed, 159 insertions(+), 86 deletions(-) + +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -1325,6 +1325,15 @@ static void dm_handle_hpd_rx_offload_wor + if (amdgpu_in_reset(adev)) + goto skip; + ++ if (offload_work->data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY || ++ offload_work->data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY) { ++ dm_handle_mst_sideband_msg_ready_event(&aconnector->mst_mgr, DOWN_OR_UP_MSG_RDY_EVENT); ++ spin_lock_irqsave(&offload_work->offload_wq->offload_lock, flags); ++ offload_work->offload_wq->is_handling_mst_msg_rdy_event = false; ++ spin_unlock_irqrestore(&offload_work->offload_wq->offload_lock, flags); ++ goto skip; ++ } ++ + mutex_lock(&adev->dm.dc_lock); + if (offload_work->data.bytes.device_service_irq.bits.AUTOMATED_TEST) { + dc_link_dp_handle_automated_test(dc_link); +@@ -3229,87 +3238,6 @@ static void handle_hpd_irq(void *param) + + } + +-static void dm_handle_mst_sideband_msg(struct amdgpu_dm_connector *aconnector) +-{ +- u8 esi[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = { 0 }; +- u8 dret; +- bool new_irq_handled = false; +- int dpcd_addr; +- int dpcd_bytes_to_read; +- +- const int max_process_count = 30; +- int process_count = 0; +- +- const struct dc_link_status *link_status = dc_link_get_status(aconnector->dc_link); +- +- if (link_status->dpcd_caps->dpcd_rev.raw < 0x12) { +- dpcd_bytes_to_read = DP_LANE0_1_STATUS - DP_SINK_COUNT; +- /* DPCD 0x200 - 0x201 for downstream IRQ */ +- dpcd_addr = DP_SINK_COUNT; +- } else { +- dpcd_bytes_to_read = DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI; +- /* DPCD 0x2002 - 0x2005 for downstream IRQ */ +- dpcd_addr = DP_SINK_COUNT_ESI; +- } +- +- dret = drm_dp_dpcd_read( +- &aconnector->dm_dp_aux.aux, +- dpcd_addr, +- esi, +- dpcd_bytes_to_read); +- +- while (dret == dpcd_bytes_to_read && +- process_count < max_process_count) { +- u8 ack[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = {}; +- u8 retry; +- +- dret = 0; +- +- process_count++; +- +- DRM_DEBUG_DRIVER("ESI %02x %02x %02x\n", esi[0], esi[1], esi[2]); +- /* handle HPD short pulse irq */ +- if (aconnector->mst_mgr.mst_state) +- drm_dp_mst_hpd_irq_handle_event(&aconnector->mst_mgr, +- esi, +- ack, +- &new_irq_handled); +- +- if (new_irq_handled) { +- /* ACK at DPCD to notify down stream */ +- for (retry = 0; retry < 3; retry++) { +- ssize_t wret; +- +- wret = drm_dp_dpcd_writeb(&aconnector->dm_dp_aux.aux, +- dpcd_addr + 1, +- ack[1]); +- if (wret == 1) +- break; +- } +- +- if (retry == 3) { +- DRM_ERROR("Failed to ack MST event.\n"); +- return; +- } +- +- drm_dp_mst_hpd_irq_send_new_request(&aconnector->mst_mgr); +- /* check if there is new irq to be handled */ +- dret = drm_dp_dpcd_read( +- &aconnector->dm_dp_aux.aux, +- dpcd_addr, +- esi, +- dpcd_bytes_to_read); +- +- new_irq_handled = false; +- } else { +- break; +- } +- } +- +- if (process_count == max_process_count) +- DRM_DEBUG_DRIVER("Loop exceeded max iterations\n"); +-} +- + static void schedule_hpd_rx_offload_work(struct hpd_rx_irq_offload_work_queue *offload_wq, + union hpd_irq_data hpd_irq_data) + { +@@ -3371,7 +3299,23 @@ static void handle_hpd_rx_irq(void *para + if (dc_link_dp_allow_hpd_rx_irq(dc_link)) { + if (hpd_irq_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY || + hpd_irq_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY) { +- dm_handle_mst_sideband_msg(aconnector); ++ bool skip = false; ++ ++ /* ++ * DOWN_REP_MSG_RDY is also handled by polling method ++ * mgr->cbs->poll_hpd_irq() ++ */ ++ spin_lock(&offload_wq->offload_lock); ++ skip = offload_wq->is_handling_mst_msg_rdy_event; ++ ++ if (!skip) ++ offload_wq->is_handling_mst_msg_rdy_event = true; ++ ++ spin_unlock(&offload_wq->offload_lock); ++ ++ if (!skip) ++ schedule_hpd_rx_offload_work(offload_wq, hpd_irq_data); ++ + goto out; + } + +@@ -3482,11 +3426,11 @@ static void register_hpd_handlers(struct + amdgpu_dm_irq_register_interrupt(adev, &int_params, + handle_hpd_rx_irq, + (void *) aconnector); +- +- if (adev->dm.hpd_rx_offload_wq) +- adev->dm.hpd_rx_offload_wq[dc_link->link_index].aconnector = +- aconnector; + } ++ ++ if (adev->dm.hpd_rx_offload_wq) ++ adev->dm.hpd_rx_offload_wq[connector->index].aconnector = ++ aconnector; + } + } + +@@ -7082,6 +7026,7 @@ void amdgpu_dm_connector_init_helper(str + aconnector->hpd.hpd = AMDGPU_HPD_NONE; /* not used */ + aconnector->audio_inst = -1; + mutex_init(&aconnector->hpd_lock); ++ mutex_init(&aconnector->handle_mst_msg_ready); + + /* + * configure support HPD hot plug connector_>polled default value is 0 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +@@ -194,6 +194,11 @@ struct hpd_rx_irq_offload_work_queue { + */ + bool is_handling_link_loss; + /** ++ * @is_handling_mst_msg_rdy_event: Used to prevent inserting mst message ++ * ready event when we're already handling mst message ready event ++ */ ++ bool is_handling_mst_msg_rdy_event; ++ /** + * @aconnector: The aconnector that this work queue is attached to + */ + struct amdgpu_dm_connector *aconnector; +@@ -614,6 +619,8 @@ struct amdgpu_dm_connector { + struct drm_dp_mst_port *port; + struct amdgpu_dm_connector *mst_port; + struct drm_dp_aux *dsc_aux; ++ struct mutex handle_mst_msg_ready; ++ + /* TODO see if we can merge with ddc_bus or make a dm_connector */ + struct amdgpu_i2c_adapter *i2c; + +--- 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 +@@ -590,8 +590,118 @@ dm_dp_add_mst_connector(struct drm_dp_ms + return connector; + } + ++void dm_handle_mst_sideband_msg_ready_event( ++ struct drm_dp_mst_topology_mgr *mgr, ++ enum mst_msg_ready_type msg_rdy_type) ++{ ++ uint8_t esi[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = { 0 }; ++ uint8_t dret; ++ bool new_irq_handled = false; ++ int dpcd_addr; ++ uint8_t dpcd_bytes_to_read; ++ const uint8_t max_process_count = 30; ++ uint8_t process_count = 0; ++ u8 retry; ++ struct amdgpu_dm_connector *aconnector = ++ container_of(mgr, struct amdgpu_dm_connector, mst_mgr); ++ ++ ++ const struct dc_link_status *link_status = dc_link_get_status(aconnector->dc_link); ++ ++ if (link_status->dpcd_caps->dpcd_rev.raw < 0x12) { ++ dpcd_bytes_to_read = DP_LANE0_1_STATUS - DP_SINK_COUNT; ++ /* DPCD 0x200 - 0x201 for downstream IRQ */ ++ dpcd_addr = DP_SINK_COUNT; ++ } else { ++ dpcd_bytes_to_read = DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI; ++ /* DPCD 0x2002 - 0x2005 for downstream IRQ */ ++ dpcd_addr = DP_SINK_COUNT_ESI; ++ } ++ ++ mutex_lock(&aconnector->handle_mst_msg_ready); ++ ++ while (process_count < max_process_count) { ++ u8 ack[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = {}; ++ ++ process_count++; ++ ++ dret = drm_dp_dpcd_read( ++ &aconnector->dm_dp_aux.aux, ++ dpcd_addr, ++ esi, ++ dpcd_bytes_to_read); ++ ++ if (dret != dpcd_bytes_to_read) { ++ DRM_DEBUG_KMS("DPCD read and acked number is not as expected!"); ++ break; ++ } ++ ++ DRM_DEBUG_DRIVER("ESI %02x %02x %02x\n", esi[0], esi[1], esi[2]); ++ ++ switch (msg_rdy_type) { ++ case DOWN_REP_MSG_RDY_EVENT: ++ /* Only handle DOWN_REP_MSG_RDY case*/ ++ esi[1] &= DP_DOWN_REP_MSG_RDY; ++ break; ++ case UP_REQ_MSG_RDY_EVENT: ++ /* Only handle UP_REQ_MSG_RDY case*/ ++ esi[1] &= DP_UP_REQ_MSG_RDY; ++ break; ++ default: ++ /* Handle both cases*/ ++ esi[1] &= (DP_DOWN_REP_MSG_RDY | DP_UP_REQ_MSG_RDY); ++ break; ++ } ++ ++ if (!esi[1]) ++ break; ++ ++ /* handle MST irq */ ++ if (aconnector->mst_mgr.mst_state) ++ drm_dp_mst_hpd_irq_handle_event(&aconnector->mst_mgr, ++ esi, ++ ack, ++ &new_irq_handled); ++ ++ if (new_irq_handled) { ++ /* ACK at DPCD to notify down stream */ ++ for (retry = 0; retry < 3; retry++) { ++ ssize_t wret; ++ ++ wret = drm_dp_dpcd_writeb(&aconnector->dm_dp_aux.aux, ++ dpcd_addr + 1, ++ ack[1]); ++ if (wret == 1) ++ break; ++ } ++ ++ if (retry == 3) { ++ DRM_ERROR("Failed to ack MST event.\n"); ++ return; ++ } ++ ++ drm_dp_mst_hpd_irq_send_new_request(&aconnector->mst_mgr); ++ ++ new_irq_handled = false; ++ } else { ++ break; ++ } ++ } ++ ++ mutex_unlock(&aconnector->handle_mst_msg_ready); ++ ++ if (process_count == max_process_count) ++ DRM_DEBUG_DRIVER("Loop exceeded max iterations\n"); ++} ++ ++static void dm_handle_mst_down_rep_msg_ready(struct drm_dp_mst_topology_mgr *mgr) ++{ ++ dm_handle_mst_sideband_msg_ready_event(mgr, DOWN_REP_MSG_RDY_EVENT); ++} ++ + static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { + .add_connector = dm_dp_add_mst_connector, ++ .poll_hpd_irq = dm_handle_mst_down_rep_msg_ready, + }; + + void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +@@ -49,6 +49,13 @@ + #define PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B 1031 + #define PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B 1000 + ++enum mst_msg_ready_type { ++ NONE_MSG_RDY_EVENT = 0, ++ DOWN_REP_MSG_RDY_EVENT = 1, ++ UP_REQ_MSG_RDY_EVENT = 2, ++ DOWN_OR_UP_MSG_RDY_EVENT = 3 ++}; ++ + struct amdgpu_display_manager; + struct amdgpu_dm_connector; + +@@ -61,6 +68,10 @@ void amdgpu_dm_initialize_dp_connector(s + void + dm_dp_create_fake_mst_encoders(struct amdgpu_device *adev); + ++void dm_handle_mst_sideband_msg_ready_event( ++ struct drm_dp_mst_topology_mgr *mgr, ++ enum mst_msg_ready_type msg_rdy_type); ++ + struct dsc_mst_fairness_vars { + int pbn; + bool dsc_enabled; diff --git a/queue-6.1/drm-amd-display-clean-up-errors-warnings-in-amdgpu_dm.c.patch b/queue-6.1/drm-amd-display-clean-up-errors-warnings-in-amdgpu_dm.c.patch new file mode 100644 index 00000000000..501e988cad2 --- /dev/null +++ b/queue-6.1/drm-amd-display-clean-up-errors-warnings-in-amdgpu_dm.c.patch @@ -0,0 +1,517 @@ +From stable-owner@vger.kernel.org Tue Jul 25 00:26:56 2023 +From: Mario Limonciello +Date: Mon, 24 Jul 2023 17:26:36 -0500 +Subject: drm/amd/display: Clean up errors & warnings in amdgpu_dm.c +To: +Cc: Mario Limonciello +Message-ID: <20230724222638.1477-6-mario.limonciello@amd.com> + +From: Srinivasan Shanmugam + +commit 87279fdf5ee0ad1360765ef70389d1c4d0f81bb6 upstream. + +Fix the following errors & warnings reported by checkpatch: + +ERROR: space required before the open brace '{' +ERROR: space required before the open parenthesis '(' +ERROR: that open brace { should be on the previous line +ERROR: space prohibited before that ',' (ctx:WxW) +ERROR: else should follow close brace '}' +ERROR: open brace '{' following function definitions go on the next line +ERROR: code indent should use tabs where possible + +WARNING: braces {} are not necessary for single statement blocks +WARNING: void function return statements are not generally useful +WARNING: Block comments use * on subsequent lines +WARNING: Block comments use a trailing */ on a separate line + +Cc: Rodrigo Siqueira +Cc: Aurabindo Pillai +Cc: Alex Deucher +Signed-off-by: Srinivasan Shanmugam +Reviewed-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +[ Modified for missing + c5a31f178e35 ("drm/amd/display: move dp irq handler functions from dc_link_dp to link_dp_irq_handler") + which landed in 6.3] +Signed-off-by: Mario Limonciello +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 133 ++++++++++------------ + 1 file changed, 65 insertions(+), 68 deletions(-) + +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -408,12 +408,12 @@ static void dm_pflip_high_irq(void *inte + + spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); + +- if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_SUBMITTED){ +- DC_LOG_PFLIP("amdgpu_crtc->pflip_status = %d !=AMDGPU_FLIP_SUBMITTED(%d) on crtc:%d[%p] \n", +- amdgpu_crtc->pflip_status, +- AMDGPU_FLIP_SUBMITTED, +- amdgpu_crtc->crtc_id, +- amdgpu_crtc); ++ if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_SUBMITTED) { ++ DC_LOG_PFLIP("amdgpu_crtc->pflip_status = %d !=AMDGPU_FLIP_SUBMITTED(%d) on crtc:%d[%p]\n", ++ amdgpu_crtc->pflip_status, ++ AMDGPU_FLIP_SUBMITTED, ++ amdgpu_crtc->crtc_id, ++ amdgpu_crtc); + spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); + return; + } +@@ -861,7 +861,7 @@ static int dm_set_powergating_state(void + } + + /* Prototypes of private functions */ +-static int dm_early_init(void* handle); ++static int dm_early_init(void *handle); + + /* Allocate memory for FBC compressed data */ + static void amdgpu_dm_fbc_init(struct drm_connector *connector) +@@ -1260,7 +1260,7 @@ static void mmhub_read_system_context(st + pa_config->system_aperture.start_addr = (uint64_t)logical_addr_low << 18; + pa_config->system_aperture.end_addr = (uint64_t)logical_addr_high << 18; + +- pa_config->system_aperture.agp_base = (uint64_t)agp_base << 24 ; ++ pa_config->system_aperture.agp_base = (uint64_t)agp_base << 24; + pa_config->system_aperture.agp_bot = (uint64_t)agp_bot << 24; + pa_config->system_aperture.agp_top = (uint64_t)agp_top << 24; + +@@ -1343,8 +1343,7 @@ static void dm_handle_hpd_rx_offload_wor + DP_TEST_RESPONSE, + &test_response.raw, + sizeof(test_response)); +- } +- else if ((dc_link->connector_signal != SIGNAL_TYPE_EDP) && ++ } else if ((dc_link->connector_signal != SIGNAL_TYPE_EDP) && + hpd_rx_irq_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); +@@ -1519,7 +1518,7 @@ static int amdgpu_dm_init(struct amdgpu_ + mutex_init(&adev->dm.audio_lock); + spin_lock_init(&adev->dm.vblank_lock); + +- if(amdgpu_dm_irq_init(adev)) { ++ if (amdgpu_dm_irq_init(adev)) { + DRM_ERROR("amdgpu: failed to initialize DM IRQ support.\n"); + goto error; + } +@@ -1654,9 +1653,8 @@ static int amdgpu_dm_init(struct amdgpu_ + if (amdgpu_dc_debug_mask & DC_DISABLE_STUTTER) + adev->dm.dc->debug.disable_stutter = true; + +- if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) { ++ if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) + adev->dm.dc->debug.disable_dsc = true; +- } + + if (amdgpu_dc_debug_mask & DC_DISABLE_CLOCK_GATING) + adev->dm.dc->debug.disable_clock_gate = true; +@@ -1877,8 +1875,6 @@ static void amdgpu_dm_fini(struct amdgpu + mutex_destroy(&adev->dm.audio_lock); + mutex_destroy(&adev->dm.dc_lock); + mutex_destroy(&adev->dm.dpia_aux_lock); +- +- return; + } + + static int load_dmcu_fw(struct amdgpu_device *adev) +@@ -1887,7 +1883,7 @@ static int load_dmcu_fw(struct amdgpu_de + int r; + const struct dmcu_firmware_header_v1_0 *hdr; + +- switch(adev->asic_type) { ++ switch (adev->asic_type) { + #if defined(CONFIG_DRM_AMD_DC_SI) + case CHIP_TAHITI: + case CHIP_PITCAIRN: +@@ -2679,7 +2675,7 @@ static void dm_gpureset_commit_state(str + struct dc_scaling_info scaling_infos[MAX_SURFACES]; + struct dc_flip_addrs flip_addrs[MAX_SURFACES]; + struct dc_stream_update stream_update; +- } * bundle; ++ } *bundle; + int k, m; + + bundle = kzalloc(sizeof(*bundle), GFP_KERNEL); +@@ -2709,8 +2705,6 @@ static void dm_gpureset_commit_state(str + + cleanup: + kfree(bundle); +- +- return; + } + + static int dm_resume(void *handle) +@@ -2924,8 +2918,7 @@ static const struct amd_ip_funcs amdgpu_ + .set_powergating_state = dm_set_powergating_state, + }; + +-const struct amdgpu_ip_block_version dm_ip_block = +-{ ++const struct amdgpu_ip_block_version dm_ip_block = { + .type = AMD_IP_BLOCK_TYPE_DCE, + .major = 1, + .minor = 0, +@@ -2982,9 +2975,12 @@ static void update_connector_ext_caps(st + caps->ext_caps = &aconnector->dc_link->dpcd_sink_ext_caps; + caps->aux_support = false; + +- if (caps->ext_caps->bits.oled == 1 /*|| +- caps->ext_caps->bits.sdr_aux_backlight_control == 1 || +- caps->ext_caps->bits.hdr_aux_backlight_control == 1*/) ++ if (caps->ext_caps->bits.oled == 1 ++ /* ++ * || ++ * caps->ext_caps->bits.sdr_aux_backlight_control == 1 || ++ * caps->ext_caps->bits.hdr_aux_backlight_control == 1 ++ */) + caps->aux_support = true; + + if (amdgpu_backlight == 0) +@@ -3248,6 +3244,7 @@ static void dm_handle_mst_sideband_msg(s + process_count < max_process_count) { + u8 ack[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = {}; + u8 retry; ++ + dret = 0; + + process_count++; +@@ -3449,7 +3446,7 @@ static void register_hpd_handlers(struct + aconnector = to_amdgpu_dm_connector(connector); + dc_link = aconnector->dc_link; + +- if (DC_IRQ_SOURCE_INVALID != dc_link->irq_source_hpd) { ++ if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) { + int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT; + int_params.irq_source = dc_link->irq_source_hpd; + +@@ -3458,7 +3455,7 @@ static void register_hpd_handlers(struct + (void *) aconnector); + } + +- if (DC_IRQ_SOURCE_INVALID != dc_link->irq_source_hpd_rx) { ++ if (dc_link->irq_source_hpd_rx != DC_IRQ_SOURCE_INVALID) { + + /* Also register for DP short pulse (hpd_rx). */ + int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT; +@@ -3484,7 +3481,7 @@ static int dce60_register_irq_handlers(s + struct dc_interrupt_params int_params = {0}; + int r; + int i; +- unsigned client_id = AMDGPU_IRQ_CLIENTID_LEGACY; ++ unsigned int client_id = AMDGPU_IRQ_CLIENTID_LEGACY; + + int_params.requested_polarity = INTERRUPT_POLARITY_DEFAULT; + int_params.current_polarity = INTERRUPT_POLARITY_DEFAULT; +@@ -3498,11 +3495,12 @@ static int dce60_register_irq_handlers(s + * Base driver will call amdgpu_dm_irq_handler() for ALL interrupts + * coming from DC hardware. + * amdgpu_dm_irq_handler() will re-direct the interrupt to DC +- * for acknowledging and handling. */ ++ * for acknowledging and handling. ++ */ + + /* Use VBLANK interrupt */ + for (i = 0; i < adev->mode_info.num_crtc; i++) { +- r = amdgpu_irq_add_id(adev, client_id, i+1 , &adev->crtc_irq); ++ r = amdgpu_irq_add_id(adev, client_id, i + 1, &adev->crtc_irq); + if (r) { + DRM_ERROR("Failed to add crtc irq id!\n"); + return r; +@@ -3510,7 +3508,7 @@ static int dce60_register_irq_handlers(s + + int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT; + int_params.irq_source = +- dc_interrupt_to_irq_source(dc, i+1 , 0); ++ dc_interrupt_to_irq_source(dc, i + 1, 0); + + c_irq_params = &adev->dm.vblank_params[int_params.irq_source - DC_IRQ_SOURCE_VBLANK1]; + +@@ -3566,7 +3564,7 @@ static int dce110_register_irq_handlers( + struct dc_interrupt_params int_params = {0}; + int r; + int i; +- unsigned client_id = AMDGPU_IRQ_CLIENTID_LEGACY; ++ unsigned int client_id = AMDGPU_IRQ_CLIENTID_LEGACY; + + if (adev->family >= AMDGPU_FAMILY_AI) + client_id = SOC15_IH_CLIENTID_DCE; +@@ -3583,7 +3581,8 @@ static int dce110_register_irq_handlers( + * Base driver will call amdgpu_dm_irq_handler() for ALL interrupts + * coming from DC hardware. + * amdgpu_dm_irq_handler() will re-direct the interrupt to DC +- * for acknowledging and handling. */ ++ * for acknowledging and handling. ++ */ + + /* Use VBLANK interrupt */ + for (i = VISLANDS30_IV_SRCID_D1_VERTICAL_INTERRUPT0; i <= VISLANDS30_IV_SRCID_D6_VERTICAL_INTERRUPT0; i++) { +@@ -4032,7 +4031,7 @@ static void amdgpu_dm_update_backlight_c + } + + static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps, +- unsigned *min, unsigned *max) ++ unsigned int *min, unsigned int *max) + { + if (!caps) + return 0; +@@ -4052,7 +4051,7 @@ static int get_brightness_range(const st + static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *caps, + uint32_t brightness) + { +- unsigned min, max; ++ unsigned int min, max; + + if (!get_brightness_range(caps, &min, &max)) + return brightness; +@@ -4065,7 +4064,7 @@ static u32 convert_brightness_from_user( + static u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps *caps, + uint32_t brightness) + { +- unsigned min, max; ++ unsigned int min, max; + + if (!get_brightness_range(caps, &min, &max)) + return brightness; +@@ -4546,7 +4545,6 @@ fail: + static void amdgpu_dm_destroy_drm_device(struct amdgpu_display_manager *dm) + { + drm_atomic_private_obj_fini(&dm->atomic_obj); +- return; + } + + /****************************************************************************** +@@ -5272,6 +5270,7 @@ static bool adjust_colour_depth_from_dis + { + enum dc_color_depth depth = timing_out->display_color_depth; + int normalized_clk; ++ + do { + normalized_clk = timing_out->pix_clk_100hz / 10; + /* YCbCr 4:2:0 requires additional adjustment of 1/2 */ +@@ -5487,6 +5486,7 @@ create_fake_sink(struct amdgpu_dm_connec + { + struct dc_sink_init_data sink_init_data = { 0 }; + struct dc_sink *sink = NULL; ++ + sink_init_data.link = aconnector->dc_link; + sink_init_data.sink_signal = aconnector->dc_link->connector_signal; + +@@ -5610,7 +5610,7 @@ get_highest_refresh_rate_mode(struct amd + return &aconnector->freesync_vid_base; + + /* Find the preferred mode */ +- list_for_each_entry (m, list_head, head) { ++ list_for_each_entry(m, list_head, head) { + if (m->type & DRM_MODE_TYPE_PREFERRED) { + m_pref = m; + break; +@@ -5634,7 +5634,7 @@ get_highest_refresh_rate_mode(struct amd + * For some monitors, preferred mode is not the mode with highest + * supported refresh rate. + */ +- list_for_each_entry (m, list_head, head) { ++ list_for_each_entry(m, list_head, head) { + current_refresh = drm_mode_vrefresh(m); + + if (m->hdisplay == m_pref->hdisplay && +@@ -5905,7 +5905,7 @@ create_stream_for_sink(struct amdgpu_dm_ + * This may not be an error, the use case is when we have no + * usermode calls to reset and set mode upon hotplug. In this + * case, we call set mode ourselves to restore the previous mode +- * and the modelist may not be filled in in time. ++ * and the modelist may not be filled in time. + */ + DRM_DEBUG_DRIVER("No preferred mode found\n"); + } else { +@@ -5929,9 +5929,9 @@ create_stream_for_sink(struct amdgpu_dm_ + drm_mode_set_crtcinfo(&mode, 0); + + /* +- * If scaling is enabled and refresh rate didn't change +- * we copy the vic and polarities of the old timings +- */ ++ * If scaling is enabled and refresh rate didn't change ++ * we copy the vic and polarities of the old timings ++ */ + if (!scale || mode_refresh != preferred_refresh) + fill_stream_properties_from_drm_display_mode( + stream, &mode, &aconnector->base, con_state, NULL, +@@ -6593,6 +6593,7 @@ static int dm_encoder_helper_atomic_chec + + if (!state->duplicated) { + int max_bpc = conn_state->max_requested_bpc; ++ + is_y420 = drm_mode_is_420_also(&connector->display_info, adjusted_mode) && + aconnector->force_yuv420_output; + color_depth = convert_color_depth_from_display_info(connector, +@@ -6913,7 +6914,7 @@ static bool is_duplicate_mode(struct amd + { + struct drm_display_mode *m; + +- list_for_each_entry (m, &aconnector->base.probed_modes, head) { ++ list_for_each_entry(m, &aconnector->base.probed_modes, head) { + if (drm_mode_equal(m, mode)) + return true; + } +@@ -7216,7 +7217,6 @@ static int amdgpu_dm_connector_init(stru + + link->priv = aconnector; + +- DRM_DEBUG_DRIVER("%s()\n", __func__); + + i2c = create_i2c(link->ddc, link->link_index, &res); + if (!i2c) { +@@ -7861,8 +7861,7 @@ static void amdgpu_dm_commit_planes(stru + * DRI3/Present extension with defined target_msc. + */ + last_flip_vblank = amdgpu_get_vblank_counter_kms(pcrtc); +- } +- else { ++ } else { + /* For variable refresh rate mode only: + * Get vblank of last completed flip to avoid > 1 vrr + * flips per video frame by use of throttling, but allow +@@ -8189,8 +8188,8 @@ static void amdgpu_dm_atomic_commit_tail + dc_resource_state_copy_construct_current(dm->dc, dc_state); + } + +- for_each_oldnew_crtc_in_state (state, crtc, old_crtc_state, +- new_crtc_state, i) { ++ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, ++ new_crtc_state, i) { + struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); + + dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); +@@ -8213,9 +8212,7 @@ static void amdgpu_dm_atomic_commit_tail + dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); + + drm_dbg_state(state->dev, +- "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, " +- "planes_changed:%d, mode_changed:%d,active_changed:%d," +- "connectors_changed:%d\n", ++ "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, planes_changed:%d, mode_changed:%d,active_changed:%d,connectors_changed:%d\n", + acrtc->crtc_id, + new_crtc_state->enable, + new_crtc_state->active, +@@ -8700,8 +8697,8 @@ static int do_aquire_global_lock(struct + &commit->flip_done, 10*HZ); + + if (ret == 0) +- DRM_ERROR("[CRTC:%d:%s] hw_done or flip_done " +- "timed out\n", crtc->base.id, crtc->name); ++ DRM_ERROR("[CRTC:%d:%s] hw_done or flip_done timed out\n", ++ crtc->base.id, crtc->name); + + drm_crtc_commit_put(commit); + } +@@ -8786,7 +8783,8 @@ is_timing_unchanged_for_freesync(struct + return false; + } + +-static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state) { ++static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state) ++{ + u64 num, den, res; + struct drm_crtc_state *new_crtc_state = &dm_new_crtc_state->base; + +@@ -8909,9 +8907,7 @@ static int dm_update_crtc_state(struct a + goto skip_modeset; + + drm_dbg_state(state->dev, +- "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, " +- "planes_changed:%d, mode_changed:%d,active_changed:%d," +- "connectors_changed:%d\n", ++ "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, planes_changed:%d, mode_changed:%d,active_changed:%d,connectors_changed:%d\n", + acrtc->crtc_id, + new_crtc_state->enable, + new_crtc_state->active, +@@ -8940,8 +8936,7 @@ static int dm_update_crtc_state(struct a + old_crtc_state)) { + new_crtc_state->mode_changed = false; + DRM_DEBUG_DRIVER( +- "Mode change not required for front porch change, " +- "setting mode_changed to %d", ++ "Mode change not required for front porch change, setting mode_changed to %d", + new_crtc_state->mode_changed); + + set_freesync_fixed_config(dm_new_crtc_state); +@@ -8953,9 +8948,8 @@ static int dm_update_crtc_state(struct a + struct drm_display_mode *high_mode; + + high_mode = get_highest_refresh_rate_mode(aconnector, false); +- if (!drm_mode_equal(&new_crtc_state->mode, high_mode)) { ++ if (!drm_mode_equal(&new_crtc_state->mode, high_mode)) + set_freesync_fixed_config(dm_new_crtc_state); +- } + } + + ret = dm_atomic_get_state(state, &dm_state); +@@ -9123,6 +9117,7 @@ static bool should_reset_plane(struct dr + */ + for_each_oldnew_plane_in_state(state, other, old_other_state, new_other_state, i) { + struct amdgpu_framebuffer *old_afb, *new_afb; ++ + if (other->type == DRM_PLANE_TYPE_CURSOR) + continue; + +@@ -9221,11 +9216,12 @@ static int dm_check_cursor_fb(struct amd + } + + /* Core DRM takes care of checking FB modifiers, so we only need to +- * check tiling flags when the FB doesn't have a modifier. */ ++ * check tiling flags when the FB doesn't have a modifier. ++ */ + if (!(fb->flags & DRM_MODE_FB_MODIFIERS)) { + if (adev->family < AMDGPU_FAMILY_AI) { + linear = AMDGPU_TILING_GET(afb->tiling_flags, ARRAY_MODE) != DC_ARRAY_2D_TILED_THIN1 && +- AMDGPU_TILING_GET(afb->tiling_flags, ARRAY_MODE) != DC_ARRAY_1D_TILED_THIN1 && ++ AMDGPU_TILING_GET(afb->tiling_flags, ARRAY_MODE) != DC_ARRAY_1D_TILED_THIN1 && + AMDGPU_TILING_GET(afb->tiling_flags, MICRO_TILE_MODE) == 0; + } else { + linear = AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE) == 0; +@@ -9438,12 +9434,12 @@ static int dm_check_crtc_cursor(struct d + /* On DCE and DCN there is no dedicated hardware cursor plane. We get a + * cursor per pipe but it's going to inherit the scaling and + * positioning from the underlying pipe. Check the cursor plane's +- * blending properties match the underlying planes'. */ ++ * blending properties match the underlying planes'. ++ */ + + new_cursor_state = drm_atomic_get_new_plane_state(state, cursor); +- if (!new_cursor_state || !new_cursor_state->fb) { ++ if (!new_cursor_state || !new_cursor_state->fb) + return 0; +- } + + dm_get_oriented_plane_size(new_cursor_state, &cursor_src_w, &cursor_src_h); + cursor_scale_w = new_cursor_state->crtc_w * 1000 / cursor_src_w; +@@ -9489,6 +9485,7 @@ static int add_affected_mst_dsc_crtcs(st + struct drm_connector_state *conn_state, *old_conn_state; + struct amdgpu_dm_connector *aconnector = NULL; + int i; ++ + for_each_oldnew_connector_in_state(state, connector, old_conn_state, conn_state, i) { + if (!conn_state->crtc) + conn_state = old_conn_state; +@@ -9931,7 +9928,7 @@ static int amdgpu_dm_atomic_check(struct + } + + /* Store the overall update type for use later in atomic check. */ +- for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) { ++ for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { + struct dm_crtc_state *dm_new_crtc_state = + to_dm_crtc_state(new_crtc_state); + +@@ -9953,7 +9950,7 @@ fail: + else if (ret == -EINTR || ret == -EAGAIN || ret == -ERESTARTSYS) + DRM_DEBUG_DRIVER("Atomic check stopped due to signal.\n"); + else +- DRM_DEBUG_DRIVER("Atomic check failed with err: %d \n", ret); ++ DRM_DEBUG_DRIVER("Atomic check failed with err: %d\n", ret); + + trace_amdgpu_dm_atomic_check_finish(state, ret); + diff --git a/queue-6.1/drm-amd-display-fix-linux-dp-link-lost-handled-only-one-time.patch b/queue-6.1/drm-amd-display-fix-linux-dp-link-lost-handled-only-one-time.patch new file mode 100644 index 00000000000..0564fb1354d --- /dev/null +++ b/queue-6.1/drm-amd-display-fix-linux-dp-link-lost-handled-only-one-time.patch @@ -0,0 +1,111 @@ +From stable-owner@vger.kernel.org Tue Jul 25 00:26:54 2023 +From: Mario Limonciello +Date: Mon, 24 Jul 2023 17:26:37 -0500 +Subject: drm/amd/display: fix linux dp link lost handled only one time +To: +Cc: Mario Limonciello +Message-ID: <20230724222638.1477-7-mario.limonciello@amd.com> + +From: Hersen Wu + +commit e322843e5e33e72ff218d661f3d15ff9c9f2f1b5 upstream. + +[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 +[ Modified due to not having + c5a31f178e352 ("drm/amd/display: move dp irq handler functions from dc_link_dp to link_dp_irq_handler") + until kernel 6.3-rc1.] +Signed-off-by: Mario Limonciello +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 +++++++++++++++++++--- + drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 - + drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h | 4 +++ + 3 files changed, 26 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -1346,10 +1346,28 @@ static void dm_handle_hpd_rx_offload_wor + } else if ((dc_link->connector_signal != SIGNAL_TYPE_EDP) && + hpd_rx_irq_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 ((read_hpd_rx_irq_data(dc_link, &irq_data) == DC_OK) && ++ hpd_rx_irq_check_link_loss_status(dc_link, &irq_data)) ++ dc_link_dp_handle_link_loss(dc_link); + } + mutex_unlock(&adev->dm.dc_lock); + +@@ -3324,7 +3342,7 @@ static void handle_hpd_rx_irq(void *para + 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)); +@@ -3466,7 +3484,7 @@ static void register_hpd_handlers(struct + (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; + } + } +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +@@ -3115,7 +3115,7 @@ struct dc_link_settings dp_get_max_link_ + return max_link_cap; + } + +-static enum dc_status read_hpd_rx_irq_data( ++enum dc_status read_hpd_rx_irq_data( + struct dc_link *link, + union hpd_irq_data *irq_data) + { +--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h +@@ -82,6 +82,10 @@ bool perform_link_training_with_retries( + enum signal_type signal, + bool do_fallback); + ++enum dc_status read_hpd_rx_irq_data( ++ struct dc_link *link, ++ union hpd_irq_data *irq_data); ++ + bool hpd_rx_irq_check_link_loss_status( + struct dc_link *link, + union hpd_irq_data *hpd_irq_dpcd_data); diff --git a/queue-6.1/drm-amd-display-fix-some-coding-style-issues.patch b/queue-6.1/drm-amd-display-fix-some-coding-style-issues.patch new file mode 100644 index 00000000000..71bbd094762 --- /dev/null +++ b/queue-6.1/drm-amd-display-fix-some-coding-style-issues.patch @@ -0,0 +1,359 @@ +From stable-owner@vger.kernel.org Tue Jul 25 00:26:52 2023 +From: Mario Limonciello +Date: Mon, 24 Jul 2023 17:26:33 -0500 +Subject: drm/amd/display: fix some coding style issues +To: +Cc: Mario Limonciello +Message-ID: <20230724222638.1477-3-mario.limonciello@amd.com> + +From: Srinivasan Shanmugam + +commit ae67558be712237109100fd14f12378adcf24356 upstream. + +Fix the following checkpatch checks in amdgpu_dm.c + +CHECK: Prefer kernel type 'u8' over 'uint8_t' +CHECK: Prefer kernel type 'u32' over 'uint32_t' +CHECK: Prefer kernel type 'u64' over 'uint64_t' +CHECK: Prefer kernel type 's32' over 'int32_t' + +Signed-off-by: Srinivasan Shanmugam +Reviewed-by: Harry Wentland +Signed-off-by: Alex Deucher +[ PSR-SU support was introduced in kernel 6.2 with commits like + 30ebe41582d1 ("drm/amd/display: add FB_DAMAGE_CLIPS support") + but PSR-SU isn't enabled in 6.1.y, so this block needs to be skipped + when backporting. ] +Signed-off-by: Mario Limonciello +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 90 +++++++++++----------- + 1 file changed, 45 insertions(+), 45 deletions(-) + +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -211,7 +211,7 @@ static void amdgpu_dm_destroy_drm_device + + static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, + struct amdgpu_dm_connector *amdgpu_dm_connector, +- uint32_t link_index, ++ u32 link_index, + struct amdgpu_encoder *amdgpu_encoder); + static int amdgpu_dm_encoder_init(struct drm_device *dev, + struct amdgpu_encoder *aencoder, +@@ -263,7 +263,7 @@ static u32 dm_vblank_get_counter(struct + static int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc, + u32 *vbl, u32 *position) + { +- uint32_t v_blank_start, v_blank_end, h_position, v_position; ++ u32 v_blank_start, v_blank_end, h_position, v_position; + + if ((crtc < 0) || (crtc >= adev->mode_info.num_crtc)) + return -EINVAL; +@@ -391,7 +391,7 @@ static void dm_pflip_high_irq(void *inte + struct amdgpu_device *adev = irq_params->adev; + unsigned long flags; + struct drm_pending_vblank_event *e; +- uint32_t vpos, hpos, v_blank_start, v_blank_end; ++ u32 vpos, hpos, v_blank_start, v_blank_end; + bool vrr_active; + + amdgpu_crtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_PFLIP); +@@ -678,7 +678,7 @@ static void dmub_hpd_callback(struct amd + struct drm_connector *connector; + struct drm_connector_list_iter iter; + struct dc_link *link; +- uint8_t link_index = 0; ++ u8 link_index = 0; + struct drm_device *dev; + + if (adev == NULL) +@@ -779,7 +779,7 @@ static void dm_dmub_outbox1_low_irq(void + struct amdgpu_device *adev = irq_params->adev; + struct amdgpu_display_manager *dm = &adev->dm; + struct dmcub_trace_buf_entry entry = { 0 }; +- uint32_t count = 0; ++ u32 count = 0; + struct dmub_hpd_work *dmub_hpd_wrk; + struct dc_link *plink = NULL; + +@@ -1045,7 +1045,7 @@ static int dm_dmub_hw_init(struct amdgpu + struct dmub_srv_hw_params hw_params; + enum dmub_status status; + const unsigned char *fw_inst_const, *fw_bss_data; +- uint32_t i, fw_inst_const_size, fw_bss_data_size; ++ u32 i, fw_inst_const_size, fw_bss_data_size; + bool has_hw_support; + + if (!dmub_srv) +@@ -1206,10 +1206,10 @@ static void dm_dmub_hw_resume(struct amd + + static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_addr_space_config *pa_config) + { +- uint64_t pt_base; +- uint32_t logical_addr_low; +- uint32_t logical_addr_high; +- uint32_t agp_base, agp_bot, agp_top; ++ u64 pt_base; ++ u32 logical_addr_low; ++ u32 logical_addr_high; ++ u32 agp_base, agp_bot, agp_top; + PHYSICAL_ADDRESS_LOC page_table_start, page_table_end, page_table_base; + + memset(pa_config, 0, sizeof(*pa_config)); +@@ -2536,7 +2536,7 @@ struct amdgpu_dm_connector * + amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state, + struct drm_crtc *crtc) + { +- uint32_t i; ++ u32 i; + struct drm_connector_state *new_con_state; + struct drm_connector *connector; + struct drm_crtc *crtc_from_state; +@@ -3172,8 +3172,8 @@ static void handle_hpd_irq(void *param) + + static void dm_handle_mst_sideband_msg(struct amdgpu_dm_connector *aconnector) + { +- uint8_t esi[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = { 0 }; +- uint8_t dret; ++ u8 esi[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = { 0 }; ++ u8 dret; + bool new_irq_handled = false; + int dpcd_addr; + int dpcd_bytes_to_read; +@@ -3201,7 +3201,7 @@ static void dm_handle_mst_sideband_msg(s + + while (dret == dpcd_bytes_to_read && + process_count < max_process_count) { +- uint8_t retry; ++ u8 retry; + dret = 0; + + process_count++; +@@ -3220,7 +3220,7 @@ static void dm_handle_mst_sideband_msg(s + dpcd_bytes_to_read - 1; + + for (retry = 0; retry < 3; retry++) { +- uint8_t wret; ++ u8 wret; + + wret = drm_dp_dpcd_write( + &aconnector->dm_dp_aux.aux, +@@ -4236,12 +4236,12 @@ static void amdgpu_set_panel_orientation + static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) + { + struct amdgpu_display_manager *dm = &adev->dm; +- int32_t i; ++ s32 i; + struct amdgpu_dm_connector *aconnector = NULL; + struct amdgpu_encoder *aencoder = NULL; + struct amdgpu_mode_info *mode_info = &adev->mode_info; +- uint32_t link_cnt; +- int32_t primary_planes; ++ u32 link_cnt; ++ s32 primary_planes; + enum dc_connection_type new_connection_type = dc_connection_none; + const struct dc_plane_cap *plane; + bool psr_feature_enabled = false; +@@ -4768,7 +4768,7 @@ fill_plane_color_attributes(const struct + static int + fill_dc_plane_info_and_addr(struct amdgpu_device *adev, + const struct drm_plane_state *plane_state, +- const uint64_t tiling_flags, ++ const u64 tiling_flags, + struct dc_plane_info *plane_info, + struct dc_plane_address *address, + bool tmz_surface, +@@ -4977,7 +4977,7 @@ static void fill_dc_dirty_rects(struct d + uint32_t num_clips; + bool bb_changed; + bool fb_changed; +- uint32_t i = 0; ++ u32 i = 0; + + flip_addrs->dirty_rect_count = 0; + +@@ -5111,7 +5111,7 @@ static enum dc_color_depth + convert_color_depth_from_display_info(const struct drm_connector *connector, + bool is_y420, int requested_bpc) + { +- uint8_t bpc; ++ u8 bpc; + + if (is_y420) { + bpc = 8; +@@ -5655,8 +5655,8 @@ static void apply_dsc_policy_for_edp(str + uint32_t max_dsc_target_bpp_limit_override) + { + const struct dc_link_settings *verified_link_cap = NULL; +- uint32_t link_bw_in_kbps; +- uint32_t edp_min_bpp_x16, edp_max_bpp_x16; ++ u32 link_bw_in_kbps; ++ u32 edp_min_bpp_x16, edp_max_bpp_x16; + struct dc *dc = sink->ctx->dc; + struct dc_dsc_bw_range bw_range = {0}; + struct dc_dsc_config dsc_cfg = {0}; +@@ -5713,11 +5713,11 @@ static void apply_dsc_policy_for_stream( + struct dsc_dec_dpcd_caps *dsc_caps) + { + struct drm_connector *drm_connector = &aconnector->base; +- uint32_t link_bandwidth_kbps; ++ u32 link_bandwidth_kbps; + struct dc *dc = sink->ctx->dc; +- uint32_t max_supported_bw_in_kbps, timing_bw_in_kbps; +- uint32_t dsc_max_supported_bw_in_kbps; +- uint32_t max_dsc_target_bpp_limit_override = ++ u32 max_supported_bw_in_kbps, timing_bw_in_kbps; ++ u32 dsc_max_supported_bw_in_kbps; ++ u32 max_dsc_target_bpp_limit_override = + drm_connector->display_info.max_dsc_bpp; + + link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link, +@@ -6871,7 +6871,7 @@ static uint add_fs_modes(struct amdgpu_d + const struct drm_display_mode *m; + struct drm_display_mode *new_mode; + uint i; +- uint32_t new_modes_count = 0; ++ u32 new_modes_count = 0; + + /* Standard FPS values + * +@@ -6885,7 +6885,7 @@ static uint add_fs_modes(struct amdgpu_d + * 60 - Commonly used + * 48,72,96,120 - Multiples of 24 + */ +- static const uint32_t common_rates[] = { ++ static const u32 common_rates[] = { + 23976, 24000, 25000, 29970, 30000, + 48000, 50000, 60000, 72000, 96000, 120000 + }; +@@ -6901,8 +6901,8 @@ static uint add_fs_modes(struct amdgpu_d + return 0; + + for (i = 0; i < ARRAY_SIZE(common_rates); i++) { +- uint64_t target_vtotal, target_vtotal_diff; +- uint64_t num, den; ++ u64 target_vtotal, target_vtotal_diff; ++ u64 num, den; + + if (drm_mode_vrefresh(m) * 1000 < common_rates[i]) + continue; +@@ -7150,7 +7150,7 @@ create_i2c(struct ddc_service *ddc_servi + */ + static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, + struct amdgpu_dm_connector *aconnector, +- uint32_t link_index, ++ u32 link_index, + struct amdgpu_encoder *aencoder) + { + int res = 0; +@@ -7641,8 +7641,8 @@ static void amdgpu_dm_commit_planes(stru + struct drm_crtc *pcrtc, + bool wait_for_vblank) + { +- uint32_t i; +- uint64_t timestamp_ns; ++ u32 i; ++ u64 timestamp_ns; + struct drm_plane *plane; + struct drm_plane_state *old_plane_state, *new_plane_state; + struct amdgpu_crtc *acrtc_attach = to_amdgpu_crtc(pcrtc); +@@ -7653,7 +7653,7 @@ static void amdgpu_dm_commit_planes(stru + to_dm_crtc_state(drm_atomic_get_old_crtc_state(state, pcrtc)); + int planes_count = 0, vpos, hpos; + unsigned long flags; +- uint32_t target_vblank, last_flip_vblank; ++ u32 target_vblank, last_flip_vblank; + bool vrr_active = amdgpu_dm_vrr_active(acrtc_state); + bool cursor_update = false; + bool pflip_present = false; +@@ -8102,7 +8102,7 @@ static void amdgpu_dm_atomic_commit_tail + struct amdgpu_display_manager *dm = &adev->dm; + struct dm_atomic_state *dm_state; + struct dc_state *dc_state = NULL, *dc_state_temp = NULL; +- uint32_t i, j; ++ u32 i, j; + struct drm_crtc *crtc; + struct drm_crtc_state *old_crtc_state, *new_crtc_state; + unsigned long flags; +@@ -8732,7 +8732,7 @@ is_timing_unchanged_for_freesync(struct + } + + static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state) { +- uint64_t num, den, res; ++ u64 num, den, res; + struct drm_crtc_state *new_crtc_state = &dm_new_crtc_state->base; + + dm_new_crtc_state->freesync_config.state = VRR_STATE_ACTIVE_FIXED; +@@ -9908,7 +9908,7 @@ fail: + static bool is_dp_capable_without_timing_msa(struct dc *dc, + struct amdgpu_dm_connector *amdgpu_dm_connector) + { +- uint8_t dpcd_data; ++ u8 dpcd_data; + bool capable = false; + + if (amdgpu_dm_connector->dc_link && +@@ -9927,7 +9927,7 @@ static bool is_dp_capable_without_timing + static bool dm_edid_parser_send_cea(struct amdgpu_display_manager *dm, + unsigned int offset, + unsigned int total_length, +- uint8_t *data, ++ u8 *data, + unsigned int length, + struct amdgpu_hdmi_vsdb_info *vsdb) + { +@@ -9982,7 +9982,7 @@ static bool dm_edid_parser_send_cea(stru + } + + static bool parse_edid_cea_dmcu(struct amdgpu_display_manager *dm, +- uint8_t *edid_ext, int len, ++ u8 *edid_ext, int len, + struct amdgpu_hdmi_vsdb_info *vsdb_info) + { + int i; +@@ -10023,7 +10023,7 @@ static bool parse_edid_cea_dmcu(struct a + } + + static bool parse_edid_cea_dmub(struct amdgpu_display_manager *dm, +- uint8_t *edid_ext, int len, ++ u8 *edid_ext, int len, + struct amdgpu_hdmi_vsdb_info *vsdb_info) + { + int i; +@@ -10039,7 +10039,7 @@ static bool parse_edid_cea_dmub(struct a + } + + static bool parse_edid_cea(struct amdgpu_dm_connector *aconnector, +- uint8_t *edid_ext, int len, ++ u8 *edid_ext, int len, + struct amdgpu_hdmi_vsdb_info *vsdb_info) + { + struct amdgpu_device *adev = drm_to_adev(aconnector->base.dev); +@@ -10053,7 +10053,7 @@ static bool parse_edid_cea(struct amdgpu + static int parse_hdmi_amd_vsdb(struct amdgpu_dm_connector *aconnector, + struct edid *edid, struct amdgpu_hdmi_vsdb_info *vsdb_info) + { +- uint8_t *edid_ext = NULL; ++ u8 *edid_ext = NULL; + int i; + bool valid_vsdb_found = false; + +@@ -10229,7 +10229,7 @@ void amdgpu_dm_trigger_timing_sync(struc + } + + void dm_write_reg_func(const struct dc_context *ctx, uint32_t address, +- uint32_t value, const char *func_name) ++ u32 value, const char *func_name) + { + #ifdef DM_CHECK_ADDR_0 + if (address == 0) { +@@ -10244,7 +10244,7 @@ void dm_write_reg_func(const struct dc_c + uint32_t dm_read_reg_func(const struct dc_context *ctx, uint32_t address, + const char *func_name) + { +- uint32_t value; ++ u32 value; + #ifdef DM_CHECK_ADDR_0 + if (address == 0) { + DC_ERR("invalid register read; address = 0\n"); diff --git a/queue-6.1/drm-amd-display-force-connector-state-when-bpc-changes-during-compliance.patch b/queue-6.1/drm-amd-display-force-connector-state-when-bpc-changes-during-compliance.patch new file mode 100644 index 00000000000..89496f41998 --- /dev/null +++ b/queue-6.1/drm-amd-display-force-connector-state-when-bpc-changes-during-compliance.patch @@ -0,0 +1,484 @@ +From stable-owner@vger.kernel.org Tue Jul 25 00:26:59 2023 +From: Mario Limonciello +Date: Mon, 24 Jul 2023 17:26:35 -0500 +Subject: drm/amd/display: force connector state when bpc changes during compliance +To: +Cc: Mario Limonciello +Message-ID: <20230724222638.1477-5-mario.limonciello@amd.com> + +From: Qingqing Zhuo + +commit 028c4ccfb8127255d60f8d9edde96cacf2958082 upstream. + +[Why] +During DP DSC compliance tests, bpc requested would +change between sub-tests, which requires stream +to be recommited. + +[How] +Force connector to disconnect and reconnect whenever +there is a bpc change in automated test. + +Reviewed-by: Jerry Zuo +Acked-by: Alan Liu +Signed-off-by: Qingqing Zhuo +Signed-off-by: hersen wu +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +[ Adjustments for headers that were moved around in later commits. ] +Signed-off-by: Mario Limonciello +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 55 +++++ + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 5 + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 125 ++++++++++++ + drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 139 +------------- + drivers/gpu/drm/amd/display/dc/dm_helpers.h | 6 + 5 files changed, 209 insertions(+), 121 deletions(-) + +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -40,6 +40,9 @@ + #include "dc/dc_stat.h" + #include "amdgpu_dm_trace.h" + #include "dc/inc/dc_link_ddc.h" ++#include "dpcd_defs.h" ++#include "dc/inc/link_dpcd.h" ++#include "link_service_types.h" + + #include "vid.h" + #include "amdgpu.h" +@@ -1273,6 +1276,21 @@ static void mmhub_read_system_context(st + + } + ++static void force_connector_state( ++ struct amdgpu_dm_connector *aconnector, ++ enum drm_connector_force force_state) ++{ ++ struct drm_connector *connector = &aconnector->base; ++ ++ mutex_lock(&connector->dev->mode_config.mutex); ++ aconnector->base.force = force_state; ++ mutex_unlock(&connector->dev->mode_config.mutex); ++ ++ mutex_lock(&aconnector->hpd_lock); ++ drm_kms_helper_connector_hotplug_event(connector); ++ mutex_unlock(&aconnector->hpd_lock); ++} ++ + static void dm_handle_hpd_rx_offload_work(struct work_struct *work) + { + struct hpd_rx_irq_offload_work *offload_work; +@@ -1281,6 +1299,9 @@ static void dm_handle_hpd_rx_offload_wor + struct amdgpu_device *adev; + enum dc_connection_type new_connection_type = dc_connection_none; + unsigned long flags; ++ union test_response test_response; ++ ++ memset(&test_response, 0, sizeof(test_response)); + + offload_work = container_of(work, struct hpd_rx_irq_offload_work, work); + aconnector = offload_work->offload_wq->aconnector; +@@ -1305,8 +1326,24 @@ static void dm_handle_hpd_rx_offload_wor + goto skip; + + mutex_lock(&adev->dm.dc_lock); +- if (offload_work->data.bytes.device_service_irq.bits.AUTOMATED_TEST) ++ if (offload_work->data.bytes.device_service_irq.bits.AUTOMATED_TEST) { + dc_link_dp_handle_automated_test(dc_link); ++ ++ if (aconnector->timing_changed) { ++ /* force connector disconnect and reconnect */ ++ force_connector_state(aconnector, DRM_FORCE_OFF); ++ msleep(100); ++ force_connector_state(aconnector, DRM_FORCE_UNSPECIFIED); ++ } ++ ++ test_response.bits.ACK = 1; ++ ++ core_link_write_dpcd( ++ dc_link, ++ DP_TEST_RESPONSE, ++ &test_response.raw, ++ sizeof(test_response)); ++ } + else if ((dc_link->connector_signal != SIGNAL_TYPE_EDP) && + hpd_rx_irq_check_link_loss_status(dc_link, &offload_work->data) && + dc_link_dp_allow_hpd_rx_irq(dc_link)) { +@@ -3076,6 +3113,10 @@ void amdgpu_dm_update_connector_after_de + aconnector->edid); + } + ++ aconnector->timing_requested = kzalloc(sizeof(struct dc_crtc_timing), GFP_KERNEL); ++ if (!aconnector->timing_requested) ++ dm_error("%s: failed to create aconnector->requested_timing\n", __func__); ++ + drm_connector_update_edid_property(connector, aconnector->edid); + amdgpu_dm_update_freesync_caps(connector, aconnector->edid); + update_connector_ext_caps(aconnector); +@@ -3087,6 +3128,8 @@ void amdgpu_dm_update_connector_after_de + dc_sink_release(aconnector->dc_sink); + aconnector->dc_sink = NULL; + aconnector->edid = NULL; ++ kfree(aconnector->timing_requested); ++ aconnector->timing_requested = NULL; + #ifdef CONFIG_DRM_AMD_DC_HDCP + /* Set CP to DESIRED if it was ENABLED, so we can re-enable it again on hotplug */ + if (connector->state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) +@@ -3131,6 +3174,8 @@ static void handle_hpd_irq_helper(struct + if (aconnector->fake_enable) + aconnector->fake_enable = false; + ++ aconnector->timing_changed = false; ++ + if (!dc_link_detect_sink(aconnector->dc_link, &new_connection_type)) + DRM_ERROR("KMS: Failed to detect connector\n"); + +@@ -5896,6 +5941,14 @@ create_stream_for_sink(struct amdgpu_dm_ + stream, &mode, &aconnector->base, con_state, old_stream, + requested_bpc); + ++ if (aconnector->timing_changed) { ++ DC_LOG_DEBUG("%s: overriding timing for automated test, bpc %d, changing to %d\n", ++ __func__, ++ stream->timing.display_color_depth, ++ aconnector->timing_requested->display_color_depth); ++ stream->timing = *aconnector->timing_requested; ++ } ++ + #if defined(CONFIG_DRM_AMD_DC_DCN) + /* SST DSC determination policy */ + update_dsc_caps(aconnector, sink, stream, &dsc_caps); +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include "link_service_types.h" + + /* + * This file contains the definition for amdgpu_display_manager +@@ -650,6 +651,10 @@ struct amdgpu_dm_connector { + + /* Record progress status of mst*/ + uint8_t mst_status; ++ ++ /* Automated testing */ ++ bool timing_changed; ++ struct dc_crtc_timing *timing_requested; + }; + + static inline void amdgpu_dm_set_mst_status(uint8_t *status, +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +@@ -38,6 +38,9 @@ + #include "amdgpu_dm.h" + #include "amdgpu_dm_irq.h" + #include "amdgpu_dm_mst_types.h" ++#include "dpcd_defs.h" ++#include "dc/inc/core_types.h" ++#include "dc_link_dp.h" + + #include "dm_helpers.h" + #include "ddc_service_types.h" +@@ -1056,6 +1059,128 @@ void dm_helpers_mst_enable_stream_featur + sizeof(new_downspread)); + } + ++bool dm_helpers_dp_handle_test_pattern_request( ++ struct dc_context *ctx, ++ const struct dc_link *link, ++ union link_test_pattern dpcd_test_pattern, ++ union test_misc dpcd_test_params) ++{ ++ enum dp_test_pattern test_pattern; ++ enum dp_test_pattern_color_space test_pattern_color_space = ++ DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED; ++ enum dc_color_depth requestColorDepth = COLOR_DEPTH_UNDEFINED; ++ enum dc_pixel_encoding requestPixelEncoding = PIXEL_ENCODING_UNDEFINED; ++ struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx; ++ struct pipe_ctx *pipe_ctx = NULL; ++ struct amdgpu_dm_connector *aconnector = link->priv; ++ int i; ++ ++ for (i = 0; i < MAX_PIPES; i++) { ++ if (pipes[i].stream == NULL) ++ continue; ++ ++ if (pipes[i].stream->link == link && !pipes[i].top_pipe && ++ !pipes[i].prev_odm_pipe) { ++ pipe_ctx = &pipes[i]; ++ break; ++ } ++ } ++ ++ if (pipe_ctx == NULL) ++ return false; ++ ++ switch (dpcd_test_pattern.bits.PATTERN) { ++ case LINK_TEST_PATTERN_COLOR_RAMP: ++ test_pattern = DP_TEST_PATTERN_COLOR_RAMP; ++ break; ++ case LINK_TEST_PATTERN_VERTICAL_BARS: ++ test_pattern = DP_TEST_PATTERN_VERTICAL_BARS; ++ break; /* black and white */ ++ case LINK_TEST_PATTERN_COLOR_SQUARES: ++ test_pattern = (dpcd_test_params.bits.DYN_RANGE == ++ TEST_DYN_RANGE_VESA ? ++ DP_TEST_PATTERN_COLOR_SQUARES : ++ DP_TEST_PATTERN_COLOR_SQUARES_CEA); ++ break; ++ default: ++ test_pattern = DP_TEST_PATTERN_VIDEO_MODE; ++ break; ++ } ++ ++ if (dpcd_test_params.bits.CLR_FORMAT == 0) ++ test_pattern_color_space = DP_TEST_PATTERN_COLOR_SPACE_RGB; ++ else ++ test_pattern_color_space = dpcd_test_params.bits.YCBCR_COEFS ? ++ DP_TEST_PATTERN_COLOR_SPACE_YCBCR709 : ++ DP_TEST_PATTERN_COLOR_SPACE_YCBCR601; ++ ++ switch (dpcd_test_params.bits.BPC) { ++ case 0: // 6 bits ++ requestColorDepth = COLOR_DEPTH_666; ++ break; ++ case 1: // 8 bits ++ requestColorDepth = COLOR_DEPTH_888; ++ break; ++ case 2: // 10 bits ++ requestColorDepth = COLOR_DEPTH_101010; ++ break; ++ case 3: // 12 bits ++ requestColorDepth = COLOR_DEPTH_121212; ++ break; ++ default: ++ break; ++ } ++ ++ switch (dpcd_test_params.bits.CLR_FORMAT) { ++ case 0: ++ requestPixelEncoding = PIXEL_ENCODING_RGB; ++ break; ++ case 1: ++ requestPixelEncoding = PIXEL_ENCODING_YCBCR422; ++ break; ++ case 2: ++ requestPixelEncoding = PIXEL_ENCODING_YCBCR444; ++ break; ++ default: ++ requestPixelEncoding = PIXEL_ENCODING_RGB; ++ break; ++ } ++ ++ if ((requestColorDepth != COLOR_DEPTH_UNDEFINED ++ && pipe_ctx->stream->timing.display_color_depth != requestColorDepth) ++ || (requestPixelEncoding != PIXEL_ENCODING_UNDEFINED ++ && pipe_ctx->stream->timing.pixel_encoding != requestPixelEncoding)) { ++ DC_LOG_DEBUG("%s: original bpc %d pix encoding %d, changing to %d %d\n", ++ __func__, ++ pipe_ctx->stream->timing.display_color_depth, ++ pipe_ctx->stream->timing.pixel_encoding, ++ requestColorDepth, ++ requestPixelEncoding); ++ pipe_ctx->stream->timing.display_color_depth = requestColorDepth; ++ pipe_ctx->stream->timing.pixel_encoding = requestPixelEncoding; ++ ++ dp_update_dsc_config(pipe_ctx); ++ ++ aconnector->timing_changed = true; ++ /* store current timing */ ++ if (aconnector->timing_requested) ++ *aconnector->timing_requested = pipe_ctx->stream->timing; ++ else ++ DC_LOG_ERROR("%s: timing storage failed\n", __func__); ++ ++ } ++ ++ dc_link_dp_set_test_pattern( ++ (struct dc_link *) link, ++ test_pattern, ++ test_pattern_color_space, ++ NULL, ++ NULL, ++ 0); ++ ++ return false; ++} ++ + void dm_set_phyd32clk(struct dc_context *ctx, int freq_khz) + { + // TODO +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +@@ -4264,124 +4264,6 @@ static void dp_test_send_phy_test_patter + test_pattern_size); + } + +-static void dp_test_send_link_test_pattern(struct dc_link *link) +-{ +- union link_test_pattern dpcd_test_pattern; +- union test_misc dpcd_test_params; +- enum dp_test_pattern test_pattern; +- enum dp_test_pattern_color_space test_pattern_color_space = +- DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED; +- enum dc_color_depth requestColorDepth = COLOR_DEPTH_UNDEFINED; +- struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx; +- struct pipe_ctx *pipe_ctx = NULL; +- int i; +- +- memset(&dpcd_test_pattern, 0, sizeof(dpcd_test_pattern)); +- memset(&dpcd_test_params, 0, sizeof(dpcd_test_params)); +- +- for (i = 0; i < MAX_PIPES; i++) { +- if (pipes[i].stream == NULL) +- continue; +- +- if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) { +- pipe_ctx = &pipes[i]; +- break; +- } +- } +- +- if (pipe_ctx == NULL) +- return; +- +- /* get link test pattern and pattern parameters */ +- core_link_read_dpcd( +- link, +- DP_TEST_PATTERN, +- &dpcd_test_pattern.raw, +- sizeof(dpcd_test_pattern)); +- core_link_read_dpcd( +- link, +- DP_TEST_MISC0, +- &dpcd_test_params.raw, +- sizeof(dpcd_test_params)); +- +- switch (dpcd_test_pattern.bits.PATTERN) { +- case LINK_TEST_PATTERN_COLOR_RAMP: +- test_pattern = DP_TEST_PATTERN_COLOR_RAMP; +- break; +- case LINK_TEST_PATTERN_VERTICAL_BARS: +- test_pattern = DP_TEST_PATTERN_VERTICAL_BARS; +- break; /* black and white */ +- case LINK_TEST_PATTERN_COLOR_SQUARES: +- test_pattern = (dpcd_test_params.bits.DYN_RANGE == +- TEST_DYN_RANGE_VESA ? +- DP_TEST_PATTERN_COLOR_SQUARES : +- DP_TEST_PATTERN_COLOR_SQUARES_CEA); +- break; +- default: +- test_pattern = DP_TEST_PATTERN_VIDEO_MODE; +- break; +- } +- +- if (dpcd_test_params.bits.CLR_FORMAT == 0) +- test_pattern_color_space = DP_TEST_PATTERN_COLOR_SPACE_RGB; +- else +- test_pattern_color_space = dpcd_test_params.bits.YCBCR_COEFS ? +- DP_TEST_PATTERN_COLOR_SPACE_YCBCR709 : +- DP_TEST_PATTERN_COLOR_SPACE_YCBCR601; +- +- switch (dpcd_test_params.bits.BPC) { +- case 0: // 6 bits +- requestColorDepth = COLOR_DEPTH_666; +- break; +- case 1: // 8 bits +- requestColorDepth = COLOR_DEPTH_888; +- break; +- case 2: // 10 bits +- requestColorDepth = COLOR_DEPTH_101010; +- break; +- case 3: // 12 bits +- requestColorDepth = COLOR_DEPTH_121212; +- break; +- default: +- break; +- } +- +- switch (dpcd_test_params.bits.CLR_FORMAT) { +- case 0: +- pipe_ctx->stream->timing.pixel_encoding = PIXEL_ENCODING_RGB; +- break; +- case 1: +- pipe_ctx->stream->timing.pixel_encoding = PIXEL_ENCODING_YCBCR422; +- break; +- case 2: +- pipe_ctx->stream->timing.pixel_encoding = PIXEL_ENCODING_YCBCR444; +- break; +- default: +- pipe_ctx->stream->timing.pixel_encoding = PIXEL_ENCODING_RGB; +- break; +- } +- +- +- if (requestColorDepth != COLOR_DEPTH_UNDEFINED +- && pipe_ctx->stream->timing.display_color_depth != requestColorDepth) { +- DC_LOG_DEBUG("%s: original bpc %d, changing to %d\n", +- __func__, +- pipe_ctx->stream->timing.display_color_depth, +- requestColorDepth); +- pipe_ctx->stream->timing.display_color_depth = requestColorDepth; +- } +- +- dp_update_dsc_config(pipe_ctx); +- +- dc_link_dp_set_test_pattern( +- link, +- test_pattern, +- test_pattern_color_space, +- NULL, +- NULL, +- 0); +-} +- + static void dp_test_get_audio_test_data(struct dc_link *link, bool disable_video) + { + union audio_test_mode dpcd_test_mode = {0}; +@@ -4494,8 +4376,25 @@ void dc_link_dp_handle_automated_test(st + test_response.bits.ACK = 0; + } + if (test_request.bits.LINK_TEST_PATTRN) { +- dp_test_send_link_test_pattern(link); +- test_response.bits.ACK = 1; ++ union test_misc dpcd_test_params; ++ union link_test_pattern dpcd_test_pattern; ++ ++ memset(&dpcd_test_pattern, 0, sizeof(dpcd_test_pattern)); ++ memset(&dpcd_test_params, 0, sizeof(dpcd_test_params)); ++ ++ /* get link test pattern and pattern parameters */ ++ core_link_read_dpcd( ++ link, ++ DP_TEST_PATTERN, ++ &dpcd_test_pattern.raw, ++ sizeof(dpcd_test_pattern)); ++ core_link_read_dpcd( ++ link, ++ DP_TEST_MISC0, ++ &dpcd_test_params.raw, ++ sizeof(dpcd_test_params)); ++ test_response.bits.ACK = dm_helpers_dp_handle_test_pattern_request(link->ctx, link, ++ dpcd_test_pattern, dpcd_test_params) ? 1 : 0; + } + + if (test_request.bits.AUDIO_TEST_PATTERN) { +--- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h ++++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h +@@ -156,6 +156,12 @@ enum dc_edid_status dm_helpers_read_loca + struct dc_link *link, + struct dc_sink *sink); + ++bool dm_helpers_dp_handle_test_pattern_request( ++ struct dc_context *ctx, ++ const struct dc_link *link, ++ union link_test_pattern dpcd_test_pattern, ++ union test_misc dpcd_test_params); ++ + void dm_set_dcn_clocks( + struct dc_context *ctx, + struct dc_clocks *clks); diff --git a/queue-6.1/drm-amd-display-use-max_dsc_bpp-in-amdgpu_dm.patch b/queue-6.1/drm-amd-display-use-max_dsc_bpp-in-amdgpu_dm.patch new file mode 100644 index 00000000000..924acdb32d2 --- /dev/null +++ b/queue-6.1/drm-amd-display-use-max_dsc_bpp-in-amdgpu_dm.patch @@ -0,0 +1,86 @@ +From stable-owner@vger.kernel.org Tue Jul 25 00:26:52 2023 +From: Mario Limonciello +Date: Mon, 24 Jul 2023 17:26:32 -0500 +Subject: drm/amd/display: use max_dsc_bpp in amdgpu_dm +To: +Cc: Mario Limonciello +Message-ID: <20230724222638.1477-2-mario.limonciello@amd.com> + +From: Hamza Mahfooz + +commit 6e5abe94c6eb9b281398e39819217e8fdd1c336f upstream. + +Since, the quirk is handled in the DRM core now, we can use that value +instead of the internal value. + +Reviewed-by: Harry Wentland +Signed-off-by: Hamza Mahfooz +Signed-off-by: Alex Deucher +Signed-off-by: Mario Limonciello +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++---- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 11 +++++++++-- + 2 files changed, 11 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -5714,16 +5714,14 @@ static void apply_dsc_policy_for_stream( + { + struct drm_connector *drm_connector = &aconnector->base; + uint32_t link_bandwidth_kbps; +- uint32_t max_dsc_target_bpp_limit_override = 0; + struct dc *dc = sink->ctx->dc; + uint32_t max_supported_bw_in_kbps, timing_bw_in_kbps; + uint32_t dsc_max_supported_bw_in_kbps; ++ uint32_t max_dsc_target_bpp_limit_override = ++ drm_connector->display_info.max_dsc_bpp; + + link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link, + dc_link_get_link_cap(aconnector->dc_link)); +- if (stream->link && stream->link->local_sink) +- max_dsc_target_bpp_limit_override = +- stream->link->local_sink->edid_caps.panel_patch.max_dsc_target_bpp_limit; + + /* Set DSC policy according to dsc_clock_en */ + dc_dsc_policy_set_enable_dsc_when_not_needed( +--- 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 +@@ -673,15 +673,18 @@ static void set_dsc_configs_from_fairnes + int count, + int k) + { ++ struct drm_connector *drm_connector; + int i; + + for (i = 0; i < count; i++) { ++ drm_connector = ¶ms[i].aconnector->base; ++ + memset(¶ms[i].timing->dsc_cfg, 0, sizeof(params[i].timing->dsc_cfg)); + if (vars[i + k].dsc_enabled && dc_dsc_compute_config( + params[i].sink->ctx->dc->res_pool->dscs[0], + ¶ms[i].sink->dsc_caps.dsc_dec_caps, + params[i].sink->ctx->dc->debug.dsc_min_slice_height_override, +- params[i].sink->edid_caps.panel_patch.max_dsc_target_bpp_limit, ++ drm_connector->display_info.max_dsc_bpp, + 0, + params[i].timing, + ¶ms[i].timing->dsc_cfg)) { +@@ -723,12 +726,16 @@ static int bpp_x16_from_pbn(struct dsc_m + struct dc_dsc_config dsc_config; + u64 kbps; + ++ struct drm_connector *drm_connector = ¶m.aconnector->base; ++ uint32_t max_dsc_target_bpp_limit_override = ++ drm_connector->display_info.max_dsc_bpp; ++ + kbps = div_u64((u64)pbn * 994 * 8 * 54, 64); + dc_dsc_compute_config( + param.sink->ctx->dc->res_pool->dscs[0], + ¶m.sink->dsc_caps.dsc_dec_caps, + param.sink->ctx->dc->debug.dsc_min_slice_height_override, +- param.sink->edid_caps.panel_patch.max_dsc_target_bpp_limit, ++ max_dsc_target_bpp_limit_override, + (int) kbps, param.timing, &dsc_config); + + return dsc_config.bits_per_pixel; diff --git a/queue-6.1/drm-dp_mst-clear-msg_rdy-flag-before-sending-new-message.patch b/queue-6.1/drm-dp_mst-clear-msg_rdy-flag-before-sending-new-message.patch new file mode 100644 index 00000000000..d9da50d93b5 --- /dev/null +++ b/queue-6.1/drm-dp_mst-clear-msg_rdy-flag-before-sending-new-message.patch @@ -0,0 +1,286 @@ +From stable-owner@vger.kernel.org Tue Jul 25 00:28:07 2023 +From: Mario Limonciello +Date: Mon, 24 Jul 2023 17:26:34 -0500 +Subject: drm/dp_mst: Clear MSG_RDY flag before sending new message +To: +Cc: Mario Limonciello +Message-ID: <20230724222638.1477-4-mario.limonciello@amd.com> + +From: Wayne Lin + +commit 72f1de49ffb90b29748284f27f1d6b829ab1de95 upstream. + +[Why] +The sequence for collecting down_reply from source perspective should +be: + +Request_n->repeat (get partial reply of Request_n->clear message ready +flag to ack DPRX that the message is received) till all partial +replies for Request_n are received->new Request_n+1. + +Now there is chance that drm_dp_mst_hpd_irq() will fire new down +request in the tx queue when the down reply is incomplete. Source is +restricted to generate interveleaved message transactions so we should +avoid it. + +Also, while assembling partial reply packets, reading out DPCD DOWN_REP +Sideband MSG buffer + clearing DOWN_REP_MSG_RDY flag should be +wrapped up as a complete operation for reading out a reply packet. +Kicking off a new request before clearing DOWN_REP_MSG_RDY flag might +be risky. e.g. If the reply of the new request has overwritten the +DPRX DOWN_REP Sideband MSG buffer before source writing one to clear +DOWN_REP_MSG_RDY flag, source then unintentionally flushes the reply +for the new request. Should handle the up request in the same way. + +[How] +Separete drm_dp_mst_hpd_irq() into 2 steps. After acking the MST IRQ +event, driver calls drm_dp_mst_hpd_irq_send_new_request() and might +trigger drm_dp_mst_kick_tx() only when there is no on going message +transaction. + +Changes since v1: +* Reworked on review comments received +-> Adjust the fix to let driver explicitly kick off new down request +when mst irq event is handled and acked +-> Adjust the commit message + +Changes since v2: +* Adjust the commit message +* Adjust the naming of the divided 2 functions and add a new input + parameter "ack". +* Adjust code flow as per review comments. + +Changes since v3: +* Update the function description of drm_dp_mst_hpd_irq_handle_event + +Changes since v4: +* Change ack of drm_dp_mst_hpd_irq_handle_event() to be an array align + the size of esi[] + +Signed-off-by: Wayne Lin +Reviewed-by: Lyude Paul +Acked-by: Jani Nikula +Cc: stable@vger.kernel.org +Signed-off-by: Alex Deucher +Signed-off-by: Mario Limonciello +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 30 ++++++------ + drivers/gpu/drm/display/drm_dp_mst_topology.c | 54 +++++++++++++++++++--- + drivers/gpu/drm/i915/display/intel_dp.c | 7 +- + drivers/gpu/drm/nouveau/dispnv50/disp.c | 12 +++- + include/drm/display/drm_dp_mst_helper.h | 7 ++ + 5 files changed, 80 insertions(+), 30 deletions(-) + +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -3201,6 +3201,7 @@ static void dm_handle_mst_sideband_msg(s + + while (dret == dpcd_bytes_to_read && + process_count < max_process_count) { ++ u8 ack[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = {}; + u8 retry; + dret = 0; + +@@ -3209,28 +3210,29 @@ static void dm_handle_mst_sideband_msg(s + DRM_DEBUG_DRIVER("ESI %02x %02x %02x\n", esi[0], esi[1], esi[2]); + /* handle HPD short pulse irq */ + if (aconnector->mst_mgr.mst_state) +- drm_dp_mst_hpd_irq( +- &aconnector->mst_mgr, +- esi, +- &new_irq_handled); ++ drm_dp_mst_hpd_irq_handle_event(&aconnector->mst_mgr, ++ esi, ++ ack, ++ &new_irq_handled); + + if (new_irq_handled) { + /* ACK at DPCD to notify down stream */ +- const int ack_dpcd_bytes_to_write = +- dpcd_bytes_to_read - 1; +- + for (retry = 0; retry < 3; retry++) { +- u8 wret; ++ ssize_t wret; + +- wret = drm_dp_dpcd_write( +- &aconnector->dm_dp_aux.aux, +- dpcd_addr + 1, +- &esi[1], +- ack_dpcd_bytes_to_write); +- if (wret == ack_dpcd_bytes_to_write) ++ wret = drm_dp_dpcd_writeb(&aconnector->dm_dp_aux.aux, ++ dpcd_addr + 1, ++ ack[1]); ++ if (wret == 1) + break; + } + ++ if (retry == 3) { ++ DRM_ERROR("Failed to ack MST event.\n"); ++ return; ++ } ++ ++ drm_dp_mst_hpd_irq_send_new_request(&aconnector->mst_mgr); + /* check if there is new irq to be handled */ + dret = drm_dp_dpcd_read( + &aconnector->dm_dp_aux.aux, +--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c ++++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c +@@ -4053,17 +4053,28 @@ out: + } + + /** +- * drm_dp_mst_hpd_irq() - MST hotplug IRQ notify ++ * drm_dp_mst_hpd_irq_handle_event() - MST hotplug IRQ handle MST event + * @mgr: manager to notify irq for. + * @esi: 4 bytes from SINK_COUNT_ESI ++ * @ack: 4 bytes used to ack events starting from SINK_COUNT_ESI + * @handled: whether the hpd interrupt was consumed or not + * +- * This should be called from the driver when it detects a short IRQ, ++ * This should be called from the driver when it detects a HPD IRQ, + * along with the value of the DEVICE_SERVICE_IRQ_VECTOR_ESI0. The +- * topology manager will process the sideband messages received as a result +- * of this. ++ * topology manager will process the sideband messages received ++ * as indicated in the DEVICE_SERVICE_IRQ_VECTOR_ESI0 and set the ++ * corresponding flags that Driver has to ack the DP receiver later. ++ * ++ * Note that driver shall also call ++ * drm_dp_mst_hpd_irq_send_new_request() if the 'handled' is set ++ * after calling this function, to try to kick off a new request in ++ * the queue if the previous message transaction is completed. ++ * ++ * See also: ++ * drm_dp_mst_hpd_irq_send_new_request() + */ +-int drm_dp_mst_hpd_irq(struct drm_dp_mst_topology_mgr *mgr, u8 *esi, bool *handled) ++int drm_dp_mst_hpd_irq_handle_event(struct drm_dp_mst_topology_mgr *mgr, const u8 *esi, ++ u8 *ack, bool *handled) + { + int ret = 0; + int sc; +@@ -4078,18 +4089,47 @@ int drm_dp_mst_hpd_irq(struct drm_dp_mst + if (esi[1] & DP_DOWN_REP_MSG_RDY) { + ret = drm_dp_mst_handle_down_rep(mgr); + *handled = true; ++ ack[1] |= DP_DOWN_REP_MSG_RDY; + } + + if (esi[1] & DP_UP_REQ_MSG_RDY) { + ret |= drm_dp_mst_handle_up_req(mgr); + *handled = true; ++ ack[1] |= DP_UP_REQ_MSG_RDY; + } + +- drm_dp_mst_kick_tx(mgr); + return ret; + } +-EXPORT_SYMBOL(drm_dp_mst_hpd_irq); ++EXPORT_SYMBOL(drm_dp_mst_hpd_irq_handle_event); ++ ++/** ++ * drm_dp_mst_hpd_irq_send_new_request() - MST hotplug IRQ kick off new request ++ * @mgr: manager to notify irq for. ++ * ++ * This should be called from the driver when mst irq event is handled ++ * and acked. Note that new down request should only be sent when ++ * previous message transaction is completed. Source is not supposed to generate ++ * interleaved message transactions. ++ */ ++void drm_dp_mst_hpd_irq_send_new_request(struct drm_dp_mst_topology_mgr *mgr) ++{ ++ struct drm_dp_sideband_msg_tx *txmsg; ++ bool kick = true; + ++ mutex_lock(&mgr->qlock); ++ txmsg = list_first_entry_or_null(&mgr->tx_msg_downq, ++ struct drm_dp_sideband_msg_tx, next); ++ /* If last transaction is not completed yet*/ ++ if (!txmsg || ++ txmsg->state == DRM_DP_SIDEBAND_TX_START_SEND || ++ txmsg->state == DRM_DP_SIDEBAND_TX_SENT) ++ kick = false; ++ mutex_unlock(&mgr->qlock); ++ ++ if (kick) ++ drm_dp_mst_kick_tx(mgr); ++} ++EXPORT_SYMBOL(drm_dp_mst_hpd_irq_send_new_request); + /** + * drm_dp_mst_detect_port() - get connection status for an MST port + * @connector: DRM connector for this port +--- a/drivers/gpu/drm/i915/display/intel_dp.c ++++ b/drivers/gpu/drm/i915/display/intel_dp.c +@@ -3804,9 +3804,7 @@ intel_dp_mst_hpd_irq(struct intel_dp *in + { + bool handled = false; + +- drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, &handled); +- if (handled) +- ack[1] |= esi[1] & (DP_DOWN_REP_MSG_RDY | DP_UP_REQ_MSG_RDY); ++ drm_dp_mst_hpd_irq_handle_event(&intel_dp->mst_mgr, esi, ack, &handled); + + if (esi[1] & DP_CP_IRQ) { + intel_hdcp_handle_cp_irq(intel_dp->attached_connector); +@@ -3881,6 +3879,9 @@ intel_dp_check_mst_status(struct intel_d + + if (!intel_dp_ack_sink_irq_esi(intel_dp, ack)) + drm_dbg_kms(&i915->drm, "Failed to ack ESI\n"); ++ ++ if (ack[1] & (DP_DOWN_REP_MSG_RDY | DP_UP_REQ_MSG_RDY)) ++ drm_dp_mst_hpd_irq_send_new_request(&intel_dp->mst_mgr); + } + + return link_ok; +--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c ++++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c +@@ -1473,22 +1473,26 @@ nv50_mstm_service(struct nouveau_drm *dr + u8 esi[8] = {}; + + while (handled) { ++ u8 ack[8] = {}; ++ + rc = drm_dp_dpcd_read(aux, DP_SINK_COUNT_ESI, esi, 8); + if (rc != 8) { + ret = false; + break; + } + +- drm_dp_mst_hpd_irq(&mstm->mgr, esi, &handled); ++ drm_dp_mst_hpd_irq_handle_event(&mstm->mgr, esi, ack, &handled); + if (!handled) + break; + +- rc = drm_dp_dpcd_write(aux, DP_SINK_COUNT_ESI + 1, &esi[1], +- 3); +- if (rc != 3) { ++ rc = drm_dp_dpcd_writeb(aux, DP_SINK_COUNT_ESI + 1, ack[1]); ++ ++ if (rc != 1) { + ret = false; + break; + } ++ ++ drm_dp_mst_hpd_irq_send_new_request(&mstm->mgr); + } + + if (!ret) +--- a/include/drm/display/drm_dp_mst_helper.h ++++ b/include/drm/display/drm_dp_mst_helper.h +@@ -815,8 +815,11 @@ void drm_dp_mst_topology_mgr_destroy(str + bool drm_dp_read_mst_cap(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE]); + int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool mst_state); + +-int drm_dp_mst_hpd_irq(struct drm_dp_mst_topology_mgr *mgr, u8 *esi, bool *handled); +- ++int drm_dp_mst_hpd_irq_handle_event(struct drm_dp_mst_topology_mgr *mgr, ++ const u8 *esi, ++ u8 *ack, ++ bool *handled); ++void drm_dp_mst_hpd_irq_send_new_request(struct drm_dp_mst_topology_mgr *mgr); + + int + drm_dp_mst_detect_port(struct drm_connector *connector, diff --git a/queue-6.1/series b/queue-6.1/series index a5321e5a9b3..9b54e19a76b 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -175,3 +175,10 @@ bpf-aggressively-forget-precise-markings-during-state-checkpointing.patch selftests-bpf-make-test_align-selftest-more-robust.patch selftests-bpf-workaround-verification-failure-for-fexit_bpf2bpf-func_replace_return_code.patch selftests-bpf-fix-sk_assign-on-s390x.patch +drm-amd-display-use-max_dsc_bpp-in-amdgpu_dm.patch +drm-amd-display-fix-some-coding-style-issues.patch +drm-dp_mst-clear-msg_rdy-flag-before-sending-new-message.patch +drm-amd-display-force-connector-state-when-bpc-changes-during-compliance.patch +drm-amd-display-clean-up-errors-warnings-in-amdgpu_dm.c.patch +drm-amd-display-fix-linux-dp-link-lost-handled-only-one-time.patch +drm-amd-display-add-polling-method-to-handle-mst-reply-packet.patch -- 2.47.3