From d24b77e444bef83155557ebf4c2b3c551f198926 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 15 Feb 2023 12:38:33 +0100 Subject: drm/amd/display: Pass proper parent for DM backlight device registration The parent for the backlight device should be the drm-connector object, not the PCI device. Userspace relies on this to be able to detect which backlight class device to use on hybrid gfx devices where there may be multiple native (raw) backlight devices registered. Specifically gnome-settings-daemon expects the parent device to have an "enabled" sysfs attribute (as drm_connector devices do) and tests that this returns "enabled" when read. This aligns the parent of the backlight device with i915, nouveau, radeon. Note that drivers/gpu/drm/amd/amdgpu/atombios_encoders.c also already uses the drm_connector as parent, only amdgpu_dm.c used the PCI device as parent before this change. Note this is marked as a RFC because I don't have hw to test, so this has only been compile tested! If someone can test this on actual hw which hits the changed code path that would be great. Link: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/730 Signed-off-by: Hans de Goede Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 c420bce47acb..49ae4ef6bbf0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4142,7 +4142,8 @@ static const struct backlight_ops amdgpu_dm_backlight_ops = { }; static void -amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm) +amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm, + struct amdgpu_dm_connector *aconnector) { char bl_name[16]; struct backlight_properties props = { 0 }; @@ -4165,7 +4166,7 @@ amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm) adev_to_drm(dm->adev)->primary->index + dm->num_of_edps); dm->backlight_dev[dm->num_of_edps] = backlight_device_register(bl_name, - adev_to_drm(dm->adev)->dev, + aconnector->base.kdev, dm, &amdgpu_dm_backlight_ops, &props); @@ -4218,6 +4219,7 @@ static int initialize_plane(struct amdgpu_display_manager *dm, static void register_backlight_device(struct amdgpu_display_manager *dm, + struct amdgpu_dm_connector *aconnector, struct dc_link *link) { if ((link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) && @@ -4228,7 +4230,7 @@ static void register_backlight_device(struct amdgpu_display_manager *dm, * is better then a black screen. */ if (!dm->backlight_dev[dm->num_of_edps]) - amdgpu_dm_register_backlight_device(dm); + amdgpu_dm_register_backlight_device(dm, aconnector); if (dm->backlight_dev[dm->num_of_edps]) { dm->backlight_link[dm->num_of_edps] = link; @@ -4415,7 +4417,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) if (ret) { amdgpu_dm_update_connector_after_detect(aconnector); - register_backlight_device(dm, link); + register_backlight_device(dm, aconnector, link); if (dm->num_of_edps) update_connector_ext_caps(aconnector); -- cgit From 28d58468ad7d9630c83e4ab3dcc0b2953a276f7e Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Fri, 17 Feb 2023 15:44:49 +0800 Subject: drm/amd/display: Modify mismatched function name No functional modification involved. drivers/gpu/drm/amd/amdgpu/../display/dc/link/link_detection.c:1199: warning: expecting prototype for dc_link_detect_connection_type(). Prototype was for link_detect_connection_type() instead. Reported-by: Abaci Robot Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=4103 Signed-off-by: Jiapeng Chong Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/link_detection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 38216c789d77..5394d8a6087a 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -1189,7 +1189,7 @@ static bool detect_link_and_local_sink(struct dc_link *link, } /** - * dc_link_detect_connection_type() - Determine if there is a sink connected + * link_detect_connection_type() - Determine if there is a sink connected * * @type: Returned connection type * Does not detect downstream devices, such as MST sinks -- cgit From 4d3ed6326449ddb1356544bf838024eb232dd315 Mon Sep 17 00:00:00 2001 From: Arthur Grillo Date: Fri, 17 Feb 2023 15:14:08 -0300 Subject: drm/amd/display: Remove unused local variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove local variables that were just set but were never used. This decrease the number of -Wunused-but-set-variable warnings. Acked-by: Christian König Signed-off-by: Arthur Grillo Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c | 3 +-- drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dpp.c | 7 ------- drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c | 4 ---- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 3 --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 5 +---- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c | 4 ---- drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c | 2 -- 9 files changed, 2 insertions(+), 30 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c index c4287147b853..ee08b545aaea 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c @@ -1219,7 +1219,6 @@ void dcn10_link_encoder_update_mst_stream_allocation_table( const struct link_mst_stream_allocation_table *table) { struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); - uint32_t value0 = 0; uint32_t value1 = 0; uint32_t value2 = 0; uint32_t slots = 0; @@ -1321,7 +1320,7 @@ void dcn10_link_encoder_update_mst_stream_allocation_table( do { udelay(10); - value0 = REG_READ(DP_MSE_SAT_UPDATE); + REG_READ(DP_MSE_SAT_UPDATE); REG_GET(DP_MSE_SAT_UPDATE, DP_MSE_SAT_UPDATE, &value1); diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dpp.c index f50ab961bc17..a7268027a472 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dpp.c @@ -185,13 +185,6 @@ static bool dpp201_get_optimal_number_of_taps( struct scaler_data *scl_data, const struct scaling_taps *in_taps) { - uint32_t pixel_width; - - if (scl_data->viewport.width > scl_data->recout.width) - pixel_width = scl_data->recout.width; - else - pixel_width = scl_data->viewport.width; - if (scl_data->viewport.width != scl_data->h_active && scl_data->viewport.height != scl_data->v_active && dpp->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT && diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c index 61bcfa03c4e7..1aeb04fbd89d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c @@ -541,8 +541,6 @@ void dcn201_pipe_control_lock( bool lock) { struct dce_hwseq *hws = dc->hwseq; - struct hubp *hubp = NULL; - hubp = dc->res_pool->hubps[pipe->pipe_idx]; /* use TG master update lock to lock everything on the TG * therefore only top pipe need to lock */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c index 95528e5ef89e..55e388c4c98b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c @@ -123,7 +123,6 @@ void afmt3_se_audio_setup( { struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt); - uint32_t speakers = 0; uint32_t channels = 0; ASSERT(audio_info); @@ -131,7 +130,6 @@ void afmt3_se_audio_setup( if (audio_info == NULL) return; - speakers = audio_info->flags.info.ALLSPEAKERS; channels = speakers_to_channels(audio_info->flags.speaker_flags).all; /* setup the audio stream source select (audio -> dig mapping) */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c index dc3e8df706b3..e46bbe7ddcc9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c @@ -47,13 +47,9 @@ void hubp3_set_vm_system_aperture_settings(struct hubp *hubp, { struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); - PHYSICAL_ADDRESS_LOC mc_vm_apt_default; PHYSICAL_ADDRESS_LOC mc_vm_apt_low; PHYSICAL_ADDRESS_LOC mc_vm_apt_high; - // The format of default addr is 48:12 of the 48 bit addr - mc_vm_apt_default.quad_part = apt->sys_default.quad_part >> 12; - // The format of high/low are 48:18 of the 48 bit addr mc_vm_apt_low.quad_part = apt->sys_low.quad_part >> 18; mc_vm_apt_high.quad_part = apt->sys_high.quad_part >> 18; diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index df787fcf8e86..9a9aac713f88 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -323,13 +323,10 @@ void dcn30_enable_writeback( { struct dwbc *dwb; struct mcif_wb *mcif_wb; - struct timing_generator *optc; dwb = dc->res_pool->dwbc[wb_info->dwb_pipe_inst]; mcif_wb = dc->res_pool->mcif_wb[wb_info->dwb_pipe_inst]; - /* set the OPTC source mux */ - optc = dc->res_pool->timing_generators[dwb->otg_inst]; DC_LOG_DWB("%s dwb_pipe_inst = %d, mpcc_inst = %d",\ __func__, wb_info->dwb_pipe_inst,\ wb_info->mpcc_inst); diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index 74e50c09bb62..e997bb98b43d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -1611,7 +1611,6 @@ bool dcn32_acquire_post_bldn_3dlut( struct dc_transfer_func **shaper) { bool ret = false; - union dc_3dlut_state *state; ASSERT(*lut == NULL && *shaper == NULL); *lut = NULL; @@ -1620,7 +1619,6 @@ bool dcn32_acquire_post_bldn_3dlut( if (!res_ctx->is_mpc_3dlut_acquired[mpcc_id]) { *lut = pool->mpc_lut[mpcc_id]; *shaper = pool->mpc_shaper[mpcc_id]; - state = &pool->mpc_lut[mpcc_id]->state; res_ctx->is_mpc_3dlut_acquired[mpcc_id] = true; ret = true; } @@ -1913,7 +1911,6 @@ int dcn32_populate_dml_pipes_from_context( struct resource_context *res_ctx = &context->res_ctx; struct pipe_ctx *pipe; bool subvp_in_use = false; - uint8_t is_pipe_split_expected[MAX_PIPES] = {0}; struct dc_crtc_timing *timing; dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate); @@ -2002,7 +1999,7 @@ int dcn32_populate_dml_pipes_from_context( } DC_FP_START(); - is_pipe_split_expected[i] = dcn32_predict_pipe_split(context, &pipes[pipe_cnt]); + dcn32_predict_pipe_split(context, &pipes[pipe_cnt]); DC_FP_END(); pipe_cnt++; diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c index 3a2d7bcc4b6d..a616cf078cf4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c @@ -59,25 +59,21 @@ uint32_t dcn32_helper_calculate_mall_bytes_for_cursor( { struct hubp *hubp = pipe_ctx->plane_res.hubp; uint32_t cursor_size = hubp->curs_attr.pitch * hubp->curs_attr.height; - uint32_t cursor_bpp = 4; uint32_t cursor_mall_size_bytes = 0; switch (pipe_ctx->stream->cursor_attributes.color_format) { case CURSOR_MODE_MONO: cursor_size /= 2; - cursor_bpp = 4; break; case CURSOR_MODE_COLOR_1BIT_AND: case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA: case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA: cursor_size *= 4; - cursor_bpp = 4; break; case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED: case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED: cursor_size *= 8; - cursor_bpp = 8; break; } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c index 35d10b4d018b..2244e4fb8c96 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c @@ -902,7 +902,6 @@ static void dml_rq_dlg_get_dlg_params( double hratio_c; double vratio_l; double vratio_c; - bool scl_enable; unsigned int swath_width_ub_l; unsigned int dpte_groups_per_row_ub_l; @@ -1020,7 +1019,6 @@ static void dml_rq_dlg_get_dlg_params( hratio_c = scl->hscl_ratio_c; vratio_l = scl->vscl_ratio; vratio_c = scl->vscl_ratio_c; - scl_enable = scl->scl_enable; swath_width_ub_l = rq_dlg_param->rq_l.swath_width_ub; dpte_groups_per_row_ub_l = rq_dlg_param->rq_l.dpte_groups_per_row_ub; -- cgit From 4f101d5710a84f334b05a96713000ce8dfd4d598 Mon Sep 17 00:00:00 2001 From: Arthur Grillo Date: Fri, 17 Feb 2023 15:14:09 -0300 Subject: drm/amd/display: Remove unused local variables and function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove a couple of local variables that are only set but never used, also remove an static utility function that is never used in consequence of the variable removal. This decrease the number of -Wunused-but-set-variable warnings. Acked-by: Christian König Signed-off-by: Arthur Grillo Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_apg.c | 41 ------------------------ 1 file changed, 41 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_apg.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_apg.c index 24e9ff65434d..05aac3e444b4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_apg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_apg.c @@ -72,40 +72,6 @@ static void apg31_disable( REG_UPDATE(APG_CONTROL2, APG_ENABLE, 0); } -static union audio_cea_channels speakers_to_channels( - struct audio_speaker_flags speaker_flags) -{ - union audio_cea_channels cea_channels = {0}; - - /* these are one to one */ - cea_channels.channels.FL = speaker_flags.FL_FR; - cea_channels.channels.FR = speaker_flags.FL_FR; - cea_channels.channels.LFE = speaker_flags.LFE; - cea_channels.channels.FC = speaker_flags.FC; - - /* if Rear Left and Right exist move RC speaker to channel 7 - * otherwise to channel 5 - */ - if (speaker_flags.RL_RR) { - cea_channels.channels.RL_RC = speaker_flags.RL_RR; - cea_channels.channels.RR = speaker_flags.RL_RR; - cea_channels.channels.RC_RLC_FLC = speaker_flags.RC; - } else { - cea_channels.channels.RL_RC = speaker_flags.RC; - } - - /* FRONT Left Right Center and REAR Left Right Center are exclusive */ - if (speaker_flags.FLC_FRC) { - cea_channels.channels.RC_RLC_FLC = speaker_flags.FLC_FRC; - cea_channels.channels.RRC_FRC = speaker_flags.FLC_FRC; - } else { - cea_channels.channels.RC_RLC_FLC = speaker_flags.RLC_RRC; - cea_channels.channels.RRC_FRC = speaker_flags.RLC_RRC; - } - - return cea_channels; -} - static void apg31_se_audio_setup( struct apg *apg, unsigned int az_inst, @@ -113,24 +79,17 @@ static void apg31_se_audio_setup( { struct dcn31_apg *apg31 = DCN31_APG_FROM_APG(apg); - uint32_t speakers = 0; - uint32_t channels = 0; - ASSERT(audio_info); /* This should not happen.it does so we don't get BSOD*/ if (audio_info == NULL) return; - speakers = audio_info->flags.info.ALLSPEAKERS; - channels = speakers_to_channels(audio_info->flags.speaker_flags).all; - /* DisplayPort only allows for one audio stream with stream ID 0 */ REG_UPDATE(APG_CONTROL2, APG_DP_AUDIO_STREAM_ID, 0); /* When running in "pair mode", pairs of audio channels have their own enable * this is for really old audio drivers */ REG_UPDATE(APG_DBG_GEN_CONTROL, APG_DBG_AUDIO_CHANNEL_ENABLE, 0xFF); - // REG_UPDATE(APG_DBG_GEN_CONTROL, APG_DBG_AUDIO_CHANNEL_ENABLE, channels); /* Disable forced mem power off */ REG_UPDATE(APG_MEM_PWR, APG_MEM_PWR_FORCE, 0); -- cgit From e47f1691adbcbba22b364888cb34686d6c7d1152 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 12 Dec 2022 13:02:25 -0500 Subject: drm/amd/display: Don't restrict bpc to 8 bpc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will let us pass the kms_hdr.bpc_switch IGT test. The reason the bpc restriction was required is historical. At one point in time we were not falling back to a lower bpc when we didn't have enough bandwidth for the maximum bpc reported by a display. This meant that we couldn't enable some high refresh modes unless we limitted the bpc. Starting with this patch the issue is fixed: commit cbd14ae7ea93 ("drm/amd/display: Fix incorrectly pruned modes with deep color") This patch implemented a fallback mechanism if mode validation failed at the max bpc. This means users now automatically get all modes that can be supported by at least 6 bpc. The driver will enable the mode with the highest possible bpc that is supported by the display. v2: - explain why this is no longer needed (Michel) - refer to commit that fixed bpc fallback (Michel) Signed-off-by: Harry Wentland Cc: Pekka Paalanen Cc: Sebastian Wick Cc: Vitaly.Prosyak@amd.com Cc: Joshua Ashton Cc: dri-devel@lists.freedesktop.org Cc: amd-gfx@lists.freedesktop.org Cc: Michel Dänzer Reviewed-by: Joshua Ashton Reviewed-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 49ae4ef6bbf0..d433be2587f4 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7237,7 +7237,7 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, drm_connector_attach_max_bpc_property(&aconnector->base, 8, 16); /* This defaults to the max in the range, but we want 8bpc for non-edp. */ - aconnector->base.state->max_bpc = (connector_type == DRM_MODE_CONNECTOR_eDP) ? 16 : 8; + aconnector->base.state->max_bpc = 16; aconnector->base.state->max_requested_bpc = aconnector->base.state->max_bpc; if (connector_type == DRM_MODE_CONNECTOR_eDP && -- cgit From 283947bbd5dd8885dbfbd86515276a9ce4a31251 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Thu, 12 Jan 2023 11:55:25 -0500 Subject: drm/amd/display: Format input and output CSC matrix Format the input and output CSC matrix so they look like 3x4 matrixes. This will make parsing them much easier and allows us to quickly spot potential mistakes. Signed-off-by: Harry Wentland Cc: Pekka Paalanen Cc: Sebastian Wick Cc: Vitaly.Prosyak@amd.com Cc: Joshua Ashton Cc: dri-devel@lists.freedesktop.org Cc: amd-gfx@lists.freedesktop.org Reviewed-by: Leo Li Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/core/dc_hw_sequencer.c | 38 +++++++++------ drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h | 54 +++++++++++++--------- 2 files changed, 56 insertions(+), 36 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c index 652270a0b498..2acbf692193f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c @@ -73,28 +73,38 @@ struct out_csc_color_matrix_type { static const struct out_csc_color_matrix_type output_csc_matrix[] = { { COLOR_SPACE_RGB_TYPE, - { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} }, + { 0x2000, 0, 0, 0, + 0, 0x2000, 0, 0, + 0, 0, 0x2000, 0} }, { COLOR_SPACE_RGB_LIMITED_TYPE, - { 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} }, + { 0x1B67, 0, 0, 0x201, + 0, 0x1B67, 0, 0x201, + 0, 0, 0x1B67, 0x201} }, { COLOR_SPACE_YCBCR601_TYPE, - { 0xE04, 0xF444, 0xFDB9, 0x1004, 0x831, 0x1016, 0x320, 0x201, 0xFB45, - 0xF6B7, 0xE04, 0x1004} }, + { 0xE04, 0xF444, 0xFDB9, 0x1004, + 0x831, 0x1016, 0x320, 0x201, + 0xFB45, 0xF6B7, 0xE04, 0x1004} }, { COLOR_SPACE_YCBCR709_TYPE, - { 0xE04, 0xF345, 0xFEB7, 0x1004, 0x5D3, 0x1399, 0x1FA, - 0x201, 0xFCCA, 0xF533, 0xE04, 0x1004} }, + { 0xE04, 0xF345, 0xFEB7, 0x1004, + 0x5D3, 0x1399, 0x1FA, 0x201, + 0xFCCA, 0xF533, 0xE04, 0x1004} }, /* TODO: correct values below */ { COLOR_SPACE_YCBCR601_LIMITED_TYPE, - { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991, - 0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} }, + { 0xE00, 0xF447, 0xFDB9, 0x1000, + 0x991, 0x12C9, 0x3A6, 0x200, + 0xFB47, 0xF6B9, 0xE00, 0x1000} }, { COLOR_SPACE_YCBCR709_LIMITED_TYPE, - { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3, - 0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }, + { 0xE00, 0xF349, 0xFEB7, 0x1000, + 0x6CE, 0x16E3, 0x24F, 0x200, + 0xFCCB, 0xF535, 0xE00, 0x1000} }, { COLOR_SPACE_YCBCR2020_TYPE, - { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868, 0x15B2, - 0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} }, + { 0x1000, 0xF149, 0xFEB7, 0x1004, + 0x0868, 0x15B2, 0x01E6, 0x201, + 0xFB88, 0xF478, 0x1000, 0x1004} }, { COLOR_SPACE_YCBCR709_BLACK_TYPE, - { 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, - 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x1000} }, + { 0x0000, 0x0000, 0x0000, 0x1000, + 0x0000, 0x0000, 0x0000, 0x0200, + 0x0000, 0x0000, 0x0000, 0x1000} }, }; static bool is_rgb_type( diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h index 131fcfa28bca..f4aa76e02518 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h @@ -70,28 +70,38 @@ struct dpp_input_csc_matrix { }; static const struct dpp_input_csc_matrix __maybe_unused dpp_input_csc_matrix[] = { - {COLOR_SPACE_SRGB, - {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} }, - {COLOR_SPACE_SRGB_LIMITED, - {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} }, - {COLOR_SPACE_YCBCR601, - {0x2cdd, 0x2000, 0, 0xe991, 0xe926, 0x2000, 0xf4fd, 0x10ef, - 0, 0x2000, 0x38b4, 0xe3a6} }, - {COLOR_SPACE_YCBCR601_LIMITED, - {0x3353, 0x2568, 0, 0xe400, 0xe5dc, 0x2568, 0xf367, 0x1108, - 0, 0x2568, 0x40de, 0xdd3a} }, - {COLOR_SPACE_YCBCR709, - {0x3265, 0x2000, 0, 0xe6ce, 0xf105, 0x2000, 0xfa01, 0xa7d, 0, - 0x2000, 0x3b61, 0xe24f} }, - {COLOR_SPACE_YCBCR709_LIMITED, - {0x39a6, 0x2568, 0, 0xe0d6, 0xeedd, 0x2568, 0xf925, 0x9a8, 0, - 0x2568, 0x43ee, 0xdbb2} }, - {COLOR_SPACE_2020_YCBCR, - {0x2F30, 0x2000, 0, 0xE869, 0xEDB7, 0x2000, 0xFABC, 0xBC6, 0, - 0x2000, 0x3C34, 0xE1E6} }, - {COLOR_SPACE_2020_RGB_LIMITEDRANGE, - {0x35E0, 0x255F, 0, 0xE2B3, 0xEB20, 0x255F, 0xF9FD, 0xB1E, 0, - 0x255F, 0x44BD, 0xDB43} } + { COLOR_SPACE_SRGB, + { 0x2000, 0, 0, 0, + 0, 0x2000, 0, 0, + 0, 0, 0x2000, 0 } }, + { COLOR_SPACE_SRGB_LIMITED, + { 0x2000, 0, 0, 0, + 0, 0x2000, 0, 0, + 0, 0, 0x2000, 0 } }, + { COLOR_SPACE_YCBCR601, + { 0x2cdd, 0x2000, 0, 0xe991, + 0xe926, 0x2000, 0xf4fd, 0x10ef, + 0, 0x2000, 0x38b4, 0xe3a6 } }, + { COLOR_SPACE_YCBCR601_LIMITED, + { 0x3353, 0x2568, 0, 0xe400, + 0xe5dc, 0x2568, 0xf367, 0x1108, + 0, 0x2568, 0x40de, 0xdd3a } }, + { COLOR_SPACE_YCBCR709, + { 0x3265, 0x2000, 0, 0xe6ce, + 0xf105, 0x2000, 0xfa01, 0xa7d, + 0, 0x2000, 0x3b61, 0xe24f } }, + { COLOR_SPACE_YCBCR709_LIMITED, + { 0x39a6, 0x2568, 0, 0xe0d6, + 0xeedd, 0x2568, 0xf925, 0x9a8, + 0, 0x2568, 0x43ee, 0xdbb2 } }, + { COLOR_SPACE_2020_YCBCR, + { 0x2F30, 0x2000, 0, 0xE869, + 0xEDB7, 0x2000, 0xFABC, 0xBC6, + 0, 0x2000, 0x3C34, 0xE1E6 } }, + { COLOR_SPACE_2020_RGB_LIMITEDRANGE, + { 0x35E0, 0x255F, 0, 0xE2B3, + 0xEB20, 0x255F, 0xF9FD, 0xB1E, + 0, 0x255F, 0x44BD, 0xDB43 } } }; struct dpp_grph_csc_adjustment { -- cgit From 60971b204c615a6881f50c3dc9a2182551282b94 Mon Sep 17 00:00:00 2001 From: tiancyin Date: Wed, 8 Feb 2023 14:10:04 +0800 Subject: drm/amd/display: fix dm irq error message in gpu recover [Why] Variable adev->crtc_irq.num_types was initialized as the value of adev->mode_info.num_crtc at early_init stage, later at hw_init stage, the num_crtc changed due to the display pipe harvest on some SKUs, but the num_types was not updated accordingly, that cause below error in gpu recover. *ERROR* amdgpu_dm_set_crtc_irq_state: crtc is NULL at id :3 *ERROR* amdgpu_dm_set_crtc_irq_state: crtc is NULL at id :3 *ERROR* amdgpu_dm_set_crtc_irq_state: crtc is NULL at id :3 *ERROR* amdgpu_dm_set_pflip_irq_state: crtc is NULL at id :3 *ERROR* amdgpu_dm_set_pflip_irq_state: crtc is NULL at id :3 *ERROR* amdgpu_dm_set_pflip_irq_state: crtc is NULL at id :3 *ERROR* amdgpu_dm_set_pflip_irq_state: crtc is NULL at id :3 *ERROR* amdgpu_dm_set_vupdate_irq_state: crtc is NULL at id :3 *ERROR* amdgpu_dm_set_vupdate_irq_state: crtc is NULL at id :3 *ERROR* amdgpu_dm_set_vupdate_irq_state: crtc is NULL at id :3 [How] Defer the initialization of num_types to eliminate the error logs. Signed-off-by: tiancyin Reviewed-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 d433be2587f4..ff4cf292781c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4267,6 +4267,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) /* Update the actual used number of crtc */ adev->mode_info.num_crtc = adev->dm.display_indexes_num; + amdgpu_dm_set_irq_funcs(adev); + link_cnt = dm->dc->caps.max_links; if (amdgpu_dm_mode_config_init(dm->adev)) { DRM_ERROR("DM: Failed to initialize mode config\n"); @@ -4759,8 +4761,6 @@ static int dm_early_init(void *handle) break; } - amdgpu_dm_set_irq_funcs(adev); - if (adev->mode_info.funcs == NULL) adev->mode_info.funcs = &dm_display_funcs; -- cgit From 1e5d4d8eb8c0f15d90c50e7abd686c980e54e42e Mon Sep 17 00:00:00 2001 From: Ryan Lin Date: Tue, 7 Feb 2023 23:03:48 +0800 Subject: drm/amd/display: Ext displays with dock can't recognized after resume [Why] Needs to set the default value of the LTTPR timeout after resume. [How] Set the default (3.2ms) timeout at resuming if the sink supports LTTPR Reviewed-by: Jerry Zuo Acked-by: Qingqing Zhuo Signed-off-by: Ryan Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++++++++++ drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h | 1 + .../gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c | 2 -- 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 ff4cf292781c..9534bb8cb40e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -41,6 +41,8 @@ #include "dpcd_defs.h" #include "link/protocols/link_dpcd.h" #include "link_service_types.h" +#include "link/protocols/link_dp_capability.h" +#include "link/protocols/link_ddc.h" #include "vid.h" #include "amdgpu.h" @@ -2302,6 +2304,14 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend) if (suspend) { drm_dp_mst_topology_mgr_suspend(mgr); } else { + /* if extended timeout is supported in hardware, + * default to LTTPR timeout (3.2ms) first as a W/A for DP link layer + * CTS 4.2.1.1 regression introduced by CTS specs requirement update. + */ + try_to_configure_aux_timeout(aconnector->dc_link->ddc, LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD); + if (!dp_is_lttpr_present(aconnector->dc_link)) + try_to_configure_aux_timeout(aconnector->dc_link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD); + ret = drm_dp_mst_topology_mgr_resume(mgr, true); if (ret < 0) { dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx, diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h index 86e9d2e886d6..aaa5064408ba 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h @@ -33,6 +33,7 @@ #define DPVGA_DONGLE_AUX_DEFER_WA_DELAY 40 #define I2C_OVER_AUX_DEFER_WA_DELAY_1MS 1 #define LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD 3200 /*us*/ +#define LINK_AUX_DEFAULT_TIMEOUT_PERIOD 552 /*us*/ #define EDID_SEGMENT_SIZE 256 diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index 4874d1bf1dcb..d4370856f164 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -60,8 +60,6 @@ #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) #endif -#define LINK_AUX_DEFAULT_TIMEOUT_PERIOD 552 /*us*/ - struct dp_lt_fallback_entry { enum dc_lane_count lane_count; enum dc_link_rate link_rate; -- cgit From b4ceeffd13870b641a284ffb0f6fb4ffe19b0b14 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Wed, 11 Jan 2023 09:54:11 -0700 Subject: drm/amd/display: fix shift-out-of-bounds in CalculateVMAndRowBytes [WHY] When PTEBufferSizeInRequests is zero, UBSAN reports the following warning because dml_log2 returns an unexpected negative value: shift exponent 4294966273 is too large for 32-bit type 'int' [HOW] In the case PTEBufferSizeInRequests is zero, skip the dml_log2() and assign the result directly. Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c index 379729b02847..c3d75e56410c 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c @@ -1802,7 +1802,10 @@ static unsigned int CalculateVMAndRowBytes( } if (SurfaceTiling == dm_sw_linear) { - *dpte_row_height = dml_min(128, 1 << (unsigned int) dml_floor(dml_log2(PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch), 1)); + if (PTEBufferSizeInRequests == 0) + *dpte_row_height = 1; + else + *dpte_row_height = dml_min(128, 1 << (unsigned int) dml_floor(dml_log2(PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch), 1)); *dpte_row_width_ub = (dml_ceil(((double) SwathWidth - 1) / *PixelPTEReqWidth, 1) + 1) * *PixelPTEReqWidth; *PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqWidth * *PTERequestSize; } else if (ScanDirection != dm_vert) { -- cgit From c69fc3d0de6ca79d946a2715f8745a1eae69c3d8 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Fri, 3 Feb 2023 17:46:05 -0500 Subject: drm/amd/display: Reduce CPU busy-waiting for long delays [WHY] udelay should not be used for long waits since it keeps CPU active, wasting power. [HOW] Use fsleep where acceptable to allow CPU cores to be parked by the scheduler. Reviewed-by: Wenjing Liu Acked-by: Qingqing Zhuo Signed-off-by: Aric Cyr Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dce_aux.c | 9 ++------- drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 2 +- drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 2 +- drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 4 ++-- .../gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c | 8 ++++---- drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c | 2 +- drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c | 7 ++----- .../drm/amd/display/dc/link/protocols/link_dp_training_dpia.c | 2 +- .../drm/amd/display/dc/link/protocols/link_edp_panel_control.c | 4 ++-- 9 files changed, 16 insertions(+), 24 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c index 140297c8ff55..739298d2dff3 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c @@ -832,13 +832,8 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc, LOG_FLAG_I2cAux_DceAux, "dce_aux_transfer_with_retries: payload->defer_delay=%u", payload->defer_delay); - if (payload->defer_delay > 1) { - msleep(payload->defer_delay); - defer_time_in_ms += payload->defer_delay; - } else if (payload->defer_delay <= 1) { - udelay(payload->defer_delay * 1000); - defer_time_in_ms += payload->defer_delay; - } + fsleep(payload->defer_delay * 1000); + defer_time_in_ms += payload->defer_delay; } } break; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index d3cc5ec46956..e74266cc0098 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -586,7 +586,7 @@ static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait) if (state == PSR_STATE0) break; } - udelay(500); + fsleep(500); } /* assert if max retry hit */ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c index 1e2d2cbe2c37..19440bdf6344 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -215,7 +215,7 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait, uint8 break; } - udelay(500); + fsleep(500); } /* assert if max retry hit */ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index 257e1c3ba00a..180c92a9f117 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -1153,7 +1153,7 @@ static bool poll_for_allocation_change_trigger(struct dc_link *link) break; } - msleep(5); + fsleep(5000); } if (result == ACT_FAILED) { @@ -1640,7 +1640,7 @@ static bool write_128b_132b_sst_payload_allocation_table( } } retries++; - msleep(5); + fsleep(5000); } if (!result && retries == max_retries) { diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index d4370856f164..0f2c59807079 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -1005,7 +1005,7 @@ static enum dc_status wake_up_aux_channel(struct dc_link *link) * signal and may need up to 1 ms before being able to reply. */ if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3) { - udelay(1000); + fsleep(1000); aux_channel_retry_cnt++; } } @@ -2121,7 +2121,7 @@ static bool dp_verify_link_cap( if (status == LINK_TRAINING_SUCCESS) { success = true; - udelay(1000); + fsleep(1000); if (dc_link_dp_read_hpd_rx_irq_data(link, &irq_data) == DC_OK && dc_link_check_link_loss_status( link, @@ -2171,7 +2171,7 @@ bool dp_verify_link_cap_with_retries( success = true; break; } - msleep(10); + fsleep(10 * 1000); } dp_trace_lt_fail_count_update(link, fail_count, true); @@ -2231,7 +2231,7 @@ bool dc_link_is_dp_sink_present(struct dc_link *link) gpio_result = dal_gpio_get_value(ddc->pin_clock, &clock_pin); ASSERT(gpio_result == GPIO_RESULT_OK); if (clock_pin) - udelay(1000); + fsleep(1000); else break; } while (retry++ < 3); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index f69e681b3b5b..fcb82bb855ed 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -424,7 +424,7 @@ int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *li timeout--; else break; - udelay(10 * 1000); + fsleep(10 * 1000); } while (!get_cm_response_ready_flag(link)); if (!timeout) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index b48d4d822991..5e613ea2cd3f 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -258,10 +258,7 @@ void dp_wait_for_training_aux_rd_interval( struct dc_link *link, uint32_t wait_in_micro_secs) { - if (wait_in_micro_secs > 1000) - msleep(wait_in_micro_secs/1000); - else - udelay(wait_in_micro_secs); + fsleep(wait_in_micro_secs); DC_LOG_HW_LINK_TRAINING("%s:\n wait = %d\n", __func__, @@ -970,7 +967,7 @@ static void dpcd_exit_training_mode(struct dc_link *link, enum dp_link_encoding if ((core_link_read_dpcd(link, DP_SINK_STATUS, &sink_status, 1) == DC_OK) && (sink_status & DP_INTRA_HOP_AUX_REPLY_INDICATION) == 0) break; - udelay(1000); + fsleep(1000); } } } diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c index e60da0532c53..9715fa754d56 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c @@ -1035,7 +1035,7 @@ enum link_training_result dc_link_dpia_perform_link_training( * falling back to lower bandwidth settings possible. */ if (result == LINK_TRAINING_SUCCESS) { - msleep(5); + fsleep(5000); if (!link->is_automated) result = dp_check_link_loss_status(link, <_settings); } else if (result == LINK_TRAINING_ABORT) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index 97e02b5b21ae..da7f83835f78 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -325,7 +325,7 @@ bool dc_link_wait_for_t12(struct dc_link *link) void link_edp_add_delay_for_T9(struct dc_link *link) { if (link && link->panel_config.pps.extra_delay_backlight_off > 0) - udelay(link->panel_config.pps.extra_delay_backlight_off * 1000); + fsleep(link->panel_config.pps.extra_delay_backlight_off * 1000); } bool link_edp_receiver_ready_T9(struct dc_link *link) @@ -383,7 +383,7 @@ bool link_edp_receiver_ready_T7(struct dc_link *link) } if (link && link->panel_config.pps.extra_t7_ms > 0) - udelay(link->panel_config.pps.extra_t7_ms * 1000); + fsleep(link->panel_config.pps.extra_t7_ms * 1000); return result; } -- cgit From c32699caeca802cfa3416f798abcff719d1633f7 Mon Sep 17 00:00:00 2001 From: Jasdeep Dhillon Date: Wed, 25 Jan 2023 10:50:19 -0500 Subject: drm/amd/display: Updating Video Format Fall Back Policy. [WHY] Adding 1920x1080 as fail safe mode for Video Format Fall Back Policy. Reviewed-by: Jerry Zuo Acked-by: Qingqing Zhuo Signed-off-by: Jasdeep Dhillon Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +++++ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 1 + drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h | 1 + 3 files changed, 7 insertions(+) (limited to 'drivers/gpu/drm/amd/display') 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 9534bb8cb40e..cfbde4fde852 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7160,12 +7160,17 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) to_amdgpu_dm_connector(connector); struct drm_encoder *encoder; struct edid *edid = amdgpu_dm_connector->edid; + struct dc_link_settings *verified_link_cap = + &amdgpu_dm_connector->dc_link->verified_link_cap; encoder = amdgpu_dm_connector_to_encoder(connector); if (!drm_edid_is_valid(edid)) { amdgpu_dm_connector->num_modes = drm_add_modes_noedid(connector, 640, 480); + if (link_dp_get_encoding_format(verified_link_cap) == DP_128b_132b_ENCODING) + amdgpu_dm_connector->num_modes += + drm_add_modes_noedid(connector, 1920, 1080); } else { amdgpu_dm_connector_ddc_get_modes(connector, edid); amdgpu_dm_connector_add_common_modes(encoder, connector); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c index 8e572f07ec47..125012426a92 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c @@ -559,6 +559,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) link->dp.rev = aconnector->dc_link->dpcd_caps.dpcd_rev.raw; link->dp.assr_enabled = config->assr_enabled; link->dp.mst_enabled = config->mst_enabled; + link->dp.dp2_enabled = config->dp2_enabled; link->dp.usb4_enabled = config->usb4_enabled; display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION; link->adjust.auth_delay = 0; diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h index 3348bb97ef81..a4d344a4db9e 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h @@ -104,6 +104,7 @@ struct mod_hdcp_displayport { uint8_t rev; uint8_t assr_enabled; uint8_t mst_enabled; + uint8_t dp2_enabled; uint8_t usb4_enabled; }; -- cgit From 36951fc9460fce96bafd131ceb0f343cae6d3cb9 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Thu, 9 Feb 2023 20:03:33 -0500 Subject: Revert "drm/amd/display: Do not set DRR on pipe commit" This reverts commit 4f1b5e739dfd1edde33329e3f376733a131fb1ff. [Why & How] Original change causes a regression. Revert until fix is available. Reviewed-by: Aric Cyr Acked-by: Qingqing Zhuo Signed-off-by: Aric Cyr Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index 9a9aac713f88..6ef85e71380c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -995,5 +995,8 @@ void dcn30_prepare_bandwidth(struct dc *dc, dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz); dcn20_prepare_bandwidth(dc, context); + + dc_dmub_srv_p_state_delegate(dc, + context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching, context); } -- cgit From a06d565b4a1c032ff8a8d22ceb39c061443208d9 Mon Sep 17 00:00:00 2001 From: Mustapha Ghaddar Date: Fri, 3 Feb 2023 13:41:13 -0500 Subject: drm/amd/display: Allocation at stream Enable [WHY & HOW] After we allocate BW at plug, we will de-alloc and allocate only what stream needs at stream_enable() [HOW] Introduce bw allocation check at link_enable() for DPIA links Reviewed-by: Wenjing Liu Acked-by: Qingqing Zhuo Signed-off-by: Mustapha Ghaddar Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_link.h | 2 ++ drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 11 ++++++-- .../display/dc/link/protocols/link_dp_dpia_bw.c | 33 +++++++++++++++++++++- .../display/dc/link/protocols/link_dp_dpia_bw.h | 14 ++++++++- 4 files changed, 56 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index cecd807f5ed8..bfe0f6877d9e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -293,6 +293,8 @@ struct dc_link { struct dc_panel_config panel_config; struct phy_state phy_state; + // BW ALLOCATON USB4 ONLY + struct dc_dpia_bw_alloc dpia_bw_alloc_config; }; diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index 180c92a9f117..a1214e5606dd 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -46,6 +46,7 @@ #include "protocols/link_dp_capability.h" #include "protocols/link_dp_training.h" #include "protocols/link_edp_panel_control.h" +#include "protocols/link_dp_dpia_bw.h" #include "dm_helpers.h" #include "link_enc_cfg.h" @@ -2044,11 +2045,17 @@ static enum dc_status enable_link_dp(struct dc_state *state, } } - /* Train with fallback when enabling DPIA link. Conventional links are + /* + * If the link is DP-over-USB4 do the following: + * - Train with fallback when enabling DPIA link. Conventional links are * trained with fallback during sink detection. + * - Allocate only what the stream needs for bw in Gbps. Inform the CM + * in case stream needs more or less bw from what has been allocated + * earlier at plug time. */ - if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) + if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { do_fallback = true; + } /* * Temporary w/a to get DP2.0 link rates to work with SST. diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index fcb82bb855ed..9d3df69fc340 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -246,7 +246,7 @@ static bool get_cm_response_ready_flag(struct dc_link *link) // ------------------------------------------------------------------ // PUBLIC FUNCTIONS // ------------------------------------------------------------------ -bool set_dptx_usb4_bw_alloc_support(struct dc_link *link) +bool link_dp_dpia_set_dptx_usb4_bw_alloc_support(struct dc_link *link) { bool ret = false; uint8_t response = 0, @@ -439,3 +439,34 @@ int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *li out: return ret; } +int link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw) +{ + int ret = 0; + uint8_t timeout = 10; + + if (!get_bw_alloc_proceed_flag(link)) + goto out; + + /* + * Sometimes stream uses same timing parameters as the already + * allocated max sink bw so no need to re-alloc + */ + if (req_bw != link->dpia_bw_alloc_config.sink_allocated_bw) { + dc_link_set_usb4_req_bw_req(link, req_bw); + do { + if (!timeout > 0) + timeout--; + else + break; + udelay(10 * 1000); + } while (!get_cm_response_ready_flag(link)); + + if (!timeout) + ret = 0;// ERROR TIMEOUT waiting for response for allocating bw + else if (link->dpia_bw_alloc_config.sink_allocated_bw > 0) + ret = get_host_router_total_bw(link, HOST_ROUTER_BW_ALLOCATED); + } + +out: + return ret; +} 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 c2c3049adcd1..46d141a1366f 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 @@ -42,6 +42,18 @@ enum bw_type { * * return: SUCCESS or FAILURE */ -bool set_dptx_usb4_bw_alloc_support(struct dc_link *link); +bool link_dp_dpia_set_dptx_usb4_bw_alloc_support(struct dc_link *link); + +/* + * Allocates only what the stream needs for bw, so if: + * If (stream_req_bw < or > already_allocated_bw_at_HPD) + * => Deallocate Max Bw & then allocate only what the stream needs + * + * @link: pointer to the dc_link struct instance + * @req_bw: Bw requested by the stream + * + * return: allocated bw else return 0 + */ +int link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw); #endif /* DC_INC_LINK_DP_DPIA_BW_H_ */ -- cgit From 504d3cae8b6718ab9c2fbef9e4cb56deb29ea9ee Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Thu, 9 Feb 2023 18:35:00 -0500 Subject: drm/amd/display: dcn32/321 dsc_pg_control not executed properly [why] during boot up or resume from s3, hw default value of domain_power_forceon is 1. when program domain_power_gate to 1 to power down hw block, hw will not change to power off due to domain_power_forceon = 1. [how] enable_power_gating_plane(true) should be executed to set domain_power_forceon to 0 before dsc_pg_control. dsc_pg_control is already called by dcn3x_init_hw--> init_pipes--> dsc_pg_control. no need be programmed with dcn3x_init_hw one more time. to trigger dchub, dsc block power state change, need program dc_ip_request_cntl to notify hw block. Reviewed-by: Nevenko Stupar Acked-by: Qingqing Zhuo Signed-off-by: Hersen Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 9 +++++++++ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 5 ----- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 19 +++++++++++++------ 3 files changed, 22 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 b83873a3a534..8b5181f3d13a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -190,10 +190,15 @@ void dcn20_enable_power_gating_plane( bool enable) { bool force_on = true; /* disable power gating */ + uint32_t org_ip_request_cntl = 0; if (enable) force_on = false; + REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); + if (org_ip_request_cntl == 0) + REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); + /* DCHUBP0/1/2/3/4/5 */ REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, force_on); REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, force_on); @@ -224,6 +229,10 @@ void dcn20_enable_power_gating_plane( REG_UPDATE(DOMAIN20_PG_CONFIG, DOMAIN20_POWER_FORCEON, force_on); if (REG(DOMAIN21_PG_CONFIG)) REG_UPDATE(DOMAIN21_PG_CONFIG, DOMAIN21_POWER_FORCEON, force_on); + + if (org_ip_request_cntl == 0) + REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); + } void dcn20_dccg_init(struct dce_hwseq *hws) diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index 6ef85e71380c..1d243c549562 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -531,11 +531,6 @@ void dcn30_init_hw(struct dc *dc) } } - /* Power gate DSCs */ - for (i = 0; i < res_pool->res_cap->num_dsc; i++) - if (hws->funcs.dsc_pg_control != NULL) - hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false); - /* we want to turn off all dp displays before doing detection */ link_blank_all_dp_displays(dc); diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index 16f892125b6f..f667f2a6f686 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -131,10 +131,15 @@ void dcn32_enable_power_gating_plane( bool enable) { bool force_on = true; /* disable power gating */ + uint32_t org_ip_request_cntl = 0; if (enable) force_on = false; + REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); + if (org_ip_request_cntl == 0) + REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); + /* DCHUBP0/1/2/3 */ REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on); REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on); @@ -146,6 +151,9 @@ void dcn32_enable_power_gating_plane( REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on); REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on); REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on); + + if (org_ip_request_cntl == 0) + REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); } void dcn32_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on) @@ -786,10 +794,11 @@ void dcn32_init_hw(struct dc *dc) } } - /* Power gate DSCs */ - for (i = 0; i < res_pool->res_cap->num_dsc; i++) - if (hws->funcs.dsc_pg_control != NULL) - hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false); + /* enable_power_gating_plane before dsc_pg_control because + * FORCEON = 1 with hw default value on bootup, resume from s3 + */ + if (hws->funcs.enable_power_gating_plane) + hws->funcs.enable_power_gating_plane(dc->hwseq, true); /* we want to turn off all dp displays before doing detection */ link_blank_all_dp_displays(dc); @@ -886,8 +895,6 @@ void dcn32_init_hw(struct dc *dc) REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); } - if (hws->funcs.enable_power_gating_plane) - hws->funcs.enable_power_gating_plane(dc->hwseq, true); if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks) dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub); -- cgit From 9bb10b7aaec3b6278f9cc410c17dcaa129bbbbf0 Mon Sep 17 00:00:00 2001 From: Ayush Gupta Date: Fri, 10 Feb 2023 13:02:09 -0500 Subject: drm/amd/display: populate subvp cmd info only for the top pipe [Why] System restart observed while changing the display resolution to 8k with extended mode. Sytem restart was caused by a page fault. [How] When the driver populates subvp info it did it for both the pipes using vblank which caused an outof bounds array access causing the page fault. added checks to allow the top pipe only to fix this issue. Co-authored-by: Ayush Gupta Reviewed-by: Alvin Lee Acked-by: Qingqing Zhuo Signed-off-by: Ayush Gupta Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index c2092775ca88..7f27e29fae11 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -750,7 +750,8 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc, !pipe->top_pipe && !pipe->prev_odm_pipe && pipe->stream->mall_stream_config.type == SUBVP_MAIN) { populate_subvp_cmd_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++); - } else if (pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_NONE) { + } else if (pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_NONE && + !pipe->top_pipe && !pipe->prev_odm_pipe) { // Don't need to check for ActiveDRAMClockChangeMargin < 0, not valid in cases where // we run through DML without calculating "natural" P-state support populate_subvp_cmd_vblank_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++); -- cgit From 1e74c05b275cb4224f3f8c2240ab24486818a823 Mon Sep 17 00:00:00 2001 From: Yihan Zhu Date: Fri, 3 Feb 2023 10:56:04 -0500 Subject: drm/amd/display: update pixel format in DP hw sequence [WHY] DP 420 formats do not light up because the pixel processing mode of the DP_FORMAT is misprogrammed [HOW] Added appropriate programming for DP pixel format Reviewed-by: Charlene Liu Reviewed-by: Nicholas Kazlauskas Acked-by: Qingqing Zhuo Signed-off-by: Yihan Zhu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c index 962a2c02b422..742e43cb8880 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c @@ -296,12 +296,14 @@ static void enc314_stream_encoder_dp_unblank( uint32_t n_vid = 0x8000; uint32_t m_vid; uint32_t n_multiply = 0; + uint32_t pix_per_cycle = 0; uint64_t m_vid_l = n_vid; /* YCbCr 4:2:0 : Computed VID_M will be 2X the input rate */ if (is_two_pixels_per_containter(¶m->timing) || param->opp_cnt > 1) { /*this logic should be the same in get_pixel_clock_parameters() */ n_multiply = 1; + pix_per_cycle = 1; } /* M / N = Fstream / Flink * m_vid / n_vid = pixel rate / link rate @@ -329,6 +331,10 @@ static void enc314_stream_encoder_dp_unblank( REG_UPDATE_2(DP_VID_TIMING, DP_VID_M_N_GEN_EN, 1, DP_VID_N_MUL, n_multiply); + + REG_UPDATE(DP_PIXEL_FORMAT, + DP_PIXEL_PER_CYCLE_PROCESSING_MODE, + pix_per_cycle); } /* make sure stream is disabled before resetting steer fifo */ -- cgit From 6ed373b0d572cde539a461bf333661cb98595e63 Mon Sep 17 00:00:00 2001 From: Sung Joon Kim Date: Fri, 10 Feb 2023 14:39:49 -0500 Subject: drm/amd/display: Extend Freesync over PCon support for more devices [why] More branch devices are able to support Freesync over PCon so include them in the list of supporting devices. [how] Add more compatible PCon devices in the whitelist for Freesync over Pcon. Reviewed-by: Harry Wentland Acked-by: Qingqing Zhuo Signed-off-by: Sung Joon Kim Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm/amd/display') 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 6fdc2027c2b4..1583157da355 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 @@ -1149,6 +1149,8 @@ static bool dm_is_freesync_pcon_whitelist(const uint32_t branch_dev_id) switch (branch_dev_id) { case DP_BRANCH_DEVICE_ID_0060AD: + case DP_BRANCH_DEVICE_ID_00E04C: + case DP_BRANCH_DEVICE_ID_90CC24: ret_val = true; break; default: -- cgit From 7bd571b274fd15e0e7dc3d79d104f32928010eff Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Fri, 10 Feb 2023 17:46:34 -0500 Subject: drm/amd/display: DAL to program DISPCLK WDIVIDER if PMFW doesn't [Why & How] - If for any reason PMFW fails to set the expected (or valid) DISPCLK WDIVIDER, then DAL will program DENTIST DISPCLK WDIVIDER to correct for this issue Reviewed-by: Samson Tam Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c | 41 ++++++++++++++++------ drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 1 + .../drm/amd/display/dc/dcn321/dcn321_resource.c | 1 + 4 files changed, 34 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c index 61768bf726f8..e686d6610fd4 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c @@ -257,25 +257,24 @@ static void dcn32_update_dppclk_dispclk_freq(struct clk_mgr_internal *clk_mgr, s static void dcn32_update_clocks_update_dentist( struct clk_mgr_internal *clk_mgr, - struct dc_state *context, - uint32_t old_dispclk_khz) + struct dc_state *context) { uint32_t new_disp_divider = 0; - uint32_t old_disp_divider = 0; uint32_t new_dispclk_wdivider = 0; uint32_t old_dispclk_wdivider = 0; uint32_t i; + uint32_t dentist_dispclk_wdivider_readback = 0; + struct dc *dc = clk_mgr->base.ctx->dc; - if (old_dispclk_khz == 0 || clk_mgr->base.clks.dispclk_khz == 0) + if (clk_mgr->base.clks.dispclk_khz == 0) return; new_disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR * clk_mgr->base.dentist_vco_freq_khz / clk_mgr->base.clks.dispclk_khz; - old_disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR - * clk_mgr->base.dentist_vco_freq_khz / old_dispclk_khz; new_dispclk_wdivider = dentist_get_did_from_divider(new_disp_divider); - old_dispclk_wdivider = dentist_get_did_from_divider(old_disp_divider); + REG_GET(DENTIST_DISPCLK_CNTL, + DENTIST_DISPCLK_WDIVIDER, &old_dispclk_wdivider); /* When changing divider to or from 127, some extra programming is required to prevent corruption */ if (old_dispclk_wdivider == 127 && new_dispclk_wdivider != 127) { @@ -314,6 +313,17 @@ static void dcn32_update_clocks_update_dentist( if (clk_mgr->smu_present) dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DISPCLK, khz_to_mhz_ceil(temp_dispclk_khz)); + if (dc->debug.override_dispclk_programming) { + REG_GET(DENTIST_DISPCLK_CNTL, + DENTIST_DISPCLK_WDIVIDER, &dentist_dispclk_wdivider_readback); + + if (dentist_dispclk_wdivider_readback != 126) { + REG_UPDATE(DENTIST_DISPCLK_CNTL, + DENTIST_DISPCLK_WDIVIDER, 126); + REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000); + } + } + for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; struct dccg *dccg = clk_mgr->base.ctx->dc->res_pool->dccg; @@ -341,6 +351,18 @@ static void dcn32_update_clocks_update_dentist( /* do requested DISPCLK updates*/ if (clk_mgr->smu_present) dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DISPCLK, khz_to_mhz_ceil(clk_mgr->base.clks.dispclk_khz)); + + if (dc->debug.override_dispclk_programming) { + REG_GET(DENTIST_DISPCLK_CNTL, + DENTIST_DISPCLK_WDIVIDER, &dentist_dispclk_wdivider_readback); + + if (dentist_dispclk_wdivider_readback > new_dispclk_wdivider) { + REG_UPDATE(DENTIST_DISPCLK_CNTL, + DENTIST_DISPCLK_WDIVIDER, new_dispclk_wdivider); + REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000); + } + } + } static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base, @@ -361,7 +383,6 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base, bool p_state_change_support; bool fclk_p_state_change_support; int total_plane_count; - int old_dispclk_khz = clk_mgr_base->clks.dispclk_khz; if (dc->work_arounds.skip_clock_update) return; @@ -504,13 +525,13 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base, if (dpp_clock_lowered) { /* if clock is being lowered, increase DTO before lowering refclk */ dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); - dcn32_update_clocks_update_dentist(clk_mgr, context, old_dispclk_khz); + dcn32_update_clocks_update_dentist(clk_mgr, context); if (clk_mgr->smu_present) dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DPPCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dppclk_khz)); } else { /* if clock is being raised, increase refclk before lowering DTO */ if (update_dppclk || update_dispclk) - dcn32_update_clocks_update_dentist(clk_mgr, context, old_dispclk_khz); + dcn32_update_clocks_update_dentist(clk_mgr, context); /* There is a check inside dcn20_update_clocks_update_dpp_dto which ensures * that we do not lower dto when it is not safe to lower. We do not need to * compare the current and new dppclk before calling this function. diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 1fde43378689..8a62f3e93e35 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -874,6 +874,7 @@ struct dc_debug_options { bool disable_unbounded_requesting; bool dig_fifo_off_in_blank; bool temp_mst_deallocation_sequence; + bool override_dispclk_programming; }; struct gpu_info_soc_bounding_box_v1_0; diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index e997bb98b43d..87f7669e81d7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -726,6 +726,7 @@ static const struct dc_debug_options debug_defaults_drv = { .alloc_extra_way_for_cursor = true, .min_prefetch_in_strobe_ns = 60000, // 60us .disable_unbounded_requesting = false, + .override_dispclk_programming = true, }; static const struct dc_debug_options debug_defaults_diags = { 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 55f918b44077..deaa4769be10 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c @@ -724,6 +724,7 @@ static const struct dc_debug_options debug_defaults_drv = { .alloc_extra_way_for_cursor = true, .min_prefetch_in_strobe_ns = 60000, // 60us .disable_unbounded_requesting = false, + .override_dispclk_programming = true, }; static const struct dc_debug_options debug_defaults_diags = { -- cgit From 627441f5a56e2ee119baf340b394cf4ec9c94251 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Sat, 11 Feb 2023 12:56:23 -0500 Subject: Revert "drm/amd/display: Fix FreeSync active bit issue" This reverts commit 6cfb6df2d645c00513ecf17832928e08979fa953. [Why & How] Original change causes black screen. Revert until fix is available. Reviewed-by: Aric Cyr Acked-by: Qingqing Zhuo Signed-off-by: Aric Cyr Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index 2be45b314922..315da61ee897 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -955,26 +955,20 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync, * Check if Freesync is supported. Return if false. If true, * set the corresponding bit in the info packet */ - bool freesync_on_desktop; - bool fams_enable; - - fams_enable = stream->ctx->dc->current_state->bw_ctx.bw.dcn.clk.fw_based_mclk_switching; - freesync_on_desktop = stream->freesync_on_desktop && fams_enable; - if (!vrr->send_info_frame) return; switch (packet_type) { case PACKET_TYPE_FS_V3: - build_vrr_infopacket_v3(stream->signal, vrr, app_tf, infopacket, freesync_on_desktop); + build_vrr_infopacket_v3(stream->signal, vrr, app_tf, infopacket, stream->freesync_on_desktop); break; case PACKET_TYPE_FS_V2: - build_vrr_infopacket_v2(stream->signal, vrr, app_tf, infopacket, freesync_on_desktop); + build_vrr_infopacket_v2(stream->signal, vrr, app_tf, infopacket, stream->freesync_on_desktop); break; case PACKET_TYPE_VRR: case PACKET_TYPE_FS_V1: default: - build_vrr_infopacket_v1(stream->signal, vrr, infopacket, freesync_on_desktop); + build_vrr_infopacket_v1(stream->signal, vrr, infopacket, stream->freesync_on_desktop); } if (true == pack_sdp_v1_3 && -- cgit From 1099238b966e9b291fca40d908d6a016ce758455 Mon Sep 17 00:00:00 2001 From: Mustapha Ghaddar Date: Mon, 13 Feb 2023 08:07:17 -0500 Subject: drm/amd/display: Update BW ALLOCATION Function declaration [WHY & HOW] Update the declaration to give a better idea of what the function does. Reviewed-by: Wenjing Liu Acked-by: Qingqing Zhuo Signed-off-by: Mustapha Ghaddar Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_link.h | 6 +++--- drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index bfe0f6877d9e..80e18c770cda 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -549,8 +549,8 @@ void dc_link_edp_panel_backlight_power_on(struct dc_link *link, 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 + * Handle function for when the status of the Request above is complete. + * We will find out the result of allocating on CM and update structs. * * @link: pointer to the dc_link struct instance * @bw: Allocated or Estimated BW depending on the result @@ -558,7 +558,7 @@ void dc_link_set_usb4_req_bw_req(struct dc_link *link, int req_bw); * * return: none */ -void dc_link_get_usb4_req_bw_resp(struct dc_link *link, uint8_t bw, uint8_t result); +void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result); /* * Handle the USB4 BW Allocation related functionality here: diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index 9d3df69fc340..72ff0ae44d01 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -300,7 +300,7 @@ bool link_dp_dpia_set_dptx_usb4_bw_alloc_support(struct dc_link *link) out: return ret; } -void dc_link_get_usb4_req_bw_resp(struct dc_link *link, uint8_t bw, uint8_t result) +void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result) { if (!get_bw_alloc_proceed_flag((link))) return; -- cgit From 7ae1dbe6547c39410d82156c96eaa9c8cf55e87a Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Mon, 6 Feb 2023 17:58:52 -0500 Subject: drm/amd/display: merge dc_link.h into dc.h and dc_types.h [why] Remove the need to include dc_link.h separately. dc.h should contain everything needed on DM side. [How] Merge dc_link.h into dc.h and dc_types.h so DM only needs to include dc.h to use all link public functions. Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Wenjing Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 2 +- drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 4 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 156 +----- .../gpu/drm/amd/display/dc/core/dc_link_exports.c | 87 ++++ drivers/gpu/drm/amd/display/dc/dc.h | 553 ++++++++++++++++++++- drivers/gpu/drm/amd/display/dc/dc_dp_types.h | 107 ++++ drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 14 + drivers/gpu/drm/amd/display/dc/dc_types.h | 104 ++++ drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c | 2 +- drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h | 5 +- .../amd/display/dc/dce110/dce110_hw_sequencer.c | 2 +- .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- .../display/dc/dcn30/dcn30_dio_stream_encoder.c | 1 + drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 2 +- .../display/dc/dcn31/dcn31_hpo_dp_link_encoder.c | 1 - .../display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c | 2 +- .../display/dc/dcn32/dcn32_hpo_dp_link_encoder.c | 1 - drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 2 +- .../amd/display/dc/dml/dcn30/display_mode_vba_30.c | 1 - .../amd/display/dc/dml/dcn31/display_mode_vba_31.c | 1 - .../display/dc/dml/dcn314/display_mode_vba_314.c | 1 - .../amd/display/dc/dml/dcn32/display_mode_vba_32.c | 1 - drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h | 14 - .../gpu/drm/amd/display/dc/inc/hw/link_encoder.h | 52 -- .../gpu/drm/amd/display/dc/inc/hw/stream_encoder.h | 1 - drivers/gpu/drm/amd/display/dc/inc/link.h | 1 - .../amd/display/dc/link/accessories/link_dp_cts.c | 17 - .../gpu/drm/amd/display/dc/link/link_detection.c | 99 ++++ .../amd/display/dc/link/protocols/link_dp_dpia.c | 1 - .../display/dc/link/protocols/link_dp_dpia_bw.c | 1 - .../dc/link/protocols/link_dp_training_dpia.c | 1 - .../drm/amd/display/include/link_service_types.h | 26 - 33 files changed, 978 insertions(+), 288 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 cfbde4fde852..824cfc4a0293 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2273,7 +2273,7 @@ static int dm_late_init(void *handle) struct dc_link *edp_links[MAX_NUM_EDP]; int edp_num; - get_edp_links(adev->dm.dc, edp_links, &edp_num); + dc_get_edp_links(adev->dm.dc, edp_links, &edp_num); for (i = 0; i < edp_num; i++) { if (!dmub_init_abm_config(adev->dm.dc->res_pool, params, i)) return -EINVAL; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 09a3efa517da..4a5dae578d97 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -724,7 +724,7 @@ static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __us for (i = 0; i < (unsigned int)(link_training_settings.link_settings.lane_count); i++) link_training_settings.hw_lane_settings[i] = link->cur_lane_setting[i]; - dc_link_set_test_pattern( + dc_link_dp_set_test_pattern( link, test_pattern, DP_TEST_PATTERN_COLOR_SPACE_RGB, diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c index 69691daf4dbb..73a45ec27f90 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c @@ -104,7 +104,7 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m int edp_num; unsigned int panel_inst; - get_edp_links(dc, edp_links, &edp_num); + dc_get_edp_links(dc, edp_links, &edp_num); if (dc->hwss.exit_optimized_pwr_state) dc->hwss.exit_optimized_pwr_state(dc, dc->current_state); @@ -129,7 +129,7 @@ void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr) int edp_num; unsigned int panel_inst; - get_edp_links(dc, edp_links, &edp_num); + dc_get_edp_links(dc, edp_links, &edp_num); if (edp_num) { for (panel_inst = 0; panel_inst < edp_num; panel_inst++) { edp_link = edp_links[panel_inst]; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 1c218c526650..d406d7b74c6c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -53,7 +53,6 @@ #include "link_encoder.h" #include "link_enc_cfg.h" -#include "dc_link.h" #include "link.h" #include "dm_helpers.h" #include "mem_input.h" @@ -1298,7 +1297,7 @@ static void detect_edp_presence(struct dc *dc) int i; int edp_num; - get_edp_links(dc, edp_links, &edp_num); + dc_get_edp_links(dc, edp_links, &edp_num); if (!edp_num) return; @@ -4317,157 +4316,6 @@ bool dc_is_dmcu_initialized(struct dc *dc) return false; } -bool dc_is_oem_i2c_device_present( - struct dc *dc, - size_t slave_address) -{ - if (dc->res_pool->oem_device) - return dce_i2c_oem_device_present( - dc->res_pool, - dc->res_pool->oem_device, - slave_address); - - return false; -} - -bool dc_submit_i2c( - struct dc *dc, - uint32_t link_index, - struct i2c_command *cmd) -{ - - struct dc_link *link = dc->links[link_index]; - struct ddc_service *ddc = link->ddc; - return dce_i2c_submit_command( - dc->res_pool, - ddc->ddc_pin, - cmd); -} - -bool dc_submit_i2c_oem( - struct dc *dc, - struct i2c_command *cmd) -{ - struct ddc_service *ddc = dc->res_pool->oem_device; - if (ddc) - return dce_i2c_submit_command( - dc->res_pool, - ddc->ddc_pin, - cmd); - - return false; -} - -static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink) -{ - if (dc_link->sink_count >= MAX_SINKS_PER_LINK) { - BREAK_TO_DEBUGGER(); - return false; - } - - dc_sink_retain(sink); - - dc_link->remote_sinks[dc_link->sink_count] = sink; - dc_link->sink_count++; - - return true; -} - -/* - * dc_link_add_remote_sink() - Create a sink and attach it to an existing link - * - * EDID length is in bytes - */ -struct dc_sink *dc_link_add_remote_sink( - struct dc_link *link, - const uint8_t *edid, - int len, - struct dc_sink_init_data *init_data) -{ - struct dc_sink *dc_sink; - enum dc_edid_status edid_status; - - if (len > DC_MAX_EDID_BUFFER_SIZE) { - dm_error("Max EDID buffer size breached!\n"); - return NULL; - } - - if (!init_data) { - BREAK_TO_DEBUGGER(); - return NULL; - } - - if (!init_data->link) { - BREAK_TO_DEBUGGER(); - return NULL; - } - - dc_sink = dc_sink_create(init_data); - - if (!dc_sink) - return NULL; - - memmove(dc_sink->dc_edid.raw_edid, edid, len); - dc_sink->dc_edid.length = len; - - if (!link_add_remote_sink_helper( - link, - dc_sink)) - goto fail_add_sink; - - edid_status = dm_helpers_parse_edid_caps( - link, - &dc_sink->dc_edid, - &dc_sink->edid_caps); - - /* - * Treat device as no EDID device if EDID - * parsing fails - */ - if (edid_status != EDID_OK && edid_status != EDID_PARTIAL_VALID) { - dc_sink->dc_edid.length = 0; - dm_error("Bad EDID, status%d!\n", edid_status); - } - - return dc_sink; - -fail_add_sink: - dc_sink_release(dc_sink); - return NULL; -} - -/* - * dc_link_remove_remote_sink() - Remove a remote sink from a dc_link - * - * Note that this just removes the struct dc_sink - it doesn't - * program hardware or alter other members of dc_link - */ -void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink) -{ - int i; - - if (!link->sink_count) { - BREAK_TO_DEBUGGER(); - return; - } - - for (i = 0; i < link->sink_count; i++) { - if (link->remote_sinks[i] == sink) { - dc_sink_release(sink); - link->remote_sinks[i] = NULL; - - /* shrink array to remove empty place */ - while (i < link->sink_count - 1) { - link->remote_sinks[i] = link->remote_sinks[i+1]; - i++; - } - link->remote_sinks[i] = NULL; - link->sink_count--; - return; - } - } -} - void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info) { info->displayClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dispclk_khz; @@ -4990,7 +4838,7 @@ void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bo return; } - get_edp_links(dc, edp_links, &edp_num); + dc_get_edp_links(dc, edp_links, &edp_num); /* Determine panel inst */ for (i = 0; i < edp_num; i++) { diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c index a951e10416ee..862cb0f93b7d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c @@ -34,6 +34,49 @@ * in this file which calls link functions. */ #include "link.h" +#include "dce/dce_i2c.h" +struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index) +{ + return dc->links[link_index]; +} + +void dc_get_edp_links(const struct dc *dc, + struct dc_link **edp_links, + int *edp_num) +{ + int i; + + *edp_num = 0; + for (i = 0; i < dc->link_count; i++) { + // report any eDP links, even unconnected DDI's + if (!dc->links[i]) + continue; + if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) { + edp_links[*edp_num] = dc->links[i]; + if (++(*edp_num) == MAX_NUM_EDP) + return; + } + } +} + +bool dc_get_edp_link_panel_inst(const struct dc *dc, + const struct dc_link *link, + unsigned int *inst_out) +{ + struct dc_link *edp_links[MAX_NUM_EDP]; + int edp_num, i; + + *inst_out = 0; + if (link->connector_signal != SIGNAL_TYPE_EDP) + return false; + dc_get_edp_links(dc, edp_links, &edp_num); + for (i = 0; i < edp_num; i++) { + if (link == edp_links[i]) + break; + (*inst_out)++; + } + return true; +} bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) { @@ -101,3 +144,47 @@ bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx) { return link_update_dsc_config(pipe_ctx); } + +bool dc_is_oem_i2c_device_present( + struct dc *dc, + size_t slave_address) +{ + if (dc->res_pool->oem_device) + return dce_i2c_oem_device_present( + dc->res_pool, + dc->res_pool->oem_device, + slave_address); + + return false; +} + +bool dc_submit_i2c( + struct dc *dc, + uint32_t link_index, + struct i2c_command *cmd) +{ + + struct dc_link *link = dc->links[link_index]; + struct ddc_service *ddc = link->ddc; + + return dce_i2c_submit_command( + dc->res_pool, + ddc->ddc_pin, + cmd); +} + +bool dc_submit_i2c_oem( + struct dc *dc, + struct i2c_command *cmd) +{ + struct ddc_service *ddc = dc->res_pool->oem_device; + + if (ddc) + return dce_i2c_submit_command( + dc->res_pool, + ddc->ddc_pin, + cmd); + + return false; +} + diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 8a62f3e93e35..c84554933dc2 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1380,8 +1380,159 @@ struct dc_plane_state *dc_get_surface_for_mpcc(struct dc *dc, uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane); /* Link Interfaces */ -/* TODO: remove this after resolving external dependencies */ -#include "dc_link.h" +/* + * A link contains one or more sinks and their connected status. + * The currently active signal type (HDMI, DP-SST, DP-MST) is also reported. + */ +struct dc_link { + struct dc_sink *remote_sinks[MAX_SINKS_PER_LINK]; + unsigned int sink_count; + struct dc_sink *local_sink; + unsigned int link_index; + enum dc_connection_type type; + enum signal_type connector_signal; + enum dc_irq_source irq_source_hpd; + enum dc_irq_source irq_source_hpd_rx;/* aka DP Short Pulse */ + + bool is_hpd_filter_disabled; + bool dp_ss_off; + + /** + * @link_state_valid: + * + * If there is no link and local sink, this variable should be set to + * false. Otherwise, it should be set to true; usually, the function + * core_link_enable_stream sets this field to true. + */ + bool link_state_valid; + bool aux_access_disabled; + bool sync_lt_in_progress; + bool skip_stream_reenable; + bool is_internal_display; + /** @todo Rename. Flag an endpoint as having a programmable mapping to a DIG encoder. */ + bool is_dig_mapping_flexible; + bool hpd_status; /* HPD status of link without physical HPD pin. */ + bool is_hpd_pending; /* Indicates a new received hpd */ + bool is_automated; /* Indicates automated testing */ + + bool edp_sink_present; + + struct dp_trace dp_trace; + + /* caps is the same as reported_link_cap. link_traing use + * reported_link_cap. Will clean up. TODO + */ + struct dc_link_settings reported_link_cap; + struct dc_link_settings verified_link_cap; + struct dc_link_settings cur_link_settings; + struct dc_lane_settings cur_lane_setting[LANE_COUNT_DP_MAX]; + struct dc_link_settings preferred_link_setting; + /* preferred_training_settings are override values that + * come from DM. DM is responsible for the memory + * management of the override pointers. + */ + struct dc_link_training_overrides preferred_training_settings; + struct dp_audio_test_data audio_test_data; + + uint8_t ddc_hw_inst; + + uint8_t hpd_src; + + uint8_t link_enc_hw_inst; + /* DIG link encoder ID. Used as index in link encoder resource pool. + * For links with fixed mapping to DIG, this is not changed after dc_link + * object creation. + */ + enum engine_id eng_id; + + bool test_pattern_enabled; + union compliance_test_state compliance_test_state; + + void *priv; + + struct ddc_service *ddc; + + bool aux_mode; + + /* Private to DC core */ + + const struct dc *dc; + + struct dc_context *ctx; + + struct panel_cntl *panel_cntl; + struct link_encoder *link_enc; + struct graphics_object_id link_id; + /* Endpoint type distinguishes display endpoints which do not have entries + * in the BIOS connector table from those that do. Helps when tracking link + * encoder to display endpoint assignments. + */ + enum display_endpoint_type ep_type; + union ddi_channel_mapping ddi_channel_mapping; + struct connector_device_tag_info device_tag; + struct dpcd_caps dpcd_caps; + uint32_t dongle_max_pix_clk; + unsigned short chip_caps; + unsigned int dpcd_sink_count; +#if defined(CONFIG_DRM_AMD_DC_HDCP) + struct hdcp_caps hdcp_caps; +#endif + enum edp_revision edp_revision; + union dpcd_sink_ext_caps dpcd_sink_ext_caps; + + struct psr_settings psr_settings; + + /* Drive settings read from integrated info table */ + struct dc_lane_settings bios_forced_drive_settings; + + /* Vendor specific LTTPR workaround variables */ + uint8_t vendor_specific_lttpr_link_rate_wa; + bool apply_vendor_specific_lttpr_link_rate_wa; + + /* MST record stream using this link */ + struct link_flags { + bool dp_keep_receiver_powered; + bool dp_skip_DID2; + bool dp_skip_reset_segment; + bool dp_skip_fs_144hz; + bool dp_mot_reset_segment; + /* Some USB4 docks do not handle turning off MST DSC once it has been enabled. */ + bool dpia_mst_dsc_always_on; + /* Forced DPIA into TBT3 compatibility mode. */ + bool dpia_forced_tbt3_mode; + bool dongle_mode_timing_override; + } wa_flags; + struct link_mst_stream_allocation_table mst_stream_alloc_table; + + struct dc_link_status link_status; + struct dprx_states dprx_states; + + struct gpio *hpd_gpio; + enum dc_link_fec_state fec_state; + bool link_powered_externally; // Used to bypass hardware sequencing delays when panel is powered down forcibly + + struct dc_panel_config panel_config; + struct phy_state phy_state; + // BW ALLOCATON USB4 ONLY + struct dc_dpia_bw_alloc dpia_bw_alloc_config; +}; + +/* Return an enumerated dc_link. + * dc_link order is constant and determined at + * boot time. They cannot be created or destroyed. + * Use dc_get_caps() to get number of links. + */ +struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index); + +/* Return instance id of the edp link. Inst 0 is primary edp link. */ +bool dc_get_edp_link_panel_inst(const struct dc *dc, + const struct dc_link *link, + unsigned int *inst_out); + +/* Return an array of link pointers to edp links. */ +void dc_get_edp_links(const struct dc *dc, + struct dc_link **edp_links, + int *edp_num); /* The function initiates detection handshake over the given link. It first * determines if there are display connections over the link. If so it initiates @@ -1405,6 +1556,38 @@ uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane); */ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason); +struct dc_sink_init_data; + +/* When link connection type is dc_connection_mst_branch, remote sink can be + * added to the link. The interface creates a remote sink and associates it with + * current link. The sink will be retained by link until remove remote sink is + * called. + * + * @dc_link - link the remote sink will be added to. + * @edid - byte array of EDID raw data. + * @len - size of the edid in byte + * @init_data - + */ +struct dc_sink *dc_link_add_remote_sink( + struct dc_link *dc_link, + const uint8_t *edid, + int len, + struct dc_sink_init_data *init_data); + +/* Remove remote sink from a link with dc_connection_mst_branch connection type. + * @link - link the sink should be removed from + * @sink - sink to be removed. + */ +void dc_link_remove_remote_sink( + struct dc_link *link, + struct dc_sink *sink); + +/* Enable HPD interrupt handler for a given link */ +void dc_link_enable_hpd(const struct dc_link *link); + +/* Disable HPD interrupt handler for a given link */ +void dc_link_disable_hpd(const struct dc_link *link); + /* determine if there is a sink connected to the link * * @type - dc_connection_single if connected, dc_connection_none otherwise. @@ -1418,15 +1601,119 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason); bool dc_link_detect_connection_type(struct dc_link *link, enum dc_connection_type *type); +/* query current hpd pin value + * return - true HPD is asserted (HPD high), false otherwise (HPD low) + * + */ +bool dc_link_get_hpd_state(struct dc_link *dc_link); + /* Getter for cached link status from given link */ const struct dc_link_status *dc_link_get_status(const struct dc_link *link); +/* enable/disable hardware HPD filter. + * + * @link - The link the HPD pin is associated with. + * @enable = true - enable hardware HPD filter. HPD event will only queued to irq + * handler once after no HPD change has been detected within dc default HPD + * filtering interval since last HPD event. i.e if display keeps toggling hpd + * pulses within default HPD interval, no HPD event will be received until HPD + * toggles have stopped. Then HPD event will be queued to irq handler once after + * dc default HPD filtering interval since last HPD event. + * + * @enable = false - disable hardware HPD filter. HPD event will be queued + * immediately to irq handler after no HPD change has been detected within + * IRQ_HPD (aka HPD short pulse) interval (i.e 2ms). + */ +void dc_link_enable_hpd_filter(struct dc_link *link, bool enable); + +/* submit i2c read/write payloads through ddc channel + * @link_index - index to a link with ddc in i2c mode + * @cmd - i2c command structure + * return - true if success, false otherwise. + */ +bool dc_submit_i2c( + struct dc *dc, + uint32_t link_index, + struct i2c_command *cmd); + +/* submit i2c read/write payloads through oem channel + * @link_index - index to a link with ddc in i2c mode + * @cmd - i2c command structure + * return - true if success, false otherwise. + */ +bool dc_submit_i2c_oem( + struct dc *dc, + struct i2c_command *cmd); + +enum aux_return_code_type; +/* Attempt to transfer the given aux payload. This function does not perform + * retries or handle error states. The reply is returned in the payload->reply + * and the result through operation_result. Returns the number of bytes + * transferred,or -1 on a failure. + */ +int dc_link_aux_transfer_raw(struct ddc_service *ddc, + struct aux_payload *payload, + enum aux_return_code_type *operation_result); + +bool dc_is_oem_i2c_device_present( + struct dc *dc, + size_t slave_address +); + #ifdef CONFIG_DRM_AMD_DC_HDCP + /* return true if the connected receiver supports the hdcp version */ bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal); bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal); #endif +/* Notify DC about DP RX Interrupt (aka DP IRQ_HPD). + * + * TODO - When defer_handling is true the function will have a different purpose. + * It no longer does complete hpd rx irq handling. We should create a separate + * interface specifically for this case. + * + * Return: + * true - Downstream port status changed. DM should call DC to do the + * detection. + * false - no change in Downstream port status. No further action required + * from DM. + */ +bool dc_link_handle_hpd_rx_irq(struct dc_link *dc_link, + union hpd_irq_data *hpd_irq_dpcd_data, bool *out_link_loss, + bool defer_handling, bool *has_left_work); +/* handle DP specs define test automation sequence*/ +void dc_link_dp_handle_automated_test(struct dc_link *link); + +/* handle DP Link loss sequence and try to recover RX link loss with best + * effort + */ +void dc_link_dp_handle_link_loss(struct dc_link *link); + +/* Determine if hpd rx irq should be handled or ignored + * return true - hpd rx irq should be handled. + * return false - it is safe to ignore hpd rx irq event + */ +bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link); + +/* Determine if link loss is indicated with a given hpd_irq_dpcd_data. + * @link - link the hpd irq data associated with + * @hpd_irq_dpcd_data - input hpd irq data + * return - true if hpd irq data indicates a link lost + */ +bool dc_link_check_link_loss_status(struct dc_link *link, + union hpd_irq_data *hpd_irq_dpcd_data); + +/* Read hpd rx irq data from a given link + * @link - link where the hpd irq data should be read from + * @irq_data - output hpd irq data + * return - DC_OK if hpd irq data is read successfully, otherwise hpd irq data + * read has failed. + */ +enum dc_status dc_link_dp_read_hpd_rx_irq_data( + struct dc_link *link, + union hpd_irq_data *irq_data); + /* The function clears recorded DP RX states in the link. DM should call this * function when it is resuming from S3 power state to previously connected links. * @@ -1494,6 +1781,268 @@ void dc_restore_link_res_map(const struct dc *dc, uint32_t *map); * interface i.e stream_update->dsc_config */ bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx); + +/* translate a raw link rate data to bandwidth in kbps */ +uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw); + +/* determine the optimal bandwidth given link and required bw. + * @link - current detected link + * @req_bw - requested bandwidth in kbps + * @link_settings - returned most optimal link settings that can fit the + * requested bandwidth + * return - false if link can't support requested bandwidth, true if link + * settings is found. + */ +bool dc_link_decide_edp_link_settings(struct dc_link *link, + struct dc_link_settings *link_settings, + uint32_t req_bw); + +/* return the max dp link settings can be driven by the link without considering + * connected RX device and its capability + */ +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, + struct dc_link_settings *max_link_enc_cap); + +/* determine when the link is driving MST mode, what DP link channel coding + * format will be used. The decision will remain unchanged until next HPD event. + * + * @link - a link with DP RX connection + * return - if stream is committed to this link with MST signal type, type of + * channel coding format dc will choose. + */ +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format( + const struct dc_link *link); + +/* get max dp link settings the link can enable with all things considered. (i.e + * TX/RX/Cable capabilities and dp override policies. + * + * @link - a link with DP RX connection + * return - max dp link settings the link can enable. + * + */ +const struct dc_link_settings *dc_link_get_link_cap(const struct dc_link *link); + +/* Check if a RX (ex. DP sink, MST hub, passive or active dongle) is connected + * to a link with dp connector signal type. + * @link - a link with dp connector signal type + * return - true if connected, false otherwise + */ +bool dc_link_is_dp_sink_present(struct dc_link *link); + +/* Force DP lane settings update to main-link video signal and notify the change + * to DP RX via DPCD. This is a debug interface used for video signal integrity + * tuning purpose. The interface assumes link has already been enabled with DP + * signal. + * + * @lt_settings - a container structure with desired hw_lane_settings + */ +void dc_link_set_drive_settings(struct dc *dc, + struct link_training_settings *lt_settings, + const struct dc_link *link); + +/* Enable a test pattern in Link or PHY layer in an active link for compliance + * test or debugging purpose. The test pattern will remain until next un-plug. + * + * @link - active link with DP signal output enabled. + * @test_pattern - desired test pattern to output. + * NOTE: set to DP_TEST_PATTERN_VIDEO_MODE to disable previous test pattern. + * @test_pattern_color_space - for video test pattern choose a desired color + * space. + * @p_link_settings - For PHY pattern choose a desired link settings + * @p_custom_pattern - some test pattern will require a custom input to + * customize some pattern details. Otherwise keep it to NULL. + * @cust_pattern_size - size of the custom pattern input. + * + */ +bool dc_link_dp_set_test_pattern( + struct dc_link *link, + enum dp_test_pattern test_pattern, + enum dp_test_pattern_color_space test_pattern_color_space, + const struct link_training_settings *p_link_settings, + const unsigned char *p_custom_pattern, + unsigned int cust_pattern_size); + +/* Force DP link settings to always use a specific value until reboot to a + * specific link. If link has already been enabled, the interface will also + * switch to desired link settings immediately. This is a debug interface to + * generic dp issue trouble shooting. + */ +void dc_link_set_preferred_link_settings(struct dc *dc, + struct dc_link_settings *link_setting, + struct dc_link *link); + +/* Force DP link to customize a specific link training behavior by overriding to + * standard DP specs defined protocol. This is a debug interface to trouble shoot + * display specific link training issues or apply some display specific + * workaround in link training. + * + * @link_settings - if not NULL, force preferred link settings to the link. + * @lt_override - a set of override pointers. If any pointer is none NULL, dc + * will apply this particular override in future link training. If NULL is + * passed in, dc resets previous overrides. + * NOTE: DM must keep the memory from override pointers until DM resets preferred + * training settings. + */ +void dc_link_set_preferred_training_settings(struct dc *dc, + struct dc_link_settings *link_setting, + struct dc_link_training_overrides *lt_overrides, + struct dc_link *link, + bool skip_immediate_retrain); + +/* return - true if FEC is supported with connected DP RX, false otherwise */ +bool dc_link_is_fec_supported(const struct dc_link *link); + +/* query FEC enablement policy to determine if FEC will be enabled by dc during + * link enablement. + * return - true if FEC should be enabled, false otherwise. + */ +bool dc_link_should_enable_fec(const struct dc_link *link); + +/* determine lttpr mode the current link should be enabled with a specific link + * settings. + */ +enum lttpr_mode dc_link_decide_lttpr_mode(struct dc_link *link, + struct dc_link_settings *link_setting); + +/* Force DP RX to update its power state. + * NOTE: this interface doesn't update dp main-link. Calling this function will + * cause DP TX main-link and DP RX power states out of sync. DM has to restore + * RX power state back upon finish DM specific execution requiring DP RX in a + * specific power state. + * @on - true to set DP RX in D0 power state, false to set DP RX in D3 power + * state. + */ +void dc_link_dp_receiver_power_ctrl(struct dc_link *link, bool on); + +/* Force link to read base dp receiver caps from dpcd 000h - 00Fh and overwrite + * current value read from extended receiver cap from 02200h - 0220Fh. + * Some DP RX has problems of providing accurate DP receiver caps from extended + * field, this interface is a workaround to revert link back to use base caps. + */ +void dc_link_overwrite_extended_receiver_cap( + struct dc_link *link); + +void dc_link_edp_panel_backlight_power_on(struct dc_link *link, + bool wait_for_hpd); + +/* Set backlight level of an embedded panel (eDP, LVDS). + * backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer + * and 16 bit fractional, where 1.0 is max backlight value. + */ +bool dc_link_set_backlight_level(const struct dc_link *dc_link, + uint32_t backlight_pwm_u16_16, + uint32_t frame_ramp); + +/* Set/get nits-based backlight level of an embedded panel (eDP, LVDS). */ +bool dc_link_set_backlight_level_nits(struct dc_link *link, + bool isHDR, + uint32_t backlight_millinits, + uint32_t transition_time_in_ms); + +bool dc_link_get_backlight_level_nits(struct dc_link *link, + uint32_t *backlight_millinits, + uint32_t *backlight_millinits_peak); + +int dc_link_get_backlight_level(const struct dc_link *dc_link); + +int dc_link_get_target_backlight_pwm(const struct dc_link *link); + +bool dc_link_set_psr_allow_active(struct dc_link *dc_link, const bool *enable, + bool wait, bool force_static, const unsigned int *power_opts); + +bool dc_link_get_psr_state(const struct dc_link *dc_link, enum dc_psr_state *state); + +bool dc_link_setup_psr(struct dc_link *dc_link, + const struct dc_stream_state *stream, struct psr_config *psr_config, + struct psr_context *psr_context); + +/* On eDP links this function call will stall until T12 has elapsed. + * If the panel is not in power off state, this function will return + * immediately. + */ +bool dc_link_wait_for_t12(struct dc_link *link); + +/* Determine if dp trace has been initialized to reflect upto date result * + * return - true if trace is initialized and has valid data. False dp trace + * doesn't have valid result. + */ +bool dc_dp_trace_is_initialized(struct dc_link *link); + +/* Query a dp trace flag to indicate if the current dp trace data has been + * logged before + */ +bool dc_dp_trace_is_logged(struct dc_link *link, + bool in_detection); + +/* Set dp trace flag to indicate whether DM has already logged the current dp + * trace data. DM can set is_logged to true upon logging and check + * dc_dp_trace_is_logged before logging to avoid logging the same result twice. + */ +void dc_dp_trace_set_is_logged_flag(struct dc_link *link, + bool in_detection, + bool is_logged); + +/* Obtain driver time stamp for last dp link training end. The time stamp is + * formatted based on dm_get_timestamp DM function. + * @in_detection - true to get link training end time stamp of last link + * training in detection sequence. false to get link training end time stamp + * of last link training in commit (dpms) sequence + */ +unsigned long long dc_dp_trace_get_lt_end_timestamp(struct dc_link *link, + bool in_detection); + +/* Get how many link training attempts dc has done with latest sequence. + * @in_detection - true to get link training count of last link + * training in detection sequence. false to get link training count of last link + * training in commit (dpms) sequence + */ +struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link, + bool in_detection); + +/* Get how many link loss has happened since last link training attempts */ +unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link); + +/* + * 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); + +/* + * Handle function for when the status of the Request above is complete. + * We will find out the result of allocating on CM and update structs. + * + * @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_handle_usb4_bw_alloc_response(struct dc_link *link, + uint8_t bw, uint8_t result); + +/* + * Handle the USB4 BW Allocation related functionality here: + * Plug => Try to allocate max bw from timing parameters supported by the sink + * Unplug => de-allocate bw + * + * @link: pointer to the dc_link struct instance + * @peak_bw: Peak bw used by the link/sink + * + * return: allocated bw else return 0 + */ +int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link( + struct dc_link *link, int peak_bw); + /* Sink Interfaces - A sink corresponds to a display output device */ struct dc_container_id { diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h index 809a1851f196..4bccce94d83b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h @@ -1261,4 +1261,111 @@ union dpcd_sink_ext_caps { } bits; uint8_t raw; }; + +enum dc_link_fec_state { + dc_link_fec_not_ready, + dc_link_fec_ready, + dc_link_fec_enabled +}; + +union dpcd_psr_configuration { + struct { + unsigned char ENABLE : 1; + unsigned char TRANSMITTER_ACTIVE_IN_PSR : 1; + unsigned char CRC_VERIFICATION : 1; + unsigned char FRAME_CAPTURE_INDICATION : 1; + /* For eDP 1.4, PSR v2*/ + unsigned char LINE_CAPTURE_INDICATION : 1; + /* For eDP 1.4, PSR v2*/ + unsigned char IRQ_HPD_WITH_CRC_ERROR : 1; + unsigned char ENABLE_PSR2 : 1; + unsigned char EARLY_TRANSPORT_ENABLE : 1; + } bits; + unsigned char raw; +}; + +union dpcd_alpm_configuration { + struct { + unsigned char ENABLE : 1; + unsigned char IRQ_HPD_ENABLE : 1; + unsigned char RESERVED : 6; + } bits; + unsigned char raw; +}; + +union dpcd_sink_active_vtotal_control_mode { + struct { + unsigned char ENABLE : 1; + unsigned char RESERVED : 7; + } bits; + unsigned char raw; +}; + +union psr_error_status { + struct { + unsigned char LINK_CRC_ERROR :1; + unsigned char RFB_STORAGE_ERROR :1; + unsigned char VSC_SDP_ERROR :1; + unsigned char RESERVED :5; + } bits; + unsigned char raw; +}; + +union psr_sink_psr_status { + struct { + unsigned char SINK_SELF_REFRESH_STATUS :3; + unsigned char RESERVED :5; + } bits; + unsigned char raw; +}; + +struct edp_trace_power_timestamps { + uint64_t poweroff; + uint64_t poweron; +}; + +struct dp_trace_lt_counts { + unsigned int total; + unsigned int fail; +}; + +enum link_training_result { + LINK_TRAINING_SUCCESS, + LINK_TRAINING_CR_FAIL_LANE0, + LINK_TRAINING_CR_FAIL_LANE1, + LINK_TRAINING_CR_FAIL_LANE23, + /* CR DONE bit is cleared during EQ step */ + LINK_TRAINING_EQ_FAIL_CR, + /* CR DONE bit is cleared but LANE0_CR_DONE is set during EQ step */ + LINK_TRAINING_EQ_FAIL_CR_PARTIAL, + /* other failure during EQ step */ + LINK_TRAINING_EQ_FAIL_EQ, + LINK_TRAINING_LQA_FAIL, + /* one of the CR,EQ or symbol lock is dropped */ + LINK_TRAINING_LINK_LOSS, + /* Abort link training (because sink unplugged) */ + LINK_TRAINING_ABORT, + DP_128b_132b_LT_FAILED, + DP_128b_132b_MAX_LOOP_COUNT_REACHED, + DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT, + DP_128b_132b_CDS_DONE_TIMEOUT, +}; + +struct dp_trace_lt { + struct dp_trace_lt_counts counts; + struct dp_trace_timestamps { + unsigned long long start; + unsigned long long end; + } timestamps; + enum link_training_result result; + bool is_logged; +}; + +struct dp_trace { + struct dp_trace_lt detect_lt_trace; + struct dp_trace_lt commit_lt_trace; + unsigned int link_loss_count; + bool is_initialized; + struct edp_trace_power_timestamps edp_trace_power_timestamps; +}; #endif /* DC_DP_TYPES_H */ 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 cc3d6fb39364..a583a72845fe 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -1085,5 +1085,19 @@ struct tg_color { uint16_t color_b_cb; }; +enum symclk_state { + SYMCLK_OFF_TX_OFF, + SYMCLK_ON_TX_ON, + SYMCLK_ON_TX_OFF, +}; + +struct phy_state { + struct { + uint8_t otg : 1; + uint8_t reserved : 7; + } symclk_ref_cnts; + enum symclk_state symclk_state; +}; + #endif /* DC_HW_TYPES_H */ diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 27d0242d6cbd..f28b8597cc1e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -38,6 +38,7 @@ #include "dc_hw_types.h" #include "dal_types.h" #include "grph_object_defs.h" +#include "grph_object_ctrl_defs.h" #ifdef CONFIG_DRM_AMD_DC_HDCP #include "dm_cp_psp.h" @@ -982,4 +983,107 @@ struct hdcp_caps { union hdcp_bcaps bcaps; }; #endif + +/* DP MST stream allocation (payload bandwidth number) */ +struct link_mst_stream_allocation { + /* DIG front */ + const struct stream_encoder *stream_enc; + /* HPO DP Stream Encoder */ + const struct hpo_dp_stream_encoder *hpo_dp_stream_enc; + /* associate DRM payload table with DC stream encoder */ + uint8_t vcp_id; + /* number of slots required for the DP stream in transport packet */ + uint8_t slot_count; +}; + +#define MAX_CONTROLLER_NUM 6 + +/* DP MST stream allocation table */ +struct link_mst_stream_allocation_table { + /* number of DP video streams */ + int stream_count; + /* array of stream allocations */ + struct link_mst_stream_allocation stream_allocations[MAX_CONTROLLER_NUM]; +}; + +/* PSR feature flags */ +struct psr_settings { + bool psr_feature_enabled; // PSR is supported by sink + bool psr_allow_active; // PSR is currently active + enum dc_psr_version psr_version; // Internal PSR version, determined based on DPCD + bool psr_vtotal_control_support; // Vtotal control is supported by sink + unsigned long long psr_dirty_rects_change_timestamp_ns; // for delay of enabling PSR-SU + + /* These parameters are calculated in Driver, + * based on display timing and Sink capabilities. + * If VBLANK region is too small and Sink takes a long time + * to set up RFB, it may take an extra frame to enter PSR state. + */ + bool psr_frame_capture_indication_req; + unsigned int psr_sdp_transmit_line_num_deadline; + uint8_t force_ffu_mode; + unsigned int psr_power_opt; +}; + +/* To split out "global" and "per-panel" config settings. + * Add a struct dc_panel_config under dc_link + */ +struct dc_panel_config { + /* extra panel power sequence parameters */ + struct pps { + unsigned int extra_t3_ms; + unsigned int extra_t7_ms; + unsigned int extra_delay_backlight_off; + unsigned int extra_post_t7_ms; + unsigned int extra_pre_t11_ms; + unsigned int extra_t12_ms; + unsigned int extra_post_OUI_ms; + } pps; + /* nit brightness */ + struct nits_brightness { + unsigned int peak; /* nits */ + unsigned int max_avg; /* nits */ + unsigned int min; /* 1/10000 nits */ + unsigned int max_nonboost_brightness_millinits; + unsigned int min_brightness_millinits; + } nits_brightness; + /* PSR */ + struct psr { + bool disable_psr; + bool disallow_psrsu; + bool rc_disable; + bool rc_allow_static_screen; + bool rc_allow_fullscreen_VPB; + } psr; + /* ABM */ + struct varib { + unsigned int varibright_feature_enable; + unsigned int def_varibright_level; + unsigned int abm_config_setting; + } varib; + /* edp DSC */ + struct dsc { + bool disable_dsc_edp; + unsigned int force_dsc_edp_policy; + } dsc; + /* eDP ILR */ + struct ilr { + bool optimize_edp_link_rate; /* eDP ILR */ + } ilr; +}; + +/* + * USB4 DPIA BW ALLOCATION STRUCTS + */ +struct dc_dpia_bw_alloc { + int sink_verified_bw; // The Verified BW that sink can allocated and use that has been verified already + int sink_allocated_bw; // The Actual Allocated BW that sink currently allocated + int sink_max_bw; // The Max BW that sink can require/support + int estimated_bw; // The estimated available BW for this DPIA + int bw_granularity; // BW Granularity + bool bw_alloc_enabled; // The BW Alloc Mode Support is turned ON for all 3: DP-Tx & Dpia & CM + bool response_ready; // Response ready from the CM side +}; + +#define MAX_SINKS_PER_LINK 4 #endif /* DC_TYPES_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c index fb0dec4ed3a6..9fc48208c2e4 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c @@ -148,7 +148,7 @@ static bool dmub_abm_set_level(struct abm *abm, uint32_t level) int edp_num; uint8_t panel_mask = 0; - get_edp_links(dc->dc, edp_links, &edp_num); + dc_get_edp_links(dc->dc, edp_links, &edp_num); for (i = 0; i < edp_num; i++) { if (edp_links[i]->link_status.link_active) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h index 74005b9d352a..289e42070ece 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h @@ -26,8 +26,9 @@ #ifndef _DMUB_PSR_H_ #define _DMUB_PSR_H_ -#include "os_types.h" -#include "dc_link.h" +#include "dc_types.h" +struct dc_link; +struct dmub_psr_funcs; struct dmub_psr { struct dc_context *ctx; diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 0d4d3d586166..cb3bb5402c52 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1739,7 +1739,7 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) get_edp_links_with_sink(dc, edp_links_with_sink, &edp_with_sink_num); - get_edp_links(dc, edp_links, &edp_num); + dc_get_edp_links(dc, edp_links, &edp_num); if (hws->funcs.init_pipes) hws->funcs.init_pipes(dc, context); 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 a1a29c508394..5b34066ffcf6 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 @@ -1638,7 +1638,7 @@ void dcn10_power_down_on_boot(struct dc *dc) int edp_num; int i = 0; - get_edp_links(dc, edp_links, &edp_num); + dc_get_edp_links(dc, edp_links, &edp_num); if (edp_num) edp_link = edp_links[0]; diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c index 5f9079d3943a..9d08127d209b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c @@ -28,6 +28,7 @@ #include "dcn30_dio_stream_encoder.h" #include "reg_helper.h" #include "hw_shared.h" +#include "dc.h" #include "core_types.h" #include diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index 1d243c549562..f8733ff6970e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -559,7 +559,7 @@ void dcn30_init_hw(struct dc *dc) struct dc_link *edp_links[MAX_NUM_EDP]; struct dc_link *edp_link = NULL; - get_edp_links(dc, edp_links, &edp_num); + dc_get_edp_links(dc, edp_links, &edp_num); if (edp_num) edp_link = edp_links[0]; if (edp_link && edp_link->link_enc->funcs->is_dig_enabled && diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c index 0b317ed31f91..5b7ad38f85e0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c @@ -26,7 +26,6 @@ #include "dc_bios_types.h" #include "dcn31_hpo_dp_link_encoder.h" #include "reg_helper.h" -#include "dc_link.h" #include "stream_encoder.h" #define DC_LOGGER \ diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c index d76f55a12eb4..0278bae50a9d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c @@ -26,7 +26,7 @@ #include "dc_bios_types.h" #include "dcn31_hpo_dp_stream_encoder.h" #include "reg_helper.h" -#include "dc_link.h" +#include "dc.h" #define DC_LOGGER \ enc3->base.ctx->logger diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hpo_dp_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hpo_dp_link_encoder.c index 4dbad8d4b4fc..8af01f579690 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hpo_dp_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hpo_dp_link_encoder.c @@ -26,7 +26,6 @@ #include "dcn31/dcn31_hpo_dp_link_encoder.h" #include "dcn32_hpo_dp_link_encoder.h" #include "reg_helper.h" -#include "dc_link.h" #include "stream_encoder.h" #define DC_LOGGER \ diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index f667f2a6f686..4ba7a10dd7ec 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -837,7 +837,7 @@ void dcn32_init_hw(struct dc *dc) struct dc_link *edp_links[MAX_NUM_EDP]; struct dc_link *edp_link; - get_edp_links(dc, edp_links, &edp_num); + dc_get_edp_links(dc, edp_links, &edp_num); if (edp_num) { for (i = 0; i < edp_num; i++) { edp_link = edp_links[i]; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c index c3d75e56410c..899105da0433 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c @@ -25,7 +25,6 @@ #ifdef CONFIG_DRM_AMD_DC_DCN #include "dc.h" -#include "dc_link.h" #include "../display_mode_lib.h" #include "display_mode_vba_30.h" #include "../dml_inline_defs.h" diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c index 27f488405335..2b57f5b2362a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c @@ -24,7 +24,6 @@ */ #include "dc.h" -#include "dc_link.h" #include "../display_mode_lib.h" #include "../dcn30/display_mode_vba_30.h" #include "display_mode_vba_31.h" 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 c843b394aeb4..461ab6d2030e 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 @@ -27,7 +27,6 @@ #define UNIT_TEST 0 #if !UNIT_TEST #include "dc.h" -#include "dc_link.h" #endif #include "../display_mode_lib.h" #include "display_mode_vba_314.h" diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c index 3b2a014ccf8f..f2499811e269 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c @@ -24,7 +24,6 @@ */ #include "dc.h" -#include "dc_link.h" #include "../display_mode_lib.h" #include "display_mode_vba_32.h" #include "../dml_inline_defs.h" diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h index a819f0f97c5f..b95ae9596c3b 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h @@ -275,20 +275,6 @@ enum dc_lut_mode { LUT_RAM_B }; -enum symclk_state { - SYMCLK_OFF_TX_OFF, - SYMCLK_ON_TX_ON, - SYMCLK_ON_TX_OFF, -}; - -struct phy_state { - struct { - uint8_t otg : 1; - uint8_t reserved : 7; - } symclk_ref_cnts; - enum symclk_state symclk_state; -}; - /** * speakersToChannels * diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h index ec572a9e4054..dbe7afa9d3a2 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h @@ -75,58 +75,6 @@ struct encoder_feature_support { bool fec_supported; }; -union dpcd_psr_configuration { - struct { - unsigned char ENABLE : 1; - unsigned char TRANSMITTER_ACTIVE_IN_PSR : 1; - unsigned char CRC_VERIFICATION : 1; - unsigned char FRAME_CAPTURE_INDICATION : 1; - /* For eDP 1.4, PSR v2*/ - unsigned char LINE_CAPTURE_INDICATION : 1; - /* For eDP 1.4, PSR v2*/ - unsigned char IRQ_HPD_WITH_CRC_ERROR : 1; - unsigned char ENABLE_PSR2 : 1; - /* For eDP 1.5, PSR v2 w/ early transport */ - unsigned char EARLY_TRANSPORT_ENABLE : 1; - } bits; - unsigned char raw; -}; - -union dpcd_alpm_configuration { - struct { - unsigned char ENABLE : 1; - unsigned char IRQ_HPD_ENABLE : 1; - unsigned char RESERVED : 6; - } bits; - unsigned char raw; -}; - -union dpcd_sink_active_vtotal_control_mode { - struct { - unsigned char ENABLE : 1; - unsigned char RESERVED : 7; - } bits; - unsigned char raw; -}; - -union psr_error_status { - struct { - unsigned char LINK_CRC_ERROR :1; - unsigned char RFB_STORAGE_ERROR :1; - unsigned char VSC_SDP_ERROR :1; - unsigned char RESERVED :5; - } bits; - unsigned char raw; -}; - -union psr_sink_psr_status { - struct { - unsigned char SINK_SELF_REFRESH_STATUS :3; - unsigned char RESERVED :5; - } bits; - unsigned char raw; -}; - struct link_encoder { const struct link_encoder_funcs *funcs; int32_t aux_channel_offset; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h index bb5ad70d4266..c4fbbf08ef86 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h @@ -30,7 +30,6 @@ #include "audio_types.h" #include "hw_shared.h" -#include "dc_link.h" struct dc_bios; struct dc_context; diff --git a/drivers/gpu/drm/amd/display/dc/inc/link.h b/drivers/gpu/drm/amd/display/dc/inc/link.h index e70fa0059223..6a346a41f07b 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link.h @@ -38,7 +38,6 @@ * into this file and prefix it with "link_". */ #include "core_types.h" -#include "dc_link.h" struct link_init_data { const struct dc *dc; diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c index 942300e0bd92..7f36d733bfca 100644 --- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c +++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c @@ -1027,20 +1027,3 @@ void dc_link_set_preferred_training_settings(struct dc *dc, if (skip_immediate_retrain == false) dc_link_set_preferred_link_settings(dc, &link->preferred_link_setting, link); } - -void dc_link_set_test_pattern(struct dc_link *link, - enum dp_test_pattern test_pattern, - enum dp_test_pattern_color_space test_pattern_color_space, - const struct link_training_settings *p_link_settings, - const unsigned char *p_custom_pattern, - unsigned int cust_pattern_size) -{ - if (link != NULL) - dc_link_dp_set_test_pattern( - link, - test_pattern, - test_pattern_color_space, - p_link_settings, - p_custom_pattern, - cust_pattern_size); -} diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 5394d8a6087a..393bdefba0ba 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -1321,3 +1321,102 @@ const struct dc_link_status *link_get_status(const struct dc_link *link) return &link->link_status; } + +static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink) +{ + if (dc_link->sink_count >= MAX_SINKS_PER_LINK) { + BREAK_TO_DEBUGGER(); + return false; + } + + dc_sink_retain(sink); + + dc_link->remote_sinks[dc_link->sink_count] = sink; + dc_link->sink_count++; + + return true; +} + +struct dc_sink *dc_link_add_remote_sink( + struct dc_link *link, + const uint8_t *edid, + int len, + struct dc_sink_init_data *init_data) +{ + struct dc_sink *dc_sink; + enum dc_edid_status edid_status; + + if (len > DC_MAX_EDID_BUFFER_SIZE) { + dm_error("Max EDID buffer size breached!\n"); + return NULL; + } + + if (!init_data) { + BREAK_TO_DEBUGGER(); + return NULL; + } + + if (!init_data->link) { + BREAK_TO_DEBUGGER(); + return NULL; + } + + dc_sink = dc_sink_create(init_data); + + if (!dc_sink) + return NULL; + + memmove(dc_sink->dc_edid.raw_edid, edid, len); + dc_sink->dc_edid.length = len; + + if (!link_add_remote_sink_helper( + link, + dc_sink)) + goto fail_add_sink; + + edid_status = dm_helpers_parse_edid_caps( + link, + &dc_sink->dc_edid, + &dc_sink->edid_caps); + + /* + * Treat device as no EDID device if EDID + * parsing fails + */ + if (edid_status != EDID_OK && edid_status != EDID_PARTIAL_VALID) { + dc_sink->dc_edid.length = 0; + dm_error("Bad EDID, status%d!\n", edid_status); + } + + return dc_sink; + +fail_add_sink: + dc_sink_release(dc_sink); + return NULL; +} + +void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink) +{ + int i; + + if (!link->sink_count) { + BREAK_TO_DEBUGGER(); + return; + } + + for (i = 0; i < link->sink_count; i++) { + if (link->remote_sinks[i] == sink) { + dc_sink_release(sink); + link->remote_sinks[i] = NULL; + + /* shrink array to remove empty place */ + while (i < link->sink_count - 1) { + link->remote_sinks[i] = link->remote_sinks[i+1]; + i++; + } + link->remote_sinks[i] = NULL; + link->sink_count--; + return; + } + } +} diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c index 32f48a48e9dd..cbfa9343ffaf 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c @@ -26,7 +26,6 @@ #include "dc.h" #include "inc/core_status.h" -#include "dc_link.h" #include "dpcd_defs.h" #include "link_dp_dpia.h" diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index 72ff0ae44d01..7b32fd010f11 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -27,7 +27,6 @@ // USB4 DPIA BANDWIDTH ALLOCATION LOGIC /*********************************************************************/ #include "dc.h" -#include "dc_link.h" #include "link_dp_dpia_bw.h" #include "drm_dp_helper_dc.h" #include "link_dpcd.h" diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c index 9715fa754d56..7711fda42261 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c @@ -29,7 +29,6 @@ #include "link_dp_training_dpia.h" #include "dc.h" #include "inc/core_status.h" -#include "dc_link.h" #include "dpcd_defs.h" #include "link_dp_dpia.h" diff --git a/drivers/gpu/drm/amd/display/include/link_service_types.h b/drivers/gpu/drm/amd/display/include/link_service_types.h index 18b9173d5a96..cd870af5fd25 100644 --- a/drivers/gpu/drm/amd/display/include/link_service_types.h +++ b/drivers/gpu/drm/amd/display/include/link_service_types.h @@ -34,10 +34,6 @@ struct ddc; struct irq_manager; -enum { - MAX_CONTROLLER_NUM = 6 -}; - enum dp_power_state { DP_POWER_STATE_D0 = 1, DP_POWER_STATE_D3 @@ -60,28 +56,6 @@ enum { DATA_EFFICIENCY_128b_132b_x10000 = 9646, /* 96.71% data efficiency x 99.75% downspread factor */ }; -enum link_training_result { - LINK_TRAINING_SUCCESS, - LINK_TRAINING_CR_FAIL_LANE0, - LINK_TRAINING_CR_FAIL_LANE1, - LINK_TRAINING_CR_FAIL_LANE23, - /* CR DONE bit is cleared during EQ step */ - LINK_TRAINING_EQ_FAIL_CR, - /* CR DONE bit is cleared but LANE0_CR_DONE is set during EQ step */ - LINK_TRAINING_EQ_FAIL_CR_PARTIAL, - /* other failure during EQ step */ - LINK_TRAINING_EQ_FAIL_EQ, - LINK_TRAINING_LQA_FAIL, - /* one of the CR,EQ or symbol lock is dropped */ - LINK_TRAINING_LINK_LOSS, - /* Abort link training (because sink unplugged) */ - LINK_TRAINING_ABORT, - DP_128b_132b_LT_FAILED, - DP_128b_132b_MAX_LOOP_COUNT_REACHED, - DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT, - DP_128b_132b_CDS_DONE_TIMEOUT, -}; - enum lttpr_mode { LTTPR_MODE_UNKNOWN, LTTPR_MODE_NON_LTTPR, -- cgit From 26a9f53198c955b15161da48cdb51041a38d5325 Mon Sep 17 00:00:00 2001 From: Paul Hsieh Date: Fri, 10 Feb 2023 12:00:16 +0800 Subject: drm/amd/display: Correct DML calculation to align HW formula MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Why] In 2560x1440@240p eDP panel, some use cases will enable MPC combine with RGB MPO then underflow happened. This case is not allowed from HW formula.  [How] Correct eDP, DP and DP2 output bpp calculation to align HW formula. Reviewed-by: Nicholas Kazlauskas Acked-by: Qingqing Zhuo Signed-off-by: Paul Hsieh Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/dc/dml/dcn31/display_mode_vba_31.c | 298 ++++++++++++++------- .../display/dc/dml/dcn314/display_mode_vba_314.c | 298 ++++++++++++++------- 2 files changed, 392 insertions(+), 204 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c index 2b57f5b2362a..536a63624595 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c @@ -4307,11 +4307,11 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l v->AudioSampleRate[k], v->AudioSampleLayout[k], v->ODMCombineEnablePerState[i][k]); - } else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp) { + } else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_dp2p0) { if (v->DSCEnable[k] == true) { v->RequiresDSC[i][k] = true; v->LinkDSCEnable = true; - if (v->Output[k] == dm_dp) { + if (v->Output[k] == dm_dp || v->Output[k] == dm_dp2p0) { v->RequiresFEC[i][k] = true; } else { v->RequiresFEC[i][k] = false; @@ -4319,107 +4319,201 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l } else { v->RequiresDSC[i][k] = false; v->LinkDSCEnable = false; - v->RequiresFEC[i][k] = false; - } - - v->Outbpp = BPP_INVALID; - if (v->PHYCLKPerState[i] >= 270.0) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 2700, - v->OutputLinkDPLanes[k], - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - // TODO: Need some other way to handle this nonsense - // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR" - } - if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 5400, - v->OutputLinkDPLanes[k], - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - // TODO: Need some other way to handle this nonsense - // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2" - } - if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 8100, - v->OutputLinkDPLanes[k], - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - // TODO: Need some other way to handle this nonsense - // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3" - } - if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 10000.0 / 18) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 10000, - 4, - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - //v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "10x4"; + if (v->Output[k] == dm_dp2p0) { + v->RequiresFEC[i][k] = true; + } else { + v->RequiresFEC[i][k] = false; + } } - if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 12000.0 / 18) { - v->Outbpp = TruncToValidBPP( - 12000, - 4, - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - //v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "12x4"; + if (v->Output[k] == dm_dp2p0) { + v->Outbpp = BPP_INVALID; + if ((v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr10) && + v->PHYCLKD18PerState[k] >= 10000.0 / 18.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 10000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 13500.0 / 18.0 && + v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) { + v->RequiresDSC[i][k] = true; + v->LinkDSCEnable = true; + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 10000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + } + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR10" + } + if (v->Outbpp == BPP_INVALID && + (v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr13p5) && + v->PHYCLKD18PerState[k] >= 13500.0 / 18.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 13500, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 20000.0 / 18.0 && + v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) { + v->RequiresDSC[i][k] = true; + v->LinkDSCEnable = true; + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 13500, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + } + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR13p5" + } + if (v->Outbpp == BPP_INVALID && + (v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr20) && + v->PHYCLKD18PerState[k] >= 20000.0 / 18.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 20000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + if (v->Outbpp == BPP_INVALID && v->DSCEnable[k] == true && + v->ForcedOutputLinkBPP[k] == 0) { + v->RequiresDSC[i][k] = true; + v->LinkDSCEnable = true; + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 20000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + } + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR20" + } + } else { + v->Outbpp = BPP_INVALID; + if (v->PHYCLKPerState[i] >= 270.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 2700, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR" + } + if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 5400, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2" + } + if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 8100, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3" + } } } } else { 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 461ab6d2030e..daf319370190 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 @@ -4405,11 +4405,11 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_ v->AudioSampleRate[k], v->AudioSampleLayout[k], v->ODMCombineEnablePerState[i][k]); - } else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp) { + } else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_dp2p0) { if (v->DSCEnable[k] == true) { v->RequiresDSC[i][k] = true; v->LinkDSCEnable = true; - if (v->Output[k] == dm_dp) { + if (v->Output[k] == dm_dp || v->Output[k] == dm_dp2p0) { v->RequiresFEC[i][k] = true; } else { v->RequiresFEC[i][k] = false; @@ -4417,107 +4417,201 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_ } else { v->RequiresDSC[i][k] = false; v->LinkDSCEnable = false; - v->RequiresFEC[i][k] = false; - } - - v->Outbpp = BPP_INVALID; - if (v->PHYCLKPerState[i] >= 270.0) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 2700, - v->OutputLinkDPLanes[k], - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - // TODO: Need some other way to handle this nonsense - // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR" - } - if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 5400, - v->OutputLinkDPLanes[k], - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - // TODO: Need some other way to handle this nonsense - // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2" - } - if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 8100, - v->OutputLinkDPLanes[k], - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - // TODO: Need some other way to handle this nonsense - // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3" - } - if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 10000.0 / 18) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 10000, - 4, - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - //v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "10x4"; + if (v->Output[k] == dm_dp2p0) { + v->RequiresFEC[i][k] = true; + } else { + v->RequiresFEC[i][k] = false; + } } - if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 12000.0 / 18) { - v->Outbpp = TruncToValidBPP( - 12000, - 4, - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - //v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "12x4"; + if (v->Output[k] == dm_dp2p0) { + v->Outbpp = BPP_INVALID; + if ((v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr10) && + v->PHYCLKD18PerState[k] >= 10000.0 / 18.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 10000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 13500.0 / 18.0 && + v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) { + v->RequiresDSC[i][k] = true; + v->LinkDSCEnable = true; + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 10000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + } + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR10" + } + if (v->Outbpp == BPP_INVALID && + (v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr13p5) && + v->PHYCLKD18PerState[k] >= 13500.0 / 18.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 13500, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 20000.0 / 18.0 && + v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) { + v->RequiresDSC[i][k] = true; + v->LinkDSCEnable = true; + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 13500, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + } + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR13p5" + } + if (v->Outbpp == BPP_INVALID && + (v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr20) && + v->PHYCLKD18PerState[k] >= 20000.0 / 18.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 20000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + if (v->Outbpp == BPP_INVALID && v->DSCEnable[k] == true && + v->ForcedOutputLinkBPP[k] == 0) { + v->RequiresDSC[i][k] = true; + v->LinkDSCEnable = true; + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 20000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + } + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR20" + } + } else { + v->Outbpp = BPP_INVALID; + if (v->PHYCLKPerState[i] >= 270.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 2700, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR" + } + if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 5400, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2" + } + if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 8100, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3" + } } } } else { -- cgit From b5fefd01e8367763840e032bf1537747905a1447 Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Tue, 14 Feb 2023 14:11:00 -0500 Subject: drm/amd/display: remove empty dc_link.c [why] We kept an empty dc_link.c file due to external build dependency. Now the last build dependency has been removed. We can safely delete this file. Reviewed-by: Rodrigo Siqueira Acked-by: Qingqing Zhuo Signed-off-by: Wenjing Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 drivers/gpu/drm/amd/display/dc/core/dc_link.c (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c deleted file mode 100644 index c26e7258a91c..000000000000 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2012-15 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -// TODO - remove this file after external build dependencies is resolved. -/* NOTE: This file is pending to be removed, do not add new code to this file */ \ No newline at end of file -- cgit From f3f8f16b10f8258f1836e1110099097490a1d6c1 Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Fri, 27 Jan 2023 18:30:08 -0500 Subject: drm/amd/display: enable DPG when disabling plane for phantom pipe [Why] In disable_dangling_plane, for phantom pipes, we enable OTG so disable programming gets the double buffer update. But this causes an underflow to occur. [How] Enable DPG prior to enabling OTG. Reviewed-by: Alvin Lee Acked-by: Qingqing Zhuo Signed-off-by: Samson Tam Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 47 +++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index d406d7b74c6c..d4a1670a5450 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -73,6 +73,8 @@ #include "dc_trace.h" +#include "hw_sequencer_private.h" + #include "dce/dmub_outbox.h" #define CTX \ @@ -1056,6 +1058,44 @@ static void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *contex } } +static void phantom_pipe_blank( + struct dc *dc, + struct timing_generator *tg, + int width, + int height) +{ + struct dce_hwseq *hws = dc->hwseq; + enum dc_color_space color_space; + struct tg_color black_color = {0}; + struct output_pixel_processor *opp = NULL; + uint32_t num_opps, opp_id_src0, opp_id_src1; + uint32_t otg_active_width, otg_active_height; + + /* program opp dpg blank color */ + color_space = COLOR_SPACE_SRGB; + color_space_to_black_color(dc, color_space, &black_color); + + otg_active_width = width; + otg_active_height = height; + + /* get the OPTC source */ + tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1); + ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp); + opp = dc->res_pool->opps[opp_id_src0]; + + opp->funcs->opp_set_disp_pattern_generator( + opp, + CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR, + CONTROLLER_DP_COLOR_SPACE_UDEFINED, + COLOR_DEPTH_UNDEFINED, + &black_color, + otg_active_width, + otg_active_height, + 0); + + hws->funcs.wait_for_blank_complete(opp); +} + static void disable_dangling_plane(struct dc *dc, struct dc_state *context) { int i, j; @@ -1114,8 +1154,13 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) * again for different use. */ if (old_stream->mall_stream_config.type == SUBVP_PHANTOM) { - if (tg->funcs->enable_crtc) + if (tg->funcs->enable_crtc) { + int main_pipe_width, main_pipe_height; + main_pipe_width = old_stream->mall_stream_config.paired_stream->dst.width; + main_pipe_height = old_stream->mall_stream_config.paired_stream->dst.height; + phantom_pipe_blank(dc, tg, main_pipe_width, main_pipe_height); tg->funcs->enable_crtc(tg); + } } dc_rem_all_planes_for_stream(dc, old_stream, dangling_context); disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context); -- cgit From 82a10aff9428f1d190de55ef7971fdb84303cc7a Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Sat, 11 Feb 2023 10:03:22 -0500 Subject: drm/amd/display: Only wait for blank completion if OTG active [why] If OTG is not active, waiting for blank completion will always fail and timeout resulting in unnecessary driver delays. [how] Check that OTG is enabled before waiting for blank. Reviewed-by: Alvin Lee Acked-by: Qingqing Zhuo Signed-off-by: Aric Cyr Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index d4a1670a5450..f07cba121d01 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1093,7 +1093,8 @@ static void phantom_pipe_blank( otg_active_height, 0); - hws->funcs.wait_for_blank_complete(opp); + if (tg->funcs->is_tg_enabled(tg)) + hws->funcs.wait_for_blank_complete(opp); } static void disable_dangling_plane(struct dc *dc, struct dc_state *context) @@ -1156,6 +1157,7 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) if (old_stream->mall_stream_config.type == SUBVP_PHANTOM) { if (tg->funcs->enable_crtc) { int main_pipe_width, main_pipe_height; + main_pipe_width = old_stream->mall_stream_config.paired_stream->dst.width; main_pipe_height = old_stream->mall_stream_config.paired_stream->dst.height; phantom_pipe_blank(dc, tg, main_pipe_width, main_pipe_height); -- cgit From 32953485c558cecf08f33fbfa251e80e44cef981 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Wed, 8 Feb 2023 19:51:42 -0500 Subject: drm/amd/display: Do not update DRR while BW optimizations pending [why] While bandwidth optimizations are pending, it's possible a pstate change will occur. During this time, VSYNC handler should not also try to update DRR parameters causing pstate hang [how] Do not adjust DRR if optimize bandwidth is set. Reviewed-by: Aric Cyr Acked-by: Qingqing Zhuo Signed-off-by: Aric Cyr Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 48 +++++++++++++++++++------------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index f07cba121d01..65b3c3052628 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -400,6 +400,13 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc, { int i; + /* + * Don't adjust DRR while there's bandwidth optimizations pending to + * avoid conflicting with firmware updates. + */ + if (dc->optimized_required || dc->wm_optimized_required) + return false; + stream->adjust.v_total_max = adjust->v_total_max; stream->adjust.v_total_mid = adjust->v_total_mid; stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num; @@ -2180,27 +2187,33 @@ void dc_post_update_surfaces_to_stream(struct dc *dc) post_surface_trace(dc); - if (dc->ctx->dce_version >= DCE_VERSION_MAX) - TRACE_DCN_CLOCK_STATE(&context->bw_ctx.bw.dcn.clk); - else + /* + * Only relevant for DCN behavior where we can guarantee the optimization + * is safe to apply - retain the legacy behavior for DCE. + */ + + if (dc->ctx->dce_version < DCE_VERSION_MAX) TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce); + else { + TRACE_DCN_CLOCK_STATE(&context->bw_ctx.bw.dcn.clk); - if (is_flip_pending_in_pipes(dc, context)) - return; + if (is_flip_pending_in_pipes(dc, context)) + return; - for (i = 0; i < dc->res_pool->pipe_count; i++) - if (context->res_ctx.pipe_ctx[i].stream == NULL || - context->res_ctx.pipe_ctx[i].plane_state == NULL) { - context->res_ctx.pipe_ctx[i].pipe_idx = i; - dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]); - } + for (i = 0; i < dc->res_pool->pipe_count; i++) + if (context->res_ctx.pipe_ctx[i].stream == NULL || + context->res_ctx.pipe_ctx[i].plane_state == NULL) { + context->res_ctx.pipe_ctx[i].pipe_idx = i; + dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]); + } - process_deferred_updates(dc); + process_deferred_updates(dc); - dc->hwss.optimize_bandwidth(dc, context); + dc->hwss.optimize_bandwidth(dc, context); - if (dc->debug.enable_double_buffered_dsc_pg_support) - dc->hwss.update_dsc_pg(dc, context, true); + if (dc->debug.enable_double_buffered_dsc_pg_support) + dc->hwss.update_dsc_pg(dc, context, true); + } dc->optimized_required = false; dc->wm_optimized_required = false; @@ -4169,12 +4182,9 @@ void dc_commit_updates_for_stream(struct dc *dc, if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state) new_pipe->plane_state->force_full_update = true; } - } else if (update_type == UPDATE_TYPE_FAST && dc_ctx->dce_version >= DCE_VERSION_MAX) { + } else if (update_type == UPDATE_TYPE_FAST) { /* * Previous frame finished and HW is ready for optimization. - * - * Only relevant for DCN behavior where we can guarantee the optimization - * is safe to apply - retain the legacy behavior for DCE. */ dc_post_update_surfaces_to_stream(dc); } -- cgit From a03e3cb16dfdf4e39ed4ed80314256f9ba671ff0 Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Tue, 21 Feb 2023 18:35:14 -0500 Subject: drm/amd/display: fix clock sequence logic for DCN32 [Why&How] The newer commit sequence on DCN32 onwards did not finish clock optimization sequence since the newer sequence did not end up calling dc_post_update_surfaces_to_stream() which resets dc->optimized_required. Call this function before passing control on to the new commit sequence. Reviewed-by: Rodrigo Siqueira Acked-by: Qingqing Zhuo Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 65b3c3052628..e3bfc4bb8341 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -4142,24 +4142,30 @@ void dc_commit_updates_for_stream(struct dc *dc, struct dc_context *dc_ctx = dc->ctx; int i, j; + stream_status = dc_stream_get_status(stream); + context = dc->current_state; + + update_type = dc_check_update_surfaces_for_stream( + dc, srf_updates, surface_count, stream_update, stream_status); + /* TODO: Since change commit sequence can have a huge impact, * we decided to only enable it for DCN3x. However, as soon as * we get more confident about this change we'll need to enable * the new sequence for all ASICs. */ if (dc->ctx->dce_version >= DCN_VERSION_3_2) { + /* + * Previous frame finished and HW is ready for optimization. + */ + if (update_type == UPDATE_TYPE_FAST) + dc_post_update_surfaces_to_stream(dc); + dc_update_planes_and_stream(dc, srf_updates, surface_count, stream, stream_update); return; } - stream_status = dc_stream_get_status(stream); - context = dc->current_state; - - update_type = dc_check_update_surfaces_for_stream( - dc, srf_updates, surface_count, stream_update, stream_status); - if (update_type >= update_surface_trace_level) update_surface_trace(dc, srf_updates, surface_count); -- cgit From f4658f43450478240e2e758f0532d19f921f9a69 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Sun, 12 Feb 2023 18:15:18 -0500 Subject: drm/amd/display: Promote DAL to 3.2.224 This version brings along the following: - Correct DML calculation - Extend Freesync over Pcon support - Fixes in pstate hang and more - Code cleanup for dc_link.h and dc_link.c Acked-by: Qingqing Zhuo 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(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index c84554933dc2..36dbe11256ac 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.223" +#define DC_VER "3.2.224" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- cgit From 7a1bb27b6ba8a05b51c1589dd9d53eb43a9e9843 Mon Sep 17 00:00:00 2001 From: Swapnil Patel Date: Wed, 1 Mar 2023 14:33:33 -0500 Subject: drm/amd/display: Update clock table to include highest clock setting [Why] Currently, the clk manager matches SocVoltage with voltage from fused settings (dfPstate clock table). And then corresponding clocks are selected. However in certain situations, this leads to clk manager not including at least one entry with highest supported clock setting. [How] Update the clk manager to include at least one entry with highest supported clock setting. Reviewed-by: Pavle Kotarac Acked-by: Qingqing Zhuo Signed-off-by: Swapnil Patel Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c index 24715ca2fa94..01383aac6b41 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c @@ -529,6 +529,19 @@ static struct clk_bw_params vg_bw_params = { }; +static uint32_t find_max_clk_value(const uint32_t clocks[], uint32_t num_clocks) +{ + uint32_t max = 0; + int i; + + for (i = 0; i < num_clocks; ++i) { + if (clocks[i] > max) + max = clocks[i]; + } + + return max; +} + static unsigned int find_dcfclk_for_voltage(const struct vg_dpm_clocks *clock_table, unsigned int voltage) { @@ -572,12 +585,16 @@ static void vg_clk_mgr_helper_populate_bw_params( bw_params->clk_table.num_entries = j + 1; - for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) { + for (i = 0; i < bw_params->clk_table.num_entries - 1; i++, j--) { bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].fclk; bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].memclk; bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].voltage; bw_params->clk_table.entries[i].dcfclk_mhz = find_dcfclk_for_voltage(clock_table, clock_table->DfPstateTable[j].voltage); } + bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].fclk; + bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].memclk; + bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].voltage; + bw_params->clk_table.entries[i].dcfclk_mhz = find_max_clk_value(clock_table->DcfClocks, VG_NUM_DCFCLK_DPM_LEVELS); bw_params->vram_type = bios_info->memory_type; bw_params->num_channels = bios_info->ma_channel_number; -- cgit From 7bb3956178e5eaeeab5134cf38e0f057bc2344c2 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Sun, 15 Jan 2023 15:30:38 +0530 Subject: drm/amd/display: Simplify same effect if/else blocks The if / else block code has same effect irrespective of the logical evaluation. Hence, simply the implementation by removing the unnecessary conditional evaluation. While at it, also fix the long line checkpatch complaint. Issue identified using cond_no_effect.cocci Coccinelle semantic patch script. Fixes: 9114b55fabae ("drm/amd/display: Fix SubVP control flow in the MPO context") Reviewed-by: Harry Wentland Signed-off-by: Deepak R Varma Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index e3bfc4bb8341..9b821d78aaaa 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -3569,14 +3569,9 @@ static void commit_planes_for_stream(struct dc *dc, /* Since phantom pipe programming is moved to post_unlock_program_front_end, * move the SubVP lock to after the phantom pipes have been setup */ - if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) { - if (dc->hwss.subvp_pipe_control_lock) - dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use); - } else { - if (dc->hwss.subvp_pipe_control_lock) - dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use); - } - + if (dc->hwss.subvp_pipe_control_lock) + dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, + NULL, subvp_prev_use); return; } -- cgit From de534c1cb0313a070f45938a53b53927cd34e5b9 Mon Sep 17 00:00:00 2001 From: Mike Hsieh Date: Tue, 10 Jan 2023 10:52:03 +0800 Subject: drm/amd/display: Add height granularity limitation for dsc slice height calculation [WHY] eDP add new limitation for Y granularity for selected update feature. DSC does not include this limitation while calculating slice height. [HOW] Add new limitation while looking for DSC slice height. Reviewed-by: Cruise Hung Acked-by: Qingqing Zhuo Signed-off-by: Mike Hsieh Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 +++++++------ .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 16 +++++++---- drivers/gpu/drm/amd/display/dc/dc_dsc.h | 11 ++++++-- drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c | 33 ++++++++++++++-------- 4 files changed, 52 insertions(+), 28 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 824cfc4a0293..7f627ab43a29 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5786,6 +5786,10 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector, struct dc *dc = sink->ctx->dc; struct dc_dsc_bw_range bw_range = {0}; struct dc_dsc_config dsc_cfg = {0}; + struct dc_dsc_config_options dsc_options = {0}; + + dc_dsc_get_default_config_option(dc, &dsc_options); + dsc_options.max_target_bpp_limit_override_x16 = max_dsc_target_bpp_limit_override * 16; verified_link_cap = dc_link_get_link_cap(stream->link); link_bw_in_kbps = dc_link_bandwidth_kbps(stream->link, verified_link_cap); @@ -5808,8 +5812,7 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector, if (bw_range.max_kbps < link_bw_in_kbps) { if (dc_dsc_compute_config(dc->res_pool->dscs[0], dsc_caps, - dc->debug.dsc_min_slice_height_override, - max_dsc_target_bpp_limit_override, + &dsc_options, 0, &stream->timing, &dsc_cfg)) { @@ -5823,8 +5826,7 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector, if (dc_dsc_compute_config(dc->res_pool->dscs[0], dsc_caps, - dc->debug.dsc_min_slice_height_override, - max_dsc_target_bpp_limit_override, + &dsc_options, link_bw_in_kbps, &stream->timing, &dsc_cfg)) { @@ -5845,6 +5847,10 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector, u32 dsc_max_supported_bw_in_kbps; u32 max_dsc_target_bpp_limit_override = drm_connector->display_info.max_dsc_bpp; + struct dc_dsc_config_options dsc_options = {0}; + + dc_dsc_get_default_config_option(dc, &dsc_options); + dsc_options.max_target_bpp_limit_override_x16 = max_dsc_target_bpp_limit_override * 16; link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link, dc_link_get_link_cap(aconnector->dc_link)); @@ -5863,8 +5869,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector, if (sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_NONE) { if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0], dsc_caps, - aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override, - max_dsc_target_bpp_limit_override, + &dsc_options, link_bandwidth_kbps, &stream->timing, &stream->timing.dsc_cfg)) { @@ -5881,8 +5886,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector, dsc_max_supported_bw_in_kbps > 0) if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0], dsc_caps, - aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override, - max_dsc_target_bpp_limit_override, + &dsc_options, dsc_max_supported_bw_in_kbps, &stream->timing, &stream->timing.dsc_cfg)) { 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 e25e1b2bf194..e10ed2935971 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 @@ -678,16 +678,19 @@ static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *p { struct drm_connector *drm_connector; int i; + struct dc_dsc_config_options dsc_options = {0}; for (i = 0; i < count; i++) { drm_connector = ¶ms[i].aconnector->base; + dc_dsc_get_default_config_option(params[i].sink->ctx->dc, &dsc_options); + dsc_options.max_target_bpp_limit_override_x16 = drm_connector->display_info.max_dsc_bpp * 16; + 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, - drm_connector->display_info.max_dsc_bpp, + &dsc_options, 0, params[i].timing, ¶ms[i].timing->dsc_cfg)) { @@ -730,15 +733,16 @@ static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn) 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; + struct dc_dsc_config_options dsc_options = {0}; + + dc_dsc_get_default_config_option(param.sink->ctx->dc, &dsc_options); + dsc_options.max_target_bpp_limit_override_x16 = drm_connector->display_info.max_dsc_bpp * 16; 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, - max_dsc_target_bpp_limit_override, + &dsc_options, (int) kbps, param.timing, &dsc_config); return dsc_config.bits_per_pixel; diff --git a/drivers/gpu/drm/amd/display/dc/dc_dsc.h b/drivers/gpu/drm/amd/display/dc/dc_dsc.h index 684713b2cff7..81e62a630d78 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dsc.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dsc.h @@ -54,6 +54,12 @@ struct dc_dsc_policy { bool enable_dsc_when_not_needed; }; +struct dc_dsc_config_options { + uint32_t dsc_min_slice_height_override; + uint32_t max_target_bpp_limit_override_x16; + uint32_t slight_height_granularity; +}; + bool dc_dsc_parse_dsc_dpcd(const struct dc *dc, const uint8_t *dpcd_dsc_basic_data, const uint8_t *dpcd_dsc_ext_data, @@ -71,8 +77,7 @@ bool dc_dsc_compute_bandwidth_range( bool dc_dsc_compute_config( const struct display_stream_compressor *dsc, const struct dsc_dec_dpcd_caps *dsc_sink_caps, - uint32_t dsc_min_slice_height_override, - uint32_t max_target_bpp_limit_override, + const struct dc_dsc_config_options *options, uint32_t target_bandwidth_kbps, const struct dc_crtc_timing *timing, struct dc_dsc_config *dsc_cfg); @@ -100,4 +105,6 @@ void dc_dsc_policy_set_enable_dsc_when_not_needed(bool enable); void dc_dsc_policy_set_disable_dsc_stream_overhead(bool disable); +void dc_dsc_get_default_config_option(const struct dc *dc, struct dc_dsc_config_options *options); + #endif diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c index d52cbc0e9b67..8b5663853efb 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c @@ -79,8 +79,7 @@ static bool setup_dsc_config( const struct dsc_enc_caps *dsc_enc_caps, int target_bandwidth_kbps, const struct dc_crtc_timing *timing, - int min_slice_height_override, - int max_dsc_target_bpp_limit_override_x16, + const struct dc_dsc_config_options *options, struct dc_dsc_config *dsc_cfg); static bool dsc_buff_block_size_from_dpcd(int dpcd_buff_block_size, int *buff_block_size) @@ -352,6 +351,11 @@ bool dc_dsc_compute_bandwidth_range( struct dsc_enc_caps dsc_enc_caps; struct dsc_enc_caps dsc_common_caps; struct dc_dsc_config config; + struct dc_dsc_config_options options = {0}; + + options.dsc_min_slice_height_override = dsc_min_slice_height_override; + options.max_target_bpp_limit_override_x16 = max_bpp_x16; + options.slight_height_granularity = 1; get_dsc_enc_caps(dsc, &dsc_enc_caps, timing->pix_clk_100hz); @@ -360,7 +364,7 @@ bool dc_dsc_compute_bandwidth_range( if (is_dsc_possible) is_dsc_possible = setup_dsc_config(dsc_sink_caps, &dsc_enc_caps, 0, timing, - dsc_min_slice_height_override, max_bpp_x16, &config); + &options, &config); if (is_dsc_possible) is_dsc_possible = decide_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16, @@ -740,8 +744,7 @@ static bool setup_dsc_config( const struct dsc_enc_caps *dsc_enc_caps, int target_bandwidth_kbps, const struct dc_crtc_timing *timing, - int min_slice_height_override, - int max_dsc_target_bpp_limit_override_x16, + const struct dc_dsc_config_options *options, struct dc_dsc_config *dsc_cfg) { struct dsc_enc_caps dsc_common_caps; @@ -760,7 +763,7 @@ static bool setup_dsc_config( memset(dsc_cfg, 0, sizeof(struct dc_dsc_config)); - dc_dsc_get_policy_for_timing(timing, max_dsc_target_bpp_limit_override_x16, &policy); + dc_dsc_get_policy_for_timing(timing, options->max_target_bpp_limit_override_x16, &policy); pic_width = timing->h_addressable + timing->h_border_left + timing->h_border_right; pic_height = timing->v_addressable + timing->v_border_top + timing->v_border_bottom; @@ -909,12 +912,13 @@ static bool setup_dsc_config( // Slice height (i.e. number of slices per column): start with policy and pick the first one that height is divisible by. // For 4:2:0 make sure the slice height is divisible by 2 as well. - if (min_slice_height_override == 0) + if (options->dsc_min_slice_height_override == 0) slice_height = min(policy.min_slice_height, pic_height); else - slice_height = min(min_slice_height_override, pic_height); + slice_height = min((int)(options->dsc_min_slice_height_override), pic_height); while (slice_height < pic_height && (pic_height % slice_height != 0 || + slice_height % options->slight_height_granularity != 0 || (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 && slice_height % 2 != 0))) slice_height++; @@ -958,8 +962,7 @@ done: bool dc_dsc_compute_config( const struct display_stream_compressor *dsc, const struct dsc_dec_dpcd_caps *dsc_sink_caps, - uint32_t dsc_min_slice_height_override, - uint32_t max_target_bpp_limit_override, + const struct dc_dsc_config_options *options, uint32_t target_bandwidth_kbps, const struct dc_crtc_timing *timing, struct dc_dsc_config *dsc_cfg) @@ -971,8 +974,7 @@ bool dc_dsc_compute_config( is_dsc_possible = setup_dsc_config(dsc_sink_caps, &dsc_enc_caps, target_bandwidth_kbps, - timing, dsc_min_slice_height_override, - max_target_bpp_limit_override * 16, dsc_cfg); + timing, options, dsc_cfg); return is_dsc_possible; } @@ -1104,3 +1106,10 @@ void dc_dsc_policy_set_disable_dsc_stream_overhead(bool disable) { dsc_policy_disable_dsc_stream_overhead = disable; } + +void dc_dsc_get_default_config_option(const struct dc *dc, struct dc_dsc_config_options *options) +{ + options->dsc_min_slice_height_override = dc->debug.dsc_min_slice_height_override; + options->max_target_bpp_limit_override_x16 = 0; + options->slight_height_granularity = 1; +} -- cgit From aee0c07a74d3f79aef553e3bfc6ddf184d33d3bf Mon Sep 17 00:00:00 2001 From: Mustapha Ghaddar Date: Wed, 15 Feb 2023 10:05:53 -0500 Subject: drm/amd/display: Unify DC logging for BW Alloc [WHY] To keep all logging within DC unified [HOW] Use the standard DC Logging functions Reviewed-by: Wenjing Liu Reviewed-by: Meenakshikumar Somasundaram Acked-by: Qingqing Zhuo Signed-off-by: Mustapha Ghaddar Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../display/dc/link/protocols/link_dp_dpia_bw.c | 56 ++++++++++------------ 1 file changed, 26 insertions(+), 30 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index 7b32fd010f11..c950857ef02c 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -31,6 +31,9 @@ #include "drm_dp_helper_dc.h" #include "link_dpcd.h" +#define DC_LOGGER \ + link->ctx->logger + #define Kbps_TO_Gbps (1000 * 1000) // ------------------------------------------------------------------ @@ -83,12 +86,11 @@ static int get_estimated_bw(struct dc_link *link) { uint8_t bw_estimated_bw = 0; - if (core_link_read_dpcd( - link, - ESTIMATED_BW, - &bw_estimated_bw, - sizeof(uint8_t)) != DC_OK) - dm_output_to_console("%s: AUX W/R ERROR @ 0x%x\n", __func__, ESTIMATED_BW); + core_link_read_dpcd( + link, + ESTIMATED_BW, + &bw_estimated_bw, + sizeof(uint8_t)); return bw_estimated_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); } @@ -226,9 +228,7 @@ static void dc_link_set_usb4_req_bw_req(struct dc_link *link, int req_bw) link, REQUESTED_BW, &requested_bw, - sizeof(uint8_t)) != DC_OK) - dm_output_to_console("%s: AUX W/R ERROR @ 0x%x\n", __func__, REQUESTED_BW); - else + sizeof(uint8_t)) == DC_OK) link->dpia_bw_alloc_config.response_ready = false; // Reset flag } /* @@ -256,22 +256,18 @@ bool link_dp_dpia_set_dptx_usb4_bw_alloc_support(struct dc_link *link) goto out; if (core_link_read_dpcd( - link, - DP_TUNNELING_CAPABILITIES, - &response, - sizeof(uint8_t)) != DC_OK) - dm_output_to_console("%s: AUX W/R ERROR @ 0x%x\n", __func__, DP_TUNNELING_CAPABILITIES); - - bw_support_dpia = (response >> 7) & 1; + link, + DP_TUNNELING_CAPABILITIES, + &response, + sizeof(uint8_t)) == DC_OK) + bw_support_dpia = (response >> 7) & 1; if (core_link_read_dpcd( link, USB4_DRIVER_BW_CAPABILITY, &response, - sizeof(uint8_t)) != DC_OK) - dm_output_to_console("%s: AUX W/R ERROR @ 0x%x\n", __func__, DP_TUNNELING_CAPABILITIES); - - bw_support_cm = (response >> 7) & 1; + sizeof(uint8_t)) == DC_OK) + bw_support_cm = (response >> 7) & 1; /* Send request acknowledgment to Turn ON DPTX support */ if (bw_support_cm && bw_support_dpia) { @@ -281,15 +277,15 @@ bool link_dp_dpia_set_dptx_usb4_bw_alloc_support(struct dc_link *link) link, DPTX_BW_ALLOCATION_MODE_CONTROL, &response, - sizeof(uint8_t)) != DC_OK) - dm_output_to_console("%s: AUX W/R ERROR @ 0x%x\n", - "**** FAILURE Enabling DPtx BW Allocation Mode Support ***\n", - __func__, DP_TUNNELING_CAPABILITIES); - else { + sizeof(uint8_t)) != DC_OK) { + DC_LOG_DEBUG("%s: **** FAILURE Enabling DPtx BW Allocation Mode Support ***\n", + __func__); + } else { // SUCCESS Enabled DPtx BW Allocation Mode Support link->dpia_bw_alloc_config.bw_alloc_enabled = true; - dm_output_to_console("**** SUCCESS Enabling DPtx BW Allocation Mode Support ***\n"); + DC_LOG_DEBUG("%s: **** SUCCESS Enabling DPtx BW Allocation Mode Support ***\n", + __func__); ret = true; init_usb4_bw_struct(link); @@ -308,7 +304,7 @@ void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uin case DPIA_BW_REQ_FAILED: - dm_output_to_console("%s: *** *** BW REQ FAILURE for DP-TX Request *** ***\n", __func__); + DC_LOG_DEBUG("%s: *** *** BW REQ FAILURE for DP-TX Request *** ***\n", __func__); // Update the new Estimated BW value updated by CM link->dpia_bw_alloc_config.estimated_bw = @@ -328,7 +324,7 @@ void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uin case DPIA_BW_REQ_SUCCESS: - dm_output_to_console("%s: *** BW REQ SUCCESS for DP-TX Request ***\n", __func__); + DC_LOG_DEBUG("%s: *** BW REQ SUCCESS for DP-TX Request ***\n", __func__); // 1. SUCCESS 1st time before any Pruning is done // 2. SUCCESS after prev. FAIL before any Pruning is done @@ -369,7 +365,7 @@ void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uin case DPIA_EST_BW_CHANGED: - dm_output_to_console("%s: *** ESTIMATED BW CHANGED for DP-TX Request ***\n", __func__); + DC_LOG_DEBUG("%s: *** ESTIMATED BW CHANGED for DP-TX Request ***\n", __func__); int available = 0, estimated = bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); int host_router_total_estimated_bw = get_host_router_total_bw(link, HOST_ROUTER_BW_ESTIMATED); @@ -397,7 +393,7 @@ void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uin case DPIA_BW_ALLOC_CAPS_CHANGED: - dm_output_to_console("%s: *** BW ALLOC CAPABILITY CHANGED for DP-TX Request ***\n", __func__); + DC_LOG_DEBUG("%s: *** BW ALLOC CAPABILITY CHANGED for DP-TX Request ***\n", __func__); link->dpia_bw_alloc_config.bw_alloc_enabled = false; break; } -- cgit From 67d198da2fd493629e498629781edc5695bbf4d9 Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Fri, 17 Feb 2023 17:54:01 -0500 Subject: drm/amd/display: When blanking during init loop to find OPP index [Description] For pipe harvesting cases we cannot rely on array index to get the correct OPP instance, we must loop through each instance to find the correct one. Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 83 ++++++++++++++++++++++ drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h | 4 ++ drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c | 2 +- 3 files changed, 88 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index 4ba7a10dd7ec..f87db2271924 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -1413,3 +1413,86 @@ void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context) } } } + +/* Blank pixel data during initialization */ +void dcn32_init_blank( + struct dc *dc, + struct timing_generator *tg) +{ + struct dce_hwseq *hws = dc->hwseq; + enum dc_color_space color_space; + struct tg_color black_color = {0}; + struct output_pixel_processor *opp = NULL; + struct output_pixel_processor *bottom_opp = NULL; + uint32_t num_opps, opp_id_src0, opp_id_src1; + uint32_t otg_active_width, otg_active_height; + uint32_t i; + + /* program opp dpg blank color */ + color_space = COLOR_SPACE_SRGB; + color_space_to_black_color(dc, color_space, &black_color); + + /* get the OTG active size */ + tg->funcs->get_otg_active_size(tg, + &otg_active_width, + &otg_active_height); + + /* get the OPTC source */ + tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1); + + if (opp_id_src0 >= dc->res_pool->res_cap->num_opp) { + ASSERT(false); + return; + } + + for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) { + if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src0) { + opp = dc->res_pool->opps[i]; + break; + } + } + + if (num_opps == 2) { + otg_active_width = otg_active_width / 2; + + if (opp_id_src1 >= dc->res_pool->res_cap->num_opp) { + ASSERT(false); + return; + } + for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) { + if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src1) { + bottom_opp = dc->res_pool->opps[i]; + break; + } + } + } + + if (opp && opp->funcs->opp_set_disp_pattern_generator) + opp->funcs->opp_set_disp_pattern_generator( + opp, + CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR, + CONTROLLER_DP_COLOR_SPACE_UDEFINED, + COLOR_DEPTH_UNDEFINED, + &black_color, + otg_active_width, + otg_active_height, + 0); + + if (num_opps == 2) { + if (bottom_opp && bottom_opp->funcs->opp_set_disp_pattern_generator) { + bottom_opp->funcs->opp_set_disp_pattern_generator( + bottom_opp, + CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR, + CONTROLLER_DP_COLOR_SPACE_UDEFINED, + COLOR_DEPTH_UNDEFINED, + &black_color, + otg_active_width, + otg_active_height, + 0); + hws->funcs.wait_for_blank_complete(bottom_opp); + } + } + + if (opp) + hws->funcs.wait_for_blank_complete(opp); +} diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h index e9e9534f3668..84c1f36c3fa6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h @@ -104,4 +104,8 @@ void dcn32_update_dsc_pg(struct dc *dc, void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context); +void dcn32_init_blank( + struct dc *dc, + struct timing_generator *tg); + #endif /* __DC_HWSS_DCN32_H__ */ 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 0694fa3a3680..dcb81662884f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c @@ -132,7 +132,7 @@ static const struct hwseq_private_funcs dcn32_private_funcs = { .enable_stream_gating = dcn20_enable_stream_gating, .setup_vupdate_interrupt = dcn20_setup_vupdate_interrupt, .did_underflow_occur = dcn10_did_underflow_occur, - .init_blank = dcn20_init_blank, + .init_blank = dcn32_init_blank, .disable_vga = dcn20_disable_vga, .bios_golden_init = dcn10_bios_golden_init, .plane_atomic_disable = dcn20_plane_atomic_disable, -- cgit From c93aa7f33e94ee9d64277fa2a345dc30c127d798 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Sun, 19 Feb 2023 20:42:43 -0500 Subject: drm/amd/display: 3.2.225 This version brings along the following: - Correct way to find OPP index - Unify DC logging for BW Alloc - Add height granularity limitation for dsc slice height calculation Acked-by: Qingqing Zhuo 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(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 36dbe11256ac..c3814f40a102 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.224" +#define DC_VER "3.2.225" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- cgit From 0db13eae41fcc67f408dbb3dfda59633c4fa03fb Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Fri, 17 Feb 2023 11:17:50 -0500 Subject: drm/amd/display: Add minimum Z8 residency debug option [Why] Allows finer control and tuning for debug and profiling. [How] Add the debug option into DC. The default remains the same as before for now. Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Nicholas Kazlauskas Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c | 1 + drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index c3814f40a102..f1ea9031a191 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -795,6 +795,7 @@ struct dc_debug_options { unsigned int force_odm_combine; //bit vector based on otg inst unsigned int seamless_boot_odm_combine; unsigned int force_odm_combine_4to1; //bit vector based on otg inst + int minimum_z8_residency_time; bool disable_z9_mpc; unsigned int force_fclk_khz; bool enable_tri_buf; 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 54ed3de869d3..8fc89aeb86d4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c @@ -887,6 +887,7 @@ static const struct dc_plane_cap plane_cap = { static const struct dc_debug_options debug_defaults_drv = { .disable_z10 = false, .enable_z9_disable_interface = true, + .minimum_z8_residency_time = 1000, .psr_skip_crtc_disable = true, .disable_dmcu = true, .force_abm_enable = false, 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 d3ba65efe1d2..f3cfc144e358 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 @@ -973,7 +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; + int minmum_z8_residency = dc->debug.minimum_z8_residency_time > 0 ? dc->debug.minimum_z8_residency_time : 1000; + bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z8_residency; bool is_pwrseq0 = link->link_index == 0; if (dc_extended_blank_supported(dc)) { -- cgit From 0215ce9057edf69aff9c1a32f4254e1ec297db31 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Tue, 21 Feb 2023 10:27:10 -0500 Subject: drm/amd/display: Update minimum stutter residency for DCN314 Z8 [Why] Block periods that are too short as they have the potential to currently cause hangs in other firmware components on the system. [How] Update the threshold, mostly targeting a block of 4k and downscaling. Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Nicholas Kazlauskas Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 8fc89aeb86d4..f9dfbc7407ee 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c @@ -887,7 +887,7 @@ static const struct dc_plane_cap plane_cap = { static const struct dc_debug_options debug_defaults_drv = { .disable_z10 = false, .enable_z9_disable_interface = true, - .minimum_z8_residency_time = 1000, + .minimum_z8_residency_time = 3080, .psr_skip_crtc_disable = true, .disable_dmcu = true, .force_abm_enable = false, -- cgit From c0a561d96a281b91d48b77278714cf5b791a70bd Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 13 Feb 2023 11:35:20 -0500 Subject: drm/amd/display: Drop CONFIG_DRM_AMD_DC_HDR [Why & How] Remove dead code. Reviewed-by: Sun peng Li Acked-by: Qingqing Zhuo Signed-off-by: Harry Wentland Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 129 --------------------- 1 file changed, 129 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c index 28fb1f02591a..a8d6b06cee95 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c @@ -741,24 +741,6 @@ static int get_plane_formats(const struct drm_plane *plane, return num_formats; } -#ifdef CONFIG_DRM_AMD_DC_HDR -static int attach_color_mgmt_properties(struct amdgpu_display_manager *dm, struct drm_plane *plane) -{ - drm_object_attach_property(&plane->base, - dm->degamma_lut_property, - 0); - drm_object_attach_property(&plane->base, - dm->degamma_lut_size_property, - MAX_COLOR_LUT_ENTRIES); - drm_object_attach_property(&plane->base, dm->ctm_property, - 0); - drm_object_attach_property(&plane->base, dm->sdr_boost_property, - DEFAULT_SDR_BOOST); - - return 0; -} -#endif - int fill_plane_buffer_attributes(struct amdgpu_device *adev, const struct amdgpu_framebuffer *afb, const enum surface_pixel_format format, @@ -1337,10 +1319,6 @@ static void dm_drm_plane_reset(struct drm_plane *plane) if (amdgpu_state) __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base); -#ifdef CONFIG_DRM_AMD_DC_HDR - if (amdgpu_state) - amdgpu_state->sdr_boost = DEFAULT_SDR_BOOST; -#endif } static struct drm_plane_state * @@ -1360,15 +1338,6 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) dc_plane_state_retain(dm_plane_state->dc_state); } -#ifdef CONFIG_DRM_AMD_DC_HDR - if (dm_plane_state->degamma_lut) - drm_property_blob_get(dm_plane_state->degamma_lut); - if (dm_plane_state->ctm) - drm_property_blob_get(dm_plane_state->ctm); - - dm_plane_state->sdr_boost = old_dm_plane_state->sdr_boost; -#endif - return &dm_plane_state->base; } @@ -1436,103 +1405,12 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane, { struct dm_plane_state *dm_plane_state = to_dm_plane_state(state); -#ifdef CONFIG_DRM_AMD_DC_HDR - drm_property_blob_put(dm_plane_state->degamma_lut); - drm_property_blob_put(dm_plane_state->ctm); -#endif if (dm_plane_state->dc_state) dc_plane_state_release(dm_plane_state->dc_state); drm_atomic_helper_plane_destroy_state(plane, state); } -#ifdef CONFIG_DRM_AMD_DC_HDR -/* copied from drm_atomic_uapi.c */ -static int atomic_replace_property_blob_from_id(struct drm_device *dev, - struct drm_property_blob **blob, - uint64_t blob_id, - ssize_t expected_size, - ssize_t expected_elem_size, - bool *replaced) -{ - struct drm_property_blob *new_blob = NULL; - - if (blob_id != 0) { - new_blob = drm_property_lookup_blob(dev, blob_id); - if (new_blob == NULL) - return -EINVAL; - - if (expected_size > 0 && - new_blob->length != expected_size) { - drm_property_blob_put(new_blob); - return -EINVAL; - } - if (expected_elem_size > 0 && - new_blob->length % expected_elem_size != 0) { - drm_property_blob_put(new_blob); - return -EINVAL; - } - } - - *replaced |= drm_property_replace_blob(blob, new_blob); - drm_property_blob_put(new_blob); - - return 0; -} - -int dm_drm_plane_set_property(struct drm_plane *plane, - struct drm_plane_state *state, - struct drm_property *property, - uint64_t val) -{ - struct amdgpu_device *adev = drm_to_adev(plane->dev); - struct dm_plane_state *dm_plane_state = to_dm_plane_state(state); - int ret = 0; - bool replaced; - - if (property == adev->dm.degamma_lut_property) { - ret = atomic_replace_property_blob_from_id(adev_to_drm(adev), - &dm_plane_state->degamma_lut, - val, -1, sizeof(struct drm_color_lut), - &replaced); - } else if (property == adev->dm.ctm_property) { - ret = atomic_replace_property_blob_from_id(adev_to_drm(adev), - &dm_plane_state->ctm, - val, - sizeof(struct drm_color_ctm), -1, - &replaced); - } else if (property == adev->dm.sdr_boost_property) { - dm_plane_state->sdr_boost = val; - } else { - return -EINVAL; - } - - return ret; -} - -int dm_drm_plane_get_property(struct drm_plane *plane, - const struct drm_plane_state *state, - struct drm_property *property, - uint64_t *val) -{ - struct dm_plane_state *dm_plane_state = to_dm_plane_state(state); - struct amdgpu_device *adev = drm_to_adev(plane->dev); - - if (property == adev->dm.degamma_lut_property) { - *val = (dm_plane_state->degamma_lut) ? - dm_plane_state->degamma_lut->base.id : 0; - } else if (property == adev->dm.ctm_property) { - *val = (dm_plane_state->ctm) ? dm_plane_state->ctm->base.id : 0; - } else if (property == adev->dm.sdr_boost_property) { - *val = dm_plane_state->sdr_boost; - } else { - return -EINVAL; - } - - return 0; -} -#endif - static const struct drm_plane_funcs dm_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, @@ -1541,10 +1419,6 @@ static const struct drm_plane_funcs dm_plane_funcs = { .atomic_duplicate_state = dm_drm_plane_duplicate_state, .atomic_destroy_state = dm_drm_plane_destroy_state, .format_mod_supported = dm_plane_format_mod_supported, -#ifdef CONFIG_DRM_AMD_DC_HDR - .atomic_set_property = dm_drm_plane_set_property, - .atomic_get_property = dm_drm_plane_get_property, -#endif }; int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, @@ -1615,9 +1489,6 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, drm_plane_helper_add(plane, &dm_plane_helper_funcs); -#ifdef CONFIG_DRM_AMD_DC_HDR - attach_color_mgmt_properties(dm, plane); -#endif /* Create (reset) the plane state */ if (plane->funcs->reset) plane->funcs->reset(plane); -- cgit From 11efe095dfe0768f5b248b77a84e5aa748f14204 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 13 Feb 2023 15:17:29 -0500 Subject: drm/amd/display: Fix no-DCN build [Why & How] This fixes a couple misplaced CONFIG_DRM_AMD_DC_DCN blocks. Reviewed-by: Sun peng Li Acked-by: Qingqing Zhuo Signed-off-by: Harry Wentland Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/amd/display') 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 e10ed2935971..19721941b069 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 @@ -1427,6 +1427,7 @@ static unsigned int kbps_from_pbn(unsigned int pbn) static bool is_dsc_common_config_possible(struct dc_stream_state *stream, struct dc_dsc_bw_range *bw_range) { +#if defined(CONFIG_DRM_AMD_DC_DCN) struct dc_dsc_policy dsc_policy = {0}; dc_dsc_get_policy_for_timing(&stream->timing, 0, &dsc_policy); @@ -1438,6 +1439,8 @@ static bool is_dsc_common_config_possible(struct dc_stream_state *stream, &stream->timing, bw_range); return bw_range->max_target_bpp_x16 && bw_range->min_target_bpp_x16; +#endif + return false; } #endif /* CONFIG_DRM_AMD_DC_DCN */ -- cgit From ab487ea8910d2a84f851cb87f2cb49adcb5b774b Mon Sep 17 00:00:00 2001 From: Mike Hsieh Date: Mon, 20 Feb 2023 11:48:26 +0800 Subject: drm/amd/display: fix typo in dc_dsc_config_options structure [WHY] There is a typo in dc_dsc_config_options structure [HOW] Fix the typo Reviewed-by: Wenjing Liu Acked-by: Qingqing Zhuo Signed-off-by: Mike Hsieh Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_dsc.h | 2 +- drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc_dsc.h b/drivers/gpu/drm/amd/display/dc/dc_dsc.h index 81e62a630d78..0e92a322c2ed 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dsc.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dsc.h @@ -57,7 +57,7 @@ struct dc_dsc_policy { struct dc_dsc_config_options { uint32_t dsc_min_slice_height_override; uint32_t max_target_bpp_limit_override_x16; - uint32_t slight_height_granularity; + uint32_t slice_height_granularity; }; bool dc_dsc_parse_dsc_dpcd(const struct dc *dc, diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c index 8b5663853efb..d9622a0f448a 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c @@ -355,7 +355,7 @@ bool dc_dsc_compute_bandwidth_range( options.dsc_min_slice_height_override = dsc_min_slice_height_override; options.max_target_bpp_limit_override_x16 = max_bpp_x16; - options.slight_height_granularity = 1; + options.slice_height_granularity = 1; get_dsc_enc_caps(dsc, &dsc_enc_caps, timing->pix_clk_100hz); @@ -918,7 +918,7 @@ static bool setup_dsc_config( slice_height = min((int)(options->dsc_min_slice_height_override), pic_height); while (slice_height < pic_height && (pic_height % slice_height != 0 || - slice_height % options->slight_height_granularity != 0 || + slice_height % options->slice_height_granularity != 0 || (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 && slice_height % 2 != 0))) slice_height++; @@ -1111,5 +1111,5 @@ void dc_dsc_get_default_config_option(const struct dc *dc, struct dc_dsc_config_ { options->dsc_min_slice_height_override = dc->debug.dsc_min_slice_height_override; options->max_target_bpp_limit_override_x16 = 0; - options->slight_height_granularity = 1; + options->slice_height_granularity = 1; } -- cgit From 1e88eb1b2c259994d034b0833cb489105a984ebb Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 13 Feb 2023 11:19:31 -0500 Subject: drm/amd/display: Drop CONFIG_DRM_AMD_DC_HDCP [Why & How] There is no reason we still need a config option for this. Reviewed-by: Wenjing Liu Acked-by: Qingqing Zhuo Signed-off-by: Harry Wentland Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/Kconfig | 6 -- drivers/gpu/drm/amd/display/Makefile | 4 - drivers/gpu/drm/amd/display/amdgpu_dm/Makefile | 2 - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 ----- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 4 - .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 11 +-- .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 5 - drivers/gpu/drm/amd/display/dc/Makefile | 2 - drivers/gpu/drm/amd/display/dc/core/dc.c | 4 - .../gpu/drm/amd/display/dc/core/dc_link_exports.c | 2 - drivers/gpu/drm/amd/display/dc/dc.h | 15 +-- drivers/gpu/drm/amd/display/dc/dc_types.h | 6 -- .../display/dc/dcn32/dcn32_dio_stream_encoder.c | 2 - drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c | 2 +- drivers/gpu/drm/amd/display/dc/inc/core_types.h | 2 - drivers/gpu/drm/amd/display/dc/inc/link.h | 2 - .../gpu/drm/amd/display/dc/link/link_detection.c | 10 -- drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 10 -- .../display/dc/link/protocols/link_dp_training.c | 2 - .../gpu/drm/amd/display/include/hdcp_msg_types.h | 103 +++++++++++++++++++++ drivers/gpu/drm/amd/display/include/hdcp_types.h | 103 --------------------- .../gpu/drm/amd/display/modules/hdcp/hdcp_log.h | 2 - 22 files changed, 106 insertions(+), 217 deletions(-) create mode 100644 drivers/gpu/drm/amd/display/include/hdcp_msg_types.h delete mode 100644 drivers/gpu/drm/amd/display/include/hdcp_types.h (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig index 0c9bd0a53e60..578a8b547ddf 100644 --- a/drivers/gpu/drm/amd/display/Kconfig +++ b/drivers/gpu/drm/amd/display/Kconfig @@ -25,12 +25,6 @@ config DRM_AMD_DC_DCN help Raven, Navi, and newer family support for display engine -config DRM_AMD_DC_HDCP - bool "Enable HDCP support in DC" - depends on DRM_AMD_DC - help - Choose this option if you want to support HDCP authentication. - config DRM_AMD_DC_SI bool "AMD DC support for Southern Islands ASICs" depends on DRM_AMDGPU_SI diff --git a/drivers/gpu/drm/amd/display/Makefile b/drivers/gpu/drm/amd/display/Makefile index 2633de77de5e..0d610cb376bb 100644 --- a/drivers/gpu/drm/amd/display/Makefile +++ b/drivers/gpu/drm/amd/display/Makefile @@ -36,18 +36,14 @@ subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/info_packet subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/power subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dmub/inc -ifdef CONFIG_DRM_AMD_DC_HDCP subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/hdcp -endif #TODO: remove when Timing Sync feature is complete subdir-ccflags-y += -DBUILD_FEATURE_TIMING_SYNC=0 DAL_LIBS = amdgpu_dm dc modules/freesync modules/color modules/info_packet modules/power dmub/src -ifdef CONFIG_DRM_AMD_DC_HDCP DAL_LIBS += modules/hdcp -endif AMD_DAL = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/,$(DAL_LIBS))) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile index 90fb0f3cdb6f..aef782ca3706 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile @@ -41,9 +41,7 @@ ifneq ($(CONFIG_DRM_AMD_DC),) AMDGPUDM += amdgpu_dm_services.o amdgpu_dm_helpers.o amdgpu_dm_pp_smu.o amdgpu_dm_psr.o endif -ifdef CONFIG_DRM_AMD_DC_HDCP AMDGPUDM += amdgpu_dm_hdcp.o -endif ifneq ($(CONFIG_DEBUG_FS),) AMDGPUDM += amdgpu_dm_crc.o amdgpu_dm_debugfs.o 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 7f627ab43a29..de270f0969f5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -52,10 +52,8 @@ #include "amdgpu_dm.h" #include "amdgpu_dm_plane.h" #include "amdgpu_dm_crtc.h" -#ifdef CONFIG_DRM_AMD_DC_HDCP #include "amdgpu_dm_hdcp.h" #include -#endif #include "amdgpu_pm.h" #include "amdgpu_atombios.h" @@ -1488,9 +1486,7 @@ static void retrieve_dmi_info(struct amdgpu_display_manager *dm) static int amdgpu_dm_init(struct amdgpu_device *adev) { struct dc_init_data init_data; -#ifdef CONFIG_DRM_AMD_DC_HDCP struct dc_callback_init init_params; -#endif int r; adev->dm.ddev = adev_to_drm(adev); @@ -1498,9 +1494,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) /* Zero all the fields */ memset(&init_data, 0, sizeof(init_data)); -#ifdef CONFIG_DRM_AMD_DC_HDCP memset(&init_params, 0, sizeof(init_params)); -#endif mutex_init(&adev->dm.dpia_aux_lock); mutex_init(&adev->dm.dc_lock); @@ -1726,7 +1720,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) DRM_ERROR("amdgpu: failed to initialize vblank_workqueue.\n"); } -#ifdef CONFIG_DRM_AMD_DC_HDCP if (adev->dm.dc->caps.max_links > 0 && adev->family >= AMDGPU_FAMILY_RV) { adev->dm.hdcp_workqueue = hdcp_create_workqueue(adev, &init_params.cp_psp, adev->dm.dc); @@ -1737,7 +1730,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) dc_init_callbacks(adev->dm.dc, &init_params); } -#endif #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) adev->dm.secure_display_ctxs = amdgpu_dm_crtc_secure_display_create_contexts(adev); if (!adev->dm.secure_display_ctxs) { @@ -1844,7 +1836,6 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev) adev->dm.secure_display_ctxs = NULL; } #endif -#ifdef CONFIG_DRM_AMD_DC_HDCP if (adev->dm.hdcp_workqueue) { hdcp_destroy(&adev->dev->kobj, adev->dm.hdcp_workqueue); adev->dm.hdcp_workqueue = NULL; @@ -1852,7 +1843,6 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev) if (adev->dm.dc) dc_deinit_callbacks(adev->dm.dc); -#endif dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv); @@ -3111,11 +3101,9 @@ void amdgpu_dm_update_connector_after_detect( 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) connector->state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; -#endif } mutex_unlock(&dev->mode_config.mutex); @@ -3132,9 +3120,7 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector) struct drm_device *dev = connector->dev; enum dc_connection_type new_connection_type = dc_connection_none; struct amdgpu_device *adev = drm_to_adev(dev); -#ifdef CONFIG_DRM_AMD_DC_HDCP struct dm_connector_state *dm_con_state = to_dm_connector_state(connector->state); -#endif bool ret = false; if (adev->dm.disable_hpd_irq) @@ -3146,12 +3132,10 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector) */ mutex_lock(&aconnector->hpd_lock); -#ifdef CONFIG_DRM_AMD_DC_HDCP if (adev->dm.hdcp_workqueue) { hdcp_reset_display(adev->dm.hdcp_workqueue, aconnector->dc_link->link_index); dm_con_state->update_hdcp = true; } -#endif if (aconnector->fake_enable) aconnector->fake_enable = false; @@ -3398,12 +3382,10 @@ out: } } } -#ifdef CONFIG_DRM_AMD_DC_HDCP if (hpd_irq_data.bytes.device_service_irq.bits.CP_IRQ) { if (adev->dm.hdcp_workqueue) hdcp_handle_cpirq(adev->dm.hdcp_workqueue, aconnector->base.index); } -#endif if (dc_link->type != dc_connection_mst_branch) drm_dp_cec_irq(&aconnector->dm_dp_aux.aux); @@ -7273,10 +7255,8 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, if (!aconnector->mst_root) drm_connector_attach_vrr_capable_property(&aconnector->base); -#ifdef CONFIG_DRM_AMD_DC_HDCP if (adev->dm.hdcp_workqueue) drm_connector_attach_content_protection_property(&aconnector->base, true); -#endif } } @@ -7538,7 +7518,6 @@ is_scaling_state_different(const struct dm_connector_state *dm_state, return false; } -#ifdef CONFIG_DRM_AMD_DC_HDCP static bool is_content_protection_different(struct drm_crtc_state *new_crtc_state, struct drm_crtc_state *old_crtc_state, struct drm_connector_state *new_conn_state, @@ -7658,7 +7637,6 @@ static bool is_content_protection_different(struct drm_crtc_state *new_crtc_stat pr_debug("[HDCP_DM] DESIRED->ENABLED %s :false\n", __func__); return false; } -#endif static void remove_stream(struct amdgpu_device *adev, struct amdgpu_crtc *acrtc, @@ -8538,7 +8516,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) acrtc->otg_inst = status->primary_otg_inst; } } -#ifdef CONFIG_DRM_AMD_DC_HDCP for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) { struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state); struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); @@ -8649,7 +8626,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) new_con_state->hdcp_content_type, enable_encryption); } } -#endif /* Handle connector state changes */ for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) { 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 ed5cbe9da40c..904f9e2fd35b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -461,9 +461,7 @@ struct amdgpu_display_manager { struct amdgpu_dm_backlight_caps backlight_caps[AMDGPU_DM_MAX_NUM_EDP]; struct mod_freesync *freesync_module; -#ifdef CONFIG_DRM_AMD_DC_HDCP struct hdcp_workqueue *hdcp_workqueue; -#endif /** * @vblank_control_workqueue: @@ -747,9 +745,7 @@ struct dm_connector_state { uint8_t underscan_hborder; bool underscan_enable; bool freesync_capable; -#ifdef CONFIG_DRM_AMD_DC_HDCP bool update_hdcp; -#endif uint8_t abm_level; int vcpi_slots; uint64_t pbn; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 4a5dae578d97..abf7895d1608 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -947,7 +947,6 @@ static ssize_t dp_dsc_passthrough_set(struct file *f, const char __user *buf, return 0; } -#ifdef CONFIG_DRM_AMD_DC_HDCP /* * Returns the HDCP capability of the Display (1.4 for now). * @@ -984,7 +983,6 @@ static int hdcp_sink_capability_show(struct seq_file *m, void *data) return 0; } -#endif /* * Returns whether the connected display is internal and not hotpluggable. @@ -2593,9 +2591,7 @@ DEFINE_SHOW_ATTRIBUTE(dp_dsc_fec_support); DEFINE_SHOW_ATTRIBUTE(dmub_fw_state); DEFINE_SHOW_ATTRIBUTE(dmub_tracebuffer); DEFINE_SHOW_ATTRIBUTE(dp_lttpr_status); -#ifdef CONFIG_DRM_AMD_DC_HDCP DEFINE_SHOW_ATTRIBUTE(hdcp_sink_capability); -#endif DEFINE_SHOW_ATTRIBUTE(internal_display); DEFINE_SHOW_ATTRIBUTE(psr_capability); DEFINE_SHOW_ATTRIBUTE(dp_is_mst_connector); @@ -2726,9 +2722,7 @@ static const struct { {"phy_settings", &dp_phy_settings_debugfs_fop}, {"lttpr_status", &dp_lttpr_status_fops}, {"test_pattern", &dp_phy_test_pattern_fops}, -#ifdef CONFIG_DRM_AMD_DC_HDCP {"hdcp_sink_capability", &hdcp_sink_capability_fops}, -#endif {"sdp_message", &sdp_message_fops}, {"aux_dpcd_address", &dp_dpcd_address_debugfs_fops}, {"aux_dpcd_size", &dp_dpcd_size_debugfs_fops}, @@ -2749,14 +2743,13 @@ static const struct { {"is_dpia_link", &is_dpia_link_fops} }; -#ifdef CONFIG_DRM_AMD_DC_HDCP static const struct { char *name; const struct file_operations *fops; } hdmi_debugfs_entries[] = { {"hdcp_sink_capability", &hdcp_sink_capability_fops} }; -#endif + /* * Force YUV420 output if available from the given mode */ @@ -3015,7 +3008,6 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector) connector->debugfs_dpcd_address = 0; connector->debugfs_dpcd_size = 0; -#ifdef CONFIG_DRM_AMD_DC_HDCP if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA) { for (i = 0; i < ARRAY_SIZE(hdmi_debugfs_entries); i++) { debugfs_create_file(hdmi_debugfs_entries[i].name, @@ -3023,7 +3015,6 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector) hdmi_debugfs_entries[i].fops); } } -#endif } #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY 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 19721941b069..1579c2839ce3 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 @@ -31,10 +31,7 @@ #include "amdgpu.h" #include "amdgpu_dm.h" #include "amdgpu_dm_mst_types.h" - -#ifdef CONFIG_DRM_AMD_DC_HDCP #include "amdgpu_dm_hdcp.h" -#endif #include "dc.h" #include "dm_helpers.h" @@ -362,7 +359,6 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) * plugged back with same display index, its hdcp properties * will be retrieved from hdcp_work within dm_dp_mst_get_modes */ -#ifdef CONFIG_DRM_AMD_DC_HDCP if (aconnector->dc_sink && connector->state) { struct drm_device *dev = connector->dev; struct amdgpu_device *adev = drm_to_adev(dev); @@ -374,7 +370,6 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) connector->state->content_protection = hdcp_w->content_protection[connector->index]; } -#endif if (aconnector->dc_sink) { amdgpu_dm_update_freesync_caps( diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile index 94f156d57220..ba75e91ef62b 100644 --- a/drivers/gpu/drm/amd/display/dc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/Makefile @@ -56,9 +56,7 @@ ifdef CONFIG_DRM_AMD_DC_SI DC_LIBS += dce60 endif -ifdef CONFIG_DRM_AMD_DC_HDCP DC_LIBS += hdcp -endif AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/dc/,$(DC_LIBS))) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 9b821d78aaaa..8be7a1fc5295 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1377,16 +1377,12 @@ void dc_hardware_init(struct dc *dc) void dc_init_callbacks(struct dc *dc, const struct dc_callback_init *init_params) { -#ifdef CONFIG_DRM_AMD_DC_HDCP dc->ctx->cp_psp = init_params->cp_psp; -#endif } void dc_deinit_callbacks(struct dc *dc) { -#ifdef CONFIG_DRM_AMD_DC_HDCP memset(&dc->ctx->cp_psp, 0, sizeof(dc->ctx->cp_psp)); -#endif } void dc_destroy(struct dc **dc) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c index 862cb0f93b7d..565c62a272d6 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c @@ -93,7 +93,6 @@ const struct dc_link_status *dc_link_get_status(const struct dc_link *link) { return link_get_status(link); } -#ifdef CONFIG_DRM_AMD_DC_HDCP /* return true if the connected receiver supports the hdcp version */ bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal) @@ -105,7 +104,6 @@ bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal) { return link_is_hdcp22(link, signal); } -#endif void dc_link_clear_dprx_states(struct dc_link *link) { diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index f1ea9031a191..ae9d31cf9a23 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -29,9 +29,7 @@ #include "dc_types.h" #include "grph_object_defs.h" #include "logger_types.h" -#if defined(CONFIG_DRM_AMD_DC_HDCP) -#include "hdcp_types.h" -#endif +#include "hdcp_msg_types.h" #include "gpio_types.h" #include "link_service_types.h" #include "grph_object_ctrl_defs.h" @@ -993,11 +991,7 @@ struct dc_init_data { }; struct dc_callback_init { -#ifdef CONFIG_DRM_AMD_DC_HDCP struct cp_psp cp_psp; -#else - uint8_t reserved; -#endif }; struct dc *dc_create(const struct dc_init_data *init_params); @@ -1475,9 +1469,7 @@ struct dc_link { uint32_t dongle_max_pix_clk; unsigned short chip_caps; unsigned int dpcd_sink_count; -#if defined(CONFIG_DRM_AMD_DC_HDCP) struct hdcp_caps hdcp_caps; -#endif enum edp_revision edp_revision; union dpcd_sink_ext_caps dpcd_sink_ext_caps; @@ -1661,12 +1653,9 @@ bool dc_is_oem_i2c_device_present( size_t slave_address ); -#ifdef CONFIG_DRM_AMD_DC_HDCP - /* return true if the connected receiver supports the hdcp version */ bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal); bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal); -#endif /* Notify DC about DP RX Interrupt (aka DP IRQ_HPD). * @@ -2154,7 +2143,6 @@ void dc_resume(struct dc *dc); void dc_power_down_on_boot(struct dc *dc); -#if defined(CONFIG_DRM_AMD_DC_HDCP) /* * HDCP Interfaces */ @@ -2162,7 +2150,6 @@ enum hdcp_message_status dc_process_hdcp_msg( enum signal_type signal, struct dc_link *link, struct hdcp_protection_message *message_info); -#endif bool dc_is_dmcu_initialized(struct dc *dc); enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping); diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index f28b8597cc1e..4b47fa00610b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -40,9 +40,7 @@ #include "grph_object_defs.h" #include "grph_object_ctrl_defs.h" -#ifdef CONFIG_DRM_AMD_DC_HDCP #include "dm_cp_psp.h" -#endif /* forward declarations */ struct dc_plane_state; @@ -813,9 +811,7 @@ struct dc_context { uint32_t dc_edp_id_count; uint64_t fbc_gpu_addr; struct dc_dmub_srv *dmub_srv; -#ifdef CONFIG_DRM_AMD_DC_HDCP struct cp_psp cp_psp; -#endif uint32_t *dcn_reg_offsets; uint32_t *nbio_reg_offsets; }; @@ -955,7 +951,6 @@ struct dc_link_status { struct dpcd_caps *dpcd_caps; }; -#if defined(CONFIG_DRM_AMD_DC_HDCP) union hdcp_rx_caps { struct { uint8_t version; @@ -982,7 +977,6 @@ struct hdcp_caps { union hdcp_rx_caps rx_caps; union hdcp_bcaps bcaps; }; -#endif /* DP MST stream allocation (payload bandwidth number) */ struct link_mst_stream_allocation { diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c index 36e6f5657942..ccf6b181c349 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c @@ -211,10 +211,8 @@ static void enc32_stream_encoder_hdmi_set_stream_attribute( HDMI_GC_SEND, 1, HDMI_NULL_SEND, 1); -#if defined(CONFIG_DRM_AMD_DC_HDCP) /* Disable Audio Content Protection packet transmission */ REG_UPDATE(HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, 0); -#endif /* following belongs to audio */ /* Enable Audio InfoFrame packet transmission. */ diff --git a/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c b/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c index e1422e5e86c9..25ffc052d53b 100644 --- a/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c +++ b/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c @@ -27,7 +27,7 @@ #include "dm_services.h" #include "dm_helpers.h" -#include "include/hdcp_types.h" +#include "include/hdcp_msg_types.h" #include "include/signal_types.h" #include "core_types.h" #include "link.h" diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index ed3c03108da6..2eb597a24425 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -51,9 +51,7 @@ void enable_surface_flip_reporting(struct dc_plane_state *plane_state, #include "clock_source.h" #include "audio.h" #include "dm_pp_smu.h" -#ifdef CONFIG_DRM_AMD_DC_HDCP #include "dm_cp_psp.h" -#endif #include "link_hwss.h" /********** DAL Core*********************/ diff --git a/drivers/gpu/drm/amd/display/dc/inc/link.h b/drivers/gpu/drm/amd/display/dc/inc/link.h index 6a346a41f07b..a3fcfa918a8f 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link.h @@ -139,11 +139,9 @@ bool link_detect(struct dc_link *link, enum dc_detect_reason reason); bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type *type); const struct dc_link_status *link_get_status(const struct dc_link *link); -#ifdef CONFIG_DRM_AMD_DC_HDCP /* return true if the connected receiver supports the hdcp version */ bool link_is_hdcp14(struct dc_link *link, enum signal_type signal); bool link_is_hdcp22(struct dc_link *link, enum signal_type signal); -#endif void link_clear_dprx_states(struct dc_link *link); bool link_reset_cur_dp_mst_topology(struct dc_link *link); uint32_t dp_link_bandwidth_kbps( diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 393bdefba0ba..99279e1e7330 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -466,7 +466,6 @@ static void link_disconnect_remap(struct dc_sink *prev_sink, struct dc_link *lin link->local_sink = prev_sink; } -#if defined(CONFIG_DRM_AMD_DC_HDCP) static void query_hdcp_capability(enum signal_type signal, struct dc_link *link) { struct hdcp_protection_message msg22; @@ -508,7 +507,6 @@ static void query_hdcp_capability(enum signal_type signal, struct dc_link *link) } } -#endif // CONFIG_DRM_AMD_DC_HDCP static void read_current_link_settings_on_detect(struct dc_link *link) { union lane_count_set lane_count_set = {0}; @@ -1084,9 +1082,7 @@ static bool detect_link_and_local_sink(struct dc_link *link, * TODO debug why certain monitors don't like * two link trainings */ -#if defined(CONFIG_DRM_AMD_DC_HDCP) query_hdcp_capability(sink->sink_signal, link); -#endif } else { // If edid is the same, then discard new sink and revert back to original sink if (same_edid) { @@ -1094,9 +1090,7 @@ static bool detect_link_and_local_sink(struct dc_link *link, sink = prev_sink; prev_sink = NULL; } -#if defined(CONFIG_DRM_AMD_DC_HDCP) query_hdcp_capability(sink->sink_signal, link); -#endif } /* HDMI-DVI Dongle */ @@ -1162,9 +1156,7 @@ static bool detect_link_and_local_sink(struct dc_link *link, /* From Connected-to-Disconnected. */ link->type = dc_connection_none; sink_caps.signal = SIGNAL_TYPE_NONE; -#if defined(CONFIG_DRM_AMD_DC_HDCP) memset(&link->hdcp_caps, 0, sizeof(struct hdcp_caps)); -#endif /* When we unplug a passive DP-HDMI dongle connection, dongle_max_pix_clk * is not cleared. If we emulate a DP signal on this connection, it thinks * the dongle is still there and limits the number of modes we can emulate. @@ -1266,7 +1258,6 @@ void link_clear_dprx_states(struct dc_link *link) { memset(&link->dprx_states, 0, sizeof(link->dprx_states)); } -#if defined(CONFIG_DRM_AMD_DC_HDCP) bool link_is_hdcp14(struct dc_link *link, enum signal_type signal) { @@ -1314,7 +1305,6 @@ bool link_is_hdcp22(struct dc_link *link, enum signal_type signal) return ret; } -#endif // CONFIG_DRM_AMD_DC_HDCP const struct dc_link_status *link_get_status(const struct dc_link *link) { diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index a1214e5606dd..0039928186ff 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -647,7 +647,6 @@ static void write_i2c_redriver_setting( if (!i2c_success) DC_LOG_DEBUG("Set redriver failed"); } -#if defined(CONFIG_DRM_AMD_DC_HDCP) static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off) { @@ -713,7 +712,6 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off) cp_psp->funcs.update_stream_config(cp_psp->handle, &config); } -#endif static void set_avmute(struct pipe_ctx *pipe_ctx, bool enable) { @@ -2269,9 +2267,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx) dc->hwss.disable_audio_stream(pipe_ctx); -#if defined(CONFIG_DRM_AMD_DC_HDCP) update_psp_stream_config(pipe_ctx, true); -#endif dc->hwss.blank_stream(pipe_ctx); if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) @@ -2417,9 +2413,7 @@ void link_set_dpms_on( dc->hwss.enable_audio_stream(pipe_ctx); } -#if defined(CONFIG_DRM_AMD_DC_HDCP) update_psp_stream_config(pipe_ctx, false); -#endif return; } @@ -2429,9 +2423,7 @@ void link_set_dpms_on( !pipe_ctx->stream->timing.flags.DSC && !pipe_ctx->next_odm_pipe) { pipe_ctx->stream->dpms_off = false; -#if defined(CONFIG_DRM_AMD_DC_HDCP) update_psp_stream_config(pipe_ctx, false); -#endif return; } @@ -2515,9 +2507,7 @@ void link_set_dpms_on( if (dc_is_dp_signal(pipe_ctx->stream->signal)) enable_stream_features(pipe_ctx); -#if defined(CONFIG_DRM_AMD_DC_HDCP) update_psp_stream_config(pipe_ctx, false); -#endif dc->hwss.enable_audio_stream(pipe_ctx); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index 5e613ea2cd3f..cb0049cd1133 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -1570,7 +1570,6 @@ bool perform_link_training_with_retries( msleep(delay_dp_power_up_in_ms); } -#ifdef CONFIG_DRM_AMD_DC_HDCP if (panel_mode == DP_PANEL_MODE_EDP) { struct cp_psp *cp_psp = &stream->ctx->cp_psp; @@ -1584,7 +1583,6 @@ bool perform_link_training_with_retries( result = cp_psp->funcs.enable_assr(cp_psp->handle, link); } } -#endif dp_set_panel_mode(link, panel_mode); diff --git a/drivers/gpu/drm/amd/display/include/hdcp_msg_types.h b/drivers/gpu/drm/amd/display/include/hdcp_msg_types.h new file mode 100644 index 000000000000..42229b4effdc --- /dev/null +++ b/drivers/gpu/drm/amd/display/include/hdcp_msg_types.h @@ -0,0 +1,103 @@ +/* +* Copyright 2019 Advanced Micro Devices, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Authors: AMD +* +*/ + +#ifndef __DC_HDCP_TYPES_H__ +#define __DC_HDCP_TYPES_H__ + +enum hdcp_message_id { + HDCP_MESSAGE_ID_INVALID = -1, + + /* HDCP 1.4 */ + + HDCP_MESSAGE_ID_READ_BKSV = 0, + /* HDMI is called Ri', DP is called R0' */ + HDCP_MESSAGE_ID_READ_RI_R0, + HDCP_MESSAGE_ID_READ_PJ, + HDCP_MESSAGE_ID_WRITE_AKSV, + HDCP_MESSAGE_ID_WRITE_AINFO, + HDCP_MESSAGE_ID_WRITE_AN, + HDCP_MESSAGE_ID_READ_VH_X, + HDCP_MESSAGE_ID_READ_VH_0, + HDCP_MESSAGE_ID_READ_VH_1, + HDCP_MESSAGE_ID_READ_VH_2, + HDCP_MESSAGE_ID_READ_VH_3, + HDCP_MESSAGE_ID_READ_VH_4, + HDCP_MESSAGE_ID_READ_BCAPS, + HDCP_MESSAGE_ID_READ_BSTATUS, + HDCP_MESSAGE_ID_READ_KSV_FIFO, + HDCP_MESSAGE_ID_READ_BINFO, + + /* HDCP 2.2 */ + + HDCP_MESSAGE_ID_HDCP2VERSION, + HDCP_MESSAGE_ID_RX_CAPS, + HDCP_MESSAGE_ID_WRITE_AKE_INIT, + HDCP_MESSAGE_ID_READ_AKE_SEND_CERT, + HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM, + HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM, + HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME, + HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO, + HDCP_MESSAGE_ID_WRITE_LC_INIT, + HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME, + HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS, + HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST, + HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK, + HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE, + HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY, + HDCP_MESSAGE_ID_READ_RXSTATUS, + HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE, + + HDCP_MESSAGE_ID_MAX +}; + +enum hdcp_version { + HDCP_Unknown = 0, + HDCP_VERSION_14, + HDCP_VERSION_22, +}; + +enum hdcp_link { + HDCP_LINK_PRIMARY, + HDCP_LINK_SECONDARY +}; + +enum hdcp_message_status { + HDCP_MESSAGE_SUCCESS, + HDCP_MESSAGE_FAILURE, + HDCP_MESSAGE_UNSUPPORTED +}; + +struct hdcp_protection_message { + enum hdcp_version version; + /* relevant only for DVI */ + enum hdcp_link link; + enum hdcp_message_id msg_id; + uint32_t length; + uint8_t max_retries; + uint8_t *data; + enum hdcp_message_status status; +}; + +#endif diff --git a/drivers/gpu/drm/amd/display/include/hdcp_types.h b/drivers/gpu/drm/amd/display/include/hdcp_types.h deleted file mode 100644 index 42229b4effdc..000000000000 --- a/drivers/gpu/drm/amd/display/include/hdcp_types.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -* Copyright 2019 Advanced Micro Devices, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining a -* copy of this software and associated documentation files (the "Software"), -* to deal in the Software without restriction, including without limitation -* the rights to use, copy, modify, merge, publish, distribute, sublicense, -* and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -* OTHER DEALINGS IN THE SOFTWARE. -* -* Authors: AMD -* -*/ - -#ifndef __DC_HDCP_TYPES_H__ -#define __DC_HDCP_TYPES_H__ - -enum hdcp_message_id { - HDCP_MESSAGE_ID_INVALID = -1, - - /* HDCP 1.4 */ - - HDCP_MESSAGE_ID_READ_BKSV = 0, - /* HDMI is called Ri', DP is called R0' */ - HDCP_MESSAGE_ID_READ_RI_R0, - HDCP_MESSAGE_ID_READ_PJ, - HDCP_MESSAGE_ID_WRITE_AKSV, - HDCP_MESSAGE_ID_WRITE_AINFO, - HDCP_MESSAGE_ID_WRITE_AN, - HDCP_MESSAGE_ID_READ_VH_X, - HDCP_MESSAGE_ID_READ_VH_0, - HDCP_MESSAGE_ID_READ_VH_1, - HDCP_MESSAGE_ID_READ_VH_2, - HDCP_MESSAGE_ID_READ_VH_3, - HDCP_MESSAGE_ID_READ_VH_4, - HDCP_MESSAGE_ID_READ_BCAPS, - HDCP_MESSAGE_ID_READ_BSTATUS, - HDCP_MESSAGE_ID_READ_KSV_FIFO, - HDCP_MESSAGE_ID_READ_BINFO, - - /* HDCP 2.2 */ - - HDCP_MESSAGE_ID_HDCP2VERSION, - HDCP_MESSAGE_ID_RX_CAPS, - HDCP_MESSAGE_ID_WRITE_AKE_INIT, - HDCP_MESSAGE_ID_READ_AKE_SEND_CERT, - HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM, - HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM, - HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME, - HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO, - HDCP_MESSAGE_ID_WRITE_LC_INIT, - HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME, - HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS, - HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST, - HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK, - HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE, - HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY, - HDCP_MESSAGE_ID_READ_RXSTATUS, - HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE, - - HDCP_MESSAGE_ID_MAX -}; - -enum hdcp_version { - HDCP_Unknown = 0, - HDCP_VERSION_14, - HDCP_VERSION_22, -}; - -enum hdcp_link { - HDCP_LINK_PRIMARY, - HDCP_LINK_SECONDARY -}; - -enum hdcp_message_status { - HDCP_MESSAGE_SUCCESS, - HDCP_MESSAGE_FAILURE, - HDCP_MESSAGE_UNSUPPORTED -}; - -struct hdcp_protection_message { - enum hdcp_version version; - /* relevant only for DVI */ - enum hdcp_link link; - enum hdcp_message_id msg_id; - uint32_t length; - uint8_t max_retries; - uint8_t *data; - enum hdcp_message_status status; -}; - -#endif diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.h b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.h index eb6f9b9c504a..c62df3bcc7cb 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.h +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.h @@ -26,13 +26,11 @@ #ifndef MOD_HDCP_LOG_H_ #define MOD_HDCP_LOG_H_ -#ifdef CONFIG_DRM_AMD_DC_HDCP #define HDCP_LOG_ERR(hdcp, ...) DRM_DEBUG_KMS(__VA_ARGS__) #define HDCP_LOG_VER(hdcp, ...) DRM_DEBUG_KMS(__VA_ARGS__) #define HDCP_LOG_FSM(hdcp, ...) DRM_DEBUG_KMS(__VA_ARGS__) #define HDCP_LOG_TOP(hdcp, ...) pr_debug("[HDCP_TOP]:"__VA_ARGS__) #define HDCP_LOG_DDC(hdcp, ...) pr_debug("[HDCP_DDC]:"__VA_ARGS__) -#endif /* default logs */ #define HDCP_ERROR_TRACE(hdcp, status) \ -- cgit From efa4c4df864ecd969670093524d3e8f69188e5eb Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 13 Feb 2023 17:36:55 -0500 Subject: drm/amd/display: call remove_stream_from_ctx from res_pool funcs [Why & How] DM should never use a non-interface function to call into DC. The original code is incorrect on ASICs that don't use DCN20's remove_stream_from_ctx function. Reviewed-by: Aurabindo Pillai Acked-by: Qingqing Zhuo Signed-off-by: Harry Wentland Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 1579c2839ce3..248f25943748 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 @@ -1153,6 +1153,7 @@ int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, bool computed_streams[MAX_PIPES]; struct amdgpu_dm_connector *aconnector; struct drm_dp_mst_topology_mgr *mst_mgr; + struct resource_pool *res_pool; int link_vars_start_index = 0; int ret = 0; @@ -1161,6 +1162,7 @@ int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, for (i = 0; i < dc_state->stream_count; i++) { stream = dc_state->streams[i]; + res_pool = stream->ctx->dc->res_pool; if (stream->signal != SIGNAL_TYPE_DISPLAY_PORT_MST) continue; @@ -1176,7 +1178,8 @@ int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, if (computed_streams[i]) continue; - if (dcn20_remove_stream_from_ctx(stream->ctx->dc, dc_state, stream) != DC_OK) + if (!res_pool->funcs->remove_stream_from_ctx || + res_pool->funcs->remove_stream_from_ctx(stream->ctx->dc, dc_state, stream) != DC_OK) return -EINVAL; if (!is_dsc_need_re_compute(state, dc_state, stream->link)) @@ -1214,6 +1217,7 @@ static int pre_compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, bool computed_streams[MAX_PIPES]; struct amdgpu_dm_connector *aconnector; struct drm_dp_mst_topology_mgr *mst_mgr; + struct resource_pool *res_pool; int link_vars_start_index = 0; int ret = 0; @@ -1222,6 +1226,7 @@ static int pre_compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, for (i = 0; i < dc_state->stream_count; i++) { stream = dc_state->streams[i]; + res_pool = stream->ctx->dc->res_pool; if (stream->signal != SIGNAL_TYPE_DISPLAY_PORT_MST) continue; -- cgit From 84c03df58d8bbf77feb2f199f10dbe8f7f72c782 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 13 Feb 2023 15:29:06 -0500 Subject: drm/amd/display: Build DSC without DCN config [Why & How] DSC needs DCN but we are trying reduce the usage of the DCN flag. It's easier to build the DSC code sprinkled around DC core and the DMs and just guard the place where DSC uses floating point code. Since DSC is never enabled on non-DCN ASICs this won't have any effect. Reviewed-by: Hamza Mahfooz Acked-by: Qingqing Zhuo Signed-off-by: Harry Wentland Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/Makefile | 3 +-- drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile index ba75e91ef62b..d2b1e824eeaa 100644 --- a/drivers/gpu/drm/amd/display/dc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/Makefile @@ -22,14 +22,13 @@ # # Makefile for Display Core (dc) component. -DC_LIBS = basics bios dml clk_mgr dce gpio irq link virtual +DC_LIBS = basics bios dml clk_mgr dce gpio irq link virtual dsc ifdef CONFIG_DRM_AMD_DC_DCN KCOV_INSTRUMENT := n DC_LIBS += dcn20 -DC_LIBS += dsc DC_LIBS += dcn10 DC_LIBS += dcn21 DC_LIBS += dcn201 diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c index e97cf09be9d5..3215ca4d5799 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c @@ -39,6 +39,7 @@ */ void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps) { +#if defined(CONFIG_DRM_AMD_DC_DCN) enum colour_mode mode; enum bits_per_comp bpc; bool is_navite_422_or_420; @@ -59,4 +60,5 @@ void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps) slice_width, slice_height, pps->dsc_version_minor); DC_FP_END(); +#endif } -- cgit From 36516001a7c9cd7901673548ec685bd180b1b548 Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Tue, 14 Feb 2023 11:24:01 -0500 Subject: drm/amd/display: move dc_link functions in accessories folder to dc_link_exports [why] link component should only have one interface serving dc. [how] We are moving dc_link functions exposed to DM to dc_link_exports and unify link component interface in link.h with function pointer to match the style of other dc component. This is the first step to move dc_link functions under accessories folder to dc_link_exports. Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Wenjing Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 2 + .../gpu/drm/amd/display/dc/core/dc_link_exports.c | 78 ++++++++++++++++++++++ drivers/gpu/drm/amd/display/dc/dc.h | 6 +- drivers/gpu/drm/amd/display/dc/inc/link.h | 37 +++++++++- .../amd/display/dc/link/accessories/link_dp_cts.c | 41 +++--------- .../amd/display/dc/link/accessories/link_dp_cts.h | 19 ++++-- .../display/dc/link/accessories/link_dp_trace.c | 13 ++-- .../display/dc/link/accessories/link_dp_trace.h | 12 ++-- drivers/gpu/drm/amd/display/dc/link/link_factory.c | 20 ++++++ .../gpu/drm/amd/display/dc/link/link_resource.h | 3 - .../amd/display/dc/link/protocols/link_dp_phy.h | 5 -- 11 files changed, 178 insertions(+), 58 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 8be7a1fc5295..081d30c98a88 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -981,6 +981,8 @@ static bool dc_construct(struct dc *dc, goto fail; } + dc->link_srv = link_get_link_service(); + dc->res_pool = dc_create_resource_pool(dc, init_params, dc_ctx->dce_version); if (!dc->res_pool) goto fail; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c index 565c62a272d6..79e763b8209d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c @@ -186,3 +186,81 @@ bool dc_submit_i2c_oem( return false; } +void dc_link_dp_handle_automated_test(struct dc_link *link) +{ + link->dc->link_srv->dp_handle_automated_test(link); +} + +bool dc_link_dp_set_test_pattern( + struct dc_link *link, + enum dp_test_pattern test_pattern, + enum dp_test_pattern_color_space test_pattern_color_space, + const struct link_training_settings *p_link_settings, + const unsigned char *p_custom_pattern, + unsigned int cust_pattern_size) +{ + return link->dc->link_srv->dp_set_test_pattern(link, test_pattern, + test_pattern_color_space, p_link_settings, + p_custom_pattern, cust_pattern_size); +} + +void dc_link_set_drive_settings(struct dc *dc, + struct link_training_settings *lt_settings, + struct dc_link *link) +{ + struct link_resource link_res; + + link_get_cur_link_res(link, &link_res); + dp_set_drive_settings(link, &link_res, lt_settings); +} + +void dc_link_set_preferred_link_settings(struct dc *dc, + struct dc_link_settings *link_setting, + struct dc_link *link) +{ + dc->link_srv->dp_set_preferred_link_settings(dc, link_setting, link); +} + +void dc_link_set_preferred_training_settings(struct dc *dc, + struct dc_link_settings *link_setting, + struct dc_link_training_overrides *lt_overrides, + struct dc_link *link, + bool skip_immediate_retrain) +{ + dc->link_srv->dp_set_preferred_training_settings(dc, link_setting, + lt_overrides, link, skip_immediate_retrain); +} + +bool dc_dp_trace_is_initialized(struct dc_link *link) +{ + return link->dc->link_srv->dp_trace_is_initialized(link); +} + +void dc_dp_trace_set_is_logged_flag(struct dc_link *link, + bool in_detection, + bool is_logged) +{ + link->dc->link_srv->dp_trace_set_is_logged_flag(link, in_detection, is_logged); +} + +bool dc_dp_trace_is_logged(struct dc_link *link, bool in_detection) +{ + return link->dc->link_srv->dp_trace_is_logged(link, in_detection); +} + +unsigned long long dc_dp_trace_get_lt_end_timestamp(struct dc_link *link, + bool in_detection) +{ + return link->dc->link_srv->dp_trace_get_lt_end_timestamp(link, in_detection); +} + +const struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link, + bool in_detection) +{ + return link->dc->link_srv->dp_trace_get_lt_counts(link, in_detection); +} + +unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link) +{ + return link->dc->link_srv->dp_trace_get_link_loss_count(link); +} diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index ae9d31cf9a23..555d3aa65889 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -714,6 +714,7 @@ struct dc_bounding_box_overrides { struct dc_state; struct resource_pool; struct dce_hwseq; +struct link_service; /** * struct dc_debug_options - DC debug struct @@ -890,6 +891,7 @@ struct dc { uint8_t link_count; struct dc_link *links[MAX_PIPES * 2]; + const struct link_service *link_srv; struct dc_state *current_state; struct resource_pool *res_pool; @@ -1828,7 +1830,7 @@ bool dc_link_is_dp_sink_present(struct dc_link *link); */ void dc_link_set_drive_settings(struct dc *dc, struct link_training_settings *lt_settings, - const struct dc_link *link); + struct dc_link *link); /* Enable a test pattern in Link or PHY layer in an active link for compliance * test or debugging purpose. The test pattern will remain until next un-plug. @@ -1986,7 +1988,7 @@ unsigned long long dc_dp_trace_get_lt_end_timestamp(struct dc_link *link, * training in detection sequence. false to get link training count of last link * training in commit (dpms) sequence */ -struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link, +const struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link, bool in_detection); /* Get how many link loss has happened since last link training attempts */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/link.h b/drivers/gpu/drm/amd/display/dc/inc/link.h index a3fcfa918a8f..cfe6fc48b6e9 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link.h @@ -48,8 +48,38 @@ struct link_init_data { bool is_dpia_link; }; +struct link_service { + void (*dp_handle_automated_test)(struct dc_link *link); + bool (*dp_set_test_pattern)( + struct dc_link *link, + enum dp_test_pattern test_pattern, + enum dp_test_pattern_color_space test_pattern_color_space, + const struct link_training_settings *p_link_settings, + const unsigned char *p_custom_pattern, + unsigned int cust_pattern_size); + void (*dp_set_preferred_link_settings)(struct dc *dc, + struct dc_link_settings *link_setting, + struct dc_link *link); + void (*dp_set_preferred_training_settings)(struct dc *dc, + struct dc_link_settings *link_setting, + struct dc_link_training_overrides *lt_overrides, + struct dc_link *link, + bool skip_immediate_retrain); + bool (*dp_trace_is_initialized)(struct dc_link *link); + void (*dp_trace_set_is_logged_flag)(struct dc_link *link, + bool in_detection, + bool is_logged); + bool (*dp_trace_is_logged)(struct dc_link *link, bool in_detection); + unsigned long long (*dp_trace_get_lt_end_timestamp)( + struct dc_link *link, bool in_detection); + const struct dp_trace_lt_counts *(*dp_trace_get_lt_counts)( + struct dc_link *link, bool in_detection); + unsigned int (*dp_trace_get_link_loss_count)(struct dc_link *link); +}; + struct dc_link *link_create(const struct link_init_data *init_params); void link_destroy(struct dc_link **link); +const struct link_service *link_get_link_service(void); // TODO - convert any function declarations below to function pointers struct gpio *link_get_hpd_gpio(struct dc_bios *dcb, @@ -150,5 +180,10 @@ uint32_t dp_link_bandwidth_kbps( uint32_t link_timing_bandwidth_kbps(const struct dc_crtc_timing *timing); void link_get_cur_res_map(const struct dc *dc, uint32_t *map); void link_restore_res_map(const struct dc *dc, uint32_t *map); - +void link_get_cur_link_res(const struct dc_link *link, + struct link_resource *link_res); +void dp_set_drive_settings( + struct dc_link *link, + const struct link_resource *link_res, + struct link_training_settings *lt_settings); #endif /* __DC_LINK_HPD_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c index 7f36d733bfca..080019f4252f 100644 --- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c +++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c @@ -75,7 +75,7 @@ static bool is_dp_phy_pattern(enum dp_test_pattern test_pattern) return false; } -void dp_retrain_link_dp_test(struct dc_link *link, +static void dp_retrain_link_dp_test(struct dc_link *link, struct dc_link_settings *link_setting, bool skip_video_pattern) { @@ -585,7 +585,7 @@ static void set_crtc_test_pattern(struct dc_link *link, } } -void dc_link_dp_handle_automated_test(struct dc_link *link) +void dp_handle_automated_test(struct dc_link *link) { union test_request test_request; union test_response test_response; @@ -651,7 +651,7 @@ void dc_link_dp_handle_automated_test(struct dc_link *link) sizeof(test_response)); } -bool dc_link_dp_set_test_pattern( +bool dp_set_test_pattern( struct dc_link *link, enum dp_test_pattern test_pattern, enum dp_test_pattern_color_space test_pattern_color_space, @@ -941,28 +941,9 @@ bool dc_link_dp_set_test_pattern( return true; } -void dc_link_set_drive_settings(struct dc *dc, - struct link_training_settings *lt_settings, - const struct dc_link *link) -{ - - int i; - struct link_resource link_res; - - for (i = 0; i < dc->link_count; i++) - if (dc->links[i] == link) - break; - - if (i >= dc->link_count) - ASSERT_CRITICAL(false); - - link_get_cur_link_res(link, &link_res); - dp_set_drive_settings(dc->links[i], &link_res, lt_settings); -} - -void dc_link_set_preferred_link_settings(struct dc *dc, - struct dc_link_settings *link_setting, - struct dc_link *link) +void dp_set_preferred_link_settings(struct dc *dc, + struct dc_link_settings *link_setting, + struct dc_link *link) { int i; struct pipe_ctx *pipe; @@ -1001,11 +982,11 @@ void dc_link_set_preferred_link_settings(struct dc *dc, dp_retrain_link_dp_test(link, &store_settings, false); } -void dc_link_set_preferred_training_settings(struct dc *dc, - struct dc_link_settings *link_setting, - struct dc_link_training_overrides *lt_overrides, - struct dc_link *link, - bool skip_immediate_retrain) +void dp_set_preferred_training_settings(struct dc *dc, + struct dc_link_settings *link_setting, + struct dc_link_training_overrides *lt_overrides, + struct dc_link *link, + bool skip_immediate_retrain) { if (lt_overrides != NULL) link->preferred_training_settings = *lt_overrides; diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.h b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.h index 7f17838b653b..eae23ea7f6ec 100644 --- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.h +++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.h @@ -25,9 +25,20 @@ #ifndef __LINK_DP_CTS_H__ #define __LINK_DP_CTS_H__ #include "link.h" - -void dp_retrain_link_dp_test(struct dc_link *link, +void dp_handle_automated_test(struct dc_link *link); +bool dp_set_test_pattern( + struct dc_link *link, + enum dp_test_pattern test_pattern, + enum dp_test_pattern_color_space test_pattern_color_space, + const struct link_training_settings *p_link_settings, + const unsigned char *p_custom_pattern, + unsigned int cust_pattern_size); +void dp_set_preferred_link_settings(struct dc *dc, struct dc_link_settings *link_setting, - bool skip_video_pattern); - + struct dc_link *link); +void dp_set_preferred_training_settings(struct dc *dc, + struct dc_link_settings *link_setting, + struct dc_link_training_overrides *lt_overrides, + struct dc_link *link, + bool skip_immediate_retrain); #endif /* __LINK_DP_CTS_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.c index 459b362ed374..277fe9137a97 100644 --- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.c +++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.c @@ -37,7 +37,7 @@ void dp_trace_reset(struct dc_link *link) memset(&link->dp_trace, 0, sizeof(link->dp_trace)); } -bool dc_dp_trace_is_initialized(struct dc_link *link) +bool dp_trace_is_initialized(struct dc_link *link) { return link->dp_trace.is_initialized; } @@ -76,7 +76,7 @@ void dp_trace_lt_total_count_increment(struct dc_link *link, link->dp_trace.commit_lt_trace.counts.total++; } -void dc_dp_trace_set_is_logged_flag(struct dc_link *link, +void dp_trace_set_is_logged_flag(struct dc_link *link, bool in_detection, bool is_logged) { @@ -86,8 +86,7 @@ void dc_dp_trace_set_is_logged_flag(struct dc_link *link, link->dp_trace.commit_lt_trace.is_logged = is_logged; } -bool dc_dp_trace_is_logged(struct dc_link *link, - bool in_detection) +bool dp_trace_is_logged(struct dc_link *link, bool in_detection) { if (in_detection) return link->dp_trace.detect_lt_trace.is_logged; @@ -123,7 +122,7 @@ void dp_trace_set_lt_end_timestamp(struct dc_link *link, link->dp_trace.commit_lt_trace.timestamps.end = dm_get_timestamp(link->dc->ctx); } -unsigned long long dc_dp_trace_get_lt_end_timestamp(struct dc_link *link, +unsigned long long dp_trace_get_lt_end_timestamp(struct dc_link *link, bool in_detection) { if (in_detection) @@ -132,7 +131,7 @@ unsigned long long dc_dp_trace_get_lt_end_timestamp(struct dc_link *link, return link->dp_trace.commit_lt_trace.timestamps.end; } -struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link, +const struct dp_trace_lt_counts *dp_trace_get_lt_counts(struct dc_link *link, bool in_detection) { if (in_detection) @@ -141,7 +140,7 @@ struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link, return &link->dp_trace.commit_lt_trace.counts; } -unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link) +unsigned int dp_trace_get_link_loss_count(struct dc_link *link) { return link->dp_trace.link_loss_count; } diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.h b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.h index 89feea1b2692..9a0aff81a251 100644 --- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.h +++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.h @@ -28,7 +28,7 @@ void dp_trace_init(struct dc_link *link); void dp_trace_reset(struct dc_link *link); -bool dc_dp_trace_is_initialized(struct dc_link *link); +bool dp_trace_is_initialized(struct dc_link *link); void dp_trace_detect_lt_init(struct dc_link *link); void dp_trace_commit_lt_init(struct dc_link *link); void dp_trace_link_loss_increment(struct dc_link *link); @@ -37,10 +37,10 @@ void dp_trace_lt_fail_count_update(struct dc_link *link, bool in_detection); void dp_trace_lt_total_count_increment(struct dc_link *link, bool in_detection); -void dc_dp_trace_set_is_logged_flag(struct dc_link *link, +void dp_trace_set_is_logged_flag(struct dc_link *link, bool in_detection, bool is_logged); -bool dc_dp_trace_is_logged(struct dc_link *link, +bool dp_trace_is_logged(struct dc_link *link, bool in_detection); void dp_trace_lt_result_update(struct dc_link *link, enum link_training_result result, @@ -49,10 +49,10 @@ void dp_trace_set_lt_start_timestamp(struct dc_link *link, bool in_detection); void dp_trace_set_lt_end_timestamp(struct dc_link *link, bool in_detection); -unsigned long long dc_dp_trace_get_lt_end_timestamp(struct dc_link *link, +unsigned long long dp_trace_get_lt_end_timestamp(struct dc_link *link, bool in_detection); -struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link, +const struct dp_trace_lt_counts *dp_trace_get_lt_counts(struct dc_link *link, bool in_detection); -unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link); +unsigned int dp_trace_get_link_loss_count(struct dc_link *link); #endif /* __LINK_DP_TRACE_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index aeb26a4d539e..88fbd04e92f2 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -27,6 +27,9 @@ * This file owns the creation/destruction of link structure. */ #include "link_factory.h" +#include "accessories/link_dp_cts.h" +#include "accessories/link_dp_trace.h" +#include "accessories/link_fpga.h" #include "protocols/link_ddc.h" #include "protocols/link_edp_panel_control.h" #include "protocols/link_hpd.h" @@ -39,6 +42,19 @@ DC_LOG_HW_HOTPLUG( \ __VA_ARGS__) +static struct link_service link_srv = { + .dp_handle_automated_test = dp_handle_automated_test, + .dp_set_test_pattern = dp_set_test_pattern, + .dp_set_preferred_link_settings = dp_set_preferred_link_settings, + .dp_set_preferred_training_settings = dp_set_preferred_training_settings, + .dp_trace_is_initialized = dp_trace_is_initialized, + .dp_trace_set_is_logged_flag = dp_trace_set_is_logged_flag, + .dp_trace_is_logged = dp_trace_is_logged, + .dp_trace_get_lt_end_timestamp = dp_trace_get_lt_end_timestamp, + .dp_trace_get_lt_counts = dp_trace_get_lt_counts, + .dp_trace_get_link_loss_count = dp_trace_get_link_loss_count, +}; + static enum transmitter translate_encoder_to_transmitter(struct graphics_object_id encoder) { switch (encoder.id) { @@ -575,3 +591,7 @@ void link_destroy(struct dc_link **link) *link = NULL; } +const struct link_service *link_get_link_service(void) +{ + return &link_srv; +} diff --git a/drivers/gpu/drm/amd/display/dc/link/link_resource.h b/drivers/gpu/drm/amd/display/dc/link/link_resource.h index 45554d30adf0..68dfbfc973cc 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_resource.h +++ b/drivers/gpu/drm/amd/display/dc/link/link_resource.h @@ -25,7 +25,4 @@ #ifndef __LINK_RESOURCE_H__ #define __LINK_RESOURCE_H__ #include "link.h" -void link_get_cur_link_res(const struct dc_link *link, - struct link_resource *link_res); - #endif /* __LINK_RESOURCE_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h index dba1f29df319..831ffd456291 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h @@ -44,11 +44,6 @@ void dp_set_hw_lane_settings( const struct link_training_settings *link_settings, uint32_t offset); -void dp_set_drive_settings( - struct dc_link *link, - const struct link_resource *link_res, - struct link_training_settings *lt_settings); - enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready); void dp_set_fec_enable(struct dc_link *link, bool enable); -- cgit From 76f5dc40ebb188b081e03783541856c03e97f8e0 Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Tue, 14 Feb 2023 12:16:55 -0500 Subject: drm/amd/display: move dc_link functions in link root folder to dc_link_exports [why] link component should only have one interface serving dc. [how] We are moving dc_link functions exposed to DM to dc_link_exports and unify link component interface in link.h with function pointer to match the style of other dc component. This is the second step to move dc_link functions under link root folder to dc_link_exports. Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Wenjing Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c | 15 +++++++++++++++ drivers/gpu/drm/amd/display/dc/inc/link.h | 6 ++++++ drivers/gpu/drm/amd/display/dc/link/link_detection.c | 4 ++-- drivers/gpu/drm/amd/display/dc/link/link_detection.h | 6 ++++++ drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 8 ++++---- drivers/gpu/drm/amd/display/dc/link/link_factory.c | 11 +++++++---- 6 files changed, 40 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c index 79e763b8209d..b1fedef193a0 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c @@ -264,3 +264,18 @@ unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link) { return link->dc->link_srv->dp_trace_get_link_loss_count(link); } + +struct dc_sink *dc_link_add_remote_sink( + struct dc_link *link, + const uint8_t *edid, + int len, + struct dc_sink_init_data *init_data) +{ + return link->dc->link_srv->add_remote_sink(link, edid, len, init_data); +} + +void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink) +{ + link->dc->link_srv->remove_remote_sink(link, sink); +} + diff --git a/drivers/gpu/drm/amd/display/dc/inc/link.h b/drivers/gpu/drm/amd/display/dc/inc/link.h index cfe6fc48b6e9..9c05333f62aa 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link.h @@ -49,6 +49,12 @@ struct link_init_data { }; struct link_service { + struct dc_sink *(*add_remote_sink)( + struct dc_link *link, + const uint8_t *edid, + int len, + struct dc_sink_init_data *init_data); + void (*remove_remote_sink)(struct dc_link *link, struct dc_sink *sink); void (*dp_handle_automated_test)(struct dc_link *link); bool (*dp_set_test_pattern)( struct dc_link *link, diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 99279e1e7330..2a248ee0d70e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -1327,7 +1327,7 @@ static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink return true; } -struct dc_sink *dc_link_add_remote_sink( +struct dc_sink *link_add_remote_sink( struct dc_link *link, const uint8_t *edid, int len, @@ -1385,7 +1385,7 @@ fail_add_sink: return NULL; } -void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink) +void link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink) { int i; diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.h b/drivers/gpu/drm/amd/display/dc/link/link_detection.h index 1831636516fb..4b1731c4fd3d 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.h +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.h @@ -26,5 +26,11 @@ #ifndef __DC_LINK_DETECTION_H__ #define __DC_LINK_DETECTION_H__ #include "link.h" +struct dc_sink *link_add_remote_sink( + struct dc_link *link, + const uint8_t *edid, + int len, + struct dc_sink_init_data *init_data); +void link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink); #endif /* __DC_LINK_DETECTION_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index 0039928186ff..650ac2a608ef 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -1000,7 +1000,7 @@ static void enable_stream_features(struct pipe_ctx *pipe_ctx) } } -static void dc_log_vcp_x_y(const struct dc_link *link, struct fixed31_32 avg_time_slots_per_mtp) +static void log_vcp_x_y(const struct dc_link *link, struct fixed31_32 avg_time_slots_per_mtp) { const uint32_t VCP_Y_PRECISION = 1000; uint64_t vcp_x, vcp_y; @@ -1516,7 +1516,7 @@ static enum dc_status allocate_mst_payload(struct pipe_ctx *pipe_ctx) pbn = get_pbn_from_timing(pipe_ctx); avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot); - dc_log_vcp_x_y(link, avg_time_slots_per_mtp); + log_vcp_x_y(link, avg_time_slots_per_mtp); if (link_hwss->ext.set_throttled_vcp_size) link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp); @@ -1669,7 +1669,7 @@ static enum dc_status update_sst_payload(struct pipe_ctx *pipe_ctx, if (!allocate) { avg_time_slots_per_mtp = dc_fixpt_from_int(0); - dc_log_vcp_x_y(link, avg_time_slots_per_mtp); + log_vcp_x_y(link, avg_time_slots_per_mtp); if (link_hwss->ext.set_throttled_vcp_size) link_hwss->ext.set_throttled_vcp_size(pipe_ctx, @@ -1720,7 +1720,7 @@ static enum dc_status update_sst_payload(struct pipe_ctx *pipe_ctx, DP_128b_132b_ENCODING) { avg_time_slots_per_mtp = link_calculate_sst_avg_time_slots_per_mtp(stream, link); - dc_log_vcp_x_y(link, avg_time_slots_per_mtp); + log_vcp_x_y(link, avg_time_slots_per_mtp); if (link_hwss->ext.set_throttled_vcp_size) link_hwss->ext.set_throttled_vcp_size(pipe_ctx, diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index 88fbd04e92f2..e37f271a6c72 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -27,6 +27,7 @@ * This file owns the creation/destruction of link structure. */ #include "link_factory.h" +#include "link_detection.h" #include "accessories/link_dp_cts.h" #include "accessories/link_dp_trace.h" #include "accessories/link_fpga.h" @@ -43,6 +44,8 @@ __VA_ARGS__) static struct link_service link_srv = { + .add_remote_sink = link_add_remote_sink, + .remove_remote_sink = link_remove_remote_sink, .dp_handle_automated_test = dp_handle_automated_test, .dp_set_test_pattern = dp_set_test_pattern, .dp_set_preferred_link_settings = dp_set_preferred_link_settings, @@ -197,7 +200,7 @@ static enum channel_id get_ddc_line(struct dc_link *link) return channel; } -static bool dc_link_construct_phy(struct dc_link *link, +static bool construct_phy(struct dc_link *link, const struct link_init_data *init_params) { uint8_t i; @@ -489,7 +492,7 @@ create_fail: return false; } -static bool dc_link_construct_dpia(struct dc_link *link, +static bool construct_dpia(struct dc_link *link, const struct link_init_data *init_params) { struct ddc_service_init_data ddc_service_init_data = { 0 }; @@ -559,9 +562,9 @@ static bool link_construct(struct dc_link *link, { /* Handle dpia case */ if (init_params->is_dpia_link == true) - return dc_link_construct_dpia(link, init_params); + return construct_dpia(link, init_params); else - return dc_link_construct_phy(link, init_params); + return construct_phy(link, init_params); } struct dc_link *link_create(const struct link_init_data *init_params) -- cgit From 6455cb522191dac057d5cc4b3f24d5d3ae6a33ef Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Wed, 15 Feb 2023 16:03:09 -0500 Subject: drm/amd/display: link link_dp_dpia_bw.o in makefile [Why & How] - We have added link_dp_dpia_bw code but it is not currently added in makefile. We are adding this to makefile so it would be built. - Remove unused dc_link.h Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Wenjing Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_dp_types.h | 66 ++- drivers/gpu/drm/amd/display/dc/dc_link.h | 579 --------------------- drivers/gpu/drm/amd/display/dc/link/Makefile | 2 +- .../display/dc/link/protocols/link_dp_dpia_bw.c | 31 +- .../display/dc/link/protocols/link_dp_dpia_bw.h | 2 +- 5 files changed, 68 insertions(+), 612 deletions(-) delete mode 100644 drivers/gpu/drm/amd/display/dc/dc_link.h (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h index 4bccce94d83b..af53278662ec 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h @@ -921,12 +921,6 @@ struct dpcd_usb4_dp_tunneling_info { #ifndef DP_DFP_CAPABILITY_EXTENSION_SUPPORT #define DP_DFP_CAPABILITY_EXTENSION_SUPPORT 0x0A3 #endif -#ifndef DP_LINK_SQUARE_PATTERN -#define DP_LINK_SQUARE_PATTERN 0x10F -#endif -#ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX -#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX 0x110 -#endif #ifndef DP_DSC_CONFIGURATION #define DP_DSC_CONFIGURATION 0x161 #endif @@ -939,12 +933,6 @@ struct dpcd_usb4_dp_tunneling_info { #ifndef DP_128b_132b_TRAINING_AUX_RD_INTERVAL #define DP_128b_132b_TRAINING_AUX_RD_INTERVAL 0x2216 #endif -#ifndef DP_LINK_SQUARE_PATTERN -#define DP_LINK_SQUARE_PATTERN 0x10F -#endif -#ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX -#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX 0x2217 -#endif #ifndef DP_TEST_264BIT_CUSTOM_PATTERN_7_0 #define DP_TEST_264BIT_CUSTOM_PATTERN_7_0 0X2230 #endif @@ -988,10 +976,6 @@ struct dpcd_usb4_dp_tunneling_info { #define DP_INTRA_HOP_AUX_REPLY_INDICATION (1 << 3) /* TODO - Use DRM header to replace above once available */ #endif // DP_INTRA_HOP_AUX_REPLY_INDICATION - -#ifndef DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE -#define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50 -#endif union dp_main_line_channel_coding_cap { struct { uint8_t DP_8b_10b_SUPPORTED :1; @@ -1368,4 +1352,54 @@ struct dp_trace { bool is_initialized; struct edp_trace_power_timestamps edp_trace_power_timestamps; }; + +/* TODO - This is a temporary location for any new DPCD definitions. + * We should move these to drm_dp header. + */ +#ifndef DP_LINK_SQUARE_PATTERN +#define DP_LINK_SQUARE_PATTERN 0x10F +#endif +#ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX +#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX 0x2217 +#endif +#ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX +#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX 0x110 +#endif +#ifndef DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE +#define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50 +#endif +#ifndef DP_TUNNELING_IRQ +#define DP_TUNNELING_IRQ (1 << 5) +#endif +/** USB4 DPCD BW Allocation Registers Chapter 10.7 **/ +#ifndef DP_TUNNELING_CAPABILITIES +#define DP_TUNNELING_CAPABILITIES 0xE000D /* 1.4a */ +#endif +#ifndef USB4_DRIVER_ID +#define USB4_DRIVER_ID 0xE000F /* 1.4a */ +#endif +#ifndef USB4_DRIVER_BW_CAPABILITY +#define USB4_DRIVER_BW_CAPABILITY 0xE0020 /* 1.4a */ +#endif +#ifndef DP_IN_ADAPTER_TUNNEL_INFO +#define DP_IN_ADAPTER_TUNNEL_INFO 0xE0021 /* 1.4a */ +#endif +#ifndef DP_BW_GRANULALITY +#define DP_BW_GRANULALITY 0xE0022 /* 1.4a */ +#endif +#ifndef ESTIMATED_BW +#define ESTIMATED_BW 0xE0023 /* 1.4a */ +#endif +#ifndef ALLOCATED_BW +#define ALLOCATED_BW 0xE0024 /* 1.4a */ +#endif +#ifndef DP_TUNNELING_STATUS +#define DP_TUNNELING_STATUS 0xE0025 /* 1.4a */ +#endif +#ifndef DPTX_BW_ALLOCATION_MODE_CONTROL +#define DPTX_BW_ALLOCATION_MODE_CONTROL 0xE0030 /* 1.4a */ +#endif +#ifndef REQUESTED_BW +#define REQUESTED_BW 0xE0031 /* 1.4a */ +#endif #endif /* DC_DP_TYPES_H */ diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h deleted file mode 100644 index 80e18c770cda..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright 2012-14 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -#ifndef DC_LINK_H_ -#define DC_LINK_H_ - -#include "dc.h" -#include "dc_types.h" -#include "grph_object_defs.h" - -struct link_resource; -enum aux_return_code_type; - -enum dc_link_fec_state { - dc_link_fec_not_ready, - dc_link_fec_ready, - dc_link_fec_enabled -}; - -/* DP MST stream allocation (payload bandwidth number) */ -struct link_mst_stream_allocation { - /* DIG front */ - const struct stream_encoder *stream_enc; - /* HPO DP Stream Encoder */ - const struct hpo_dp_stream_encoder *hpo_dp_stream_enc; - /* associate DRM payload table with DC stream encoder */ - uint8_t vcp_id; - /* number of slots required for the DP stream in transport packet */ - uint8_t slot_count; -}; - -/* DP MST stream allocation table */ -struct link_mst_stream_allocation_table { - /* number of DP video streams */ - int stream_count; - /* array of stream allocations */ - struct link_mst_stream_allocation stream_allocations[MAX_CONTROLLER_NUM]; -}; - -struct edp_trace_power_timestamps { - uint64_t poweroff; - uint64_t poweron; -}; - -struct dp_trace_lt_counts { - unsigned int total; - unsigned int fail; -}; - -struct dp_trace_lt { - struct dp_trace_lt_counts counts; - struct dp_trace_timestamps { - unsigned long long start; - unsigned long long end; - } timestamps; - enum link_training_result result; - bool is_logged; -}; - -struct dp_trace { - struct dp_trace_lt detect_lt_trace; - struct dp_trace_lt commit_lt_trace; - unsigned int link_loss_count; - bool is_initialized; - struct edp_trace_power_timestamps edp_trace_power_timestamps; -}; - -/* PSR feature flags */ -struct psr_settings { - bool psr_feature_enabled; // PSR is supported by sink - bool psr_allow_active; // PSR is currently active - enum dc_psr_version psr_version; // Internal PSR version, determined based on DPCD - bool psr_vtotal_control_support; // Vtotal control is supported by sink - unsigned long long psr_dirty_rects_change_timestamp_ns; // for delay of enabling PSR-SU - - /* These parameters are calculated in Driver, - * based on display timing and Sink capabilities. - * If VBLANK region is too small and Sink takes a long time - * to set up RFB, it may take an extra frame to enter PSR state. - */ - bool psr_frame_capture_indication_req; - unsigned int psr_sdp_transmit_line_num_deadline; - uint8_t force_ffu_mode; - unsigned int psr_power_opt; -}; - -/* To split out "global" and "per-panel" config settings. - * Add a struct dc_panel_config under dc_link - */ -struct dc_panel_config { - /* extra panel power sequence parameters */ - struct pps { - unsigned int extra_t3_ms; - unsigned int extra_t7_ms; - unsigned int extra_delay_backlight_off; - unsigned int extra_post_t7_ms; - unsigned int extra_pre_t11_ms; - unsigned int extra_t12_ms; - unsigned int extra_post_OUI_ms; - } pps; - /* PSR */ - struct psr { - bool disable_psr; - bool disallow_psrsu; - bool rc_disable; - bool rc_allow_static_screen; - bool rc_allow_fullscreen_VPB; - } psr; - /* ABM */ - struct varib { - unsigned int varibright_feature_enable; - unsigned int def_varibright_level; - unsigned int abm_config_setting; - } varib; - /* edp DSC */ - struct dsc { - bool disable_dsc_edp; - unsigned int force_dsc_edp_policy; - } dsc; - /* eDP ILR */ - struct ilr { - bool optimize_edp_link_rate; /* eDP ILR */ - } ilr; -}; - -/* - * USB4 DPIA BW ALLOCATION STRUCTS - */ -struct dc_dpia_bw_alloc { - int sink_verified_bw; // The Verified BW that sink can allocated and use that has been verified already - int sink_allocated_bw; // The Actual Allocated BW that sink currently allocated - int sink_max_bw; // The Max BW that sink can require/support - int estimated_bw; // The estimated available BW for this DPIA - int bw_granularity; // BW Granularity - bool bw_alloc_enabled; // The BW Alloc Mode Support is turned ON for all 3: DP-Tx & Dpia & CM - bool response_ready; // Response ready from the CM side -}; - -#define MAX_SINKS_PER_LINK 4 - -/* - * A link contains one or more sinks and their connected status. - * The currently active signal type (HDMI, DP-SST, DP-MST) is also reported. - */ -struct dc_link { - struct dc_sink *remote_sinks[MAX_SINKS_PER_LINK]; - unsigned int sink_count; - struct dc_sink *local_sink; - unsigned int link_index; - enum dc_connection_type type; - enum signal_type connector_signal; - enum dc_irq_source irq_source_hpd; - enum dc_irq_source irq_source_hpd_rx;/* aka DP Short Pulse */ - bool is_hpd_filter_disabled; - bool dp_ss_off; - - /** - * @link_state_valid: - * - * If there is no link and local sink, this variable should be set to - * false. Otherwise, it should be set to true; usually, the function - * core_link_enable_stream sets this field to true. - */ - bool link_state_valid; - bool aux_access_disabled; - bool sync_lt_in_progress; - bool is_internal_display; - - /* TODO: Rename. Flag an endpoint as having a programmable mapping to a - * DIG encoder. */ - bool is_dig_mapping_flexible; - bool hpd_status; /* HPD status of link without physical HPD pin. */ - bool is_hpd_pending; /* Indicates a new received hpd */ - bool is_automated; /* Indicates automated testing */ - - bool edp_sink_present; - - struct dp_trace dp_trace; - - /* caps is the same as reported_link_cap. link_traing use - * reported_link_cap. Will clean up. TODO - */ - struct dc_link_settings reported_link_cap; - struct dc_link_settings verified_link_cap; - struct dc_link_settings cur_link_settings; - struct dc_lane_settings cur_lane_setting[LANE_COUNT_DP_MAX]; - struct dc_link_settings preferred_link_setting; - /* preferred_training_settings are override values that - * come from DM. DM is responsible for the memory - * management of the override pointers. - */ - struct dc_link_training_overrides preferred_training_settings; - struct dp_audio_test_data audio_test_data; - - uint8_t ddc_hw_inst; - - uint8_t hpd_src; - - uint8_t link_enc_hw_inst; - /* DIG link encoder ID. Used as index in link encoder resource pool. - * For links with fixed mapping to DIG, this is not changed after dc_link - * object creation. - */ - enum engine_id eng_id; - - bool test_pattern_enabled; - union compliance_test_state compliance_test_state; - - void *priv; - - struct ddc_service *ddc; - - bool aux_mode; - - /* Private to DC core */ - - const struct dc *dc; - - struct dc_context *ctx; - - struct panel_cntl *panel_cntl; - struct link_encoder *link_enc; - struct graphics_object_id link_id; - /* Endpoint type distinguishes display endpoints which do not have entries - * in the BIOS connector table from those that do. Helps when tracking link - * encoder to display endpoint assignments. - */ - enum display_endpoint_type ep_type; - union ddi_channel_mapping ddi_channel_mapping; - struct connector_device_tag_info device_tag; - struct dpcd_caps dpcd_caps; - uint32_t dongle_max_pix_clk; - unsigned short chip_caps; - unsigned int dpcd_sink_count; -#if defined(CONFIG_DRM_AMD_DC_HDCP) - struct hdcp_caps hdcp_caps; -#endif - enum edp_revision edp_revision; - union dpcd_sink_ext_caps dpcd_sink_ext_caps; - - struct psr_settings psr_settings; - - /* Drive settings read from integrated info table */ - struct dc_lane_settings bios_forced_drive_settings; - - /* Vendor specific LTTPR workaround variables */ - uint8_t vendor_specific_lttpr_link_rate_wa; - bool apply_vendor_specific_lttpr_link_rate_wa; - - /* MST record stream using this link */ - struct link_flags { - bool dp_keep_receiver_powered; - bool dp_skip_DID2; - bool dp_skip_reset_segment; - bool dp_skip_fs_144hz; - bool dp_mot_reset_segment; - /* Some USB4 docks do not handle turning off MST DSC once it has been enabled. */ - bool dpia_mst_dsc_always_on; - /* Forced DPIA into TBT3 compatibility mode. */ - bool dpia_forced_tbt3_mode; - bool dongle_mode_timing_override; - } wa_flags; - struct link_mst_stream_allocation_table mst_stream_alloc_table; - - struct dc_link_status link_status; - struct dprx_states dprx_states; - - struct gpio *hpd_gpio; - enum dc_link_fec_state fec_state; - bool link_powered_externally; // Used to bypass hardware sequencing delays when panel is powered down forcibly - - struct dc_panel_config panel_config; - struct phy_state phy_state; - // BW ALLOCATON USB4 ONLY - struct dc_dpia_bw_alloc dpia_bw_alloc_config; -}; - - -/** - * dc_get_link_at_index() - Return an enumerated dc_link. - * - * dc_link order is constant and determined at - * boot time. They cannot be created or destroyed. - * Use dc_get_caps() to get number of links. - */ -static inline struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index) -{ - return dc->links[link_index]; -} - -static inline void get_edp_links(const struct dc *dc, - struct dc_link **edp_links, - int *edp_num) -{ - int i; - - *edp_num = 0; - for (i = 0; i < dc->link_count; i++) { - // report any eDP links, even unconnected DDI's - if (!dc->links[i]) - continue; - if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) { - edp_links[*edp_num] = dc->links[i]; - if (++(*edp_num) == MAX_NUM_EDP) - return; - } - } -} - -static inline bool dc_get_edp_link_panel_inst(const struct dc *dc, - const struct dc_link *link, - unsigned int *inst_out) -{ - struct dc_link *edp_links[MAX_NUM_EDP]; - int edp_num, i; - - *inst_out = 0; - if (link->connector_signal != SIGNAL_TYPE_EDP) - return false; - get_edp_links(dc, edp_links, &edp_num); - for (i = 0; i < edp_num; i++) { - if (link == edp_links[i]) - break; - (*inst_out)++; - } - return true; -} - -/* Set backlight level of an embedded panel (eDP, LVDS). - * backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer - * and 16 bit fractional, where 1.0 is max backlight value. - */ -bool dc_link_set_backlight_level(const struct dc_link *dc_link, - uint32_t backlight_pwm_u16_16, - uint32_t frame_ramp); - -/* Set/get nits-based backlight level of an embedded panel (eDP, LVDS). */ -bool dc_link_set_backlight_level_nits(struct dc_link *link, - bool isHDR, - uint32_t backlight_millinits, - uint32_t transition_time_in_ms); - -bool dc_link_get_backlight_level_nits(struct dc_link *link, - uint32_t *backlight_millinits, - uint32_t *backlight_millinits_peak); - -int dc_link_get_backlight_level(const struct dc_link *dc_link); - -int dc_link_get_target_backlight_pwm(const struct dc_link *link); - -bool dc_link_set_psr_allow_active(struct dc_link *dc_link, const bool *enable, - bool wait, bool force_static, const unsigned int *power_opts); - -bool dc_link_get_psr_state(const struct dc_link *dc_link, enum dc_psr_state *state); - -bool dc_link_setup_psr(struct dc_link *dc_link, - const struct dc_stream_state *stream, struct psr_config *psr_config, - struct psr_context *psr_context); - -bool dc_link_get_hpd_state(struct dc_link *dc_link); - -/* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt). - * Return: - * true - Downstream port status changed. DM should call DC to do the - * detection. - * false - no change in Downstream port status. No further action required - * from DM. */ -bool dc_link_handle_hpd_rx_irq(struct dc_link *dc_link, - union hpd_irq_data *hpd_irq_dpcd_data, bool *out_link_loss, - bool defer_handling, bool *has_left_work); - -/* - * On eDP links this function call will stall until T12 has elapsed. - * If the panel is not in power off state, this function will return - * immediately. - */ -bool dc_link_wait_for_t12(struct dc_link *link); - -void dc_link_dp_handle_automated_test(struct dc_link *link); -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 dc_link_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( - struct dc_link *dc_link, - const uint8_t *edid, - int len, - struct dc_sink_init_data *init_data); - -void dc_link_remove_remote_sink( - struct dc_link *link, - struct dc_sink *sink); - -/* Used by diagnostics for virtual link at the moment */ - -bool dc_link_dp_set_test_pattern( - struct dc_link *link, - enum dp_test_pattern test_pattern, - enum dp_test_pattern_color_space test_pattern_color_space, - const struct link_training_settings *p_link_settings, - const unsigned char *p_custom_pattern, - unsigned int cust_pattern_size); - -bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap); - -/** - ***************************************************************************** - * Function: dc_link_enable_hpd_filter - * - * @brief - * If enable is true, programs HPD filter on associated HPD line to default - * values dependent on link->connector_signal - * - * If enable is false, programs HPD filter on associated HPD line with no - * delays on connect or disconnect - * - * @param [in] link: pointer to the dc link - * @param [in] enable: boolean specifying whether to enable hbd - ***************************************************************************** - */ -void dc_link_enable_hpd_filter(struct dc_link *link, bool enable); - -bool dc_link_is_dp_sink_present(struct dc_link *link); -/* - * DPCD access interfaces - */ - -void dc_link_set_drive_settings(struct dc *dc, - struct link_training_settings *lt_settings, - const struct dc_link *link); -void dc_link_set_preferred_link_settings(struct dc *dc, - struct dc_link_settings *link_setting, - struct dc_link *link); -void dc_link_set_preferred_training_settings(struct dc *dc, - struct dc_link_settings *link_setting, - struct dc_link_training_overrides *lt_overrides, - struct dc_link *link, - bool skip_immediate_retrain); -void dc_link_enable_hpd(const struct dc_link *link); -void dc_link_disable_hpd(const struct dc_link *link); -void dc_link_set_test_pattern(struct dc_link *link, - enum dp_test_pattern test_pattern, - enum dp_test_pattern_color_space test_pattern_color_space, - const struct link_training_settings *p_link_settings, - const unsigned char *p_custom_pattern, - unsigned int cust_pattern_size); - -const struct dc_link_settings *dc_link_get_link_cap( - const struct dc_link *link); - -void dc_link_overwrite_extended_receiver_cap( - struct dc_link *link); - -bool dc_is_oem_i2c_device_present( - struct dc *dc, - size_t slave_address -); - -bool dc_submit_i2c( - struct dc *dc, - uint32_t link_index, - struct i2c_command *cmd); - -bool dc_submit_i2c_oem( - struct dc *dc, - struct i2c_command *cmd); - -bool dc_link_is_fec_supported(const struct dc_link *link); -bool dc_link_should_enable_fec(const struct dc_link *link); - -uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw); -enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link); - -/* take a snapshot of current link resource allocation state */ -void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map); -/* restore link resource allocation state from a snapshot */ -void dc_restore_link_res_map(const struct dc *dc, uint32_t *map); -void dp_trace_reset(struct dc_link *link); -bool dc_dp_trace_is_initialized(struct dc_link *link); -unsigned long long dc_dp_trace_get_lt_end_timestamp(struct dc_link *link, - bool in_detection); -void dc_dp_trace_set_is_logged_flag(struct dc_link *link, - bool in_detection, - bool is_logged); -bool dc_dp_trace_is_logged(struct dc_link *link, - bool in_detection); -struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link, - bool in_detection); -unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link); - -/* Attempt to transfer the given aux payload. This function does not perform - * retries or handle error states. The reply is returned in the payload->reply - * and the result through operation_result. Returns the number of bytes - * transferred,or -1 on a failure. - */ -int dc_link_aux_transfer_raw(struct ddc_service *ddc, - struct aux_payload *payload, - enum aux_return_code_type *operation_result); - -enum lttpr_mode dc_link_decide_lttpr_mode(struct dc_link *link, - struct dc_link_settings *link_setting); -void dc_link_dp_receiver_power_ctrl(struct dc_link *link, bool on); -bool dc_link_decide_edp_link_settings(struct dc_link *link, - struct dc_link_settings *link_setting, - uint32_t req_bw); -void dc_link_edp_panel_backlight_power_on(struct dc_link *link, - bool wait_for_hpd); - -/* - * 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); - -/* - * Handle function for when the status of the Request above is complete. - * We will find out the result of allocating on CM and update structs. - * - * @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_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result); - -/* - * Handle the USB4 BW Allocation related functionality here: - * Plug => Try to allocate max bw from timing parameters supported by the sink - * Unplug => de-allocate bw - * - * @link: pointer to the dc_link struct instance - * @peak_bw: Peak bw used by the link/sink - * - * return: allocated bw else return 0 - */ -int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int peak_bw); - -/* TODO: this is not meant to be exposed to DM. Should switch to stream update - * interface i.e stream_update->dsc_config - */ -bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx); -#endif /* DC_LINK_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/Makefile b/drivers/gpu/drm/amd/display/dc/link/Makefile index 40352d8d7648..a52b56e2859e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/Makefile +++ b/drivers/gpu/drm/amd/display/dc/link/Makefile @@ -55,7 +55,7 @@ LINK_PROTOCOLS = link_hpd.o link_ddc.o link_dpcd.o link_dp_dpia.o \ link_dp_training.o link_dp_training_8b_10b.o link_dp_training_128b_132b.o \ link_dp_training_dpia.o link_dp_training_auxless.o \ link_dp_training_fixed_vs_pe_retimer.o link_dp_phy.o link_dp_capability.o \ -link_edp_panel_control.o link_dp_irq_handler.o +link_edp_panel_control.o link_dp_irq_handler.o link_dp_dpia_bw.o AMD_DAL_LINK_PROTOCOLS = $(addprefix $(AMDDALPATH)/dc/link/protocols/, \ $(LINK_PROTOCOLS)) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index c950857ef02c..65f43572011b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -26,10 +26,9 @@ /*********************************************************************/ // USB4 DPIA BANDWIDTH ALLOCATION LOGIC /*********************************************************************/ -#include "dc.h" #include "link_dp_dpia_bw.h" -#include "drm_dp_helper_dc.h" #include "link_dpcd.h" +#include "dc_dmub_srv.h" #define DC_LOGGER \ link->ctx->logger @@ -195,15 +194,13 @@ static int get_host_router_total_bw(struct dc_link *link, uint8_t type) */ static bool dpia_bw_alloc_unplug(struct dc_link *link) { - bool ret = false; - if (!link) return true; return deallocate_usb4_bw(&link->dpia_bw_alloc_config.sink_allocated_bw, link->dpia_bw_alloc_config.sink_allocated_bw, link); } -static void dc_link_set_usb4_req_bw_req(struct dc_link *link, int req_bw) +void dc_link_set_usb4_req_bw_req(struct dc_link *link, int req_bw) { uint8_t requested_bw; uint32_t temp; @@ -281,7 +278,6 @@ bool link_dp_dpia_set_dptx_usb4_bw_alloc_support(struct dc_link *link) DC_LOG_DEBUG("%s: **** FAILURE Enabling DPtx BW Allocation Mode Support ***\n", __func__); } else { - // SUCCESS Enabled DPtx BW Allocation Mode Support link->dpia_bw_alloc_config.bw_alloc_enabled = true; DC_LOG_DEBUG("%s: **** SUCCESS Enabling DPtx BW Allocation Mode Support ***\n", @@ -297,6 +293,11 @@ out: } void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result) { + int bw_needed = 0; + int available = 0; + int estimated = 0; + int host_router_total_estimated_bw = 0; + if (!get_bw_alloc_proceed_flag((link))) return; @@ -330,12 +331,12 @@ void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uin // 2. SUCCESS after prev. FAIL before any Pruning is done // 3. SUCCESS after Pruning is done but before enabling link - int needed = bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); + bw_needed = bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); // 1. if (!link->dpia_bw_alloc_config.sink_allocated_bw) { - allocate_usb4_bw(&link->dpia_bw_alloc_config.sink_allocated_bw, needed, link); + allocate_usb4_bw(&link->dpia_bw_alloc_config.sink_allocated_bw, bw_needed, link); link->dpia_bw_alloc_config.sink_verified_bw = link->dpia_bw_alloc_config.sink_allocated_bw; @@ -349,12 +350,12 @@ void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uin else if (link->dpia_bw_alloc_config.sink_allocated_bw) { // Find out how much do we need to de-alloc - if (link->dpia_bw_alloc_config.sink_allocated_bw > needed) + if (link->dpia_bw_alloc_config.sink_allocated_bw > bw_needed) deallocate_usb4_bw(&link->dpia_bw_alloc_config.sink_allocated_bw, - link->dpia_bw_alloc_config.sink_allocated_bw - needed, link); + link->dpia_bw_alloc_config.sink_allocated_bw - bw_needed, link); else allocate_usb4_bw(&link->dpia_bw_alloc_config.sink_allocated_bw, - needed - link->dpia_bw_alloc_config.sink_allocated_bw, link); + bw_needed - link->dpia_bw_alloc_config.sink_allocated_bw, link); } // 4. If this is the 2nd sink then any unused bw will be reallocated to master DPIA @@ -367,8 +368,8 @@ void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uin DC_LOG_DEBUG("%s: *** ESTIMATED BW CHANGED for DP-TX Request ***\n", __func__); - int available = 0, estimated = bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); - int host_router_total_estimated_bw = get_host_router_total_bw(link, HOST_ROUTER_BW_ESTIMATED); + estimated = bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); + host_router_total_estimated_bw = get_host_router_total_bw(link, HOST_ROUTER_BW_ESTIMATED); // 1. If due to unplug of other sink if (estimated == host_router_total_estimated_bw) { @@ -415,7 +416,7 @@ int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *li dc_link_set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.sink_max_bw); do { - if (!timeout > 0) + if (!(timeout > 0)) timeout--; else break; @@ -449,7 +450,7 @@ int link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int re if (req_bw != link->dpia_bw_alloc_config.sink_allocated_bw) { dc_link_set_usb4_req_bw_req(link, req_bw); do { - if (!timeout > 0) + if (!(timeout > 0)) timeout--; else break; 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 46d141a1366f..e869e5e36568 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 @@ -25,7 +25,7 @@ #ifndef DC_INC_LINK_DP_DPIA_BW_H_ #define DC_INC_LINK_DP_DPIA_BW_H_ - +#include "link.h" /* * Host Router BW type */ -- cgit From 202a3816f37e49ab490ff4582f1fb34390e5824e Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Wed, 15 Feb 2023 12:50:59 -0500 Subject: drm/amd/display: move dc_link functions in protocols folder to dc_link_exports [why] link component should only have one interface serving dc. [how] We are moving dc_link functions exposed to DM to dc_link_exports and unify link component interface in link.h with function pointer to match the style of other dc component. This is the third step to move dc_link functions under protocols folder to dc_link_exports. Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Wenjing Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/core/dc_link_exports.c | 199 +++++++++++++++++++++ drivers/gpu/drm/amd/display/dc/dc.h | 5 +- .../amd/display/dc/dce110/dce110_hw_sequencer.h | 2 - drivers/gpu/drm/amd/display/dc/inc/link.h | 83 ++++++++- .../gpu/drm/amd/display/dc/link/link_detection.c | 2 +- drivers/gpu/drm/amd/display/dc/link/link_factory.c | 53 ++++++ .../drm/amd/display/dc/link/protocols/link_ddc.c | 24 ++- .../drm/amd/display/dc/link/protocols/link_ddc.h | 3 + .../display/dc/link/protocols/link_dp_capability.c | 30 ++-- .../display/dc/link/protocols/link_dp_capability.h | 19 ++ .../amd/display/dc/link/protocols/link_dp_dpia.c | 2 +- .../amd/display/dc/link/protocols/link_dp_dpia.h | 4 +- .../display/dc/link/protocols/link_dp_dpia_bw.c | 12 +- .../display/dc/link/protocols/link_dp_dpia_bw.h | 24 +++ .../dc/link/protocols/link_dp_irq_handler.c | 13 +- .../dc/link/protocols/link_dp_irq_handler.h | 12 +- .../amd/display/dc/link/protocols/link_dp_phy.c | 2 +- .../amd/display/dc/link/protocols/link_dp_phy.h | 3 + .../display/dc/link/protocols/link_dp_training.c | 6 +- .../display/dc/link/protocols/link_dp_training.h | 3 + .../dc/link/protocols/link_dp_training_auxless.c | 2 +- .../dc/link/protocols/link_dp_training_auxless.h | 2 +- .../dc/link/protocols/link_dp_training_dpia.c | 2 +- .../dc/link/protocols/link_dp_training_dpia.h | 2 +- .../dc/link/protocols/link_edp_panel_control.c | 20 +-- .../dc/link/protocols/link_edp_panel_control.h | 20 +++ .../drm/amd/display/dc/link/protocols/link_hpd.c | 14 +- .../drm/amd/display/dc/link/protocols/link_hpd.h | 4 + 28 files changed, 486 insertions(+), 81 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c index b1fedef193a0..217c80db190d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c @@ -279,3 +279,202 @@ void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink) link->dc->link_srv->remove_remote_sink(link, sink); } +int dc_link_aux_transfer_raw(struct ddc_service *ddc, + struct aux_payload *payload, + enum aux_return_code_type *operation_result) +{ + const struct dc *dc = ddc->link->dc; + + return dc->link_srv->aux_transfer_raw( + ddc, payload, operation_result); +} + +uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data( + struct dc *dc, uint8_t bw) +{ + return dc->link_srv->bw_kbps_from_raw_frl_link_rate_data(bw); +} + +bool dc_link_decide_edp_link_settings(struct dc_link *link, + struct dc_link_settings *link_setting, uint32_t req_bw) +{ + return link->dc->link_srv->edp_decide_link_settings(link, link_setting, req_bw); +} + + +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, + struct dc_link_settings *max_link_enc_cap) +{ + return link->dc->link_srv->dp_get_max_link_enc_cap(link, max_link_enc_cap); +} + +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format( + const struct dc_link *link) +{ + return link->dc->link_srv->mst_decide_link_encoding_format(link); +} + +const struct dc_link_settings *dc_link_get_link_cap(const struct dc_link *link) +{ + return link->dc->link_srv->dp_get_verified_link_cap(link); +} + +bool dc_link_is_dp_sink_present(struct dc_link *link) +{ + return link->dc->link_srv->dp_is_sink_present(link); +} + +bool dc_link_is_fec_supported(const struct dc_link *link) +{ + return link->dc->link_srv->dp_is_fec_supported(link); +} + +void dc_link_overwrite_extended_receiver_cap( + struct dc_link *link) +{ + link->dc->link_srv->dp_overwrite_extended_receiver_cap(link); +} + +bool dc_link_should_enable_fec(const struct dc_link *link) +{ + return link->dc->link_srv->dp_should_enable_fec(link); +} + +int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link( + struct dc_link *link, int peak_bw) +{ + return link->dc->link_srv->dpia_handle_usb4_bandwidth_allocation_for_link(link, peak_bw); +} + +void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result) +{ + link->dc->link_srv->dpia_handle_bw_alloc_response(link, bw, result); +} + +bool dc_link_check_link_loss_status( + struct dc_link *link, + union hpd_irq_data *hpd_irq_dpcd_data) +{ + return link->dc->link_srv->dp_parse_link_loss_status(link, hpd_irq_dpcd_data); +} + +bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link) +{ + return link->dc->link_srv->dp_should_allow_hpd_rx_irq(link); +} + +void dc_link_dp_handle_link_loss(struct dc_link *link) +{ + link->dc->link_srv->dp_handle_link_loss(link); +} + +enum dc_status dc_link_dp_read_hpd_rx_irq_data( + struct dc_link *link, + union hpd_irq_data *irq_data) +{ + return link->dc->link_srv->dp_read_hpd_rx_irq_data(link, irq_data); +} + +bool dc_link_handle_hpd_rx_irq(struct dc_link *link, + union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss, + bool defer_handling, bool *has_left_work) +{ + return link->dc->link_srv->dp_handle_hpd_rx_irq(link, out_hpd_irq_dpcd_data, + out_link_loss, defer_handling, has_left_work); +} + +void dc_link_dp_receiver_power_ctrl(struct dc_link *link, bool on) +{ + link->dc->link_srv->dpcd_write_rx_power_ctrl(link, on); +} + +enum lttpr_mode dc_link_decide_lttpr_mode(struct dc_link *link, + struct dc_link_settings *link_setting) +{ + return link->dc->link_srv->dp_decide_lttpr_mode(link, link_setting); +} + +void dc_link_edp_panel_backlight_power_on(struct dc_link *link, bool wait_for_hpd) +{ + link->dc->link_srv->edp_panel_backlight_power_on(link, wait_for_hpd); +} + +int dc_link_get_backlight_level(const struct dc_link *link) +{ + return link->dc->link_srv->edp_get_backlight_level(link); +} + +bool dc_link_get_backlight_level_nits(struct dc_link *link, + uint32_t *backlight_millinits_avg, + uint32_t *backlight_millinits_peak) +{ + return link->dc->link_srv->edp_get_backlight_level_nits(link, + backlight_millinits_avg, + backlight_millinits_peak); +} + +bool dc_link_set_backlight_level(const struct dc_link *link, + uint32_t backlight_pwm_u16_16, + uint32_t frame_ramp) +{ + return link->dc->link_srv->edp_set_backlight_level(link, + backlight_pwm_u16_16, frame_ramp); +} + +bool dc_link_set_backlight_level_nits(struct dc_link *link, + bool isHDR, + uint32_t backlight_millinits, + uint32_t transition_time_in_ms) +{ + return link->dc->link_srv->edp_set_backlight_level_nits(link, isHDR, + backlight_millinits, transition_time_in_ms); +} + +int dc_link_get_target_backlight_pwm(const struct dc_link *link) +{ + return link->dc->link_srv->edp_get_target_backlight_pwm(link); +} + +bool dc_link_get_psr_state(const struct dc_link *link, enum dc_psr_state *state) +{ + return link->dc->link_srv->edp_get_psr_state(link, state); +} + +bool dc_link_set_psr_allow_active(struct dc_link *link, const bool *allow_active, + bool wait, bool force_static, const unsigned int *power_opts) +{ + return link->dc->link_srv->edp_set_psr_allow_active(link, allow_active, wait, + force_static, power_opts); +} + +bool dc_link_setup_psr(struct dc_link *link, + const struct dc_stream_state *stream, struct psr_config *psr_config, + struct psr_context *psr_context) +{ + return link->dc->link_srv->edp_setup_psr(link, stream, psr_config, psr_context); +} + +bool dc_link_wait_for_t12(struct dc_link *link) +{ + return link->dc->link_srv->edp_wait_for_t12(link); +} + +bool dc_link_get_hpd_state(struct dc_link *link) +{ + return link->dc->link_srv->get_hpd_state(link); +} + +void dc_link_enable_hpd(const struct dc_link *link) +{ + link->dc->link_srv->enable_hpd(link); +} + +void dc_link_disable_hpd(const struct dc_link *link) +{ + link->dc->link_srv->disable_hpd(link); +} + +void dc_link_enable_hpd_filter(struct dc_link *link, bool enable) +{ + link->dc->link_srv->enable_hpd_filter(link, enable); +} diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 555d3aa65889..c1e69fdd5020 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1600,7 +1600,7 @@ bool dc_link_detect_connection_type(struct dc_link *link, * return - true HPD is asserted (HPD high), false otherwise (HPD low) * */ -bool dc_link_get_hpd_state(struct dc_link *dc_link); +bool dc_link_get_hpd_state(struct dc_link *link); /* Getter for cached link status from given link */ const struct dc_link_status *dc_link_get_status(const struct dc_link *link); @@ -1775,7 +1775,8 @@ void dc_restore_link_res_map(const struct dc *dc, uint32_t *map); bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx); /* translate a raw link rate data to bandwidth in kbps */ -uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw); +uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data( + struct dc *dc, uint8_t bw); /* determine the optimal bandwidth given link and required bw. * @link - current detected link diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h index 394d83a97f33..08028a1779ae 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h @@ -71,8 +71,6 @@ void dce110_optimize_bandwidth( struct dc *dc, struct dc_state *context); -void dc_link_dp_receiver_power_ctrl(struct dc_link *link, bool on); - void dce110_edp_power_control( struct dc_link *link, bool power_up); diff --git a/drivers/gpu/drm/amd/display/dc/inc/link.h b/drivers/gpu/drm/amd/display/dc/inc/link.h index 9c05333f62aa..45cdf3bce2d3 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link.h @@ -28,14 +28,10 @@ /* FILE POLICY AND INTENDED USAGE: * - * This header declares link functions exposed to dc. All functions must have - * "link_" as prefix. For example link_run_my_function. This header is strictly - * private in dc and should never be included in other header files. dc - * components should include this header in their .c files in order to access - * functions in link folder. This file should never include any header files in - * link folder. If there is a need to expose a function declared in one of - * header files in side link folder, you need to move the function declaration - * into this file and prefix it with "link_". + * This header declares link functions exposed to dc. All functions must use + * function pointers. This header is strictly private in dc and should never be + * included by DM. If DM needs to call a new link function, it needs to be + * translated by dc_link_exports.c. */ #include "core_types.h" @@ -49,12 +45,81 @@ struct link_init_data { }; struct link_service { + /* Detection */ struct dc_sink *(*add_remote_sink)( struct dc_link *link, const uint8_t *edid, int len, struct dc_sink_init_data *init_data); void (*remove_remote_sink)(struct dc_link *link, struct dc_sink *sink); + bool (*get_hpd_state)(struct dc_link *link); + void (*enable_hpd)(const struct dc_link *link); + void (*disable_hpd)(const struct dc_link *link); + void (*enable_hpd_filter)(struct dc_link *link, bool enable); + + /* DDC */ + int (*aux_transfer_raw)(struct ddc_service *ddc, + struct aux_payload *payload, + enum aux_return_code_type *operation_result); + + /* DP Capability */ + bool (*dp_is_sink_present)(struct dc_link *link); + bool (*dp_is_fec_supported)(const struct dc_link *link); + bool (*dp_get_max_link_enc_cap)(const struct dc_link *link, + struct dc_link_settings *max_link_enc_cap); + const struct dc_link_settings *(*dp_get_verified_link_cap)( + const struct dc_link *link); + bool (*dp_should_enable_fec)(const struct dc_link *link); + enum dp_link_encoding (*mst_decide_link_encoding_format)(const struct dc_link *link); + bool (*edp_decide_link_settings)(struct dc_link *link, + struct dc_link_settings *link_setting, uint32_t req_bw); + uint32_t (*bw_kbps_from_raw_frl_link_rate_data)(uint8_t bw); + bool (*dp_overwrite_extended_receiver_cap)(struct dc_link *link); + enum lttpr_mode (*dp_decide_lttpr_mode)(struct dc_link *link, + struct dc_link_settings *link_setting); + + /* DP DPIA/PHY */ + int (*dpia_handle_usb4_bandwidth_allocation_for_link)(struct dc_link *link, int peak_bw); + void (*dpia_handle_bw_alloc_response)(struct dc_link *link, uint8_t bw, uint8_t result); + void (*dpcd_write_rx_power_ctrl)(struct dc_link *link, bool on); + + /* DP IRQ Handler */ + bool (*dp_parse_link_loss_status)( + struct dc_link *link, + union hpd_irq_data *hpd_irq_dpcd_data); + bool (*dp_should_allow_hpd_rx_irq)(const struct dc_link *link); + void (*dp_handle_link_loss)(struct dc_link *link); + enum dc_status (*dp_read_hpd_rx_irq_data)( + struct dc_link *link, + union hpd_irq_data *irq_data); + bool (*dp_handle_hpd_rx_irq)(struct dc_link *link, + union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss, + bool defer_handling, bool *has_left_work); + + /* eDP Panel Control */ + void (*edp_panel_backlight_power_on)(struct dc_link *link, bool wait_for_hpd); + int (*edp_get_backlight_level)(const struct dc_link *link); + bool (*edp_get_backlight_level_nits)(struct dc_link *link, + uint32_t *backlight_millinits_avg, + uint32_t *backlight_millinits_peak); + bool (*edp_set_backlight_level)(const struct dc_link *link, + uint32_t backlight_pwm_u16_16, + uint32_t frame_ramp); + bool (*edp_set_backlight_level_nits)(struct dc_link *link, + bool isHDR, + uint32_t backlight_millinits, + uint32_t transition_time_in_ms); + int (*edp_get_target_backlight_pwm)(const struct dc_link *link); + bool (*edp_get_psr_state)(const struct dc_link *link, enum dc_psr_state *state); + bool (*edp_set_psr_allow_active)(struct dc_link *link, const bool *allow_active, + bool wait, bool force_static, const unsigned int *power_opts); + bool (*edp_setup_psr)(struct dc_link *link, + const struct dc_stream_state *stream, + struct psr_config *psr_config, + struct psr_context *psr_context); + bool (*edp_wait_for_t12)(struct dc_link *link); + + /* DP CTS */ void (*dp_handle_automated_test)(struct dc_link *link); bool (*dp_set_test_pattern)( struct dc_link *link, @@ -71,6 +136,8 @@ struct link_service { struct dc_link_training_overrides *lt_overrides, struct dc_link *link, bool skip_immediate_retrain); + + /* DP Trace */ bool (*dp_trace_is_initialized)(struct dc_link *link); void (*dp_trace_set_is_logged_flag)(struct dc_link *link, bool in_detection, diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 2a248ee0d70e..a51f761ba018 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -1205,7 +1205,7 @@ bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type * /* Link may not have physical HPD pin. */ if (link->ep_type != DISPLAY_ENDPOINT_PHY) { - if (link->is_hpd_pending || !dc_link_dpia_query_hpd_status(link)) + if (link->is_hpd_pending || !dpia_query_hpd_status(link)) *type = dc_connection_none; else *type = dc_connection_single; diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index e37f271a6c72..d9ce83f0bbef 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -32,6 +32,12 @@ #include "accessories/link_dp_trace.h" #include "accessories/link_fpga.h" #include "protocols/link_ddc.h" +#include "protocols/link_dp_capability.h" +#include "protocols/link_dp_dpia_bw.h" +#include "protocols/link_dp_dpia.h" +#include "protocols/link_dp_irq_handler.h" +#include "protocols/link_dp_phy.h" +#include "protocols/link_dp_training.h" #include "protocols/link_edp_panel_control.h" #include "protocols/link_hpd.h" #include "gpio_service_interface.h" @@ -44,12 +50,59 @@ __VA_ARGS__) static struct link_service link_srv = { + /* Detection */ .add_remote_sink = link_add_remote_sink, .remove_remote_sink = link_remove_remote_sink, + .get_hpd_state = link_get_hpd_state, + .enable_hpd = link_enable_hpd, + .disable_hpd = link_disable_hpd, + .enable_hpd_filter = link_enable_hpd_filter, + + /* DDC */ + .aux_transfer_raw = link_aux_transfer_raw, + + /* DP Capability */ + .dp_is_sink_present = dp_is_sink_present, + .dp_is_fec_supported = dp_is_fec_supported, + .dp_get_max_link_enc_cap = dp_get_max_link_enc_cap, + .dp_get_verified_link_cap = dp_get_verified_link_cap, + .dp_should_enable_fec = dp_should_enable_fec, + .mst_decide_link_encoding_format = mst_decide_link_encoding_format, + .edp_decide_link_settings = edp_decide_link_settings, + .bw_kbps_from_raw_frl_link_rate_data = link_bw_kbps_from_raw_frl_link_rate_data, + .dp_overwrite_extended_receiver_cap = dp_overwrite_extended_receiver_cap, + .dp_decide_lttpr_mode = dp_decide_lttpr_mode, + + /* DP DPIA/PHY */ + .dpia_handle_usb4_bandwidth_allocation_for_link = dpia_handle_usb4_bandwidth_allocation_for_link, + .dpia_handle_bw_alloc_response = dpia_handle_bw_alloc_response, + /* DP IRQ Handler */ + .dp_parse_link_loss_status = dp_parse_link_loss_status, + .dp_should_allow_hpd_rx_irq = dp_should_allow_hpd_rx_irq, + .dp_handle_link_loss = dp_handle_link_loss, + .dp_read_hpd_rx_irq_data = dp_read_hpd_rx_irq_data, + .dp_handle_hpd_rx_irq = dp_handle_hpd_rx_irq, + .dpcd_write_rx_power_ctrl = dpcd_write_rx_power_ctrl, + + /* eDP Panel Control */ + .edp_panel_backlight_power_on = edp_panel_backlight_power_on, + .edp_get_backlight_level = edp_get_backlight_level, + .edp_get_backlight_level_nits = edp_get_backlight_level_nits, + .edp_set_backlight_level = edp_set_backlight_level, + .edp_set_backlight_level_nits = edp_set_backlight_level_nits, + .edp_get_target_backlight_pwm = edp_get_target_backlight_pwm, + .edp_get_psr_state = edp_get_psr_state, + .edp_set_psr_allow_active = edp_set_psr_allow_active, + .edp_setup_psr = edp_setup_psr, + .edp_wait_for_t12 = edp_wait_for_t12, + + /* DP CTS */ .dp_handle_automated_test = dp_handle_automated_test, .dp_set_test_pattern = dp_set_test_pattern, .dp_set_preferred_link_settings = dp_set_preferred_link_settings, .dp_set_preferred_training_settings = dp_set_preferred_training_settings, + + /* DP Trace */ .dp_trace_is_initialized = dp_trace_is_initialized, .dp_trace_set_is_logged_flag = dp_trace_set_is_logged_flag, .dp_trace_is_logged = dp_trace_is_logged, diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c index 5269125bc2a4..0fa1228bc178 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c @@ -53,7 +53,7 @@ struct aux_payloads { struct vector payloads; }; -static bool dal_ddc_i2c_payloads_create( +static bool i2c_payloads_create( struct dc_context *ctx, struct i2c_payloads *payloads, uint32_t count) @@ -65,16 +65,24 @@ static bool dal_ddc_i2c_payloads_create( return false; } -static struct i2c_payload *dal_ddc_i2c_payloads_get(struct i2c_payloads *p) +static struct i2c_payload *i2c_payloads_get(struct i2c_payloads *p) { return (struct i2c_payload *)p->payloads.container; } -static uint32_t dal_ddc_i2c_payloads_get_count(struct i2c_payloads *p) +static uint32_t i2c_payloads_get_count(struct i2c_payloads *p) { return p->payloads.count; } +static void i2c_payloads_destroy(struct i2c_payloads *p) +{ + if (!p) + return; + + dal_vector_destruct(&p->payloads); +} + #define DDC_MIN(a, b) (((a) < (b)) ? (a) : (b)) static void i2c_payloads_add( @@ -364,10 +372,10 @@ bool link_query_ddc_data( struct i2c_command command = {0}; struct i2c_payloads payloads; - if (!dal_ddc_i2c_payloads_create(ddc->ctx, &payloads, payloads_num)) + if (!i2c_payloads_create(ddc->ctx, &payloads, payloads_num)) return false; - command.payloads = dal_ddc_i2c_payloads_get(&payloads); + command.payloads = i2c_payloads_get(&payloads); command.number_of_payloads = 0; command.engine = DDC_I2C_COMMAND_ENGINE; command.speed = ddc->ctx->dc->caps.i2c_speed_in_khz; @@ -379,20 +387,20 @@ bool link_query_ddc_data( &payloads, address, read_size, read_buf, false); command.number_of_payloads = - dal_ddc_i2c_payloads_get_count(&payloads); + i2c_payloads_get_count(&payloads); success = dm_helpers_submit_i2c( ddc->ctx, ddc->link, &command); - dal_vector_destruct(&payloads.payloads); + i2c_payloads_destroy(&payloads); } return success; } -int dc_link_aux_transfer_raw(struct ddc_service *ddc, +int link_aux_transfer_raw(struct ddc_service *ddc, struct aux_payload *payload, enum aux_return_code_type *operation_result) { diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h index aaa5064408ba..f002fa01508e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h @@ -57,5 +57,8 @@ void set_dongle_type(struct ddc_service *ddc, struct ddc *get_ddc_pin(struct ddc_service *ddc_service); +int link_aux_transfer_raw(struct ddc_service *ddc, + struct aux_payload *payload, + enum aux_return_code_type *operation_result); #endif /* __DAL_DDC_SERVICE_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index 0f2c59807079..97856c4d0904 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -155,7 +155,7 @@ uint8_t dp_parse_lttpr_repeater_count(uint8_t lttpr_repeater_count) return 0; // invalid value } -uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw) +uint32_t link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw) { switch (bw) { case 0b001: @@ -309,7 +309,7 @@ static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data, link->wa_flags.dp_keep_receiver_powered = false; } -bool dc_link_is_fec_supported(const struct dc_link *link) +bool dp_is_fec_supported(const struct dc_link *link) { /* TODO - use asic cap instead of link_enc->features * we no longer know which link enc to use for this link before commit @@ -325,7 +325,7 @@ bool dc_link_is_fec_supported(const struct dc_link *link) !IS_FPGA_MAXIMUS_DC(link->ctx->dce_environment)); } -bool dc_link_should_enable_fec(const struct dc_link *link) +bool dp_should_enable_fec(const struct dc_link *link) { bool force_disable = false; @@ -679,7 +679,8 @@ static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_setting return false; } -bool dc_link_decide_edp_link_settings(struct dc_link *link, struct dc_link_settings *link_setting, uint32_t req_bw) +bool edp_decide_link_settings(struct dc_link *link, + struct dc_link_settings *link_setting, uint32_t req_bw) { struct dc_link_settings initial_link_setting; struct dc_link_settings current_link_setting; @@ -948,7 +949,7 @@ enum dp_link_encoding link_dp_get_encoding_format(const struct dc_link_settings return DP_UNKNOWN_ENCODING; } -enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link) +enum dp_link_encoding mst_decide_link_encoding_format(const struct dc_link *link) { struct dc_link_settings link_settings = {0}; @@ -1121,7 +1122,7 @@ static void get_active_converter_info( union hdmi_encoded_link_bw hdmi_encoded_link_bw; link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps = - dc_link_bw_kbps_from_raw_frl_link_rate_data( + link_bw_kbps_from_raw_frl_link_rate_data( hdmi_color_caps.bits.MAX_ENCODED_LINK_BW_SUPPORT); // Intersect reported max link bw support with the supported link rate post FRL link training @@ -1216,7 +1217,7 @@ static void apply_usbc_combo_phy_reset_wa(struct dc_link *link, dp_disable_link_phy(link, &link_res, link->connector_signal); } -static bool dp_overwrite_extended_receiver_cap(struct dc_link *link) +bool dp_overwrite_extended_receiver_cap(struct dc_link *link) { uint8_t dpcd_data[16]; uint32_t read_dpcd_retry_cnt = 3; @@ -1278,12 +1279,6 @@ static bool dp_overwrite_extended_receiver_cap(struct dc_link *link) return true; } -void dc_link_overwrite_extended_receiver_cap( - struct dc_link *link) -{ - dp_overwrite_extended_receiver_cap(link); -} - void dpcd_set_source_specific_data(struct dc_link *link) { if (!link->dc->vendor_signature.is_valid) { @@ -1972,7 +1967,7 @@ void detect_edp_sink_caps(struct dc_link *link) sizeof(link->dpcd_caps.alpm_caps.raw)); } -bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap) +bool dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap) { struct link_encoder *link_enc = NULL; @@ -1995,7 +1990,7 @@ bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_ return false; } -const struct dc_link_settings *dc_link_get_link_cap( +const struct dc_link_settings *dp_get_verified_link_cap( const struct dc_link *link) { if (link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN && @@ -2181,10 +2176,9 @@ bool dp_verify_link_cap_with_retries( } /** - * dc_link_is_dp_sink_present() - Check if there is a native DP - * or passive DP-HDMI dongle connected + * Check if there is a native DP or passive DP-HDMI dongle connected */ -bool dc_link_is_dp_sink_present(struct dc_link *link) +bool dp_is_sink_present(struct dc_link *link) { enum gpio_result gpio_result; uint32_t clock_pin = 0; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h index f79e4a4a9db6..62980ae17d41 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h @@ -34,32 +34,47 @@ void detect_edp_sink_caps(struct dc_link *link); struct dc_link_settings dp_get_max_link_cap(struct dc_link *link); +bool dp_get_max_link_enc_cap(const struct dc_link *link, + struct dc_link_settings *max_link_enc_cap); + +const struct dc_link_settings *dp_get_verified_link_cap( + const struct dc_link *link); enum dc_status dp_retrieve_lttpr_cap(struct dc_link *link); /* Convert PHY repeater count read from DPCD uint8_t. */ uint8_t dp_parse_lttpr_repeater_count(uint8_t lttpr_repeater_count); +bool dp_is_sink_present(struct dc_link *link); + bool dp_is_lttpr_present(struct dc_link *link); +bool dp_is_fec_supported(const struct dc_link *link); + bool is_dp_active_dongle(const struct dc_link *link); bool is_dp_branch_device(const struct dc_link *link); void dpcd_write_cable_id_to_dprx(struct dc_link *link); +bool dp_should_enable_fec(const struct dc_link *link); + /* Initialize output parameter lt_settings. */ void dp_decide_training_settings( struct dc_link *link, const struct dc_link_settings *link_setting, struct link_training_settings *lt_settings); +bool edp_decide_link_settings(struct dc_link *link, + struct dc_link_settings *link_setting, uint32_t req_bw); bool decide_edp_link_settings_with_dsc(struct dc_link *link, struct dc_link_settings *link_setting, uint32_t req_bw, enum dc_link_rate max_link_rate); +enum dp_link_encoding mst_decide_link_encoding_format(const struct dc_link *link); + void dpcd_set_source_specific_data(struct dc_link *link); /*query dpcd for version and mst cap addresses*/ @@ -76,4 +91,8 @@ bool dp_verify_link_cap_with_retries( struct dc_link_settings *known_limit_link_setting, int attempts); +uint32_t link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw); + +bool dp_overwrite_extended_receiver_cap(struct dc_link *link); + #endif /* __DC_LINK_DP_CAPABILITY_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c index cbfa9343ffaf..4626fabc0a96 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c @@ -78,7 +78,7 @@ enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link) return status; } -bool dc_link_dpia_query_hpd_status(struct dc_link *link) +bool dpia_query_hpd_status(struct dc_link *link) { union dmub_rb_cmd cmd = {0}; struct dc_dmub_srv *dmub_srv = link->ctx->dmub_srv; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.h index 98935cc10bb7..363f45a1a964 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.h @@ -37,7 +37,5 @@ enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link); /* Query hot plug status of USB4 DP tunnel. * Returns true if HPD high. */ -bool dc_link_dpia_query_hpd_status(struct dc_link *link); - - +bool dpia_query_hpd_status(struct dc_link *link); #endif /* __DC_LINK_DPIA_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index 65f43572011b..f14217cc16fd 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -200,7 +200,7 @@ static bool dpia_bw_alloc_unplug(struct dc_link *link) return deallocate_usb4_bw(&link->dpia_bw_alloc_config.sink_allocated_bw, link->dpia_bw_alloc_config.sink_allocated_bw, link); } -void dc_link_set_usb4_req_bw_req(struct dc_link *link, int req_bw) +static void set_usb4_req_bw_req(struct dc_link *link, int req_bw) { uint8_t requested_bw; uint32_t temp; @@ -291,7 +291,7 @@ bool link_dp_dpia_set_dptx_usb4_bw_alloc_support(struct dc_link *link) out: return ret; } -void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result) +void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result) { int bw_needed = 0; int available = 0; @@ -311,7 +311,7 @@ void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uin link->dpia_bw_alloc_config.estimated_bw = bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); - dc_link_set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.estimated_bw); + set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.estimated_bw); link->dpia_bw_alloc_config.response_ready = false; /* @@ -399,7 +399,7 @@ void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uin break; } } -int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int peak_bw) +int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int peak_bw) { int ret = 0; uint8_t timeout = 10; @@ -413,7 +413,7 @@ int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *li // If DP over USB4 then we need to check BW allocation link->dpia_bw_alloc_config.sink_max_bw = peak_bw; - dc_link_set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.sink_max_bw); + set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.sink_max_bw); do { if (!(timeout > 0)) @@ -448,7 +448,7 @@ int link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int re * allocated max sink bw so no need to re-alloc */ if (req_bw != link->dpia_bw_alloc_config.sink_allocated_bw) { - dc_link_set_usb4_req_bw_req(link, req_bw); + set_usb4_req_bw_req(link, req_bw); do { if (!(timeout > 0)) timeout--; 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 e869e5e36568..cfb255b63dd1 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 @@ -56,4 +56,28 @@ bool link_dp_dpia_set_dptx_usb4_bw_alloc_support(struct dc_link *link); */ int link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw); +/* + * Handle the USB4 BW Allocation related functionality here: + * Plug => Try to allocate max bw from timing parameters supported by the sink + * Unplug => de-allocate bw + * + * @link: pointer to the dc_link struct instance + * @peak_bw: Peak bw used by the link/sink + * + * return: allocated bw else return 0 + */ +int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int peak_bw); + +/* + * Handle function for when the status of the Request above is complete. + * We will find out the result of allocating on CM and update structs. + * + * @link: pointer to the dc_link struct instance + * @bw: Allocated or Estimated BW depending on the result + * @result: Response type + * + * return: none + */ +void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result); + #endif /* DC_INC_LINK_DP_DPIA_BW_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c index 9d80427520cf..6611d0767bd4 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c @@ -39,7 +39,7 @@ #define DC_LOGGER_INIT(logger) -bool dc_link_check_link_loss_status( +bool dp_parse_link_loss_status( struct dc_link *link, union hpd_irq_data *hpd_irq_dpcd_data) { @@ -174,7 +174,7 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link) return false; } -void dc_link_dp_handle_link_loss(struct dc_link *link) +void dp_handle_link_loss(struct dc_link *link) { struct pipe_ctx *pipes[MAX_PIPES]; struct dc_state *state = link->dc->current_state; @@ -200,7 +200,7 @@ void dc_link_dp_handle_link_loss(struct dc_link *link) } } -enum dc_status dc_link_dp_read_hpd_rx_irq_data( +enum dc_status dp_read_hpd_rx_irq_data( struct dc_link *link, union hpd_irq_data *irq_data) { @@ -247,7 +247,7 @@ enum dc_status dc_link_dp_read_hpd_rx_irq_data( } /*************************Short Pulse IRQ***************************/ -bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link) +bool dp_should_allow_hpd_rx_irq(const struct dc_link *link) { /* * Don't handle RX IRQ unless one of following is met: @@ -262,8 +262,9 @@ bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link) return false; } -bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss, - bool defer_handling, bool *has_left_work) +bool dp_handle_hpd_rx_irq(struct dc_link *link, + union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss, + bool defer_handling, bool *has_left_work) { union hpd_irq_data hpd_irq_dpcd_data = {0}; union device_service_irq device_service_clear = {0}; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.h index 39b2e51ea79d..ac33730fedd4 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.h @@ -27,5 +27,15 @@ #define __DC_LINK_DP_IRQ_HANDLER_H__ #include "link.h" - +bool dp_parse_link_loss_status( + struct dc_link *link, + union hpd_irq_data *hpd_irq_dpcd_data); +bool dp_should_allow_hpd_rx_irq(const struct dc_link *link); +void dp_handle_link_loss(struct dc_link *link); +enum dc_status dp_read_hpd_rx_irq_data( + struct dc_link *link, + union hpd_irq_data *irq_data); +bool dp_handle_hpd_rx_irq(struct dc_link *link, + union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss, + bool defer_handling, bool *has_left_work); #endif /* __DC_LINK_DP_IRQ_HANDLER_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c index cd9fb8126bcf..92c2aa104eb5 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c @@ -40,7 +40,7 @@ #define DC_LOGGER \ link->ctx->logger -void dc_link_dp_receiver_power_ctrl(struct dc_link *link, bool on) +void dpcd_write_rx_power_ctrl(struct dc_link *link, bool on) { uint8_t state; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h index 831ffd456291..207bff2ec32e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h @@ -46,6 +46,9 @@ void dp_set_hw_lane_settings( enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready); + void dp_set_fec_enable(struct dc_link *link, bool enable); +void dpcd_write_rx_power_ctrl(struct dc_link *link, bool on); + #endif /* __DC_LINK_DP_PHY_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index cb0049cd1133..2948319b06f8 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -777,7 +777,7 @@ enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *link, return pattern; } -enum lttpr_mode dc_link_decide_lttpr_mode(struct dc_link *link, +enum lttpr_mode dp_decide_lttpr_mode(struct dc_link *link, struct dc_link_settings *link_setting) { enum dp_link_encoding encoding = link_dp_get_encoding_format(link_setting); @@ -1587,12 +1587,12 @@ bool perform_link_training_with_retries( dp_set_panel_mode(link, panel_mode); if (link->aux_access_disabled) { - dc_link_dp_perform_link_training_skip_aux(link, &pipe_ctx->link_res, &cur_link_settings); + dp_perform_link_training_skip_aux(link, &pipe_ctx->link_res, &cur_link_settings); return true; } else { /** @todo Consolidate USB4 DP and DPx.x training. */ if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { - status = dc_link_dpia_perform_link_training( + status = dpia_perform_link_training( link, &pipe_ctx->link_res, &cur_link_settings, diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h index a04948635369..7d027bac8255 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h @@ -119,6 +119,9 @@ enum dc_dp_training_pattern decide_cr_training_pattern( enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *link, const struct dc_link_settings *link_settings); +enum lttpr_mode dp_decide_lttpr_mode(struct dc_link *link, + struct dc_link_settings *link_setting); + void dp_get_lttpr_mode_override(struct dc_link *link, enum lttpr_mode *override); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_auxless.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_auxless.c index e50ec5012559..4c6b886a9da8 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_auxless.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_auxless.c @@ -30,7 +30,7 @@ #include "link_dp_phy.h" #define DC_LOGGER \ link->ctx->logger -bool dc_link_dp_perform_link_training_skip_aux( +bool dp_perform_link_training_skip_aux( struct dc_link *link, const struct link_resource *link_res, const struct dc_link_settings *link_setting) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_auxless.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_auxless.h index 413999cd03c4..546387a5f32d 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_auxless.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_auxless.h @@ -28,7 +28,7 @@ #define __DC_LINK_DP_TRAINING_AUXLESS_H__ #include "link_dp_training.h" -bool dc_link_dp_perform_link_training_skip_aux( +bool dp_perform_link_training_skip_aux( struct dc_link *link, const struct link_resource *link_res, const struct dc_link_settings *link_setting); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c index 7711fda42261..0f56db4018e1 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c @@ -985,7 +985,7 @@ static void dpia_training_abort( core_link_send_set_config(link, DPIA_SET_CFG_SET_LINK, data); } -enum link_training_result dc_link_dpia_perform_link_training( +enum link_training_result dpia_perform_link_training( struct dc_link *link, const struct link_resource *link_res, const struct dc_link_settings *link_setting, diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.h index 0150f2916421..b39fb9faf1c2 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.h @@ -32,7 +32,7 @@ * DPIA equivalent of dc_link_dp_perfrorm_link_training. * Aborts link training upon detection of sink unplug. */ -enum link_training_result dc_link_dpia_perform_link_training( +enum link_training_result dpia_perform_link_training( struct dc_link *link, const struct link_resource *link_res, const struct dc_link_settings *link_setting, diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index da7f83835f78..2f7e0f464144 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -139,7 +139,7 @@ enum dp_panel_mode dp_get_panel_mode(struct dc_link *link) return DP_PANEL_MODE_DEFAULT; } -bool dc_link_set_backlight_level_nits(struct dc_link *link, +bool edp_set_backlight_level_nits(struct dc_link *link, bool isHDR, uint32_t backlight_millinits, uint32_t transition_time_in_ms) @@ -171,7 +171,7 @@ bool dc_link_set_backlight_level_nits(struct dc_link *link, return true; } -bool dc_link_get_backlight_level_nits(struct dc_link *link, +bool edp_get_backlight_level_nits(struct dc_link *link, uint32_t *backlight_millinits_avg, uint32_t *backlight_millinits_peak) { @@ -299,7 +299,7 @@ bool link_is_edp_ilr_optimization_required(struct dc_link *link, return false; } -void dc_link_edp_panel_backlight_power_on(struct dc_link *link, bool wait_for_hpd) +void edp_panel_backlight_power_on(struct dc_link *link, bool wait_for_hpd) { if (link->connector_signal != SIGNAL_TYPE_EDP) return; @@ -311,7 +311,7 @@ void dc_link_edp_panel_backlight_power_on(struct dc_link *link, bool wait_for_hp link->dc->hwss.edp_backlight_control(link, true); } -bool dc_link_wait_for_t12(struct dc_link *link) +bool edp_wait_for_t12(struct dc_link *link) { if (link->connector_signal == SIGNAL_TYPE_EDP && link->dc->hwss.edp_wait_for_T12) { link->dc->hwss.edp_wait_for_T12(link); @@ -422,7 +422,7 @@ static struct pipe_ctx *get_pipe_from_link(const struct dc_link *link) return pipe_ctx; } -bool dc_link_set_backlight_level(const struct dc_link *link, +bool edp_set_backlight_level(const struct dc_link *link, uint32_t backlight_pwm_u16_16, uint32_t frame_ramp) { @@ -453,7 +453,7 @@ bool dc_link_set_backlight_level(const struct dc_link *link, return true; } -bool dc_link_set_psr_allow_active(struct dc_link *link, const bool *allow_active, +bool edp_set_psr_allow_active(struct dc_link *link, const bool *allow_active, bool wait, bool force_static, const unsigned int *power_opts) { struct dc *dc = link->ctx->dc; @@ -502,7 +502,7 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, const bool *allow_active return true; } -bool dc_link_get_psr_state(const struct dc_link *link, enum dc_psr_state *state) +bool edp_get_psr_state(const struct dc_link *link, enum dc_psr_state *state) { struct dc *dc = link->ctx->dc; struct dmcu *dmcu = dc->res_pool->dmcu; @@ -557,7 +557,7 @@ transmitter_to_phy_id(struct dc_link *link) } } -bool dc_link_setup_psr(struct dc_link *link, +bool edp_setup_psr(struct dc_link *link, const struct dc_stream_state *stream, struct psr_config *psr_config, struct psr_context *psr_context) { @@ -803,7 +803,7 @@ static struct abm *get_abm_from_stream_res(const struct dc_link *link) return abm; } -int dc_link_get_backlight_level(const struct dc_link *link) +int edp_get_backlight_level(const struct dc_link *link) { struct abm *abm = get_abm_from_stream_res(link); struct panel_cntl *panel_cntl = link->panel_cntl; @@ -822,7 +822,7 @@ int dc_link_get_backlight_level(const struct dc_link *link) return DC_ERROR_UNEXPECTED; } -int dc_link_get_target_backlight_pwm(const struct dc_link *link) +int edp_get_target_backlight_pwm(const struct dc_link *link) { struct abm *abm = get_abm_from_stream_res(link); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h index 7f91a564b089..4439598f9f7d 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h @@ -30,4 +30,24 @@ enum dp_panel_mode dp_get_panel_mode(struct dc_link *link); void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode); bool set_default_brightness_aux(struct dc_link *link); +void edp_panel_backlight_power_on(struct dc_link *link, bool wait_for_hpd); +int edp_get_backlight_level(const struct dc_link *link); +bool edp_get_backlight_level_nits(struct dc_link *link, + uint32_t *backlight_millinits_avg, + uint32_t *backlight_millinits_peak); +bool edp_set_backlight_level(const struct dc_link *link, + uint32_t backlight_pwm_u16_16, + uint32_t frame_ramp); +bool edp_set_backlight_level_nits(struct dc_link *link, + bool isHDR, + uint32_t backlight_millinits, + uint32_t transition_time_in_ms); +int edp_get_target_backlight_pwm(const struct dc_link *link); +bool edp_get_psr_state(const struct dc_link *link, enum dc_psr_state *state); +bool edp_set_psr_allow_active(struct dc_link *link, const bool *allow_active, + bool wait, bool force_static, const unsigned int *power_opts); +bool edp_setup_psr(struct dc_link *link, + const struct dc_stream_state *stream, struct psr_config *psr_config, + struct psr_context *psr_context); +bool edp_wait_for_t12(struct dc_link *link); #endif /* __DC_LINK_EDP_POWER_CONTROL_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c index 5f39dfe06e9a..e3d729ab5b9f 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c @@ -33,18 +33,18 @@ #include "link_hpd.h" #include "gpio_service_interface.h" -bool dc_link_get_hpd_state(struct dc_link *dc_link) +bool link_get_hpd_state(struct dc_link *link) { uint32_t state; - dal_gpio_lock_pin(dc_link->hpd_gpio); - dal_gpio_get_value(dc_link->hpd_gpio, &state); - dal_gpio_unlock_pin(dc_link->hpd_gpio); + dal_gpio_lock_pin(link->hpd_gpio); + dal_gpio_get_value(link->hpd_gpio, &state); + dal_gpio_unlock_pin(link->hpd_gpio); return state; } -void dc_link_enable_hpd(const struct dc_link *link) +void link_enable_hpd(const struct dc_link *link) { struct link_encoder *encoder = link->link_enc; @@ -52,7 +52,7 @@ void dc_link_enable_hpd(const struct dc_link *link) encoder->funcs->enable_hpd(encoder); } -void dc_link_disable_hpd(const struct dc_link *link) +void link_disable_hpd(const struct dc_link *link) { struct link_encoder *encoder = link->link_enc; @@ -60,7 +60,7 @@ void dc_link_disable_hpd(const struct dc_link *link) encoder->funcs->disable_hpd(encoder); } -void dc_link_enable_hpd_filter(struct dc_link *link, bool enable) +void link_enable_hpd_filter(struct dc_link *link, bool enable) { struct gpio *hpd; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.h index 3d122def0c88..bd471b63476e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.h @@ -44,4 +44,8 @@ bool program_hpd_filter(const struct dc_link *link); */ bool dpia_query_hpd_status(struct dc_link *link); bool query_hpd_status(struct dc_link *link, uint32_t *is_hpd_high); +bool link_get_hpd_state(struct dc_link *link); +void link_enable_hpd(const struct dc_link *link); +void link_disable_hpd(const struct dc_link *link); +void link_enable_hpd_filter(struct dc_link *link, bool enable); #endif /* __DC_LINK_HPD_H__ */ -- cgit From 788c6e2ce5c74c0a22d4e44cca348c8458b3f01d Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Thu, 16 Feb 2023 16:22:01 -0500 Subject: drm/amd/display: replace all dc_link function call in link with link functions [why] Link components should not reply on dc_link_exports to access link function in other link components. Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Wenjing Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/dc/dcn31/dcn31_dio_link_encoder.c | 5 ++-- .../amd/display/dc/link/accessories/link_dp_cts.c | 6 ++--- drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 2 +- .../gpu/drm/amd/display/dc/link/link_validation.c | 5 ++-- .../display/dc/link/protocols/link_dp_capability.c | 28 ++++++++++++---------- .../dc/link/protocols/link_dp_irq_handler.c | 17 ++++++------- .../amd/display/dc/link/protocols/link_dp_phy.c | 8 +++---- .../display/dc/link/protocols/link_dp_training.c | 7 +++--- .../dc/link/protocols/link_dp_training_dpia.c | 2 +- .../dc/link/protocols/link_edp_panel_control.c | 6 ++--- 10 files changed, 46 insertions(+), 40 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c index 275e78c06dee..745a5d187a98 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c @@ -37,6 +37,7 @@ #include "link_enc_cfg.h" #include "dc_dmub_srv.h" #include "dal_asic_id.h" +#include "link.h" #define CTX \ enc10->base.ctx @@ -485,7 +486,7 @@ void dcn31_link_encoder_enable_dp_output( if (link) { dpia_control.dpia_id = link->ddc_hw_inst; - dpia_control.fec_rdy = dc_link_should_enable_fec(link); + dpia_control.fec_rdy = link->dc->link_srv->dp_should_enable_fec(link); } else { DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__); BREAK_TO_DEBUGGER(); @@ -532,7 +533,7 @@ void dcn31_link_encoder_enable_dp_mst_output( if (link) { dpia_control.dpia_id = link->ddc_hw_inst; - dpia_control.fec_rdy = dc_link_should_enable_fec(link); + dpia_control.fec_rdy = link->dc->link_srv->dp_should_enable_fec(link); } else { DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__); BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c index 080019f4252f..704373d4d110 100644 --- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c +++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c @@ -250,7 +250,7 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) /* prepare link training settings */ link_training_settings.link_settings = link->cur_link_settings; - link_training_settings.lttpr_mode = dc_link_decide_lttpr_mode(link, &link->cur_link_settings); + link_training_settings.lttpr_mode = dp_decide_lttpr_mode(link, &link->cur_link_settings); if ((link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && link_training_settings.lttpr_mode == LTTPR_MODE_TRANSPARENT) @@ -408,7 +408,7 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) * all the time. Do not touch it. * forward request to DS */ - dc_link_dp_set_test_pattern( + dp_set_test_pattern( link, test_pattern, DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED, @@ -1006,5 +1006,5 @@ void dp_set_preferred_training_settings(struct dc *dc, /* Retrain now, or wait until next stream update to apply */ if (skip_immediate_retrain == false) - dc_link_set_preferred_link_settings(dc, &link->preferred_link_setting, link); + dp_set_preferred_link_settings(dc, &link->preferred_link_setting, link); } diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index 650ac2a608ef..00d441cacbff 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -137,7 +137,7 @@ void link_blank_dp_stream(struct dc_link *link, bool hw_init) } if ((!link->wa_flags.dp_keep_receiver_powered) || hw_init) - dc_link_dp_receiver_power_ctrl(link, false); + dpcd_write_rx_power_ctrl(link, false); } } diff --git a/drivers/gpu/drm/amd/display/dc/link/link_validation.c b/drivers/gpu/drm/amd/display/dc/link/link_validation.c index d4f6ee6ca948..b29f62337ba0 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_validation.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_validation.c @@ -29,6 +29,7 @@ * provides helper functions exposing bandwidth formulas used in validation. */ #include "link_validation.h" +#include "protocols/link_dp_capability.h" #include "resource.h" #define DC_LOGGER_INIT(logger) @@ -233,7 +234,7 @@ uint32_t dp_link_bandwidth_kbps( */ link_rate_per_lane_kbps = link_settings->link_rate * LINK_RATE_REF_FREQ_IN_KHZ * BITS_PER_DP_BYTE; total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_8b_10b_x10000; - if (dc_link_should_enable_fec(link)) { + if (dp_should_enable_fec(link)) { total_data_bw_efficiency_x10000 /= 100; total_data_bw_efficiency_x10000 *= DATA_EFFICIENCY_8b_10b_FEC_EFFICIENCY_x100; } @@ -329,7 +330,7 @@ static bool dp_validate_mode_timing( timing->v_addressable == (uint32_t) 480) return true; - link_setting = dc_link_get_link_cap(link); + link_setting = dp_get_verified_link_cap(link); /* TODO: DYNAMIC_VALIDATION needs to be implemented */ /*if (flags.DYNAMIC_VALIDATION == 1 && diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index 97856c4d0904..75e1a687608a 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -42,6 +42,8 @@ #include "link_edp_panel_control.h" #include "link_dp_irq_handler.h" #include "link/accessories/link_dp_trace.h" +#include "link/link_detection.h" +#include "link/link_validation.h" #include "link_dp_training.h" #include "atomfirmware.h" #include "resource.h" @@ -278,7 +280,7 @@ static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data, if (!link->dpcd_caps.dpcd_rev.raw) { do { - dc_link_dp_receiver_power_ctrl(link, true); + dpcd_write_rx_power_ctrl(link, true); core_link_read_dpcd(link, DP_DPCD_REV, dpcd_data, length); link->dpcd_caps.dpcd_rev.raw = dpcd_data[ @@ -342,7 +344,7 @@ bool dp_should_enable_fec(const struct dc_link *link) || !link->dc->caps.edp_dsc_support)) force_disable = true; - return !force_disable && dc_link_is_fec_supported(link); + return !force_disable && dp_is_fec_supported(link); } bool link_is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx) @@ -645,7 +647,7 @@ static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_setting initial_link_setting; uint32_t link_bw; - if (req_bw > dc_link_bandwidth_kbps(link, &link->verified_link_cap)) + if (req_bw > dp_link_bandwidth_kbps(link, &link->verified_link_cap)) return false; /* search for the minimum link setting that: @@ -765,7 +767,7 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link, initial_link_setting.use_link_rate_set = false; initial_link_setting.link_rate_set = 0; current_link_setting = initial_link_setting; - if (req_bw > dc_link_bandwidth_kbps(link, &link->verified_link_cap)) + if (req_bw > dp_link_bandwidth_kbps(link, &link->verified_link_cap)) return false; /* search for the minimum link setting that: @@ -774,7 +776,7 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link, */ while (current_link_setting.link_rate <= max_link_rate) { - link_bw = dc_link_bandwidth_kbps( + link_bw = dp_link_bandwidth_kbps( link, ¤t_link_setting); if (req_bw <= link_bw) { @@ -831,7 +833,7 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link, */ while (current_link_setting.link_rate <= max_link_rate) { - link_bw = dc_link_bandwidth_kbps( + link_bw = dp_link_bandwidth_kbps( link, ¤t_link_setting); if (req_bw <= link_bw) { @@ -889,7 +891,7 @@ bool link_decide_link_settings(struct dc_stream_state *stream, struct dc_link_settings *link_setting) { struct dc_link *link = stream->link; - uint32_t req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing); + uint32_t req_bw = link_timing_bandwidth_kbps(&stream->timing); memset(link_setting, 0, sizeof(*link_setting)); @@ -922,13 +924,13 @@ bool link_decide_link_settings(struct dc_stream_state *stream, tmp_link_setting.link_rate = LINK_RATE_UNKNOWN; tmp_timing.flags.DSC = 0; - orig_req_bw = dc_bandwidth_in_kbps_from_timing(&tmp_timing); - dc_link_decide_edp_link_settings(link, &tmp_link_setting, orig_req_bw); + orig_req_bw = link_timing_bandwidth_kbps(&tmp_timing); + edp_decide_link_settings(link, &tmp_link_setting, orig_req_bw); max_link_rate = tmp_link_setting.link_rate; } decide_edp_link_settings_with_dsc(link, link_setting, req_bw, max_link_rate); } else { - dc_link_decide_edp_link_settings(link, link_setting, req_bw); + edp_decide_link_settings(link, link_setting, req_bw); } } else { decide_dp_link_settings(link, link_setting, req_bw); @@ -2117,8 +2119,8 @@ static bool dp_verify_link_cap( if (status == LINK_TRAINING_SUCCESS) { success = true; fsleep(1000); - if (dc_link_dp_read_hpd_rx_irq_data(link, &irq_data) == DC_OK && - dc_link_check_link_loss_status( + if (dp_read_hpd_rx_irq_data(link, &irq_data) == DC_OK && + dp_parse_link_loss_status( link, &irq_data)) (*fail_count)++; @@ -2158,7 +2160,7 @@ bool dp_verify_link_cap_with_retries( memset(&link->verified_link_cap, 0, sizeof(struct dc_link_settings)); - if (!dc_link_detect_connection_type(link, &type) || type == dc_connection_none) { + if (!link_detect_connection_type(link, &type) || type == dc_connection_none) { link->verified_link_cap = fail_safe_link_settings; break; } else if (dp_verify_link_cap(link, known_limit_link_setting, diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c index 6611d0767bd4..ba95facc4ee8 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c @@ -33,6 +33,7 @@ #include "link_dpcd.h" #include "link_dp_training.h" #include "link_dp_capability.h" +#include "link_edp_panel_control.h" #include "link/accessories/link_dp_trace.h" #include "link/link_dpms.h" #include "dm_helpers.h" @@ -155,9 +156,9 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link) /* PSR error, disable and re-enable PSR */ if (link->psr_settings.psr_allow_active) { allow_active = false; - dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL); + edp_set_psr_allow_active(link, &allow_active, true, false, NULL); allow_active = true; - dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL); + edp_set_psr_allow_active(link, &allow_active, true, false, NULL); } return true; @@ -289,7 +290,7 @@ bool dp_handle_hpd_rx_irq(struct dc_link *link, * dal_dpsst_ls_read_hpd_irq_data * Order of calls is important too */ - result = dc_link_dp_read_hpd_rx_irq_data(link, &hpd_irq_dpcd_data); + result = dp_read_hpd_rx_irq_data(link, &hpd_irq_dpcd_data); if (out_hpd_irq_dpcd_data) *out_hpd_irq_dpcd_data = hpd_irq_dpcd_data; @@ -316,7 +317,7 @@ bool dp_handle_hpd_rx_irq(struct dc_link *link, return false; } - if (!dc_link_dp_allow_hpd_rx_irq(link)) { + if (!dp_should_allow_hpd_rx_irq(link)) { DC_LOG_HW_HPD_IRQ("%s: skipping HPD handling on %d\n", __func__, link->link_index); return false; @@ -349,9 +350,9 @@ bool dp_handle_hpd_rx_irq(struct dc_link *link, * then DM should call DC to do the detection. * NOTE: Do not handle link loss on eDP since it is internal link*/ if ((link->connector_signal != SIGNAL_TYPE_EDP) && - dc_link_check_link_loss_status( - link, - &hpd_irq_dpcd_data)) { + dp_parse_link_loss_status( + link, + &hpd_irq_dpcd_data)) { /* Connectivity log: link loss */ CONN_DATA_LINK_LOSS(link, hpd_irq_dpcd_data.raw, @@ -361,7 +362,7 @@ bool dp_handle_hpd_rx_irq(struct dc_link *link, if (defer_handling && has_left_work) *has_left_work = true; else - dc_link_dp_handle_link_loss(link); + dp_handle_link_loss(link); status = false; if (out_link_loss) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c index 92c2aa104eb5..b7abba55bc2f 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c @@ -64,7 +64,7 @@ void dp_enable_link_phy( link->cur_link_settings = *link_settings; link->dc->hwss.enable_dp_link_output(link, link_res, signal, clock_source, link_settings); - dc_link_dp_receiver_power_ctrl(link, true); + dpcd_write_rx_power_ctrl(link, true); } void dp_disable_link_phy(struct dc_link *link, @@ -74,7 +74,7 @@ void dp_disable_link_phy(struct dc_link *link, struct dc *dc = link->ctx->dc; if (!link->wa_flags.dp_keep_receiver_powered) - dc_link_dp_receiver_power_ctrl(link, false); + dpcd_write_rx_power_ctrl(link, false); dc->hwss.disable_link_output(link, link_res, signal); /* Clear current link setting.*/ @@ -143,7 +143,7 @@ enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource link_enc = link_enc_cfg_get_link_enc(link); ASSERT(link_enc); - if (!dc_link_should_enable_fec(link)) + if (!dp_should_enable_fec(link)) return status; if (link_enc->funcs->fec_set_ready && @@ -183,7 +183,7 @@ void dp_set_fec_enable(struct dc_link *link, bool enable) link_enc = link_enc_cfg_get_link_enc(link); ASSERT(link_enc); - if (!dc_link_should_enable_fec(link)) + if (!dp_should_enable_fec(link)) return; if (link_enc->funcs->fec_set_enable && diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index 2948319b06f8..4a3758ea04f5 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -41,6 +41,7 @@ #include "link_dp_phy.h" #include "link_dp_capability.h" #include "link_edp_panel_control.h" +#include "link/link_detection.h" #include "atomfirmware.h" #include "link_enc_cfg.h" #include "resource.h" @@ -1644,7 +1645,7 @@ bool perform_link_training_with_retries( if (status == LINK_TRAINING_ABORT) { enum dc_connection_type type = dc_connection_none; - dc_link_detect_connection_type(link, &type); + link_detect_connection_type(link, &type); if (type == dc_connection_none) { DC_LOG_HW_LINK_TRAINING("%s: Aborting training because sink unplugged\n", __func__); break; @@ -1676,8 +1677,8 @@ bool perform_link_training_with_retries( /* Flag if reduced link bandwidth no longer meets stream requirements or fallen back to * minimum link bandwidth. */ - req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing); - link_bw = dc_link_bandwidth_kbps(link, &cur_link_settings); + req_bw = link_timing_bandwidth_kbps(&stream->timing); + link_bw = dp_link_bandwidth_kbps(link, &cur_link_settings); is_link_bw_low = (req_bw > link_bw); is_link_bw_min = ((cur_link_settings.link_rate <= LINK_RATE_LOW) && (cur_link_settings.lane_count <= LANE_COUNT_ONE)); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c index 0f56db4018e1..ab4aafdb5e5c 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c @@ -998,7 +998,7 @@ enum link_training_result dpia_perform_link_training( struct dc_link_settings link_settings = *link_setting; // non-const copy to pass in - lt_settings.lttpr_mode = dc_link_decide_lttpr_mode(link, &link_settings); + lt_settings.lttpr_mode = dp_decide_lttpr_mode(link, &link_settings); /* Configure link as prescribed in link_setting and set LTTPR mode. */ result = dpia_configure_link(link, link_res, link_setting, <_settings); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index 2f7e0f464144..eaafa00a7b9f 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -243,7 +243,7 @@ bool set_default_brightness_aux(struct dc_link *link) if (default_backlight < 5000 || default_backlight > 5000000) default_backlight = 150000; // - return dc_link_set_backlight_level_nits(link, true, + return edp_set_backlight_level_nits(link, true, default_backlight, 0); } return false; @@ -282,10 +282,10 @@ bool link_is_edp_ilr_optimization_required(struct dc_link *link, core_link_read_dpcd(link, DP_LANE_COUNT_SET, &lane_count_set.raw, sizeof(lane_count_set)); - req_bw = dc_bandwidth_in_kbps_from_timing(crtc_timing); + req_bw = link_timing_bandwidth_kbps(crtc_timing); if (!crtc_timing->flags.DSC) - dc_link_decide_edp_link_settings(link, &link_setting, req_bw); + edp_decide_link_settings(link, &link_setting, req_bw); else decide_edp_link_settings_with_dsc(link, &link_setting, req_bw, LINK_RATE_UNKNOWN); -- cgit From 34fd6df7886989019d4f6996da2d2edfde5bcd34 Mon Sep 17 00:00:00 2001 From: Chris Park Date: Thu, 23 Feb 2023 01:07:23 -0500 Subject: drm/amd/display: Simplify register offsets [Why] Runtime initialization of register addresses define duplicate register offsets in resource file, and makes register offsets in sub-block defined for compile time initialization obsolete. [How] Remove obsolete sub block register offsets that is no longer referenced. Reviewed-by: Martin Leung Acked-by: Qingqing Zhuo Signed-off-by: Chris Park Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h | 36 ----------- .../display/dc/dcn32/dcn32_dio_stream_encoder.h | 64 ------------------- .../gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.h | 62 ------------------- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.h | 6 -- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.h | 71 ---------------------- 5 files changed, 239 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h index 1c46fad0977b..271c163e4844 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h @@ -31,42 +31,6 @@ #define DCCG_SFII(block, reg_name, field_prefix, field_name, inst, post_fix)\ .field_prefix ## _ ## field_name[inst] = block ## inst ## _ ## reg_name ## __ ## field_prefix ## inst ## _ ## field_name ## post_fix - -#define DCCG_REG_LIST_DCN32() \ - SR(DPPCLK_DTO_CTRL),\ - DCCG_SRII(DTO_PARAM, DPPCLK, 0),\ - DCCG_SRII(DTO_PARAM, DPPCLK, 1),\ - DCCG_SRII(DTO_PARAM, DPPCLK, 2),\ - DCCG_SRII(DTO_PARAM, DPPCLK, 3),\ - DCCG_SRII(CLOCK_CNTL, HDMICHARCLK, 0),\ - SR(PHYASYMCLK_CLOCK_CNTL),\ - SR(PHYBSYMCLK_CLOCK_CNTL),\ - SR(PHYCSYMCLK_CLOCK_CNTL),\ - SR(PHYDSYMCLK_CLOCK_CNTL),\ - SR(PHYESYMCLK_CLOCK_CNTL),\ - SR(DPSTREAMCLK_CNTL),\ - SR(HDMISTREAMCLK_CNTL),\ - SR(SYMCLK32_SE_CNTL),\ - SR(SYMCLK32_LE_CNTL),\ - DCCG_SRII(PIXEL_RATE_CNTL, OTG, 0),\ - DCCG_SRII(PIXEL_RATE_CNTL, OTG, 1),\ - DCCG_SRII(PIXEL_RATE_CNTL, OTG, 2),\ - DCCG_SRII(PIXEL_RATE_CNTL, OTG, 3),\ - DCCG_SRII(MODULO, DTBCLK_DTO, 0),\ - DCCG_SRII(MODULO, DTBCLK_DTO, 1),\ - DCCG_SRII(MODULO, DTBCLK_DTO, 2),\ - DCCG_SRII(MODULO, DTBCLK_DTO, 3),\ - DCCG_SRII(PHASE, DTBCLK_DTO, 0),\ - DCCG_SRII(PHASE, DTBCLK_DTO, 1),\ - DCCG_SRII(PHASE, DTBCLK_DTO, 2),\ - DCCG_SRII(PHASE, DTBCLK_DTO, 3),\ - SR(DCCG_AUDIO_DTBCLK_DTO_MODULO),\ - SR(DCCG_AUDIO_DTBCLK_DTO_PHASE),\ - SR(OTG_PIXEL_RATE_DIV),\ - SR(DTBCLK_P_CNTL),\ - SR(DCCG_AUDIO_DTO_SOURCE) - - #define DCCG_MASK_SH_LIST_DCN32(mask_sh) \ DCCG_SFI(DPPCLK_DTO_CTRL, DTO_ENABLE, DPPCLK, 0, mask_sh),\ DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 0, mask_sh),\ diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h index ecd041a446d2..875b1cd46056 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h @@ -31,70 +31,6 @@ #include "stream_encoder.h" #include "dcn20/dcn20_stream_encoder.h" -#define SE_DCN32_REG_LIST(id)\ - SRI(AFMT_CNTL, DIG, id), \ - SRI(DIG_FE_CNTL, DIG, id), \ - SRI(HDMI_CONTROL, DIG, id), \ - SRI(HDMI_DB_CONTROL, DIG, id), \ - SRI(HDMI_GC, DIG, id), \ - SRI(HDMI_GENERIC_PACKET_CONTROL0, DIG, id), \ - SRI(HDMI_GENERIC_PACKET_CONTROL1, DIG, id), \ - SRI(HDMI_GENERIC_PACKET_CONTROL2, DIG, id), \ - SRI(HDMI_GENERIC_PACKET_CONTROL3, DIG, id), \ - SRI(HDMI_GENERIC_PACKET_CONTROL4, DIG, id), \ - SRI(HDMI_GENERIC_PACKET_CONTROL5, DIG, id), \ - SRI(HDMI_GENERIC_PACKET_CONTROL6, DIG, id), \ - SRI(HDMI_GENERIC_PACKET_CONTROL7, DIG, id), \ - SRI(HDMI_GENERIC_PACKET_CONTROL8, DIG, id), \ - SRI(HDMI_GENERIC_PACKET_CONTROL9, DIG, id), \ - SRI(HDMI_GENERIC_PACKET_CONTROL10, DIG, id), \ - SRI(HDMI_INFOFRAME_CONTROL0, DIG, id), \ - SRI(HDMI_INFOFRAME_CONTROL1, DIG, id), \ - SRI(HDMI_VBI_PACKET_CONTROL, DIG, id), \ - SRI(HDMI_AUDIO_PACKET_CONTROL, DIG, id),\ - SRI(HDMI_ACR_PACKET_CONTROL, DIG, id),\ - SRI(HDMI_ACR_32_0, DIG, id),\ - SRI(HDMI_ACR_32_1, DIG, id),\ - SRI(HDMI_ACR_44_0, DIG, id),\ - SRI(HDMI_ACR_44_1, DIG, id),\ - SRI(HDMI_ACR_48_0, DIG, id),\ - SRI(HDMI_ACR_48_1, DIG, id),\ - SRI(DP_DB_CNTL, DP, id), \ - SRI(DP_MSA_MISC, DP, id), \ - SRI(DP_MSA_VBID_MISC, DP, id), \ - SRI(DP_MSA_COLORIMETRY, DP, id), \ - SRI(DP_MSA_TIMING_PARAM1, DP, id), \ - SRI(DP_MSA_TIMING_PARAM2, DP, id), \ - SRI(DP_MSA_TIMING_PARAM3, DP, id), \ - SRI(DP_MSA_TIMING_PARAM4, DP, id), \ - SRI(DP_MSE_RATE_CNTL, DP, id), \ - SRI(DP_MSE_RATE_UPDATE, DP, id), \ - SRI(DP_PIXEL_FORMAT, DP, id), \ - SRI(DP_SEC_CNTL, DP, id), \ - SRI(DP_SEC_CNTL1, DP, id), \ - SRI(DP_SEC_CNTL2, DP, id), \ - SRI(DP_SEC_CNTL5, DP, id), \ - SRI(DP_SEC_CNTL6, DP, id), \ - SRI(DP_STEER_FIFO, DP, id), \ - SRI(DP_VID_M, DP, id), \ - SRI(DP_VID_N, DP, id), \ - SRI(DP_VID_STREAM_CNTL, DP, id), \ - SRI(DP_VID_TIMING, DP, id), \ - SRI(DP_SEC_AUD_N, DP, id), \ - SRI(DP_SEC_TIMESTAMP, DP, id), \ - SRI(DP_DSC_CNTL, DP, id), \ - SRI(DP_SEC_METADATA_TRANSMISSION, DP, id), \ - SRI(HDMI_METADATA_PACKET_CONTROL, DIG, id), \ - SRI(DP_SEC_FRAMING4, DP, id), \ - SRI(DP_GSP11_CNTL, DP, id), \ - SRI(DME_CONTROL, DME, id),\ - SRI(DP_SEC_METADATA_TRANSMISSION, DP, id), \ - SRI(HDMI_METADATA_PACKET_CONTROL, DIG, id), \ - SRI(DIG_FE_CNTL, DIG, id), \ - SRI(DIG_CLOCK_PATTERN, DIG, id), \ - SRI(DIG_FIFO_CTRL0, DIG, id) - - #define SE_COMMON_MASK_SH_LIST_DCN32(mask_sh)\ SE_SF(DP0_DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, mask_sh),\ SE_SF(DP0_DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, mask_sh),\ diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.h index b20eb04724bb..ad33427192c6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.h @@ -28,68 +28,6 @@ #include "dcn21/dcn21_hubbub.h" -#define HUBBUB_REG_LIST_DCN32(id)\ - SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A),\ - SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B),\ - SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C),\ - SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D),\ - SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL),\ - SR(DCHUBBUB_ARB_DRAM_STATE_CNTL),\ - SR(DCHUBBUB_ARB_SAT_LEVEL),\ - SR(DCHUBBUB_ARB_DF_REQ_OUTSTAND),\ - SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \ - SR(DCHUBBUB_SOFT_RESET),\ - SR(DCHUBBUB_CRC_CTRL), \ - SR(DCN_VM_FB_LOCATION_BASE),\ - SR(DCN_VM_FB_LOCATION_TOP),\ - SR(DCN_VM_FB_OFFSET),\ - SR(DCN_VM_AGP_BOT),\ - SR(DCN_VM_AGP_TOP),\ - SR(DCN_VM_AGP_BASE),\ - HUBBUB_SR_WATERMARK_REG_LIST(), \ - SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A),\ - SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B),\ - SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C),\ - SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D),\ - SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A),\ - SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B),\ - SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C),\ - SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D),\ - SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A),\ - SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B),\ - SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C),\ - SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D),\ - SR(DCHUBBUB_DET0_CTRL),\ - SR(DCHUBBUB_DET1_CTRL),\ - SR(DCHUBBUB_DET2_CTRL),\ - SR(DCHUBBUB_DET3_CTRL),\ - SR(DCHUBBUB_COMPBUF_CTRL),\ - SR(COMPBUF_RESERVED_SPACE),\ - SR(DCHUBBUB_DEBUG_CTRL_0),\ - SR(DCHUBBUB_ARB_USR_RETRAINING_CNTL),\ - SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A),\ - SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B),\ - SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C),\ - SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D),\ - SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A),\ - SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B),\ - SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C),\ - SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D),\ - SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A),\ - SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B),\ - SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C),\ - SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D),\ - SR(DCN_VM_FAULT_ADDR_MSB),\ - SR(DCN_VM_FAULT_ADDR_LSB),\ - SR(DCN_VM_FAULT_CNTL),\ - SR(DCN_VM_FAULT_STATUS),\ - SR(SDPIF_REQUEST_RATE_LIMIT),\ - SR(DCHUBBUB_CLOCK_CNTL),\ - SR(DCHUBBUB_SDPIF_CFG0),\ - SR(DCHUBBUB_SDPIF_CFG1),\ - SR(DCHUBBUB_MEM_PWR_MODE_CTRL) - - #define HUBBUB_MASK_SH_LIST_DCN32(mask_sh)\ HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \ HUBBUB_SF(DCHUBBUB_SOFT_RESET, DCHUBBUB_GLOBAL_SOFT_RESET, mask_sh), \ diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.h index 4cdbf63c952b..d5e5ed8ab869 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.h @@ -31,12 +31,6 @@ #include "dcn30/dcn30_hubp.h" #include "dcn31/dcn31_hubp.h" -#define HUBP_REG_LIST_DCN32(id)\ - HUBP_REG_LIST_DCN30(id),\ - SRI(DCHUBP_MALL_CONFIG, HUBP, id),\ - SRI(DCHUBP_VMPG_CONFIG, HUBP, id),\ - SRI(UCLK_PSTATE_FORCE, HUBPREQ, id) - #define HUBP_MASK_SH_LIST_DCN32(mask_sh)\ HUBP_MASK_SH_LIST_DCN31(mask_sh),\ HUBP_SF(HUBP0_DCHUBP_MALL_CONFIG, USE_MALL_SEL, mask_sh),\ diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.h index 5e57c39235fa..b92ba8c75694 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.h @@ -28,77 +28,6 @@ #include "dcn10/dcn10_optc.h" -#define OPTC_COMMON_REG_LIST_DCN3_2(inst) \ - SRI(OTG_VSTARTUP_PARAM, OTG, inst),\ - SRI(OTG_VUPDATE_PARAM, OTG, inst),\ - SRI(OTG_VREADY_PARAM, OTG, inst),\ - SRI(OTG_MASTER_UPDATE_LOCK, OTG, inst),\ - SRI(OTG_GLOBAL_CONTROL0, OTG, inst),\ - SRI(OTG_GLOBAL_CONTROL1, OTG, inst),\ - SRI(OTG_GLOBAL_CONTROL2, OTG, inst),\ - SRI(OTG_GLOBAL_CONTROL4, OTG, inst),\ - SRI(OTG_DOUBLE_BUFFER_CONTROL, OTG, inst),\ - SRI(OTG_H_TOTAL, OTG, inst),\ - SRI(OTG_H_BLANK_START_END, OTG, inst),\ - SRI(OTG_H_SYNC_A, OTG, inst),\ - SRI(OTG_H_SYNC_A_CNTL, OTG, inst),\ - SRI(OTG_H_TIMING_CNTL, OTG, inst),\ - SRI(OTG_V_TOTAL, OTG, inst),\ - SRI(OTG_V_BLANK_START_END, OTG, inst),\ - SRI(OTG_V_SYNC_A, OTG, inst),\ - SRI(OTG_V_SYNC_A_CNTL, OTG, inst),\ - SRI(OTG_CONTROL, OTG, inst),\ - SRI(OTG_STEREO_CONTROL, OTG, inst),\ - SRI(OTG_3D_STRUCTURE_CONTROL, OTG, inst),\ - SRI(OTG_STEREO_STATUS, OTG, inst),\ - SRI(OTG_V_TOTAL_MAX, OTG, inst),\ - SRI(OTG_V_TOTAL_MIN, OTG, inst),\ - SRI(OTG_V_TOTAL_CONTROL, OTG, inst),\ - SRI(OTG_TRIGA_CNTL, OTG, inst),\ - SRI(OTG_FORCE_COUNT_NOW_CNTL, OTG, inst),\ - SRI(OTG_STATIC_SCREEN_CONTROL, OTG, inst),\ - SRI(OTG_STATUS_FRAME_COUNT, OTG, inst),\ - SRI(OTG_STATUS, OTG, inst),\ - SRI(OTG_STATUS_POSITION, OTG, inst),\ - SRI(OTG_NOM_VERT_POSITION, OTG, inst),\ - SRI(OTG_M_CONST_DTO0, OTG, inst),\ - SRI(OTG_M_CONST_DTO1, OTG, inst),\ - SRI(OTG_CLOCK_CONTROL, OTG, inst),\ - SRI(OTG_VERTICAL_INTERRUPT0_CONTROL, OTG, inst),\ - SRI(OTG_VERTICAL_INTERRUPT0_POSITION, OTG, inst),\ - SRI(OTG_VERTICAL_INTERRUPT1_CONTROL, OTG, inst),\ - SRI(OTG_VERTICAL_INTERRUPT1_POSITION, OTG, inst),\ - SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\ - SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\ - SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\ - SRI(OPTC_DATA_SOURCE_SELECT, ODM, inst),\ - SRI(OPTC_INPUT_GLOBAL_CONTROL, ODM, inst),\ - SRI(CONTROL, VTG, inst),\ - SRI(OTG_VERT_SYNC_CONTROL, OTG, inst),\ - SRI(OTG_GSL_CONTROL, OTG, inst),\ - SRI(OTG_CRC_CNTL, OTG, inst),\ - SRI(OTG_CRC0_DATA_RG, OTG, inst),\ - SRI(OTG_CRC0_DATA_B, OTG, inst),\ - SRI(OTG_CRC0_WINDOWA_X_CONTROL, OTG, inst),\ - SRI(OTG_CRC0_WINDOWA_Y_CONTROL, OTG, inst),\ - SRI(OTG_CRC0_WINDOWB_X_CONTROL, OTG, inst),\ - SRI(OTG_CRC0_WINDOWB_Y_CONTROL, OTG, inst),\ - SR(GSL_SOURCE_SELECT),\ - SRI(OTG_TRIGA_MANUAL_TRIG, OTG, inst),\ - SRI(OTG_GLOBAL_CONTROL1, OTG, inst),\ - SRI(OTG_GLOBAL_CONTROL2, OTG, inst),\ - SRI(OTG_GSL_WINDOW_X, OTG, inst),\ - SRI(OTG_GSL_WINDOW_Y, OTG, inst),\ - SRI(OTG_VUPDATE_KEEPOUT, OTG, inst),\ - SRI(OTG_DSC_START_POSITION, OTG, inst),\ - SRI(OTG_DRR_TRIGGER_WINDOW, OTG, inst),\ - SRI(OTG_DRR_V_TOTAL_CHANGE, OTG, inst),\ - SRI(OPTC_DATA_FORMAT_CONTROL, ODM, inst),\ - SRI(OPTC_BYTES_PER_PIXEL, ODM, inst),\ - SRI(OPTC_WIDTH_CONTROL, ODM, inst),\ - SRI(OPTC_MEMORY_CONFIG, ODM, inst),\ - SRI(OTG_DRR_CONTROL, OTG, inst) - #define OPTC_COMMON_MASK_SH_LIST_DCN3_2(mask_sh)\ SF(OTG0_OTG_VSTARTUP_PARAM, VSTARTUP_START, mask_sh),\ SF(OTG0_OTG_VUPDATE_PARAM, VUPDATE_OFFSET, mask_sh),\ -- cgit From 2b02d746c1818baf741f4eeeff9b97ab4b81e1cf Mon Sep 17 00:00:00 2001 From: Agustin Gutierrez Date: Tue, 21 Feb 2023 16:08:15 -0500 Subject: drm/amd/display: Keep PHY active for dp config [Why] Current hotplug sequence causes temporary hang at the re-entry of the optimized power state. [How] Keep a PHY active when detecting DP signal + DPMS active Reviewed-by: Nicholas Kazlauskas Acked-by: Qingqing Zhuo Signed-off-by: Agustin Gutierrez Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/amd/display') 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..5cb44f838bde 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 @@ -108,6 +108,11 @@ static int dcn314_get_active_display_cnt_wa( stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK || stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) tmds_present = true; + + /* Checking stream / link detection ensuring that PHY is active*/ + if (dc_is_dp_signal(stream->signal) && !stream->dpms_off) + display_count++; + } for (i = 0; i < dc->link_count; i++) { -- cgit From bf77fda02411fe2cac3522f40d8d6882d27ac14b Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 13 Feb 2023 17:46:45 -0500 Subject: drm/amd/display: Drop unnecessary DCN guards [Why] DM is littered with DCN guards leading to frequent breakages on non-DCN builds when new code is added. [How] Remove all guards that are not needed. Reviewed-by: Rodrigo Siqueira Acked-by: Qingqing Zhuo Signed-off-by: Harry Wentland Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 -------------------- .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 8 -------- .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 14 -------------- 3 files changed, 42 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 de270f0969f5..26abb62bbd93 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5737,7 +5737,6 @@ static bool is_freesync_video_mode(const struct drm_display_mode *mode, return true; } -#if defined(CONFIG_DRM_AMD_DC_DCN) static void update_dsc_caps(struct amdgpu_dm_connector *aconnector, struct dc_sink *sink, struct dc_stream_state *stream, struct dsc_dec_dpcd_caps *dsc_caps) @@ -5892,7 +5891,6 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector, if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_bits_per_pixel) stream->timing.dsc_cfg.bits_per_pixel = aconnector->dsc_settings.dsc_bits_per_pixel; } -#endif /* CONFIG_DRM_AMD_DC_DCN */ static struct dc_stream_state * create_stream_for_sink(struct amdgpu_dm_connector *aconnector, @@ -5915,9 +5913,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, int mode_refresh; int preferred_refresh = 0; enum color_transfer_func tf = TRANSFER_FUNC_UNKNOWN; -#if defined(CONFIG_DRM_AMD_DC_DCN) struct dsc_dec_dpcd_caps dsc_caps; -#endif struct dc_sink *sink = NULL; @@ -6016,12 +6012,10 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, stream->timing = *aconnector->timing_requested; } -#if defined(CONFIG_DRM_AMD_DC_DCN) /* SST DSC determination policy */ update_dsc_caps(aconnector, sink, stream, &dsc_caps); if (aconnector->dsc_settings.dsc_force_enable != DSC_CLK_FORCE_DISABLE && dsc_caps.is_dsc_supported) apply_dsc_policy_for_stream(aconnector, sink, stream, &dsc_caps); -#endif update_stream_scaling_settings(&mode, dm_state, stream); @@ -6747,7 +6741,6 @@ const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs = { .atomic_check = dm_encoder_helper_atomic_check }; -#if defined(CONFIG_DRM_AMD_DC_DCN) static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state, struct dc_state *dc_state, struct dsc_mst_fairness_vars *vars) @@ -6821,7 +6814,6 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state, } return 0; } -#endif static int to_drm_connector_type(enum signal_type st) { @@ -9758,7 +9750,6 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state, return 0; } -#if defined(CONFIG_DRM_AMD_DC_DCN) static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm_crtc *crtc) { struct drm_connector *connector; @@ -9784,7 +9775,6 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm return drm_dp_mst_add_affected_dsc_crtcs(state, &aconnector->mst_root->mst_mgr); } -#endif /** * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM. @@ -9828,11 +9818,9 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, bool lock_and_validation_needed = false; bool is_top_most_overlay = true; struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state; -#if defined(CONFIG_DRM_AMD_DC_DCN) struct drm_dp_mst_topology_mgr *mgr; struct drm_dp_mst_topology_state *mst_state; struct dsc_mst_fairness_vars vars[MAX_PIPES]; -#endif trace_amdgpu_dm_atomic_check_begin(state); @@ -9863,7 +9851,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, new_crtc_state->connectors_changed = true; } -#if defined(CONFIG_DRM_AMD_DC_DCN) if (dc_resource_is_dsc_encoding_supported(dc)) { for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { if (drm_atomic_crtc_needs_modeset(new_crtc_state)) { @@ -9875,7 +9862,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, } } } -#endif for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); @@ -10013,13 +9999,11 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, } } -#if defined(CONFIG_DRM_AMD_DC_DCN) if (dc_resource_is_dsc_encoding_supported(dc)) { ret = pre_validate_dsc(state, &dm_state, vars); if (ret != 0) goto fail; } -#endif /* Run this here since we want to validate the streams we created */ ret = drm_atomic_helper_check_planes(dev, state); @@ -10085,7 +10069,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, lock_and_validation_needed = true; } -#if defined(CONFIG_DRM_AMD_DC_DCN) /* set the slot info for each mst_state based on the link encoding format */ for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) { struct amdgpu_dm_connector *aconnector; @@ -10105,7 +10088,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, } drm_connector_list_iter_end(&iter); } -#endif /** * Streams and planes are reset when there are changes that affect @@ -10133,7 +10115,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, goto fail; } -#if defined(CONFIG_DRM_AMD_DC_DCN) ret = compute_mst_dsc_configs_for_state(state, dm_state->context, vars); if (ret) { DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n"); @@ -10145,7 +10126,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, DRM_DEBUG_DRIVER("dm_update_mst_vcpi_slots_for_dsc() failed\n"); goto fail; } -#endif /* * Perform validation of MST topology in the state: 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 1583157da355..1be04c613deb 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 @@ -525,7 +525,6 @@ bool dm_helpers_submit_i2c( return result; } -#if defined(CONFIG_DRM_AMD_DC_DCN) static bool execute_synaptics_rc_command(struct drm_dp_aux *aux, bool is_write_cmd, unsigned char cmd, @@ -693,7 +692,6 @@ static uint8_t write_dsc_enable_synaptics_non_virtual_dpcd_mst( return ret; } -#endif bool dm_helpers_dp_write_dsc_enable( struct dc_context *ctx, @@ -719,13 +717,11 @@ bool dm_helpers_dp_write_dsc_enable( if (!aconnector->dsc_aux) return false; -#if defined(CONFIG_DRM_AMD_DC_DCN) // apply w/a to synaptics if (needs_dsc_aux_workaround(aconnector->dc_link) && (aconnector->mst_downstream_port_present.byte & 0x7) != 0x3) return write_dsc_enable_synaptics_non_virtual_dpcd_mst( aconnector->dsc_aux, stream, enable_dsc); -#endif port = aconnector->mst_output_port; @@ -763,17 +759,13 @@ bool dm_helpers_dp_write_dsc_enable( } if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || stream->signal == SIGNAL_TYPE_EDP) { -#if defined(CONFIG_DRM_AMD_DC_DCN) if (stream->sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_NONE) { -#endif ret = dm_helpers_dp_write_dpcd(ctx, stream->link, DP_DSC_ENABLE, &enable_dsc, 1); DC_LOG_DC("Send DSC %s to SST RX\n", enable_dsc ? "enable" : "disable"); -#if defined(CONFIG_DRM_AMD_DC_DCN) } else if (stream->sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER) { ret = dm_helpers_dp_write_dpcd(ctx, stream->link, DP_DSC_ENABLE, &enable_dsc, 1); DC_LOG_DC("Send DSC %s to DP-HDMI PCON\n", enable_dsc ? "enable" : "disable"); } -#endif } return ret; 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 248f25943748..2739bef9b90c 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 @@ -198,7 +198,6 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = { .early_unregister = amdgpu_dm_mst_connector_early_unregister, }; -#if defined(CONFIG_DRM_AMD_DC_DCN) bool needs_dsc_aux_workaround(struct dc_link *link) { if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 && @@ -268,7 +267,6 @@ static bool retrieve_downstream_port_device(struct amdgpu_dm_connector *aconnect return true; } -#endif static int dm_dp_mst_get_modes(struct drm_connector *connector) { @@ -375,7 +373,6 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) amdgpu_dm_update_freesync_caps( connector, aconnector->edid); -#if defined(CONFIG_DRM_AMD_DC_DCN) if (!validate_dsc_caps_on_connector(aconnector)) memset(&aconnector->dc_sink->dsc_caps, 0, sizeof(aconnector->dc_sink->dsc_caps)); @@ -383,7 +380,6 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) if (!retrieve_downstream_port_device(aconnector)) memset(&aconnector->mst_downstream_port_present, 0, sizeof(aconnector->mst_downstream_port_present)); -#endif } } @@ -642,8 +638,6 @@ int dm_mst_get_pbn_divider(struct dc_link *link) dc_link_get_link_cap(link)) / (8 * 1000 * 54); } -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct dsc_mst_fairness_params { struct dc_crtc_timing *timing; struct dc_sink *sink; @@ -1427,7 +1421,6 @@ static unsigned int kbps_from_pbn(unsigned int pbn) static bool is_dsc_common_config_possible(struct dc_stream_state *stream, struct dc_dsc_bw_range *bw_range) { -#if defined(CONFIG_DRM_AMD_DC_DCN) struct dc_dsc_policy dsc_policy = {0}; dc_dsc_get_policy_for_timing(&stream->timing, 0, &dsc_policy); @@ -1439,17 +1432,13 @@ static bool is_dsc_common_config_possible(struct dc_stream_state *stream, &stream->timing, bw_range); return bw_range->max_target_bpp_x16 && bw_range->min_target_bpp_x16; -#endif - return false; } -#endif /* CONFIG_DRM_AMD_DC_DCN */ enum dc_status dm_dp_mst_is_port_support_mode( struct amdgpu_dm_connector *aconnector, struct dc_stream_state *stream) { int bpp, pbn, branch_max_throughput_mps = 0; -#if defined(CONFIG_DRM_AMD_DC_DCN) struct dc_link_settings cur_link_settings; unsigned int end_to_end_bw_in_kbps = 0; unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0; @@ -1491,16 +1480,13 @@ enum dc_status dm_dp_mst_is_port_support_mode( return DC_FAIL_BANDWIDTH_VALIDATE; } } else { -#endif /* check if mode could be supported within full_pbn */ bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3; pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false); if (pbn > aconnector->mst_output_port->full_pbn) return DC_FAIL_BANDWIDTH_VALIDATE; -#if defined(CONFIG_DRM_AMD_DC_DCN) } -#endif /* check is mst dsc output bandwidth branch_overall_throughput_0_mps */ switch (stream->timing.pixel_encoding) { -- cgit From c186c13e65286a46b61f5c295f9f9c65c75c926e Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 13 Feb 2023 17:58:22 -0500 Subject: drm/amd/display: Drop unnecessary DCN guards [Why & How] DC is littered with many DCN guards that are not needed. Drop them. Reviewed-by: Rodrigo Siqueira Acked-by: Qingqing Zhuo Signed-off-by: Harry Wentland Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_vm_helper.c | 2 -- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 2 -- .../gpu/drm/amd/display/dc/dce/dce_clock_source.c | 27 ++++++++++++---------- .../gpu/drm/amd/display/dc/dce/dce_clock_source.h | 6 ----- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dwb.c | 5 ---- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dwb.h | 4 ---- .../amd/display/dc/dcn10/dcn10_stream_encoder.c | 3 +-- .../drm/amd/display/dc/dcn303/dcn303_resource.c | 2 -- .../amd/display/dc/dml/dcn30/display_mode_vba_30.c | 2 -- .../display/dc/dml/dcn30/display_rq_dlg_calc_30.c | 3 --- drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h | 6 ----- .../gpu/drm/amd/display/dc/link/link_validation.c | 2 -- .../display/dc/link/protocols/link_dp_training.c | 2 -- .../dc/link/protocols/link_edp_panel_control.c | 5 ---- .../drm/amd/display/modules/power/power_helpers.c | 7 ------ 15 files changed, 16 insertions(+), 62 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_vm_helper.c b/drivers/gpu/drm/amd/display/dc/core/dc_vm_helper.c index cde8ed2560b3..eda2152dcd1f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_vm_helper.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_vm_helper.c @@ -47,9 +47,7 @@ int dc_setup_system_context(struct dc *dc, struct dc_phy_addr_space_config *pa_c */ memcpy(&dc->vm_pa_config, pa_config, sizeof(struct dc_phy_addr_space_config)); dc->vm_pa_config.valid = true; -#if defined(CONFIG_DRM_AMD_DC_DCN) dc_z10_save_init(dc); -#endif } return num_vmids; diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 7f27e29fae11..027f6ebe0496 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -421,7 +421,6 @@ void dc_dmub_srv_get_visual_confirm_color_cmd(struct dc *dc, struct pipe_ctx *pi } } -#ifdef CONFIG_DRM_AMD_DC_DCN /** * populate_subvp_cmd_drr_info - Helper to populate DRR pipe info for the DMCUB subvp command * @@ -776,7 +775,6 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc, dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv); dc_dmub_srv_wait_idle(dc->ctx->dmub_srv); } -#endif bool dc_dmub_srv_get_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv, struct dmub_diagnostic_data *diag_data) { diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c index 165392380842..67e3df7e1b05 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c @@ -930,7 +930,13 @@ static bool dce112_program_pix_clk( REG_WRITE(MODULO[inst], dp_dto_ref_100hz); /* Enable DTO */ - REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1); + if (clk_src->cs_mask->PIPE0_DTO_SRC_SEL) + REG_UPDATE_2(PIXEL_RATE_CNTL[inst], + DP_DTO0_ENABLE, 1, + PIPE0_DTO_SRC_SEL, 1); + else + REG_UPDATE(PIXEL_RATE_CNTL[inst], + DP_DTO0_ENABLE, 1); return true; } /* First disable SS @@ -995,7 +1001,6 @@ static bool dcn31_program_pix_clk( REG_WRITE(PHASE[inst], pll_settings->actual_pix_clk_100hz * 100); REG_WRITE(MODULO[inst], dp_dto_ref_khz * 1000); } -#if defined(CONFIG_DRM_AMD_DC_DCN) /* Enable DTO */ if (clk_src->cs_mask->PIPE0_DTO_SRC_SEL) if (encoding == DP_128b_132b_ENCODING) @@ -1009,9 +1014,6 @@ static bool dcn31_program_pix_clk( else REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1); -#else - REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1); -#endif } else { if (IS_FPGA_MAXIMUS_DC(clock_source->ctx->dce_environment)) { unsigned int inst = pix_clk_params->controller_id - CONTROLLER_ID_D0; @@ -1023,7 +1025,6 @@ static bool dcn31_program_pix_clk( REG_WRITE(MODULO[inst], dp_dto_ref_100hz); /* Enable DTO */ - #if defined(CONFIG_DRM_AMD_DC_DCN) if (clk_src->cs_mask->PIPE0_DTO_SRC_SEL) REG_UPDATE_2(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1, @@ -1031,17 +1032,12 @@ static bool dcn31_program_pix_clk( else REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1); - #else - REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1); - #endif return true; } -#if defined(CONFIG_DRM_AMD_DC_DCN) if (clk_src->cs_mask->PIPE0_DTO_SRC_SEL) REG_UPDATE(PIXEL_RATE_CNTL[inst], PIPE0_DTO_SRC_SEL, 0); -#endif /*ATOMBIOS expects pixel rate adjusted by deep color ratio)*/ bp_pc_params.controller_id = pix_clk_params->controller_id; @@ -1274,7 +1270,14 @@ static bool dcn3_program_pix_clk( REG_WRITE(PHASE[inst], pll_settings->actual_pix_clk_100hz * 100); REG_WRITE(MODULO[inst], dp_dto_ref_khz * 1000); } - REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1); + /* Enable DTO */ + if (clk_src->cs_mask->PIPE0_DTO_SRC_SEL) + REG_UPDATE_2(PIXEL_RATE_CNTL[inst], + DP_DTO0_ENABLE, 1, + PIPE0_DTO_SRC_SEL, 1); + else + REG_UPDATE(PIXEL_RATE_CNTL[inst], + DP_DTO0_ENABLE, 1); } else // For other signal types(HDMI_TYPE_A, DVI) Driver still to call VBIOS Command table dce112_program_pix_clk(clock_source, pix_clk_params, encoding, pll_settings); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h index aaf33c79b09b..f600b7431e23 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h @@ -204,23 +204,17 @@ type DP_DTO0_MODULO; \ type DP_DTO0_ENABLE; -#if defined(CONFIG_DRM_AMD_DC_DCN) #define CS_REG_FIELD_LIST_DCN32(type) \ type PIPE0_DTO_SRC_SEL; -#endif struct dce110_clk_src_shift { CS_REG_FIELD_LIST(uint8_t) -#if defined(CONFIG_DRM_AMD_DC_DCN) CS_REG_FIELD_LIST_DCN32(uint8_t) -#endif }; struct dce110_clk_src_mask{ CS_REG_FIELD_LIST(uint32_t) -#if defined(CONFIG_DRM_AMD_DC_DCN) CS_REG_FIELD_LIST_DCN32(uint32_t) -#endif }; struct dce110_clk_src_regs { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dwb.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dwb.c index b6391a5ead78..365a3215f6d5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dwb.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dwb.c @@ -23,8 +23,6 @@ * */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - #include "reg_helper.h" #include "resource.h" #include "dwb.h" @@ -129,6 +127,3 @@ void dcn10_dwbc_construct(struct dcn10_dwbc *dwbc10, dwbc10->dwbc_shift = dwbc_shift; dwbc10->dwbc_mask = dwbc_mask; } - - -#endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dwb.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dwb.h index d56ea7c8171e..5268c46ae907 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dwb.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dwb.h @@ -24,8 +24,6 @@ #ifndef __DC_DWBC_DCN10_H__ #define __DC_DWBC_DCN10_H__ -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* DCN */ #define BASE_INNER(seg) \ DCE_BASE__INST0_SEG ## seg @@ -267,5 +265,3 @@ void dcn10_dwbc_construct(struct dcn10_dwbc *dwbc10, int inst); #endif - -#endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c index 3c451ab5d3ca..2e5f8dc401ff 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c @@ -1470,10 +1470,9 @@ void enc1_se_hdmi_audio_setup( void enc1_se_hdmi_audio_disable( struct stream_encoder *enc) { -#if defined(CONFIG_DRM_AMD_DC_DCN) if (enc->afmt && enc->afmt->funcs->afmt_powerdown) enc->afmt->funcs->afmt_powerdown(enc->afmt); -#endif + enc1_se_enable_audio_clock(enc, false); } diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c index 31e212064168..727f458f6ee9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c @@ -1163,7 +1163,6 @@ static bool dcn303_resource_construct( dc->caps.max_cursor_size = 256; dc->caps.min_horizontal_blanking_period = 80; dc->caps.dmdata_alloc_size = 2048; -#if defined(CONFIG_DRM_AMD_DC_DCN) dc->caps.mall_size_per_mem_channel = 4; /* total size = mall per channel * num channels * 1024 * 1024 */ dc->caps.mall_size_total = dc->caps.mall_size_per_mem_channel * @@ -1171,7 +1170,6 @@ static bool dcn303_resource_construct( 1024 * 1024; dc->caps.cursor_cache_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size * 8; -#endif dc->caps.max_slave_planes = 1; dc->caps.post_blend_color_processing = true; dc->caps.force_dp_tps4_for_cp2520 = true; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c index 899105da0433..d0303173ce80 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c @@ -23,7 +23,6 @@ * */ -#ifdef CONFIG_DRM_AMD_DC_DCN #include "dc.h" #include "../display_mode_lib.h" #include "display_mode_vba_30.h" @@ -6634,4 +6633,3 @@ static noinline_for_stack void UseMinimumDCFCLK( } } -#endif /* CONFIG_DRM_AMD_DC_DCN */ diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c index 8179be1f34bb..cd3cfcb2a2b0 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c @@ -23,8 +23,6 @@ * */ -#ifdef CONFIG_DRM_AMD_DC_DCN - #include "../display_mode_lib.h" #include "../display_mode_vba.h" #include "../dml_inline_defs.h" @@ -1792,4 +1790,3 @@ void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, dml_print("DML_DLG: Calculation for pipe[%d] end\n", pipe_idx); } -#endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h index b982be64c792..42f7081cf3b3 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h @@ -53,9 +53,7 @@ enum dwb_source { /* DCN1.x, DCN2.x support 2 pipes */ enum dwb_pipe { dwb_pipe0 = 0, -#if defined(CONFIG_DRM_AMD_DC_DCN) dwb_pipe1, -#endif dwb_pipe_max_num, }; @@ -72,14 +70,11 @@ enum wbscl_coef_filter_type_sel { }; -#if defined(CONFIG_DRM_AMD_DC_DCN) enum dwb_boundary_mode { DWBSCL_BOUNDARY_MODE_EDGE = 0, DWBSCL_BOUNDARY_MODE_BLACK = 1 }; -#endif -#if defined(CONFIG_DRM_AMD_DC_DCN) enum dwb_output_csc_mode { DWB_OUTPUT_CSC_DISABLE = 0, DWB_OUTPUT_CSC_COEF_A = 1, @@ -132,7 +127,6 @@ struct dwb_efc_display_settings { unsigned int dwbOutputBlack; // 0 - Normal, 1 - Output Black }; -#endif struct dwb_warmup_params { bool warmup_en; /* false: normal mode, true: enable pattern generator */ bool warmup_mode; /* false: 420, true: 444 */ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_validation.c b/drivers/gpu/drm/amd/display/dc/link/link_validation.c index b29f62337ba0..2ab23bdf5a89 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_validation.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_validation.c @@ -261,13 +261,11 @@ uint32_t link_timing_bandwidth_kbps( uint32_t bits_per_channel = 0; uint32_t kbps; -#if defined(CONFIG_DRM_AMD_DC_DCN) if (timing->flags.DSC) return dc_dsc_stream_bandwidth_in_kbps(timing, timing->dsc_cfg.bits_per_pixel, timing->dsc_cfg.num_slices_h, timing->dsc_cfg.is_dp); -#endif /* CONFIG_DRM_AMD_DC_DCN */ switch (timing->display_color_depth) { case COLOR_DEPTH_666: diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index 4a3758ea04f5..eee1853f6b32 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -723,12 +723,10 @@ void override_training_settings( if (link->preferred_training_settings.fec_enable != NULL) lt_settings->should_set_fec_ready = *link->preferred_training_settings.fec_enable; -#if defined(CONFIG_DRM_AMD_DC_DCN) /* Check DP tunnel LTTPR mode debug option. */ if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && link->dc->debug.dpia_debug.bits.force_non_lttpr) lt_settings->lttpr_mode = LTTPR_MODE_NON_LTTPR; -#endif dp_get_lttpr_mode_override(link, <_settings->lttpr_mode); } diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index eaafa00a7b9f..4d78ac932845 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -695,7 +695,6 @@ bool edp_setup_psr(struct dc_link *link, psr_context->psr_level.u32all = 0; /*skip power down the single pipe since it blocks the cstate*/ -#if defined(CONFIG_DRM_AMD_DC_DCN) if (link->ctx->asic_id.chip_family >= FAMILY_RV) { switch (link->ctx->asic_id.chip_family) { case FAMILY_YELLOW_CARP: @@ -709,10 +708,6 @@ bool edp_setup_psr(struct dc_link *link, break; } } -#else - if (link->ctx->asic_id.chip_family >= FAMILY_RV) - psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true; -#endif /* SMU will perform additional powerdown sequence. * For unsupported ASICs, set psr_level flag to skip PSR diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c index e39b133d05af..fa469de3e935 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -678,13 +678,8 @@ bool dmub_init_abm_config(struct resource_pool *res_pool, bool result = false; uint32_t i, j = 0; -#if defined(CONFIG_DRM_AMD_DC_DCN) if (res_pool->abm == NULL && res_pool->multiple_abms[inst] == NULL) return false; -#else - if (res_pool->abm == NULL) - return false; -#endif memset(&ram_table, 0, sizeof(ram_table)); memset(&config, 0, sizeof(config)); @@ -737,12 +732,10 @@ bool dmub_init_abm_config(struct resource_pool *res_pool, config.min_abm_backlight = ram_table.min_abm_backlight; -#if defined(CONFIG_DRM_AMD_DC_DCN) if (res_pool->multiple_abms[inst]) { result = res_pool->multiple_abms[inst]->funcs->init_abm_config( res_pool->multiple_abms[inst], (char *)(&config), sizeof(struct abm_config_table), inst); } else -#endif result = res_pool->abm->funcs->init_abm_config( res_pool->abm, (char *)(&config), sizeof(struct abm_config_table), 0); -- cgit From 4652ae7a51b78d7607c247228ac2a14fa0088bbf Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Tue, 14 Feb 2023 14:14:49 -0500 Subject: drm/amd/display: Rename DCN config to FP [Why & How] The only reason we have the DCN config is for floating point support. Rename it to make that clear and (hopefully) avoid misuse of the config in the future. Reviewed-by: Rodrigo Siqueira Acked-by: Qingqing Zhuo Signed-off-by: Harry Wentland Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/Kconfig | 8 ++++---- drivers/gpu/drm/amd/display/amdgpu_dm/Makefile | 2 +- drivers/gpu/drm/amd/display/dc/Makefile | 2 +- drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 2 +- drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile | 2 +- drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 8 ++++---- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 2 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 2 +- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 8 ++++---- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 2 +- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c | 4 ++-- drivers/gpu/drm/amd/display/dc/dml/Makefile | 2 +- drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c | 2 +- drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h | 2 +- drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h | 2 +- drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h | 2 +- drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h | 2 +- drivers/gpu/drm/amd/display/dc/inc/resource.h | 2 +- drivers/gpu/drm/amd/display/dc/link/link_validation.c | 2 +- drivers/gpu/drm/amd/display/dc/os_types.h | 4 ++-- 21 files changed, 32 insertions(+), 32 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig index 578a8b547ddf..06b438217c61 100644 --- a/drivers/gpu/drm/amd/display/Kconfig +++ b/drivers/gpu/drm/amd/display/Kconfig @@ -8,7 +8,7 @@ config DRM_AMD_DC depends on BROKEN || !CC_IS_CLANG || X86_64 || SPARC64 || ARM64 select SND_HDA_COMPONENT if SND_HDA_CORE # !CC_IS_CLANG: https://github.com/ClangBuiltLinux/linux/issues/1752 - select DRM_AMD_DC_DCN if (X86 || PPC_LONG_DOUBLE_128 || (ARM64 && KERNEL_MODE_NEON && !CC_IS_CLANG)) + select DRM_AMD_DC_FP if (X86 || PPC64 || (ARM64 && KERNEL_MODE_NEON && !CC_IS_CLANG)) help Choose this option if you want to use the new display engine support for AMDGPU. This adds required support for Vega and @@ -20,10 +20,10 @@ config DRM_AMD_DC panic on most architectures. We'll revert this when the following bug report has been resolved: https://github.com/llvm/llvm-project/issues/41896. -config DRM_AMD_DC_DCN +config DRM_AMD_DC_FP def_bool n help - Raven, Navi, and newer family support for display engine + Floating point support, required for DCN-based SoCs config DRM_AMD_DC_SI bool "AMD DC support for Southern Islands ASICs" @@ -44,7 +44,7 @@ config DEBUG_KERNEL_DC config DRM_AMD_SECURE_DISPLAY bool "Enable secure display support" depends on DEBUG_FS - depends on DRM_AMD_DC_DCN + depends on DRM_AMD_DC_FP help Choose this option if you want to support secure display diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile index aef782ca3706..249b073f6a23 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile @@ -33,7 +33,7 @@ AMDGPUDM = \ amdgpu_dm_mst_types.o \ amdgpu_dm_color.o -ifdef CONFIG_DRM_AMD_DC_DCN +ifdef CONFIG_DRM_AMD_DC_FP AMDGPUDM += dc_fpu.o endif diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile index d2b1e824eeaa..69ffd4424dc7 100644 --- a/drivers/gpu/drm/amd/display/dc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/Makefile @@ -24,7 +24,7 @@ DC_LIBS = basics bios dml clk_mgr dce gpio irq link virtual dsc -ifdef CONFIG_DRM_AMD_DC_DCN +ifdef CONFIG_DRM_AMD_DC_FP KCOV_INSTRUMENT := n diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index e381de2429fa..f0f948501e9a 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -2064,7 +2064,7 @@ static enum bp_result bios_parser_get_encoder_cap_info( if (!info) return BP_RESULT_BADINPUT; -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) /* encoder cap record not available in v1_5 */ if (bp->object_info_tbl.revision.minor == 5) return BP_RESULT_NORECORD; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile index 271d8e573181..ad390e4cd0a9 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile @@ -74,7 +74,7 @@ CLK_MGR_DCE120 = dce120_clk_mgr.o AMD_DAL_CLK_MGR_DCE120 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dce120/,$(CLK_MGR_DCE120)) AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCE120) -ifdef CONFIG_DRM_AMD_DC_DCN +ifdef CONFIG_DRM_AMD_DC_FP ############################################################################### # DCN10 ############################################################################### diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c index 73a45ec27f90..ee81d36146e4 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c @@ -221,7 +221,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p dce120_clk_mgr_construct(ctx, clk_mgr); return &clk_mgr->base; } -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) case FAMILY_RV: { struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); @@ -351,7 +351,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p } break; -#endif +#endif /* CONFIG_DRM_AMD_DC_FP - Family RV */ default: ASSERT(0); /* Unknown Asic */ break; @@ -364,7 +364,7 @@ void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base) { struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); -#ifdef CONFIG_DRM_AMD_DC_DCN +#ifdef CONFIG_DRM_AMD_DC_FP switch (clk_mgr_base->ctx->asic_id.chip_family) { case FAMILY_NV: if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { @@ -405,7 +405,7 @@ void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base) default: break; } -#endif +#endif /* CONFIG_DRM_AMD_DC_FP */ kfree(clk_mgr); } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c index ca6dfd2d7561..bd9fd0b54f46 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c @@ -706,7 +706,7 @@ void rn_clk_mgr_construct( enum pp_smu_status status = 0; int is_green_sardine = 0; -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) is_green_sardine = ASICREV_IS_GREEN_SARDINE(ctx->asic_id.hw_internal_rev); #endif diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 081d30c98a88..9f085af00f15 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -994,7 +994,7 @@ static bool dc_construct(struct dc *dc, dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg); if (!dc->clk_mgr) goto fail; -#ifdef CONFIG_DRM_AMD_DC_DCN +#ifdef CONFIG_DRM_AMD_DC_FP dc->clk_mgr->force_smu_not_present = init_params->force_smu_not_present; if (dc->res_pool->funcs->update_bw_bounding_box) { diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index d9f2ef242b0f..2e3b2fd23b56 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -232,7 +232,7 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc, init_data->num_virtual_links, dc); break; -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) case DCN_VERSION_1_0: case DCN_VERSION_1_01: res_pool = dcn10_create_resource_pool(init_data, dc); @@ -276,7 +276,7 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc, case DCN_VERSION_3_21: res_pool = dcn321_create_resource_pool(init_data, dc); break; -#endif +#endif /* CONFIG_DRM_AMD_DC_FP */ default: break; } @@ -4027,14 +4027,14 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm( else sec_pipe->stream_res.opp = sec_pipe->top_pipe->stream_res.opp; if (sec_pipe->stream->timing.flags.DSC == 1) { -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) dcn20_acquire_dsc(dc, &state->res_ctx, &sec_pipe->stream_res.dsc, pipe_idx); #endif ASSERT(sec_pipe->stream_res.dsc); if (sec_pipe->stream_res.dsc == NULL) return false; } -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) dcn20_build_mapped_resource(dc, state, sec_pipe->stream); #endif } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index c1e69fdd5020..0f6873449d15 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -2054,7 +2054,7 @@ struct dc_sink_dsc_caps { // 'true' if these are virtual DPCD's DSC caps (immediately upstream of sink in MST topology), // 'false' if they are sink's DSC caps bool is_virtual_dpcd_dsc; -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) // 'true' if MST topology supports DSC passthrough for sink // 'false' if MST topology does not support DSC passthrough bool is_dsc_passthrough_supported; 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 a583a72845fe..100d62162b71 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -829,7 +829,7 @@ struct dc_dsc_config { uint32_t version_minor; /* DSC minor version. Full version is formed as 1.version_minor. */ bool ycbcr422_simple; /* Tell DSC engine to convert YCbCr 4:2:2 to 'YCbCr 4:2:2 simple'. */ int32_t rc_buffer_size; /* DSC RC buffer block size in bytes */ -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) bool is_frl; /* indicate if DSC is applied based on HDMI FRL sink's capability */ #endif bool is_dp; /* indicate if DSC is applied based on DP's capability */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c index d13e46eeee3c..80a0c5a575a9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c @@ -97,7 +97,7 @@ static void enable_memory_low_power(struct dc *dc) // Power down VPGs for (i = 0; i < dc->res_pool->stream_enc_count; i++) dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg); -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++) dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg); #endif @@ -291,7 +291,7 @@ void dcn31_init_hw(struct dc *dc) if (dc->res_pool->hubbub->funcs->force_pstate_change_control) dc->res_pool->hubbub->funcs->force_pstate_change_control( dc->res_pool->hubbub, false, false); -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) if (dc->res_pool->hubbub->funcs->init_crb) dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub); #endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile index 0ecea87cf48f..d1b49ac2e535 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile @@ -128,7 +128,7 @@ CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/calcs/dcn_calc_math.o := $(dml_rcflags) DML = calcs/dce_calcs.o calcs/custom_float.o calcs/bw_fixed.o -ifdef CONFIG_DRM_AMD_DC_DCN +ifdef CONFIG_DRM_AMD_DC_FP DML += display_mode_lib.o display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o DML += dcn10/dcn10_fpu.o DML += dcn20/dcn20_fpu.o diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c index 3215ca4d5799..64cee8c80110 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c @@ -39,7 +39,7 @@ */ void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps) { -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) enum colour_mode mode; enum bits_per_comp bpc; bool is_navite_422_or_420; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h index 42f7081cf3b3..86b711dcc785 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h @@ -202,7 +202,7 @@ struct dwbc_funcs { struct dwb_warmup_params *warmup_params); -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) void (*dwb_program_output_csc)( struct dwbc *dwbc, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h index d5ea7545583e..b5d353c41aa9 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h @@ -146,7 +146,7 @@ struct hubp_funcs { void (*set_blank)(struct hubp *hubp, bool blank); void (*set_blank_regs)(struct hubp *hubp, bool blank); -#ifdef CONFIG_DRM_AMD_DC_DCN +#ifdef CONFIG_DRM_AMD_DC_FP void (*phantom_hubp_post_enable)(struct hubp *hubp); #endif void (*set_hubp_blank_en)(struct hubp *hubp, bool blank); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h index 1d9f9c53d2bd..c21e7ffd5bd0 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h @@ -182,7 +182,7 @@ struct timing_generator_funcs { bool (*enable_crtc)(struct timing_generator *tg); bool (*disable_crtc)(struct timing_generator *tg); -#ifdef CONFIG_DRM_AMD_DC_DCN +#ifdef CONFIG_DRM_AMD_DC_FP void (*phantom_crtc_post_enable)(struct timing_generator *tg); #endif void (*disable_phantom_crtc)(struct timing_generator *tg); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h index a4d61bb724b6..45d37c584551 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h @@ -148,7 +148,7 @@ struct hwseq_private_funcs { void (*PLAT_58856_wa)(struct dc_state *context, struct pipe_ctx *pipe_ctx); void (*setup_hpo_hw_control)(const struct dce_hwseq *hws, bool enable); -#ifdef CONFIG_DRM_AMD_DC_DCN +#ifdef CONFIG_DRM_AMD_DC_FP void (*program_mall_pipe_config)(struct dc *dc, struct dc_state *context); void (*subvp_update_force_pstate)(struct dc *dc, struct dc_state *context); void (*update_mall_sel)(struct dc *dc, struct dc_state *context); diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index fa6da93caa88..eaeb684c8a48 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -201,7 +201,7 @@ bool get_temp_dp_link_res(struct dc_link *link, struct link_resource *link_res, struct dc_link_settings *link_settings); -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) struct hpo_dp_link_encoder *resource_get_hpo_dp_link_enc_for_det_lt( const struct resource_context *res_ctx, const struct resource_pool *pool, diff --git a/drivers/gpu/drm/amd/display/dc/link/link_validation.c b/drivers/gpu/drm/amd/display/dc/link/link_validation.c index 2ab23bdf5a89..62aa5f6b1f0c 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_validation.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_validation.c @@ -124,7 +124,7 @@ static bool dp_active_dongle_validate_timing( if (dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps > 0) { // DP to HDMI FRL converter struct dc_crtc_timing outputTiming = *timing; -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) if (timing->flags.DSC && !timing->dsc_cfg.is_frl) /* DP input has DSC, HDMI FRL output doesn't have DSC, remove DSC from output timing */ outputTiming.flags.DSC = 0; diff --git a/drivers/gpu/drm/amd/display/dc/os_types.h b/drivers/gpu/drm/amd/display/dc/os_types.h index 6b88ae14f1f9..aad8095660c9 100644 --- a/drivers/gpu/drm/amd/display/dc/os_types.h +++ b/drivers/gpu/drm/amd/display/dc/os_types.h @@ -53,11 +53,11 @@ #define dm_error(fmt, ...) DRM_ERROR(fmt, ##__VA_ARGS__) -#if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_FP) #include "amdgpu_dm/dc_fpu.h" #define DC_FP_START() dc_fpu_begin(__func__, __LINE__) #define DC_FP_END() dc_fpu_end(__func__, __LINE__) -#endif +#endif /* CONFIG_DRM_AMD_DC_FP */ /* * -- cgit From de930140bb578ebb075772e946e20db68550bf2f Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Fri, 24 Feb 2023 09:45:36 -0500 Subject: drm/amd/display: Update to correct min FCLK when construction BB [Description] - For min FCLK, choose the min of 300Mhz and PMFW requirement - Also only apply min DET check in DML for non-UR cases Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 5 +++-- drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c | 6 ++++-- drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c | 6 +++++- drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h | 3 ++- drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c | 5 +++-- 5 files changed, 17 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 e47828e3b6d5..077674be452b 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 @@ -2315,6 +2315,9 @@ static int build_synthetic_soc_states(struct clk_bw_params *bw_params, num_dcfclk_dpms++; } + if (num_dcfclk_dpms > 0 && bw_params->clk_table.entries[0].fclk_mhz > min_fclk_mhz) + min_fclk_mhz = bw_params->clk_table.entries[0].fclk_mhz; + if (!max_dcfclk_mhz || !max_dispclk_mhz || !max_dtbclk_mhz) return -1; @@ -2423,7 +2426,6 @@ static int build_synthetic_soc_states(struct clk_bw_params *bw_params, for (i = *num_entries - 1; i >= 0 ; i--) { if (table[i].fabricclk_mhz < min_fclk_mhz) { table[i].fabricclk_mhz = min_fclk_mhz; - break; } } } @@ -2432,7 +2434,6 @@ static int build_synthetic_soc_states(struct clk_bw_params *bw_params, for (i = *num_entries - 1; i >= 0 ; i--) { if (table[i].dcfclk_mhz < min_dcfclk_mhz) { table[i].dcfclk_mhz = min_dcfclk_mhz; - break; } } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c index f2499811e269..f74730c2abbd 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c @@ -689,7 +689,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman mode_lib->vba.PixelClock, mode_lib->vba.VRatio, mode_lib->vba.VRatioChroma, - mode_lib->vba.UsesMALLForPStateChange); + mode_lib->vba.UsesMALLForPStateChange, + mode_lib->vba.UseUnboundedRequesting); for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) { v->MaxVStartupLines[k] = ((mode_lib->vba.Interlace[k] && @@ -3215,7 +3216,8 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l mode_lib->vba.PixelClock, mode_lib->vba.VRatio, mode_lib->vba.VRatioChroma, - mode_lib->vba.UsesMALLForPStateChange); + mode_lib->vba.UsesMALLForPStateChange, + mode_lib->vba.UseUnboundedRequesting); v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.VMDataOnlyReturnBWPerState = dml32_get_return_bw_mbps_vm_only(&mode_lib->vba.soc, i, mode_lib->vba.DCFCLKState[i][j], mode_lib->vba.FabricClockPerState[i], diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c index d1000aa4c481..61cc4904ade4 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c @@ -6271,7 +6271,8 @@ bool dml32_CalculateDETSwathFillLatencyHiding(unsigned int NumberOfActiveSurface double PixelClock[], double VRatioY[], double VRatioC[], - enum dm_use_mall_for_pstate_change_mode UsesMALLForPStateChange[]) + enum dm_use_mall_for_pstate_change_mode UsesMALLForPStateChange[], + enum unbounded_requesting_policy UseUnboundedRequesting) { int k; double SwathSizeAllSurfaces = 0; @@ -6283,6 +6284,9 @@ bool dml32_CalculateDETSwathFillLatencyHiding(unsigned int NumberOfActiveSurface double SwathSizePerSurfaceC[DC__NUM_DPP__MAX]; bool NotEnoughDETSwathFillLatencyHiding = false; + if (UseUnboundedRequesting == dm_unbounded_requesting) + return false; + /* calculate sum of single swath size for all pipes in bytes */ for (k = 0; k < NumberOfActiveSurfaces; k++) { SwathSizePerSurfaceY[k] = SwathHeightY[k] * SwathWidthY[k] * BytePerPixelInDETY[k] * NumOfDPP[k]; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h index 9ba792c633a5..592d174df6c6 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h @@ -1163,6 +1163,7 @@ bool dml32_CalculateDETSwathFillLatencyHiding(unsigned int NumberOfActiveSurface double PixelClock[], double VRatioY[], double VRatioC[], - enum dm_use_mall_for_pstate_change_mode UsesMALLForPStateChange[]); + enum dm_use_mall_for_pstate_change_mode UsesMALLForPStateChange[], + enum unbounded_requesting_policy UseUnboundedRequesting); #endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c index b80cef70fa60..57b9bd896678 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c @@ -294,6 +294,9 @@ static int build_synthetic_soc_states(struct clk_bw_params *bw_params, num_dcfclk_dpms++; } + if (num_dcfclk_dpms > 0 && bw_params->clk_table.entries[0].fclk_mhz > min_fclk_mhz) + min_fclk_mhz = bw_params->clk_table.entries[0].fclk_mhz; + if (!max_dcfclk_mhz || !max_dispclk_mhz || !max_dtbclk_mhz) return -1; @@ -402,7 +405,6 @@ static int build_synthetic_soc_states(struct clk_bw_params *bw_params, for (i = *num_entries - 1; i >= 0 ; i--) { if (table[i].fabricclk_mhz < min_fclk_mhz) { table[i].fabricclk_mhz = min_fclk_mhz; - break; } } } @@ -411,7 +413,6 @@ static int build_synthetic_soc_states(struct clk_bw_params *bw_params, for (i = *num_entries - 1; i >= 0 ; i--) { if (table[i].dcfclk_mhz < min_dcfclk_mhz) { table[i].dcfclk_mhz = min_dcfclk_mhz; - break; } } -- cgit From b5ac70369e3669df4a0c192c40c0e70c3e56439e Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Fri, 17 Feb 2023 13:26:56 +0800 Subject: drm/amd/display: Pass the right info to drm_dp_remove_payload [Why & How] drm_dp_remove_payload() interface was changed. Correct amdgpu dm code to pass the right parameter to the drm helper function. Reviewed-by: Jerry Zuo Acked-by: Qingqing Zhuo Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 57 +++++++++++++++++++--- 1 file changed, 50 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 1be04c613deb..8d598b322e5b 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 @@ -177,6 +177,40 @@ void dm_helpers_dp_update_branch_info( const struct dc_link *link) {} +static void dm_helpers_construct_old_payload( + struct dc_link *link, + int pbn_per_slot, + struct drm_dp_mst_atomic_payload *new_payload, + struct drm_dp_mst_atomic_payload *old_payload) +{ + struct link_mst_stream_allocation_table current_link_table = + link->mst_stream_alloc_table; + struct link_mst_stream_allocation *dc_alloc; + int i; + + *old_payload = *new_payload; + + /* Set correct time_slots/PBN of old payload. + * other fields (delete & dsc_enabled) in + * struct drm_dp_mst_atomic_payload are don't care fields + * while calling drm_dp_remove_payload() + */ + for (i = 0; i < current_link_table.stream_count; i++) { + dc_alloc = + ¤t_link_table.stream_allocations[i]; + + if (dc_alloc->vcp_id == new_payload->vcpi) { + old_payload->time_slots = dc_alloc->slot_count; + old_payload->pbn = dc_alloc->slot_count * pbn_per_slot; + break; + } + } + + /* make sure there is an old payload*/ + ASSERT(i != current_link_table.stream_count); + +} + /* * Writes payload allocation table in immediate downstream device. */ @@ -188,7 +222,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( { struct amdgpu_dm_connector *aconnector; struct drm_dp_mst_topology_state *mst_state; - struct drm_dp_mst_atomic_payload *payload; + struct drm_dp_mst_atomic_payload *target_payload, *new_payload, old_payload; struct drm_dp_mst_topology_mgr *mst_mgr; aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; @@ -204,17 +238,26 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state); /* It's OK for this to fail */ - payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port); - if (enable) - drm_dp_add_payload_part1(mst_mgr, mst_state, payload); - else - drm_dp_remove_payload(mst_mgr, mst_state, payload, payload); + new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port); + + if (enable) { + target_payload = new_payload; + + drm_dp_add_payload_part1(mst_mgr, mst_state, new_payload); + } else { + /* construct old payload by VCPI*/ + dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div, + new_payload, &old_payload); + target_payload = &old_payload; + + drm_dp_remove_payload(mst_mgr, mst_state, &old_payload, new_payload); + } /* mst_mgr->->payloads are VC payload notify MST branch using DPCD or * AUX message. The sequence is slot 1-63 allocated sequence for each * stream. AMD ASIC stream slot allocation should follow the same * sequence. copy DRM MST allocation to dc */ - fill_dc_mst_payload_table_from_drm(stream->link, enable, payload, proposed_table); + fill_dc_mst_payload_table_from_drm(stream->link, enable, target_payload, proposed_table); return true; } -- cgit From 97fa4dfa66fdd52ad3d0c9fadeaaa1e87605bac7 Mon Sep 17 00:00:00 2001 From: Gabe Teeger Date: Thu, 23 Feb 2023 11:30:31 -0500 Subject: drm/amd/display: Enable HostVM based on rIOMMU active [Why] There is underflow and flickering occuring. The underflow stops when hostvm is forced to active. According to policy, hostvm should be enabled if riommu is active, but this is not taken into account when deciding whether to enable hostvm. [What] For DCN314, set hostvm to true if riommu is active. Reviewed-by: Nicholas Kazlauskas Acked-by: Qingqing Zhuo Signed-off-by: Gabe Teeger Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c index acda3e1babd4..c52b76610bd2 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c @@ -308,6 +308,10 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c pipe->plane_state->src_rect.width < pipe->plane_state->dst_rect.width)) upscaled = true; + /* Apply HostVM policy - either based on hypervisor globally enabled, or rIOMMU active */ + if (dc->debug.dml_hostvm_override == DML_HOSTVM_NO_OVERRIDE) + pipes[i].pipe.src.hostvm = dc->vm_pa_config.is_hvm_enabled || dc->res_pool->hubbub->riommu_active; + /* * Immediate flip can be set dynamically after enabling the plane. * We need to require support for immediate flip or underflow can be -- cgit From 7da2bcda5899e92ef3442d5997154d8220245370 Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Fri, 24 Feb 2023 10:39:17 -0500 Subject: drm/amd/display: Pass tg and hubp inst instead of pipe index for SubVP [Description] - For pipe harvesting cases, the pipe index does not necessarily match up with the OTG instance, so pass index by OTG Instance instead - For pipe split cases pass HUBP instance, since the split index is only used for HUBP programming - Also check for OPP ID when accessing opp for pipe harvesting cases Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 30 ++++++++++++++++++---------- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 8 ++++---- 2 files changed, 23 insertions(+), 15 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 9f085af00f15..05923593ec66 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1079,6 +1079,7 @@ static void phantom_pipe_blank( struct output_pixel_processor *opp = NULL; uint32_t num_opps, opp_id_src0, opp_id_src1; uint32_t otg_active_width, otg_active_height; + uint32_t i; /* program opp dpg blank color */ color_space = COLOR_SPACE_SRGB; @@ -1090,17 +1091,24 @@ static void phantom_pipe_blank( /* get the OPTC source */ tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1); ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp); - opp = dc->res_pool->opps[opp_id_src0]; - - opp->funcs->opp_set_disp_pattern_generator( - opp, - CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR, - CONTROLLER_DP_COLOR_SPACE_UDEFINED, - COLOR_DEPTH_UNDEFINED, - &black_color, - otg_active_width, - otg_active_height, - 0); + + for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) { + if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src0) { + opp = dc->res_pool->opps[i]; + break; + } + } + + if (opp && opp->funcs->opp_set_disp_pattern_generator) + opp->funcs->opp_set_disp_pattern_generator( + opp, + CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR, + CONTROLLER_DP_COLOR_SPACE_UDEFINED, + COLOR_DEPTH_UNDEFINED, + &black_color, + otg_active_width, + otg_active_height, + 0); if (tg->funcs->is_tg_enabled(tg)) hws->funcs.wait_for_blank_complete(opp); diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 027f6ebe0496..b5c6501c28fc 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -637,7 +637,7 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc, pipe_data->pipe_config.subvp_data.main_vblank_end = main_timing->v_total - main_timing->v_front_porch - main_timing->v_addressable; pipe_data->pipe_config.subvp_data.mall_region_lines = phantom_timing->v_addressable; - pipe_data->pipe_config.subvp_data.main_pipe_index = subvp_pipe->pipe_idx; + pipe_data->pipe_config.subvp_data.main_pipe_index = subvp_pipe->stream_res.tg->inst; pipe_data->pipe_config.subvp_data.is_drr = subvp_pipe->stream->ignore_msa_timing_param; /* Calculate the scaling factor from the src and dst height. @@ -679,11 +679,11 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc, struct pipe_ctx *phantom_pipe = &context->res_ctx.pipe_ctx[j]; if (phantom_pipe->stream == subvp_pipe->stream->mall_stream_config.paired_stream) { - pipe_data->pipe_config.subvp_data.phantom_pipe_index = phantom_pipe->pipe_idx; + pipe_data->pipe_config.subvp_data.phantom_pipe_index = phantom_pipe->stream_res.tg->inst; if (phantom_pipe->bottom_pipe) { - pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = phantom_pipe->bottom_pipe->pipe_idx; + pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = phantom_pipe->bottom_pipe->plane_res.hubp->inst; } else if (phantom_pipe->next_odm_pipe) { - pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = phantom_pipe->next_odm_pipe->pipe_idx; + pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = phantom_pipe->next_odm_pipe->plane_res.hubp->inst; } else { pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = 0; } -- cgit From 2820433be2a33beb44b13b367e155cf221f29610 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Fri, 24 Feb 2023 11:35:43 -0700 Subject: drm/amd/display: Ensure vmin and vmax adjust for DCE [Why & How] In the commit 32953485c558 ("drm/amd/display: Do not update DRR while BW optimizations pending"), a modification was added to avoid adjusting DRR if optimized bandwidth is set. This change was only intended for DCN, but one part of the patch changed the code path for DCE devices and caused regressions to the kms_vrr test. To address this problem, this commit adds a modification in which dc_stream_adjust_vmin_vmax will be fully executed in DCE devices. Fixes: 32953485c558 ("drm/amd/display: Do not update DRR while BW optimizations pending") Reviewed-by: Aric Cyr Acked-by: Qingqing Zhuo Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 05923593ec66..4ac11f169119 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -404,8 +404,9 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc, * Don't adjust DRR while there's bandwidth optimizations pending to * avoid conflicting with firmware updates. */ - if (dc->optimized_required || dc->wm_optimized_required) - return false; + if (dc->ctx->dce_version > DCE_VERSION_MAX) + if (dc->optimized_required || dc->wm_optimized_required) + return false; stream->adjust.v_total_max = adjust->v_total_max; stream->adjust.v_total_mid = adjust->v_total_mid; -- cgit From b8272241ff9df5b57e2777a07c1fe8af3d9cbf93 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Thu, 6 Oct 2022 14:57:31 -0400 Subject: drm/amd/display: Drop dc_commit_state in favor of dc_commit_streams [Why & How] There are two functions responsible for handling the DC commit state: dc_commit_state and dc_commit_streams. Both have the same goal, but dc_commit_streams surpess dc_commit_state in terms of completeness. For this reason, maintaining these two functions makes maintainability unnecessarily complicated. This commit replaces the old dc_commit_state in favor of dc_commit_streams, and removes the old dc_commit_state. Reviewed-by: Harry Wentland Acked-by: Qingqing Zhuo Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 +-- drivers/gpu/drm/amd/display/dc/core/dc.c | 47 ----------------------- drivers/gpu/drm/amd/display/dc/dc.h | 4 -- 3 files changed, 3 insertions(+), 54 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 26abb62bbd93..0d0d2f8b4e3b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2486,7 +2486,7 @@ static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc) goto fail; } - res = dc_commit_state(dc, context); + res = dc_commit_streams(dc, context->streams, context->stream_count); fail: dc_release_state(context); @@ -2745,7 +2745,7 @@ static int dm_resume(void *handle) dc_enable_dmub_outbox(adev->dm.dc); } - WARN_ON(!dc_commit_state(dm->dc, dc_state)); + WARN_ON(!dc_commit_streams(dm->dc, dc_state->streams, dc_state->stream_count)); dm_gpureset_commit_state(dm->cached_dc_state, dm); @@ -8482,7 +8482,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) dm_enable_per_frame_crtc_master_sync(dc_state); mutex_lock(&dm->dc_lock); - WARN_ON(!dc_commit_state(dm->dc, dc_state)); + WARN_ON(!dc_commit_streams(dm->dc, dc_state->streams, dc_state->stream_count)); /* Allow idle optimization when vblank count is 0 for display off */ if (dm->active_vblank_irq_count == 0) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 4ac11f169119..a5f2f880610d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2061,53 +2061,6 @@ context_alloc_fail: return res; } -/* TODO: When the transition to the new commit sequence is done, remove this - * function in favor of dc_commit_streams. */ -bool dc_commit_state(struct dc *dc, struct dc_state *context) -{ - enum dc_status result = DC_ERROR_UNEXPECTED; - int i; - - /* TODO: Since change commit sequence can have a huge impact, - * we decided to only enable it for DCN3x. However, as soon as - * we get more confident about this change we'll need to enable - * the new sequence for all ASICs. */ - if (dc->ctx->dce_version >= DCN_VERSION_3_2) { - result = dc_commit_streams(dc, context->streams, context->stream_count); - return result == DC_OK; - } - - if (!streams_changed(dc, context->streams, context->stream_count)) { - return DC_OK; - } - - DC_LOG_DC("%s: %d streams\n", - __func__, context->stream_count); - - for (i = 0; i < context->stream_count; i++) { - struct dc_stream_state *stream = context->streams[i]; - - dc_stream_log(dc, stream); - } - - /* - * Previous validation was perfomred with fast_validation = true and - * the full DML state required for hardware programming was skipped. - * - * Re-validate here to calculate these parameters / watermarks. - */ - result = dc_validate_global_state(dc, context, false); - if (result != DC_OK) { - DC_LOG_ERROR("DC commit global validation failure: %s (%d)", - dc_status_to_str(result), result); - return result; - } - - result = dc_commit_state_no_check(dc, context); - - return (result == DC_OK); -} - bool dc_acquire_release_mpc_3dlut( struct dc *dc, bool acquire, struct dc_stream_state *stream, diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 0f6873449d15..b51dfe0f507c 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1360,10 +1360,6 @@ enum dc_status dc_commit_streams(struct dc *dc, struct dc_stream_state *streams[], uint8_t stream_count); -/* TODO: When the transition to the new commit sequence is done, remove this - * function in favor of dc_commit_streams. */ -bool dc_commit_state(struct dc *dc, struct dc_state *context); - struct dc_state *dc_create_state(struct dc *dc); struct dc_state *dc_copy_state(struct dc_state *src_ctx); void dc_retain_state(struct dc_state *context); -- cgit From f7511289821ffccc07579406d6ab520aa11049f5 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Thu, 6 Oct 2022 16:40:55 -0400 Subject: drm/amd/display: Use dc_update_planes_and_stream [Why & How] The old dc_commit_updates_for_stream lacks manipulation for many corner cases where the DC feature requires special attention; as a result, it starts to show its limitation (e.g., the SubVP feature is not supported by it, among other cases). To modernize and unify our internal API, this commit replaces the old dc_commit_updates_for_stream with dc_update_planes_and_stream, which has more features. Reviewed-by: Harry Wentland Acked-by: Qingqing Zhuo Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 30 +++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 0d0d2f8b4e3b..5e2e4aee5896 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2672,10 +2672,12 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, bundle->surface_updates[m].surface->force_full_update = true; } - dc_commit_updates_for_stream( - dm->dc, bundle->surface_updates, + + dc_update_planes_and_stream(dm->dc, + bundle->surface_updates, dc_state->stream_status->plane_count, - dc_state->streams[k], &bundle->stream_update, dc_state); + dc_state->streams[k], + &bundle->stream_update); } cleanup: @@ -8159,12 +8161,11 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, acrtc_state->stream->link->psr_settings.psr_allow_active) amdgpu_dm_psr_disable(acrtc_state->stream); - dc_commit_updates_for_stream(dm->dc, - bundle->surface_updates, - planes_count, - acrtc_state->stream, - &bundle->stream_update, - dc_state); + dc_update_planes_and_stream(dm->dc, + bundle->surface_updates, + planes_count, + acrtc_state->stream, + &bundle->stream_update); /** * Enable or disable the interrupts on the backend. @@ -8694,12 +8695,11 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) mutex_lock(&dm->dc_lock); - dc_commit_updates_for_stream(dm->dc, - dummy_updates, - status->plane_count, - dm_new_crtc_state->stream, - &stream_update, - dc_state); + dc_update_planes_and_stream(dm->dc, + dummy_updates, + status->plane_count, + dm_new_crtc_state->stream, + &stream_update); mutex_unlock(&dm->dc_lock); } -- cgit From 7222f5841ff49709ca666b05ff336776e0664a20 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Tue, 1 Nov 2022 10:20:09 -0400 Subject: drm/amd/display: Use DC_LOG_DC in the trasform pixel function [Why & How] DC now uses a new commit sequence which is more robust since it addresses cases where we need to reorganize pipes based on planes and other parameters. As a result, this new commit sequence reset the DC state by cleaning plane states and re-creating them accordingly with the need. For this reason, the dce_transform_set_pixel_storage_depth can be invoked after a plane state is destroyed and before its re-creation. In this situation and on DCE devices, DC will hit a condition that will trigger a dmesg log that looks like this: Console: switching to colour frame buffer device 240x67 ------------[ cut here ]------------ [..] Hardware name: System manufacturer System Product Name/PRIME X370-PRO, BIOS 5603 07/28/2020 RIP: 0010:dce_transform_set_pixel_storage_depth+0x3f8/0x480 [amdgpu] [..] RSP: 0018:ffffc9000202b850 EFLAGS: 00010293 RAX: ffffffffa081d100 RBX: ffff888110790000 RCX: 000000000000000c RDX: ffff888100bedbf8 RSI: 0000000000001a50 RDI: ffff88810463c900 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000007 R10: 0000000000000001 R11: 0000000000000f00 R12: ffff88810f500010 R13: ffff888100bedbf8 R14: ffff88810f515688 R15: 0000000000000000 FS: 00007ff0159249c0(0000) GS:ffff88840e940000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ff01528e550 CR3: 0000000002a10000 CR4: 00000000003506e0 Call Trace: ? dm_write_reg_func+0x21/0x80 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8] dc_stream_set_dither_option+0xfb/0x130 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8] amdgpu_dm_crtc_configure_crc_source+0x10b/0x190 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8] amdgpu_dm_atomic_commit_tail+0x20a8/0x2a90 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8] ? free_unref_page_commit+0x98/0x170 ? free_unref_page+0xcc/0x150 commit_tail+0x94/0x120 drm_atomic_helper_commit+0x10f/0x140 drm_atomic_commit+0x94/0xc0 ? drm_plane_get_damage_clips.cold+0x1c/0x1c drm_client_modeset_commit_atomic+0x203/0x250 drm_client_modeset_commit_locked+0x56/0x150 drm_client_modeset_commit+0x21/0x40 drm_fb_helper_lastclose+0x42/0x70 amdgpu_driver_lastclose_kms+0xa/0x10 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8] drm_release+0xda/0x110 __fput+0x89/0x240 task_work_run+0x5c/0x90 do_exit+0x333/0xae0 do_group_exit+0x2d/0x90 __x64_sys_exit_group+0x14/0x20 do_syscall_64+0x5b/0x80 ? exit_to_user_mode_prepare+0x1e/0x140 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7ff016ceaca1 Code: Unable to access opcode bytes at RIP 0x7ff016ceac77. RSP: 002b:00007ffe7a2357e8 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7 RAX: ffffffffffffffda RBX: 00007ff016e15a00 RCX: 00007ff016ceaca1 RDX: 000000000000003c RSI: 00000000000000e7 RDI: 0000000000000000 RBP: 0000000000000000 R08: ffffffffffffff78 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007ff016e15a00 R13: 0000000000000000 R14: 00007ff016e1aee8 R15: 00007ff016e1af00 Since this issue only happens in a transition state on DC, this commit replace BREAK_TO_DEBUGGER with DC_LOG_DC. Reviewed-by: Harry Wentland Acked-by: Qingqing Zhuo Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dce_transform.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c index d9fd4ec60588..670d5ab9d998 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c @@ -1009,7 +1009,7 @@ static void dce_transform_set_pixel_storage_depth( color_depth = COLOR_DEPTH_101010; pixel_depth = 0; expan_mode = 1; - BREAK_TO_DEBUGGER(); + DC_LOG_DC("The pixel depth %d is not valid, set COLOR_DEPTH_101010 instead.", depth); break; } @@ -1023,8 +1023,7 @@ static void dce_transform_set_pixel_storage_depth( if (!(xfm_dce->lb_pixel_depth_supported & depth)) { /*we should use unsupported capabilities * unless it is required by w/a*/ - DC_LOG_WARNING("%s: Capability not supported", - __func__); + DC_LOG_DC("%s: Capability not supported", __func__); } } -- cgit From 81f743a08f3b214638aa389e252ae5e6c3592e7c Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Thu, 23 Feb 2023 11:36:08 -0700 Subject: drm/amd/display: Add wrapper to call planes and stream update [Why & How] This commit is part of a sequence of changes that replaces the commit sequence used in the DC with a new one. As a result of this transition, we moved some specific parts from the commit sequence and brought them to amdgpu_dm. This commit adds a wrapper inside DM that enable our drivers to do any necessary preparation or change before we offload the plane/stream update to DC. Reviewed-by: Harry Wentland Acked-by: Qingqing Zhuo Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 51 ++++++++++++++++++----- 1 file changed, 41 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 5e2e4aee5896..53dcb3518976 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -348,6 +348,35 @@ static inline bool is_dc_timing_adjust_needed(struct dm_crtc_state *old_state, return false; } +/** + * update_planes_and_stream_adapter() - Send planes to be updated in DC + * + * DC has a generic way to update planes and stream via + * dc_update_planes_and_stream function; however, DM might need some + * adjustments and preparation before calling it. This function is a wrapper + * for the dc_update_planes_and_stream that does any required configuration + * before passing control to DC. + */ +static inline bool update_planes_and_stream_adapter(struct dc *dc, + int update_type, + int planes_count, + struct dc_stream_state *stream, + struct dc_stream_update *stream_update, + struct dc_surface_update *array_of_surface_update) +{ + /* + * Previous frame finished and HW is ready for optimization. + */ + if (update_type == UPDATE_TYPE_FAST) + dc_post_update_surfaces_to_stream(dc); + + return dc_update_planes_and_stream(dc, + array_of_surface_update, + planes_count, + stream, + stream_update); +} + /** * dm_pflip_high_irq() - Handle pageflip interrupt * @interrupt_params: ignored @@ -2673,11 +2702,12 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, true; } - dc_update_planes_and_stream(dm->dc, - bundle->surface_updates, - dc_state->stream_status->plane_count, - dc_state->streams[k], - &bundle->stream_update); + update_planes_and_stream_adapter(dm->dc, + UPDATE_TYPE_FULL, + dc_state->stream_status->plane_count, + dc_state->streams[k], + &bundle->stream_update, + bundle->surface_updates); } cleanup: @@ -8161,11 +8191,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, acrtc_state->stream->link->psr_settings.psr_allow_active) amdgpu_dm_psr_disable(acrtc_state->stream); - dc_update_planes_and_stream(dm->dc, - bundle->surface_updates, - planes_count, - acrtc_state->stream, - &bundle->stream_update); + update_planes_and_stream_adapter(dm->dc, + acrtc_state->update_type, + planes_count, + acrtc_state->stream, + &bundle->stream_update, + bundle->surface_updates); /** * Enable or disable the interrupts on the backend. -- cgit From bb46a6a9bab134b9d15043ea8fa9d6c276e938b8 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Thu, 16 Feb 2023 09:49:22 -0700 Subject: drm/amd/display: Ensure that planes are in the same order The function dc_update_planes_and_stream handles multiple cases where DC needs to remove and add planes in the commit tail phase. After Linux started to use this function, some of the IGT kms_plane started to fail; one good example to illustrate why the new sequence regressed IGT is the subtest plane-position-hole which has the following diagram as a template: +--------------------+ +-----------------------+ | +-----+ | | +-----+ | | | | | | | +-----+ | | | +--+ | ==> | | | | | | | |__| | | +-|---+ | | | | | +-----+ | | | | | +--------------------+ +-----------------------+ (a) Final image (b) Composed image IGT expects image (a) as the final result of two plane compositions as described in figure (b). After the migration to the new sequence, the last plane order is changed, and DC generates the following image: +---------------------+ | +-----+ | | | | | | | | | | +-----+ | | | +---------------------+ Notice that the generated image by DC is different because the small square that should be composed on top of the primary plane is below the primary plane. For this reason, the CRC will mismatch with the expected value. Since the function dc_add_all_planes_for_stream re-append all the new planes back to the dc_validation_set, this commit ensures that the original sequence is maintained. After this change, all CI tests in all ASICs start to pass again. Reviewed-by: Harry Wentland Acked-by: Qingqing Zhuo Suggested-by: Melissa Wen Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers/gpu/drm/amd/display') 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 53dcb3518976..c27fb97b0135 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -348,6 +348,19 @@ static inline bool is_dc_timing_adjust_needed(struct dm_crtc_state *old_state, return false; } +static inline void reverse_planes_order(struct dc_surface_update *array_of_surface_update, + int planes_count) +{ + int i, j; + struct dc_surface_update surface_updates_temp; + + for (i = 0, j = planes_count - 1; i < j; i++, j--) { + surface_updates_temp = array_of_surface_update[i]; + array_of_surface_update[i] = array_of_surface_update[j]; + array_of_surface_update[j] = surface_updates_temp; + } +} + /** * update_planes_and_stream_adapter() - Send planes to be updated in DC * @@ -364,6 +377,8 @@ static inline bool update_planes_and_stream_adapter(struct dc *dc, struct dc_stream_update *stream_update, struct dc_surface_update *array_of_surface_update) { + reverse_planes_order(array_of_surface_update, planes_count); + /* * Previous frame finished and HW is ready for optimization. */ -- cgit From 1fd0da91a882a2421e7702201f707c5e06bba6aa Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Sun, 26 Feb 2023 21:54:21 -0500 Subject: drm/amd/display: 3.2.226 In this new version there are two major changes: 1) Transitioning to the new DC commit sequence There is an extended effort to migrate to the new DC commit sequence that better adheres to the DCN hardware constraints. Most of the code was upstreamed already but not connected to amdgpu_dm, and in this new DC version, our DM finally started to use it for all ASICs. This should improve stability and enable us to improve how pipe split works. 2) Drop old CONFIG_DRM_AMD_DC_DCN in favor of new CONFIG_DRM_AMD_DC_FP For historical reasons, we created CONFIG_DRM_AMD_DC_DCN to isolate FPU-related code to only be used for DCN. Over the years, we lost control over this guard, and it was spread in multiple areas. In this new DC version, there is an effort to remove all unnecessary CONFIG_DRM_AMD_DC_DCN and replace the others for CONFIG_DRM_AMD_DC_FP, which better describes which type of code this guard is intended for. Finally, this version brings along the following: - Enable HostVM based on rIOMMU active - Keep PHY active for dp confi - Improves Z8 - Update clock table - Code and directives clean up Acked-by: Qingqing Zhuo 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(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index b51dfe0f507c..f0a1934ebf8c 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -45,7 +45,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.225" +#define DC_VER "3.2.226" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- cgit From 20ce5ed69bfee125b223bb0c6a731128caf07b09 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Sat, 4 Mar 2023 10:26:40 -0500 Subject: drm/amd/display: change several dcn201 variables storage-class-specifier to static smatch reports these similar problems in dcn201 drivers/gpu/drm/amd/amdgpu/../display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c:165:22: warning: symbol 'dcn201_funcs' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dcn201/dcn201_resource.c:77:30: warning: symbol 'dcn201_ip' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dcn201/dcn201_resource.c:139:37: warning: symbol 'dcn201_soc' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dcn201/dcn201_mpc.c:79:24: warning: symbol 'dcn201_mpc_funcs' was not declared. Should it be static? All of these are only used in their definition file, so they should be static Signed-off-by: Tom Rix Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn201/dcn201_mpc.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c index f0577dcd1af6..811720749faf 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c @@ -162,7 +162,7 @@ static void dcn201_update_clocks(struct clk_mgr *clk_mgr_base, } } -struct clk_mgr_funcs dcn201_funcs = { +static struct clk_mgr_funcs dcn201_funcs = { .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, .update_clocks = dcn201_update_clocks, .init_clocks = dcn201_init_clocks, diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_mpc.c index 95c4c55f067c..1af03a86ec9b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_mpc.c @@ -76,7 +76,7 @@ static void mpc201_init_mpcc(struct mpcc *mpcc, int mpcc_inst) mpcc->shared_bottom = false; } -const struct mpc_funcs dcn201_mpc_funcs = { +static const struct mpc_funcs dcn201_mpc_funcs = { .read_mpcc_state = mpc1_read_mpcc_state, .insert_plane = mpc1_insert_plane, .remove_mpcc = mpc1_remove_mpcc, diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c index 407d995bfa99..cd46701398d9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c @@ -74,7 +74,7 @@ #define MIN_DISP_CLK_KHZ 100000 #define MIN_DPP_CLK_KHZ 100000 -struct _vcs_dpi_ip_params_st dcn201_ip = { +static struct _vcs_dpi_ip_params_st dcn201_ip = { .gpuvm_enable = 0, .hostvm_enable = 0, .gpuvm_max_page_table_levels = 4, @@ -136,7 +136,7 @@ struct _vcs_dpi_ip_params_st dcn201_ip = { .number_of_cursors = 1, }; -struct _vcs_dpi_soc_bounding_box_st dcn201_soc = { +static struct _vcs_dpi_soc_bounding_box_st dcn201_soc = { .clock_limits = { { .state = 0, -- cgit From 5fd1bea5c23bb921720b6c48ceba5d6415f2ed02 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Sat, 4 Mar 2023 11:22:13 -0500 Subject: drm/amd/display: change several dcn20 variables storage-class-specifier to static smatch reports these similar problems in dcn20 drivers/gpu/drm/amd/amdgpu/../display/dc/dcn20/dcn20_dsc.c:53:24: warning: symbol 'dcn20_dsc_funcs' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dcn20/dcn20_dwb.c:304:25: warning: symbol 'dcn20_dwbc_funcs' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dcn20/dcn20_mmhubbub.c:300:28: warning: symbol 'dcn20_mmhubbub_funcs' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dcn20/dcn20_mpc.c:545:24: warning: symbol 'dcn20_mpc_funcs' was not declared. Should it be static? All of these are only used in their definition file, so they should be static Signed-off-by: Tom Rix Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 42344aec60d6..5bd698cd6d20 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c @@ -50,7 +50,7 @@ static void dsc2_enable(struct display_stream_compressor *dsc, int opp_pipe); static void dsc2_disable(struct display_stream_compressor *dsc); static void dsc2_disconnect(struct display_stream_compressor *dsc); -const struct dsc_funcs dcn20_dsc_funcs = { +static const struct dsc_funcs dcn20_dsc_funcs = { .dsc_get_enc_caps = dsc2_get_enc_caps, .dsc_read_state = dsc2_read_state, .dsc_validate_stream = dsc2_validate_stream, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb.c index f1490e97b6ce..f8667be57046 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb.c @@ -301,7 +301,7 @@ void dwb2_set_scaler(struct dwbc *dwbc, struct dc_dwb_params *params) } -const struct dwbc_funcs dcn20_dwbc_funcs = { +static const struct dwbc_funcs dcn20_dwbc_funcs = { .get_caps = dwb2_get_caps, .enable = dwb2_enable, .disable = dwb2_disable, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.c index ccd91792991b..259a98e4ee2c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.c @@ -297,7 +297,7 @@ void mcifwb2_dump_frame(struct mcif_wb *mcif_wb, dump_info->size = dest_height * (mcif_params->luma_pitch + mcif_params->chroma_pitch); } -const struct mcif_wb_funcs dcn20_mmhubbub_funcs = { +static const struct mcif_wb_funcs dcn20_mmhubbub_funcs = { .enable_mcif = mmhubbub2_enable_mcif, .disable_mcif = mmhubbub2_disable_mcif, .config_mcif_buf = mmhubbub2_config_mcif_buf, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c index 116f67a0b989..5da6e44f284a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c @@ -542,7 +542,7 @@ static struct mpcc *mpc2_get_mpcc_for_dpp(struct mpc_tree *tree, int dpp_id) return NULL; } -const struct mpc_funcs dcn20_mpc_funcs = { +static const struct mpc_funcs dcn20_mpc_funcs = { .read_mpcc_state = mpc1_read_mpcc_state, .insert_plane = mpc1_insert_plane, .remove_mpcc = mpc1_remove_mpcc, -- cgit From b79f85b7aa5a9ff9f702f40c6a5fe4a53e965cf6 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Sun, 5 Mar 2023 07:52:26 -0500 Subject: drm/amd/display: change several dcn30 variables storage-class-specifier to static smatch reports these similar problems in dcn30 drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_dwb.c:223:25: warning: symbol 'dcn30_dwbc_funcs' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_mmhubbub.c:214:28: warning: symbol 'dcn30_mmhubbub_funcs' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_mpc.c:1402:24: warning: symbol 'dcn30_mpc_funcs' was not declared. Should it be static? All of these are only used in their definition file, so they should be static Signed-off-by: Tom Rix Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mmhubbub.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c index f14f69616692..0d98918bf0fc 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c @@ -220,7 +220,7 @@ void dwb3_set_denorm(struct dwbc *dwbc, struct dc_dwb_params *params) } -const struct dwbc_funcs dcn30_dwbc_funcs = { +static const struct dwbc_funcs dcn30_dwbc_funcs = { .get_caps = dwb3_get_caps, .enable = dwb3_enable, .disable = dwb3_disable, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mmhubbub.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mmhubbub.c index 7a93eff183d9..6f2a0d5d963b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mmhubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mmhubbub.c @@ -211,7 +211,7 @@ static void mmhubbub3_config_mcif_arb(struct mcif_wb *mcif_wb, REG_UPDATE(MCIF_WB_ARBITRATION_CONTROL, MCIF_WB_CLIENT_ARBITRATION_SLICE, params->arbitration_slice); } -const struct mcif_wb_funcs dcn30_mmhubbub_funcs = { +static const struct mcif_wb_funcs dcn30_mmhubbub_funcs = { .warmup_mcif = mmhubbub3_warmup_mcif, .enable_mcif = mmhubbub2_enable_mcif, .disable_mcif = mmhubbub2_disable_mcif, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c index ad1c1b703874..6cf40c1332bc 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c @@ -1399,7 +1399,7 @@ static void mpc3_set_mpc_mem_lp_mode(struct mpc *mpc) } } -const struct mpc_funcs dcn30_mpc_funcs = { +static const struct mpc_funcs dcn30_mpc_funcs = { .read_mpcc_state = mpc1_read_mpcc_state, .insert_plane = mpc1_insert_plane, .remove_mpcc = mpc1_remove_mpcc, -- cgit From 8bf0d9cdf36b0bebf17b733e3f5158783d765df3 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Sun, 5 Mar 2023 23:24:27 -0300 Subject: drm/amd/display: add prefix to amdgpu_dm_plane.h functions The amdgpu_dm_plane.h functions didn't have names that indicated where they were declared. To better filter results in debug tools like ftrace, prefix these functions with 'amdgpu_dm_plane_'. Note that we may want to make this same change in other files like amdgpu_dm_crtc.h. Signed-off-by: David Tadokoro Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +++++++------- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 20 ++++++++++---------- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h | 12 ++++++------ 3 files changed, 23 insertions(+), 23 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 c27fb97b0135..6db59972ae27 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2960,7 +2960,7 @@ const struct amdgpu_ip_block_version dm_ip_block = static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = { .fb_create = amdgpu_display_user_framebuffer_create, - .get_format_info = amd_get_format_info, + .get_format_info = amdgpu_dm_plane_get_format_info, .atomic_check = amdgpu_dm_atomic_check, .atomic_commit = drm_atomic_helper_commit, }; @@ -4978,7 +4978,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, if (ret) return ret; - ret = fill_plane_buffer_attributes(adev, afb, plane_info->format, + ret = amdgpu_dm_plane_fill_plane_buffer_attributes(adev, afb, plane_info->format, plane_info->rotation, tiling_flags, &plane_info->tiling_info, &plane_info->plane_size, @@ -4987,7 +4987,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, if (ret) return ret; - fill_blending_from_plane_state( + amdgpu_dm_plane_fill_blending_from_plane_state( plane_state, &plane_info->per_pixel_alpha, &plane_info->pre_multiplied_alpha, &plane_info->global_alpha, &plane_info->global_alpha_value); @@ -5006,7 +5006,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, int ret; bool force_disable_dcc = false; - ret = fill_dc_scaling_info(adev, plane_state, &scaling_info); + ret = amdgpu_dm_plane_fill_dc_scaling_info(adev, plane_state, &scaling_info); if (ret) return ret; @@ -7901,7 +7901,7 @@ static void amdgpu_dm_commit_cursors(struct drm_atomic_state *state) */ for_each_old_plane_in_state(state, plane, old_plane_state, i) if (plane->type == DRM_PLANE_TYPE_CURSOR) - handle_cursor_update(plane, old_plane_state); + amdgpu_dm_plane_handle_cursor_update(plane, old_plane_state); } static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, @@ -7986,7 +7986,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix; } - fill_dc_scaling_info(dm->adev, new_plane_state, + amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state, &bundle->scaling_infos[planes_count]); bundle->surface_updates[planes_count].scaling_info = @@ -9650,7 +9650,7 @@ static int dm_update_plane_state(struct dc *dc, if (!needs_reset) return 0; - ret = dm_plane_helper_check_state(new_plane_state, new_crtc_state); + ret = amdgpu_dm_plane_helper_check_state(new_plane_state, new_crtc_state); if (ret) return ret; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c index a8d6b06cee95..322668973747 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c @@ -90,12 +90,12 @@ enum dm_micro_swizzle { MICRO_SWIZZLE_R = 3 }; -const struct drm_format_info *amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd) +const struct drm_format_info *amdgpu_dm_plane_get_format_info(const struct drm_mode_fb_cmd2 *cmd) { return amdgpu_lookup_format_info(cmd->pixel_format, cmd->modifier[0]); } -void fill_blending_from_plane_state(const struct drm_plane_state *plane_state, +void amdgpu_dm_plane_fill_blending_from_plane_state(const struct drm_plane_state *plane_state, bool *per_pixel_alpha, bool *pre_multiplied_alpha, bool *global_alpha, int *global_alpha_value) { @@ -741,7 +741,7 @@ static int get_plane_formats(const struct drm_plane *plane, return num_formats; } -int fill_plane_buffer_attributes(struct amdgpu_device *adev, +int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev, const struct amdgpu_framebuffer *afb, const enum surface_pixel_format format, const enum dc_rotation_angle rotation, @@ -900,7 +900,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, dm_plane_state_new->dc_state; bool force_disable_dcc = !plane_state->dcc.enable; - fill_plane_buffer_attributes( + amdgpu_dm_plane_fill_plane_buffer_attributes( adev, afb, plane_state->format, plane_state->rotation, afb->tiling_flags, &plane_state->tiling_info, &plane_state->plane_size, @@ -981,7 +981,7 @@ static void get_min_max_dc_plane_scaling(struct drm_device *dev, *min_downscale = 1000; } -int dm_plane_helper_check_state(struct drm_plane_state *state, +int amdgpu_dm_plane_helper_check_state(struct drm_plane_state *state, struct drm_crtc_state *new_crtc_state) { struct drm_framebuffer *fb = state->fb; @@ -1035,7 +1035,7 @@ int dm_plane_helper_check_state(struct drm_plane_state *state, state, new_crtc_state, min_scale, max_scale, true, true); } -int fill_dc_scaling_info(struct amdgpu_device *adev, +int amdgpu_dm_plane_fill_dc_scaling_info(struct amdgpu_device *adev, const struct drm_plane_state *state, struct dc_scaling_info *scaling_info) { @@ -1143,11 +1143,11 @@ static int dm_plane_atomic_check(struct drm_plane *plane, if (!new_crtc_state) return -EINVAL; - ret = dm_plane_helper_check_state(new_plane_state, new_crtc_state); + ret = amdgpu_dm_plane_helper_check_state(new_plane_state, new_crtc_state); if (ret) return ret; - ret = fill_dc_scaling_info(adev, new_plane_state, &scaling_info); + ret = amdgpu_dm_plane_fill_dc_scaling_info(adev, new_plane_state, &scaling_info); if (ret) return ret; @@ -1211,7 +1211,7 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc, return 0; } -void handle_cursor_update(struct drm_plane *plane, +void amdgpu_dm_plane_handle_cursor_update(struct drm_plane *plane, struct drm_plane_state *old_plane_state) { struct amdgpu_device *adev = drm_to_adev(plane->dev); @@ -1296,7 +1296,7 @@ static void dm_plane_atomic_async_update(struct drm_plane *plane, plane->state->crtc_w = new_state->crtc_w; plane->state->crtc_h = new_state->crtc_h; - handle_cursor_update(plane, old_state); + amdgpu_dm_plane_handle_cursor_update(plane, old_state); } static const struct drm_plane_helper_funcs dm_plane_helper_funcs = { diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h index a4bee8528a51..930f1572f898 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h @@ -29,17 +29,17 @@ #include "dc.h" -void handle_cursor_update(struct drm_plane *plane, +void amdgpu_dm_plane_handle_cursor_update(struct drm_plane *plane, struct drm_plane_state *old_plane_state); -int fill_dc_scaling_info(struct amdgpu_device *adev, +int amdgpu_dm_plane_fill_dc_scaling_info(struct amdgpu_device *adev, const struct drm_plane_state *state, struct dc_scaling_info *scaling_info); -int dm_plane_helper_check_state(struct drm_plane_state *state, +int amdgpu_dm_plane_helper_check_state(struct drm_plane_state *state, struct drm_crtc_state *new_crtc_state); -int fill_plane_buffer_attributes(struct amdgpu_device *adev, +int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev, const struct amdgpu_framebuffer *afb, const enum surface_pixel_format format, const enum dc_rotation_angle rotation, @@ -56,9 +56,9 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, unsigned long possible_crtcs, const struct dc_plane_cap *plane_cap); -const struct drm_format_info *amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd); +const struct drm_format_info *amdgpu_dm_plane_get_format_info(const struct drm_mode_fb_cmd2 *cmd); -void fill_blending_from_plane_state(const struct drm_plane_state *plane_state, +void amdgpu_dm_plane_fill_blending_from_plane_state(const struct drm_plane_state *plane_state, bool *per_pixel_alpha, bool *pre_multiplied_alpha, bool *global_alpha, int *global_alpha_value); -- cgit From 36e88a9e4569df86e81dc75a7fc6f2d41f8ab8e0 Mon Sep 17 00:00:00 2001 From: Husain Alshehhi Date: Sun, 5 Mar 2023 21:24:22 +0000 Subject: drivers/gpu: fix typo in comment Replace "isntance" with "instance". Signed-off-by: Husain Alshehhi Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 007d6bdc3e39..734b34902fa7 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -1971,7 +1971,7 @@ struct dmub_cmd_psr_copy_settings_data { uint8_t cmd_version; /** * Panel Instance. - * Panel isntance to identify which psr_state to use + * Panel instance to identify which psr_state to use * Currently the support is only for 0 or 1 */ uint8_t panel_inst; @@ -2029,7 +2029,7 @@ struct dmub_cmd_psr_set_level_data { uint8_t cmd_version; /** * Panel Instance. - * Panel isntance to identify which psr_state to use + * Panel instance to identify which psr_state to use * Currently the support is only for 0 or 1 */ uint8_t panel_inst; @@ -2056,7 +2056,7 @@ struct dmub_rb_cmd_psr_enable_data { uint8_t cmd_version; /** * Panel Instance. - * Panel isntance to identify which psr_state to use + * Panel instance to identify which psr_state to use * Currently the support is only for 0 or 1 */ uint8_t panel_inst; @@ -2100,7 +2100,7 @@ struct dmub_cmd_psr_set_version_data { uint8_t cmd_version; /** * Panel Instance. - * Panel isntance to identify which psr_state to use + * Panel instance to identify which psr_state to use * Currently the support is only for 0 or 1 */ uint8_t panel_inst; @@ -2131,7 +2131,7 @@ struct dmub_cmd_psr_force_static_data { uint8_t cmd_version; /** * Panel Instance. - * Panel isntance to identify which psr_state to use + * Panel instance to identify which psr_state to use * Currently the support is only for 0 or 1 */ uint8_t panel_inst; @@ -2206,7 +2206,7 @@ struct dmub_cmd_update_dirty_rect_data { uint8_t cmd_version; /** * Panel Instance. - * Panel isntance to identify which psr_state to use + * Panel instance to identify which psr_state to use * Currently the support is only for 0 or 1 */ uint8_t panel_inst; @@ -2344,7 +2344,7 @@ struct dmub_cmd_update_cursor_payload0 { uint8_t cmd_version; /** * Panel Instance. - * Panel isntance to identify which psr_state to use + * Panel instance to identify which psr_state to use * Currently the support is only for 0 or 1 */ uint8_t panel_inst; @@ -2391,7 +2391,7 @@ struct dmub_cmd_psr_set_vtotal_data { uint8_t cmd_version; /** * Panel Instance. - * Panel isntance to identify which psr_state to use + * Panel instance to identify which psr_state to use * Currently the support is only for 0 or 1 */ uint8_t panel_inst; @@ -2429,7 +2429,7 @@ struct dmub_cmd_psr_set_power_opt_data { uint8_t cmd_version; /** * Panel Instance. - * Panel isntance to identify which psr_state to use + * Panel instance to identify which psr_state to use * Currently the support is only for 0 or 1 */ uint8_t panel_inst; -- cgit From 83923cb27323139f9e2185db9b3b1299e6cf22bc Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 28 Feb 2023 14:54:43 -0500 Subject: Revert "drm/amdgpu/display: change pipe policy for DCN 2.1" This reverts commit fa458eb10dc7218146a84e6d2e072424e64d188a. The issue is no longer present even with this commit present as verified by the original reporter. Reviewed-by: Rodrigo Siqueira Signed-off-by: Alex Deucher Link: https://gitlab.freedesktop.org/drm/amd/-/issues/1849#note_1759599 Signed-off-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 8f9244fe5c86..c10ff621cb1d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -642,7 +642,7 @@ static const struct dc_debug_options debug_defaults_drv = { .clock_trace = true, .disable_pplib_clock_request = true, .min_disp_clk_khz = 100000, - .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, + .pipe_split_policy = MPC_SPLIT_DYNAMIC, .force_single_disp_pipe_split = false, .disable_dcc = DCC_ENABLE, .vsr_support = true, -- cgit From c0a76ae8743a8d6cfa5c06b5efa497139100bed6 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Tue, 7 Mar 2023 19:53:41 -0300 Subject: drm/amd/display: remove legacy fields of dc_plane_cap struct The fields blends_with_above and blends_with_below of struct dc_plane_cap (defined in dc/dc.h) are boolean and set to true by default. All instances of a dc_plane_cap maintain the default values of both. Also, there is only one if statement that checks those fields and there would be the same effect if it was deleted (assuming that those fields are always going to be true). For this reason, considering both fields as legacy ones, this commit removes them and the aforementioned if statement. Reviewed-by: Rodrigo Siqueira Signed-off-by: David Tadokoro Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 --- drivers/gpu/drm/amd/display/dc/dc.h | 2 -- drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c | 3 --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 2 -- drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c | 2 -- 17 files changed, 36 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 6db59972ae27..4458e00f5b15 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4351,9 +4351,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) if (plane->type != DC_PLANE_TYPE_DCN_UNIVERSAL) continue; - if (!plane->blends_with_above || !plane->blends_with_below) - continue; - if (!plane->pixel_format_support.argb8888) continue; diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index f0a1934ebf8c..ccc27d482640 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -82,8 +82,6 @@ enum det_size { struct dc_plane_cap { enum dc_plane_type type; - uint32_t blends_with_above : 1; - uint32_t blends_with_below : 1; uint32_t per_pixel_alpha : 1; struct { uint32_t argb8888 : 1; diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index f808315b2835..a4a45a6ce61e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -401,8 +401,6 @@ static const struct resource_caps stoney_resource_cap = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCE_RGB, - .blends_with_below = true, - .blends_with_above = true, .per_pixel_alpha = 1, .pixel_format_support = { @@ -428,7 +426,6 @@ static const struct dc_plane_cap plane_cap = { static const struct dc_plane_cap underlay_plane_cap = { .type = DC_PLANE_TYPE_DCE_UNDERLAY, - .blends_with_above = true, .per_pixel_alpha = 1, .pixel_format_support = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 6bfac8088ab0..2bb8e11f26e0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -504,8 +504,6 @@ static const struct resource_caps rv2_res_cap = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCN_UNIVERSAL, - .blends_with_above = true, - .blends_with_below = true, .per_pixel_alpha = true, .pixel_format_support = { 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 3af24ef9cb2d..00668df0938e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -670,8 +670,6 @@ static const struct resource_caps res_cap_nv10 = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCN_UNIVERSAL, - .blends_with_above = true, - .blends_with_below = true, .per_pixel_alpha = true, .pixel_format_support = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c index cd46701398d9..6ea70da28aaa 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c @@ -571,8 +571,6 @@ static const struct resource_caps res_cap_dnc201 = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCN_UNIVERSAL, - .blends_with_above = true, - .blends_with_below = true, .per_pixel_alpha = true, .pixel_format_support = { 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 c10ff621cb1d..19aaa557b2db 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -609,8 +609,6 @@ static const struct resource_caps res_cap_rn_FPGA_2pipe_dsc = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCN_UNIVERSAL, - .blends_with_above = true, - .blends_with_below = true, .per_pixel_alpha = true, .pixel_format_support = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index b5b5320c7bef..d60c17d5a0d8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -680,8 +680,6 @@ static const struct resource_caps res_cap_dcn3 = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCN_UNIVERSAL, - .blends_with_above = true, - .blends_with_below = true, .per_pixel_alpha = true, .pixel_format_support = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c index ee62ae3eb98f..b93b4498dba4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c @@ -651,8 +651,6 @@ static struct resource_caps res_cap_dcn301 = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCN_UNIVERSAL, - .blends_with_above = true, - .blends_with_below = true, .per_pixel_alpha = true, .pixel_format_support = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c index 03ddf4f5f065..6ccad53f1e49 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c @@ -147,8 +147,6 @@ static const struct resource_caps res_cap_dcn302 = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCN_UNIVERSAL, - .blends_with_above = true, - .blends_with_below = true, .per_pixel_alpha = true, .pixel_format_support = { .argb8888 = true, diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c index 727f458f6ee9..5c28f7151d13 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c @@ -126,8 +126,6 @@ static const struct resource_caps res_cap_dcn303 = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCN_UNIVERSAL, - .blends_with_above = true, - .blends_with_below = true, .per_pixel_alpha = true, .pixel_format_support = { .argb8888 = true, diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c index d3918a10773a..eaaa2e01f6d0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c @@ -827,8 +827,6 @@ static const struct resource_caps res_cap_dcn31 = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCN_UNIVERSAL, - .blends_with_above = true, - .blends_with_below = true, .per_pixel_alpha = true, .pixel_format_support = { 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 f9dfbc7407ee..50ed7e09d5ba 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c @@ -855,8 +855,6 @@ static const struct resource_caps res_cap_dcn314 = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCN_UNIVERSAL, - .blends_with_above = true, - .blends_with_below = true, .per_pixel_alpha = true, .pixel_format_support = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c index 7887078c5f64..41c972c8eb19 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c @@ -824,8 +824,6 @@ static const struct resource_caps res_cap_dcn31 = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCN_UNIVERSAL, - .blends_with_above = true, - .blends_with_below = true, .per_pixel_alpha = true, .pixel_format_support = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c index dc0b49506275..9ead347a33e9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c @@ -824,8 +824,6 @@ static const struct resource_caps res_cap_dcn31 = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCN_UNIVERSAL, - .blends_with_above = true, - .blends_with_below = true, .per_pixel_alpha = true, .pixel_format_support = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index 87f7669e81d7..100b6df33b33 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -657,8 +657,6 @@ static const struct resource_caps res_cap_dcn32 = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCN_UNIVERSAL, - .blends_with_above = true, - .blends_with_below = true, .per_pixel_alpha = true, .pixel_format_support = { 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 deaa4769be10..0f477d50e935 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c @@ -655,8 +655,6 @@ static const struct resource_caps res_cap_dcn321 = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCN_UNIVERSAL, - .blends_with_above = true, - .blends_with_below = true, .per_pixel_alpha = true, .pixel_format_support = { -- cgit From a9d491d99ece898fe6fd5f7374eacb5223e1531b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 8 Mar 2023 09:29:37 -0500 Subject: Revert "drm/amd/display: Pass proper parent for DM backlight device registration" This reverts commit d24b77e444bef83155557ebf4c2b3c551f198926. This does not work as expected. Bug: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/730 Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 4458e00f5b15..0e92bf6d286e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4181,8 +4181,7 @@ static const struct backlight_ops amdgpu_dm_backlight_ops = { }; static void -amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm, - struct amdgpu_dm_connector *aconnector) +amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm) { char bl_name[16]; struct backlight_properties props = { 0 }; @@ -4205,7 +4204,7 @@ amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm, adev_to_drm(dm->adev)->primary->index + dm->num_of_edps); dm->backlight_dev[dm->num_of_edps] = backlight_device_register(bl_name, - aconnector->base.kdev, + adev_to_drm(dm->adev)->dev, dm, &amdgpu_dm_backlight_ops, &props); @@ -4258,7 +4257,6 @@ static int initialize_plane(struct amdgpu_display_manager *dm, static void register_backlight_device(struct amdgpu_display_manager *dm, - struct amdgpu_dm_connector *aconnector, struct dc_link *link) { if ((link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) && @@ -4269,7 +4267,7 @@ static void register_backlight_device(struct amdgpu_display_manager *dm, * is better then a black screen. */ if (!dm->backlight_dev[dm->num_of_edps]) - amdgpu_dm_register_backlight_device(dm, aconnector); + amdgpu_dm_register_backlight_device(dm); if (dm->backlight_dev[dm->num_of_edps]) { dm->backlight_link[dm->num_of_edps] = link; @@ -4455,7 +4453,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) if (ret) { amdgpu_dm_update_connector_after_detect(aconnector); - register_backlight_device(dm, aconnector, link); + register_backlight_device(dm, link); if (dm->num_of_edps) update_connector_ext_caps(aconnector); -- cgit From 6c5e25a0255d56e8455869cd7f90bb9be7478132 Mon Sep 17 00:00:00 2001 From: David Tadokoro Date: Tue, 7 Mar 2023 16:14:17 -0300 Subject: drm/amd/display: add prefix to amdgpu_dm_crtc.h functions Some amdgpu_dm_crtc.h functions didn't have names that indicated where they were declared. To better filter results in debug tools like ftrace, prefix these functions with 'amdgpu_dm_crtc_'. Signed-off-by: David Tadokoro Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 32 +++++++++++----------- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 26 +++++++++--------- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h | 14 +++++----- 3 files changed, 36 insertions(+), 36 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 0e92bf6d286e..ae994c6c65ac 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -342,7 +342,7 @@ static inline bool is_dc_timing_adjust_needed(struct dm_crtc_state *old_state, { if (new_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED) return true; - else if (amdgpu_dm_vrr_active(old_state) != amdgpu_dm_vrr_active(new_state)) + else if (amdgpu_dm_crtc_vrr_active(old_state) != amdgpu_dm_crtc_vrr_active(new_state)) return true; else return false; @@ -436,7 +436,7 @@ static void dm_pflip_high_irq(void *interrupt_params) WARN_ON(!e); - vrr_active = amdgpu_dm_vrr_active_irq(amdgpu_crtc); + vrr_active = amdgpu_dm_crtc_vrr_active_irq(amdgpu_crtc); /* Fixed refresh rate, or VRR scanout position outside front-porch? */ if (!vrr_active || @@ -510,7 +510,7 @@ static void dm_vupdate_high_irq(void *interrupt_params) acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VUPDATE); if (acrtc) { - vrr_active = amdgpu_dm_vrr_active_irq(acrtc); + vrr_active = amdgpu_dm_crtc_vrr_active_irq(acrtc); drm_dev = acrtc->base.dev; vblank = &drm_dev->vblank[acrtc->base.index]; previous_timestamp = atomic64_read(&irq_params->previous_timestamp); @@ -534,7 +534,7 @@ static void dm_vupdate_high_irq(void *interrupt_params) * if a pageflip happened inside front-porch. */ if (vrr_active) { - dm_crtc_handle_vblank(acrtc); + amdgpu_dm_crtc_handle_vblank(acrtc); /* BTR processing for pre-DCE12 ASICs */ if (acrtc->dm_irq_params.stream && @@ -574,7 +574,7 @@ static void dm_crtc_high_irq(void *interrupt_params) if (!acrtc) return; - vrr_active = amdgpu_dm_vrr_active_irq(acrtc); + vrr_active = amdgpu_dm_crtc_vrr_active_irq(acrtc); DC_LOG_VBLANK("crtc:%d, vupdate-vrr:%d, planes:%d\n", acrtc->crtc_id, vrr_active, acrtc->dm_irq_params.active_planes); @@ -586,7 +586,7 @@ static void dm_crtc_high_irq(void *interrupt_params) * to dm_vupdate_high_irq after end of front-porch. */ if (!vrr_active) - dm_crtc_handle_vblank(acrtc); + amdgpu_dm_crtc_handle_vblank(acrtc); /** * Following stuff must happen at start of vblank, for crc @@ -2483,11 +2483,11 @@ static void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev, enable ? "enable" : "disable"); if (enable) { - rc = dm_enable_vblank(&acrtc->base); + rc = amdgpu_dm_crtc_enable_vblank(&acrtc->base); if (rc) DRM_WARN("Failed to enable vblank interrupts\n"); } else { - dm_disable_vblank(&acrtc->base); + amdgpu_dm_crtc_disable_vblank(&acrtc->base); } } @@ -7739,7 +7739,7 @@ static void update_freesync_state_on_stream( &vrr_params); if (adev->family < AMDGPU_FAMILY_AI && - amdgpu_dm_vrr_active(new_crtc_state)) { + amdgpu_dm_crtc_vrr_active(new_crtc_state)) { mod_freesync_handle_v_update(dm->freesync_module, new_stream, &vrr_params); @@ -7857,8 +7857,8 @@ static void update_stream_irq_parameters( static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, struct dm_crtc_state *new_state) { - bool old_vrr_active = amdgpu_dm_vrr_active(old_state); - bool new_vrr_active = amdgpu_dm_vrr_active(new_state); + bool old_vrr_active = amdgpu_dm_crtc_vrr_active(old_state); + bool new_vrr_active = amdgpu_dm_crtc_vrr_active(new_state); if (!old_vrr_active && new_vrr_active) { /* Transition VRR inactive -> active: @@ -7869,7 +7869,7 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, * We also need vupdate irq for the actual core vblank handling * at end of vblank. */ - WARN_ON(dm_set_vupdate_irq(new_state->base.crtc, true) != 0); + WARN_ON(amdgpu_dm_crtc_set_vupdate_irq(new_state->base.crtc, true) != 0); WARN_ON(drm_crtc_vblank_get(new_state->base.crtc) != 0); DRM_DEBUG_DRIVER("%s: crtc=%u VRR off->on: Get vblank ref\n", __func__, new_state->base.crtc->base.id); @@ -7877,7 +7877,7 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, /* Transition VRR active -> inactive: * Allow vblank irq disable again for fixed refresh rate. */ - WARN_ON(dm_set_vupdate_irq(new_state->base.crtc, false) != 0); + WARN_ON(amdgpu_dm_crtc_set_vupdate_irq(new_state->base.crtc, false) != 0); drm_crtc_vblank_put(new_state->base.crtc); DRM_DEBUG_DRIVER("%s: crtc=%u VRR on->off: Drop vblank ref\n", __func__, new_state->base.crtc->base.id); @@ -7919,7 +7919,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, int planes_count = 0, vpos, hpos; unsigned long flags; u32 target_vblank, last_flip_vblank; - bool vrr_active = amdgpu_dm_vrr_active(acrtc_state); + bool vrr_active = amdgpu_dm_crtc_vrr_active(acrtc_state); bool cursor_update = false; bool pflip_present = false; bool dirty_rects_changed = false; @@ -8469,7 +8469,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) * aconnector as needed */ - if (modeset_required(new_crtc_state, dm_new_crtc_state->stream, dm_old_crtc_state->stream)) { + if (amdgpu_dm_crtc_modeset_required(new_crtc_state, dm_new_crtc_state->stream, dm_old_crtc_state->stream)) { DRM_DEBUG_ATOMIC("Atomic commit: SET crtc id %d: [%p]\n", acrtc->crtc_id, acrtc); @@ -9294,7 +9294,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, if (modereset_required(new_crtc_state)) goto skip_modeset; - if (modeset_required(new_crtc_state, new_stream, + if (amdgpu_dm_crtc_modeset_required(new_crtc_state, new_stream, dm_old_crtc_state->stream)) { WARN_ON(dm_new_crtc_state->stream); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index dc4f37240beb..1d924dc51a3e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -34,7 +34,7 @@ #include "amdgpu_dm_trace.h" #include "amdgpu_dm_debugfs.h" -void dm_crtc_handle_vblank(struct amdgpu_crtc *acrtc) +void amdgpu_dm_crtc_handle_vblank(struct amdgpu_crtc *acrtc) { struct drm_crtc *crtc = &acrtc->base; struct drm_device *dev = crtc->dev; @@ -54,14 +54,14 @@ void dm_crtc_handle_vblank(struct amdgpu_crtc *acrtc) spin_unlock_irqrestore(&dev->event_lock, flags); } -bool modeset_required(struct drm_crtc_state *crtc_state, +bool amdgpu_dm_crtc_modeset_required(struct drm_crtc_state *crtc_state, struct dc_stream_state *new_stream, struct dc_stream_state *old_stream) { return crtc_state->active && drm_atomic_crtc_needs_modeset(crtc_state); } -bool amdgpu_dm_vrr_active_irq(struct amdgpu_crtc *acrtc) +bool amdgpu_dm_crtc_vrr_active_irq(struct amdgpu_crtc *acrtc) { return acrtc->dm_irq_params.freesync_config.state == @@ -70,7 +70,7 @@ bool amdgpu_dm_vrr_active_irq(struct amdgpu_crtc *acrtc) VRR_STATE_ACTIVE_FIXED; } -int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable) +int amdgpu_dm_crtc_set_vupdate_irq(struct drm_crtc *crtc, bool enable) { enum dc_irq_source irq_source; struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); @@ -89,7 +89,7 @@ int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable) return rc; } -bool amdgpu_dm_vrr_active(struct dm_crtc_state *dm_state) +bool amdgpu_dm_crtc_vrr_active(struct dm_crtc_state *dm_state) { return dm_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE || dm_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED; @@ -159,11 +159,11 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable) if (enable) { /* vblank irq on -> Only need vupdate irq in vrr mode */ - if (amdgpu_dm_vrr_active(acrtc_state)) - rc = dm_set_vupdate_irq(crtc, true); + if (amdgpu_dm_crtc_vrr_active(acrtc_state)) + rc = amdgpu_dm_crtc_set_vupdate_irq(crtc, true); } else { /* vblank irq off -> vupdate irq off */ - rc = dm_set_vupdate_irq(crtc, false); + rc = amdgpu_dm_crtc_set_vupdate_irq(crtc, false); } if (rc) @@ -199,12 +199,12 @@ skip: return 0; } -int dm_enable_vblank(struct drm_crtc *crtc) +int amdgpu_dm_crtc_enable_vblank(struct drm_crtc *crtc) { return dm_set_vblank(crtc, true); } -void dm_disable_vblank(struct drm_crtc *crtc) +void amdgpu_dm_crtc_disable_vblank(struct drm_crtc *crtc) { dm_set_vblank(crtc, false); } @@ -300,8 +300,8 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { .verify_crc_source = amdgpu_dm_crtc_verify_crc_source, .get_crc_sources = amdgpu_dm_crtc_get_crc_sources, .get_vblank_counter = amdgpu_get_vblank_counter_kms, - .enable_vblank = dm_enable_vblank, - .disable_vblank = dm_disable_vblank, + .enable_vblank = amdgpu_dm_crtc_enable_vblank, + .disable_vblank = amdgpu_dm_crtc_disable_vblank, .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp, #if defined(CONFIG_DEBUG_FS) .late_register = amdgpu_dm_crtc_late_register, @@ -381,7 +381,7 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, dm_update_crtc_active_planes(crtc, crtc_state); if (WARN_ON(unlikely(!dm_crtc_state->stream && - modeset_required(crtc_state, NULL, dm_crtc_state->stream)))) { + amdgpu_dm_crtc_modeset_required(crtc_state, NULL, dm_crtc_state->stream)))) { return ret; } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h index 1ac8692354cf..17e948753f59 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h @@ -27,21 +27,21 @@ #ifndef __AMDGPU_DM_CRTC_H__ #define __AMDGPU_DM_CRTC_H__ -void dm_crtc_handle_vblank(struct amdgpu_crtc *acrtc); +void amdgpu_dm_crtc_handle_vblank(struct amdgpu_crtc *acrtc); -bool modeset_required(struct drm_crtc_state *crtc_state, +bool amdgpu_dm_crtc_modeset_required(struct drm_crtc_state *crtc_state, struct dc_stream_state *new_stream, struct dc_stream_state *old_stream); -int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable); +int amdgpu_dm_crtc_set_vupdate_irq(struct drm_crtc *crtc, bool enable); -bool amdgpu_dm_vrr_active_irq(struct amdgpu_crtc *acrtc); +bool amdgpu_dm_crtc_vrr_active_irq(struct amdgpu_crtc *acrtc); -bool amdgpu_dm_vrr_active(struct dm_crtc_state *dm_state); +bool amdgpu_dm_crtc_vrr_active(struct dm_crtc_state *dm_state); -int dm_enable_vblank(struct drm_crtc *crtc); +int amdgpu_dm_crtc_enable_vblank(struct drm_crtc *crtc); -void dm_disable_vblank(struct drm_crtc *crtc); +void amdgpu_dm_crtc_disable_vblank(struct drm_crtc *crtc); int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, struct drm_plane *plane, -- cgit From 3a906a0cb150a872a23f6204449d3f8b50693837 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Wed, 8 Mar 2023 09:09:43 -0500 Subject: drm/amd/display: remove unused variable res_pool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With gcc and W=1, there is this error drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_mst_types.c:1214:31: error: variable ‘res_pool’ set but not used [-Werror=unused-but-set-variable] 1214 | struct resource_pool *res_pool; | ^~~~~~~~ Since res_pool is unused, remove it. Signed-off-by: Tom Rix Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 2739bef9b90c..4b9b5e4050fc 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 @@ -1211,7 +1211,6 @@ static int pre_compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, bool computed_streams[MAX_PIPES]; struct amdgpu_dm_connector *aconnector; struct drm_dp_mst_topology_mgr *mst_mgr; - struct resource_pool *res_pool; int link_vars_start_index = 0; int ret = 0; @@ -1220,7 +1219,6 @@ static int pre_compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, for (i = 0; i < dc_state->stream_count; i++) { stream = dc_state->streams[i]; - res_pool = stream->ctx->dc->res_pool; if (stream->signal != SIGNAL_TYPE_DISPLAY_PORT_MST) continue; -- cgit From 5922231bd346da717ceee8d14b4361fd595e58ac Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Wed, 8 Mar 2023 09:10:57 -0500 Subject: drm/amd/display: remove unused variable available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With gcc and W=1, there is this error drivers/gpu/drm/amd/amdgpu/../display/dc/link/protocols/link_dp_dpia_bw.c:297:13: error: variable ‘available’ set but not used [-Werror=unused-but-set-variable] 297 | int available = 0; | ^~~~~~~~~ Since available is unused, remove it. Signed-off-by: Tom Rix Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index f14217cc16fd..2f0311c42f90 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -294,7 +294,6 @@ out: void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result) { int bw_needed = 0; - int available = 0; int estimated = 0; int host_router_total_estimated_bw = 0; @@ -373,20 +372,13 @@ void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t res // 1. If due to unplug of other sink if (estimated == host_router_total_estimated_bw) { - // First update the estimated & max_bw fields if (link->dpia_bw_alloc_config.estimated_bw < estimated) { - available = estimated - link->dpia_bw_alloc_config.estimated_bw; link->dpia_bw_alloc_config.estimated_bw = estimated; } } // 2. If due to realloc bw btw 2 dpia due to plug OR realloc unused Bw else { - - // We took from another unplugged/problematic sink to give to us - if (link->dpia_bw_alloc_config.estimated_bw < estimated) - available = estimated - link->dpia_bw_alloc_config.estimated_bw; - // We lost estimated bw usually due to plug event of other dpia link->dpia_bw_alloc_config.estimated_bw = estimated; } -- cgit From 8866d62716c918e5d09d8297281ef93155434da0 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Thu, 9 Mar 2023 10:52:50 +0800 Subject: drm/amd/display: Use swap() instead of open coding it Swap is a function interface that provides exchange function. To avoid code duplication, we can use swap function. ./drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c:359:57-58: WARNING opportunity for swap(). Reported-by: Abaci Robot Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=4448 Signed-off-by: Jiapeng Chong Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 ae994c6c65ac..f6d9bbce15b2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -352,13 +352,9 @@ static inline void reverse_planes_order(struct dc_surface_update *array_of_surfa int planes_count) { int i, j; - struct dc_surface_update surface_updates_temp; - for (i = 0, j = planes_count - 1; i < j; i++, j--) { - surface_updates_temp = array_of_surface_update[i]; - array_of_surface_update[i] = array_of_surface_update[j]; - array_of_surface_update[j] = surface_updates_temp; - } + for (i = 0, j = planes_count - 1; i < j; i++, j--) + swap(array_of_surface_update[i], array_of_surface_update[j]); } /** -- cgit From 22f1482aff4aee39e5f3354808bc099084c2b64b Mon Sep 17 00:00:00 2001 From: Shirish S Date: Fri, 10 Mar 2023 11:54:17 +0530 Subject: drm/amd/display: add sysfs entry to read PSR residency from firmware [Why] Currently there aren't any methods to determine PSR state residency. [How] create a sysfs entry for reading residency and internally hook it up to existing functionality of reading PSR residency from firmware. [Hamza: dropped the link.h include and made checkpatch happy] Signed-off-by: Shirish S Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index abf7895d1608..f669f8a16c20 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -2793,6 +2793,22 @@ static int psr_get(void *data, u64 *val) return 0; } +/* + * Read PSR state residency + */ +static int psr_read_residency(void *data, u64 *val) +{ + struct amdgpu_dm_connector *connector = data; + struct dc_link *link = connector->dc_link; + u32 residency; + + link_get_psr_residency(link, &residency); + + *val = (u64)residency; + + return 0; +} + /* * Set dmcub trace event IRQ enable or disable. * Usage to enable dmcub trace event IRQ: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dmcub_trace_event_en @@ -2828,6 +2844,8 @@ DEFINE_DEBUGFS_ATTRIBUTE(dmcub_trace_event_state_fops, dmcub_trace_event_state_g dmcub_trace_event_state_set, "%llu\n"); DEFINE_DEBUGFS_ATTRIBUTE(psr_fops, psr_get, NULL, "%llu\n"); +DEFINE_DEBUGFS_ATTRIBUTE(psr_residency_fops, psr_read_residency, NULL, + "%llu\n"); DEFINE_SHOW_ATTRIBUTE(current_backlight); DEFINE_SHOW_ATTRIBUTE(target_backlight); @@ -2991,6 +3009,8 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector) if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) { debugfs_create_file_unsafe("psr_capability", 0444, dir, connector, &psr_capability_fops); debugfs_create_file_unsafe("psr_state", 0444, dir, connector, &psr_fops); + debugfs_create_file_unsafe("psr_residency", 0444, dir, + connector, &psr_residency_fops); debugfs_create_file("amdgpu_current_backlight_pwm", 0444, dir, connector, ¤t_backlight_fops); debugfs_create_file("amdgpu_target_backlight_pwm", 0444, dir, connector, -- cgit From 28f7e8971846519720a83b85004ddfe33680be92 Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Fri, 17 Feb 2023 16:08:21 -0500 Subject: drm/amd/display: Fix HDCP failing to enable after suspend [Why] On resume some displays are not ready for HDCP, so they will fail if we start the hdcp authentintication too soon. Add a delay so that the displays can be ready before we start. NOTE: Previoulsy this delay was set to 3 seconds but it was causing issues with compliance, 2 seconds should enough for compliance and the s3 resume case. [How] Change the Delay to 2 seconds. Reviewed-by: Aurabindo Pillai Acked-by: Qingqing Zhuo Signed-off-by: Bhawanpreet Lakha Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c index 125012426a92..5536d17306d0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c @@ -562,7 +562,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) link->dp.dp2_enabled = config->dp2_enabled; link->dp.usb4_enabled = config->usb4_enabled; display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION; - link->adjust.auth_delay = 0; + link->adjust.auth_delay = 2; link->adjust.hdcp1.disable = 0; conn_state = aconnector->base.state; -- cgit From 566b6577849fcca743aa63d43793062aba62166c Mon Sep 17 00:00:00 2001 From: Benjamin Cheng Date: Sun, 12 Mar 2023 20:47:39 -0400 Subject: drm/amd/display: Write to correct dirty_rect When FB_DAMAGE_CLIPS are provided in a non-MPO scenario, the loop does not use the counter i. This causes the fill_dc_dity_rect() to always fill dirty_rects[0], causing graphical artifacts when a damage clip aware DRM client sends more than 1 damage clip. Instead, use the flip_addrs->dirty_rect_count which is incremented by fill_dc_dirty_rect() on a successful fill. Fixes: 30ebe41582d1 ("drm/amd/display: add FB_DAMAGE_CLIPS support") Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2453 Signed-off-by: Benjamin Cheng Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 f6d9bbce15b2..92783cb97439 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5127,9 +5127,9 @@ static void fill_dc_dirty_rects(struct drm_plane *plane, for (; flip_addrs->dirty_rect_count < num_clips; clips++) fill_dc_dirty_rect(new_plane_state->plane, - &dirty_rects[i], clips->x1, - clips->y1, clips->x2 - clips->x1, - clips->y2 - clips->y1, + &dirty_rects[flip_addrs->dirty_rect_count], + clips->x1, clips->y1, + clips->x2 - clips->x1, clips->y2 - clips->y1, &flip_addrs->dirty_rect_count, false); return; -- cgit From 4648cf5fc8c78d71ebb22c9fca760062b7747ec4 Mon Sep 17 00:00:00 2001 From: Hamza Mahfooz Date: Wed, 8 Mar 2023 16:14:08 -0500 Subject: drm/amd/display: use a more accurate check in dm_helpers_dp_read_dpcd() We should be checking if drm_dp_dpcd_read() returns the size that we are asking it to read instead of just checking if it is greater than zero. So, compare the return value of drm_dp_dpcd_read() to the requested read size. Reviewed-by: Rodrigo Siqueira Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 8d598b322e5b..9c1e91c2179e 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 @@ -511,8 +511,8 @@ bool dm_helpers_dp_read_dpcd( return false; } - return drm_dp_dpcd_read(&aconnector->dm_dp_aux.aux, address, - data, size) > 0; + return drm_dp_dpcd_read(&aconnector->dm_dp_aux.aux, address, data, + size) == size; } bool dm_helpers_dp_write_dpcd( -- cgit From 728cefa53a36ba378ed4a7f31a0c08289687d824 Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Fri, 17 Feb 2023 16:08:21 -0500 Subject: drm/amd/display: Fix HDCP failing to enable after suspend [Why] On resume some displays are not ready for HDCP, so they will fail if we start the hdcp authentintication too soon. Add a delay so that the displays can be ready before we start. NOTE: Previoulsy this delay was set to 3 seconds but it was causing issues with compliance, 2 seconds should enough for compliance and the s3 resume case. [How] Change the Delay to 2 seconds. Reviewed-by: Aurabindo Pillai Acked-by: Qingqing Zhuo Signed-off-by: Bhawanpreet Lakha Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c index 8e572f07ec47..4abfd2c9679f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c @@ -561,7 +561,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) link->dp.mst_enabled = config->mst_enabled; link->dp.usb4_enabled = config->usb4_enabled; display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION; - link->adjust.auth_delay = 0; + link->adjust.auth_delay = 2; link->adjust.hdcp1.disable = 0; conn_state = aconnector->base.state; -- cgit From 751281c55579f0cb0e56c9797d4663f689909681 Mon Sep 17 00:00:00 2001 From: Benjamin Cheng Date: Sun, 12 Mar 2023 20:47:39 -0400 Subject: drm/amd/display: Write to correct dirty_rect When FB_DAMAGE_CLIPS are provided in a non-MPO scenario, the loop does not use the counter i. This causes the fill_dc_dity_rect() to always fill dirty_rects[0], causing graphical artifacts when a damage clip aware DRM client sends more than 1 damage clip. Instead, use the flip_addrs->dirty_rect_count which is incremented by fill_dc_dirty_rect() on a successful fill. Fixes: 30ebe41582d1 ("drm/amd/display: add FB_DAMAGE_CLIPS support") Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2453 Signed-off-by: Benjamin Cheng Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 6.1.x --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 009ef917dad4..32abbafd43fa 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5105,9 +5105,9 @@ static void fill_dc_dirty_rects(struct drm_plane *plane, for (; flip_addrs->dirty_rect_count < num_clips; clips++) fill_dc_dirty_rect(new_plane_state->plane, - &dirty_rects[i], clips->x1, - clips->y1, clips->x2 - clips->x1, - clips->y2 - clips->y1, + &dirty_rects[flip_addrs->dirty_rect_count], + clips->x1, clips->y1, + clips->x2 - clips->x1, clips->y2 - clips->y1, &flip_addrs->dirty_rect_count, false); return; -- cgit From 54c7b715b5efe405dfd5fdafcaf930214b9c1fa9 Mon Sep 17 00:00:00 2001 From: Fangzhi Zuo Date: Fri, 24 Feb 2023 13:45:21 -0500 Subject: drm/amd/display: Add DSC Support for Synaptics Cascaded MST Hub Traditional synaptics hub has one MST branch device without virtual dpcd. Synaptics cascaded hub has two chained MST branch devices. DSC decoding is performed via root MST branch device, instead of the second MST branch device. Reviewed-by: Hersen Wu Acked-by: Qingqing Zhuo Signed-off-by: Fangzhi Zuo Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 19 +++++++++++++++++++ .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h | 12 ++++++++++++ 2 files changed, 31 insertions(+) (limited to 'drivers/gpu/drm/amd/display') 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 4b9b5e4050fc..9241d48e9d98 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 @@ -208,6 +208,21 @@ bool needs_dsc_aux_workaround(struct dc_link *link) return false; } +bool is_synaptics_cascaded_panamera(struct dc_link *link, struct drm_dp_mst_port *port) +{ + u8 branch_vendor_data[4] = { 0 }; // Vendor data 0x50C ~ 0x50F + + if (drm_dp_dpcd_read(port->mgr->aux, DP_BRANCH_VENDOR_SPECIFIC_START, &branch_vendor_data, 4) == 4) { + if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 && + IS_SYNAPTICS_CASCADED_PANAMERA(link->dpcd_caps.branch_dev_name, branch_vendor_data)) { + DRM_INFO("Synaptics Cascaded MST hub\n"); + return true; + } + } + + return false; +} + static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector) { struct dc_sink *dc_sink = aconnector->dc_sink; @@ -231,6 +246,10 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto needs_dsc_aux_workaround(aconnector->dc_link)) aconnector->dsc_aux = &aconnector->mst_root->dm_dp_aux.aux; + /* synaptics cascaded MST hub case */ + if (!aconnector->dsc_aux && is_synaptics_cascaded_panamera(aconnector->dc_link, port)) + aconnector->dsc_aux = port->mgr->aux; + if (!aconnector->dsc_aux) return false; diff --git 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 index 97fd70df531b..0b5750202e73 100644 --- 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 @@ -34,6 +34,18 @@ #define SYNAPTICS_RC_OFFSET 0x4BC #define SYNAPTICS_RC_DATA 0x4C0 +#define DP_BRANCH_VENDOR_SPECIFIC_START 0x50C + +/** + * Panamera MST Hub detection + * Offset DPCD 050Eh == 0x5A indicates cascaded MST hub case + * Check from beginning of branch device vendor specific field (050Ch) + */ +#define IS_SYNAPTICS_PANAMERA(branchDevName) (((int)branchDevName[4] & 0xF0) == 0x50 ? 1 : 0) +#define BRANCH_HW_REVISION_PANAMERA_A2 0x10 +#define SYNAPTICS_CASCADED_HUB_ID 0x5A +#define IS_SYNAPTICS_CASCADED_PANAMERA(devName, data) ((IS_SYNAPTICS_PANAMERA(devName) && ((int)data[2] == SYNAPTICS_CASCADED_HUB_ID)) ? 1 : 0) + struct amdgpu_display_manager; struct amdgpu_dm_connector; -- cgit From 932698c88dc414e36e0683fbf6cf551b928441ac Mon Sep 17 00:00:00 2001 From: Swapnil Patel Date: Fri, 24 Feb 2023 20:16:09 -0500 Subject: drm/amd/display: default values for luminance range if they are 0 [why] Currently if invalid luminescence range is reported in edid, then the driver doesn't have default range to fallback to. [How] Add default range if, the range is 0. Reviewed-by: Roman Li Acked-by: Qingqing Zhuo Signed-off-by: Swapnil Patel Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 92783cb97439..1629a750dc55 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3007,8 +3007,14 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) caps->aux_support = true; luminance_range = &conn_base->display_info.luminance_range; - caps->aux_min_input_signal = luminance_range->min_luminance; - caps->aux_max_input_signal = luminance_range->max_luminance; + + if (luminance_range->max_luminance) { + caps->aux_min_input_signal = luminance_range->min_luminance; + caps->aux_max_input_signal = luminance_range->max_luminance; + } else { + caps->aux_min_input_signal = 0; + caps->aux_max_input_signal = 512; + } } void amdgpu_dm_update_connector_after_detect( -- cgit From cd487b6d506329917bdd2a594b307aa469a53872 Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Mon, 27 Feb 2023 18:37:34 -0500 Subject: drm/amd/display: Use DPP inst instead of pipe idx for DPP DTO programming [Description] - For pipe harvesting cases we must use DPP inst instead of pipe index for DPP related programming Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c | 38 ++++++++++++++++++++-- .../amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.h | 3 ++ 2 files changed, 39 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c index e686d6610fd4..af108f88b112 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c @@ -255,6 +255,40 @@ static void dcn32_update_dppclk_dispclk_freq(struct clk_mgr_internal *clk_mgr, s } } +void dcn32_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr, + struct dc_state *context, bool safe_to_lower) +{ + int i; + + clk_mgr->dccg->ref_dppclk = clk_mgr->base.clks.dppclk_khz; + for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) { + int dpp_inst, dppclk_khz, prev_dppclk_khz; + + dppclk_khz = context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz; + + if (context->res_ctx.pipe_ctx[i].plane_res.dpp) + dpp_inst = context->res_ctx.pipe_ctx[i].plane_res.dpp->inst; + else if (!context->res_ctx.pipe_ctx[i].plane_res.dpp && dppclk_khz == 0) { + /* dpp == NULL && dppclk_khz == 0 is valid because of pipe harvesting. + * In this case just continue in loop + */ + continue; + } else if (!context->res_ctx.pipe_ctx[i].plane_res.dpp && dppclk_khz > 0) { + /* The software state is not valid if dpp resource is NULL and + * dppclk_khz > 0. + */ + ASSERT(false); + continue; + } + + prev_dppclk_khz = clk_mgr->dccg->pipe_dppclk_khz[i]; + + if (safe_to_lower || prev_dppclk_khz < dppclk_khz) + clk_mgr->dccg->funcs->update_dpp_dto( + clk_mgr->dccg, dpp_inst, dppclk_khz); + } +} + static void dcn32_update_clocks_update_dentist( struct clk_mgr_internal *clk_mgr, struct dc_state *context) @@ -524,7 +558,7 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base, if (dc->config.forced_clocks == false || (force_reset && safe_to_lower)) { if (dpp_clock_lowered) { /* if clock is being lowered, increase DTO before lowering refclk */ - dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); + dcn32_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); dcn32_update_clocks_update_dentist(clk_mgr, context); if (clk_mgr->smu_present) dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DPPCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dppclk_khz)); @@ -536,7 +570,7 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base, * that we do not lower dto when it is not safe to lower. We do not need to * compare the current and new dppclk before calling this function. */ - dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); + dcn32_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); } } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.h index 57e09c7c95f5..186daada7b03 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.h @@ -32,6 +32,9 @@ void dcn32_clk_mgr_construct(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg); +void dcn32_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr, + struct dc_state *context, bool safe_to_lower); + void dcn32_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr); -- cgit From 98ef34186286c457b7fe6a73ece9b279438d645d Mon Sep 17 00:00:00 2001 From: Zhikai Zhai Date: Mon, 27 Feb 2023 19:39:35 +0800 Subject: drm/amd/display: reset the scaler boundary mode [WHY] The VBIOS select the black boundary mode when using auto scale mode. But it doesn't recover if there is no reset. [HOW] Clean the scaler boundary mode to default edge in the manual scale mode. Reviewed-by: Dmytro Laktyushkin Acked-by: Qingqing Zhuo Signed-off-by: Zhikai Zhai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h | 4 ++++ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c | 4 ++++ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.h | 2 ++ 3 files changed, 10 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h index 71b3a6949001..c9e045666dcc 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h @@ -59,6 +59,7 @@ SRI(LB_DATA_FORMAT, DSCL, id), \ SRI(LB_MEMORY_CTRL, DSCL, id), \ SRI(DSCL_AUTOCAL, DSCL, id), \ + SRI(DSCL_CONTROL, DSCL, id), \ SRI(SCL_BLACK_OFFSET, DSCL, id), \ SRI(SCL_TAP_CONTROL, DSCL, id), \ SRI(SCL_COEF_RAM_TAP_SELECT, DSCL, id), \ @@ -209,6 +210,7 @@ TF_SF(DSCL0_DSCL_AUTOCAL, AUTOCAL_MODE, mask_sh),\ TF_SF(DSCL0_DSCL_AUTOCAL, AUTOCAL_NUM_PIPE, mask_sh),\ TF_SF(DSCL0_DSCL_AUTOCAL, AUTOCAL_PIPE_ID, mask_sh),\ + TF_SF(DSCL0_DSCL_CONTROL, SCL_BOUNDARY_MODE, mask_sh),\ TF_SF(DSCL0_SCL_BLACK_OFFSET, SCL_BLACK_OFFSET_RGB_Y, mask_sh),\ TF_SF(DSCL0_SCL_BLACK_OFFSET, SCL_BLACK_OFFSET_CBCR, mask_sh),\ TF_SF(DSCL0_SCL_TAP_CONTROL, SCL_V_NUM_TAPS, mask_sh),\ @@ -495,6 +497,7 @@ type AUTOCAL_MODE; \ type AUTOCAL_NUM_PIPE; \ type AUTOCAL_PIPE_ID; \ + type SCL_BOUNDARY_MODE; \ type SCL_BLACK_OFFSET_RGB_Y; \ type SCL_BLACK_OFFSET_CBCR; \ type SCL_V_NUM_TAPS; \ @@ -1108,6 +1111,7 @@ struct dcn_dpp_mask { uint32_t LB_DATA_FORMAT; \ uint32_t LB_MEMORY_CTRL; \ uint32_t DSCL_AUTOCAL; \ + uint32_t DSCL_CONTROL; \ uint32_t SCL_BLACK_OFFSET; \ uint32_t SCL_TAP_CONTROL; \ uint32_t SCL_COEF_RAM_TAP_SELECT; \ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c index f62368da875d..b33955928bd0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c @@ -655,6 +655,10 @@ void dpp1_dscl_set_scaler_manual_scale(struct dpp *dpp_base, AUTOCAL_NUM_PIPE, 0, AUTOCAL_PIPE_ID, 0); + /*clean scaler boundary mode when Autocal off*/ + REG_SET(DSCL_CONTROL, 0, + SCL_BOUNDARY_MODE, 0); + /* Recout */ dpp1_dscl_set_recout(dpp, &scl_data->recout); diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.h index 6263408d71fc..2082372d69ee 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.h @@ -102,6 +102,7 @@ SRI(LB_DATA_FORMAT, DSCL, id), \ SRI(LB_MEMORY_CTRL, DSCL, id), \ SRI(DSCL_AUTOCAL, DSCL, id), \ + SRI(DSCL_CONTROL, DSCL, id), \ SRI(SCL_TAP_CONTROL, DSCL, id), \ SRI(SCL_COEF_RAM_TAP_SELECT, DSCL, id), \ SRI(SCL_COEF_RAM_TAP_DATA, DSCL, id), \ @@ -237,6 +238,7 @@ TF_SF(DSCL0_LB_MEMORY_CTRL, LB_MAX_PARTITIONS, mask_sh),\ TF_SF(DSCL0_DSCL_AUTOCAL, AUTOCAL_MODE, mask_sh),\ TF_SF(DSCL0_DSCL_AUTOCAL, AUTOCAL_NUM_PIPE, mask_sh),\ + TF_SF(DSCL0_DSCL_CONTROL, SCL_BOUNDARY_MODE, mask_sh),\ TF_SF(DSCL0_DSCL_AUTOCAL, AUTOCAL_PIPE_ID, mask_sh),\ TF_SF(DSCL0_SCL_TAP_CONTROL, SCL_V_NUM_TAPS, mask_sh),\ TF_SF(DSCL0_SCL_TAP_CONTROL, SCL_H_NUM_TAPS, mask_sh),\ -- cgit From 98ce7d32e2154a6676d4dc7e6877af68cebf8832 Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Thu, 23 Feb 2023 17:04:47 -0500 Subject: drm/amd/display: convert link.h functions to function pointer style [Why & How] All dc subcomponents should call another dc component via function pointers stored in a component structure. This is part of dc coding convention since the beginning. The reason behind this is to improve encapsulation and polymorphism. The function contract is extracted into a single link service structure defined in link.h header file and implemented only in link_factory.c instead of spreading across multiple files in link component file structure. Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Wenjing Liu 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_debugfs.c | 2 +- drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 4 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 33 ++- .../gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c | 2 +- .../gpu/drm/amd/display/dc/core/dc_link_exports.c | 34 +-- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 13 +- drivers/gpu/drm/amd/display/dc/dc.h | 13 +- .../amd/display/dc/dce110/dce110_hw_sequencer.c | 60 ++-- .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 6 +- .../amd/display/dc/dcn10/dcn10_stream_encoder.c | 7 +- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 14 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 9 +- .../amd/display/dc/dcn20/dcn20_stream_encoder.c | 3 +- drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c | 4 +- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 2 +- .../gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 9 +- .../drm/amd/display/dc/dcn302/dcn302_resource.c | 9 +- .../drm/amd/display/dc/dcn303/dcn303_resource.c | 9 +- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c | 10 +- .../display/dc/dcn314/dcn314_dio_stream_encoder.c | 2 +- .../gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c | 2 +- .../display/dc/dcn32/dcn32_dio_stream_encoder.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 13 +- .../gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 9 +- .../drm/amd/display/dc/dcn321/dcn321_resource.c | 9 +- .../gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 4 +- .../gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 2 +- drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c | 53 ++++ drivers/gpu/drm/amd/display/dc/inc/link.h | 314 ++++++++++++--------- .../amd/display/dc/link/accessories/link_dp_cts.c | 1 + .../display/dc/link/accessories/link_dp_trace.c | 8 +- .../display/dc/link/accessories/link_dp_trace.h | 5 + .../drm/amd/display/dc/link/hwss/link_hwss_dio.c | 22 +- .../amd/display/dc/link/hwss/link_hwss_hpo_dp.c | 8 +- .../gpu/drm/amd/display/dc/link/link_detection.c | 2 +- .../gpu/drm/amd/display/dc/link/link_detection.h | 9 +- drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 43 +-- drivers/gpu/drm/amd/display/dc/link/link_dpms.h | 23 +- drivers/gpu/drm/amd/display/dc/link/link_factory.c | 313 +++++++++++++++----- drivers/gpu/drm/amd/display/dc/link/link_factory.h | 2 + .../gpu/drm/amd/display/dc/link/link_resource.h | 4 + .../gpu/drm/amd/display/dc/link/link_validation.c | 5 +- .../gpu/drm/amd/display/dc/link/link_validation.h | 7 + .../drm/amd/display/dc/link/protocols/link_ddc.h | 28 ++ .../display/dc/link/protocols/link_dp_capability.c | 10 +- .../display/dc/link/protocols/link_dp_capability.h | 9 + .../amd/display/dc/link/protocols/link_dp_phy.h | 5 + .../display/dc/link/protocols/link_dp_training.c | 6 +- .../dc/link/protocols/link_edp_panel_control.c | 20 +- .../dc/link/protocols/link_edp_panel_control.h | 10 + .../drm/amd/display/dc/link/protocols/link_hpd.h | 3 + 52 files changed, 806 insertions(+), 393 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 1629a750dc55..e0b7ef6d1a62 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7184,13 +7184,14 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) struct edid *edid = amdgpu_dm_connector->edid; struct dc_link_settings *verified_link_cap = &amdgpu_dm_connector->dc_link->verified_link_cap; + const struct dc *dc = amdgpu_dm_connector->dc_link->dc; encoder = amdgpu_dm_connector_to_encoder(connector); if (!drm_edid_is_valid(edid)) { amdgpu_dm_connector->num_modes = drm_add_modes_noedid(connector, 640, 480); - if (link_dp_get_encoding_format(verified_link_cap) == DP_128b_132b_ENCODING) + if (dc->link_srv->dp_get_encoding_format(verified_link_cap) == DP_128b_132b_ENCODING) amdgpu_dm_connector->num_modes += drm_add_modes_noedid(connector, 1920, 1080); } else { diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index f669f8a16c20..827fcb4fb3b3 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -2802,7 +2802,7 @@ static int psr_read_residency(void *data, u64 *val) struct dc_link *link = connector->dc_link; u32 residency; - link_get_psr_residency(link, &residency); + link->dc->link_srv->edp_get_psr_residency(link, &residency); *val = (u64)residency; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c index ee81d36146e4..6127d6045336 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c @@ -116,7 +116,7 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m if (!edp_link->psr_settings.psr_feature_enabled) continue; clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active; - dc_link_set_psr_allow_active(edp_link, &allow_active, false, false, NULL); + dc->link_srv->edp_set_psr_allow_active(edp_link, &allow_active, false, false, NULL); } } @@ -135,7 +135,7 @@ void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr) edp_link = edp_links[panel_inst]; if (!edp_link->psr_settings.psr_feature_enabled) continue; - dc_link_set_psr_allow_active(edp_link, + dc->link_srv->edp_set_psr_allow_active(edp_link, &clk_mgr->psr_allow_active_cache, false, false, NULL); } } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index a5f2f880610d..ae5f1b7b4fef 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -148,7 +148,7 @@ static void destroy_links(struct dc *dc) for (i = 0; i < dc->link_count; i++) { if (NULL != dc->links[i]) - link_destroy(&dc->links[i]); + dc->link_srv->destroy_link(&dc->links[i]); } } @@ -217,7 +217,7 @@ static bool create_links( link_init_params.connector_index = i; link_init_params.link_index = dc->link_count; link_init_params.dc = dc; - link = link_create(&link_init_params); + link = dc->link_srv->create_link(&link_init_params); if (link) { dc->links[dc->link_count] = link; @@ -239,7 +239,7 @@ static bool create_links( link_init_params.dc = dc; link_init_params.is_dpia_link = true; - link = link_create(&link_init_params); + link = dc->link_srv->create_link(&link_init_params); if (link) { dc->links[dc->link_count] = link; link->dc = dc; @@ -823,6 +823,9 @@ static void dc_destruct(struct dc *dc) dc_destroy_resource_pool(dc); + if (dc->link_srv) + link_destroy_link_service(&dc->link_srv); + if (dc->ctx->gpio_service) dal_gpio_service_destroy(&dc->ctx->gpio_service); @@ -982,7 +985,7 @@ static bool dc_construct(struct dc *dc, goto fail; } - dc->link_srv = link_get_link_service(); + dc->link_srv = link_create_link_service(); dc->res_pool = dc_create_resource_pool(dc, init_params, dc_ctx->dce_version); if (!dc->res_pool) @@ -1263,7 +1266,7 @@ static void disable_vbios_mode_if_required( pipe->stream_res.pix_clk_params.requested_pix_clk_100hz; if (pix_clk_100hz != requested_pix_clk_100hz) { - link_set_dpms_off(pipe); + dc->link_srv->set_dpms_off(pipe); pipe->stream->dpms_off = false; } } @@ -1718,7 +1721,7 @@ bool dc_validate_boot_timing(const struct dc *dc, return false; } - if (link_is_edp_ilr_optimization_required(link, crtc_timing)) { + if (dc->link_srv->edp_is_ilr_optimization_required(link, crtc_timing)) { DC_LOG_EVENT_LINK_TRAINING("Seamless boot disabled to optimize eDP link rate\n"); return false; } @@ -3192,7 +3195,9 @@ static void commit_planes_do_stream_update(struct dc *dc, dc->hwss.update_info_frame(pipe_ctx); if (dc_is_dp_signal(pipe_ctx->stream->signal)) - link_dp_source_sequence_trace(pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME); + dc->link_srv->dp_trace_source_sequence( + pipe_ctx->stream->link, + DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME); } if (stream_update->hdr_static_metadata && @@ -3228,13 +3233,15 @@ static void commit_planes_do_stream_update(struct dc *dc, continue; if (stream_update->dsc_config) - link_update_dsc_config(pipe_ctx); + dc->link_srv->update_dsc_config(pipe_ctx); if (stream_update->mst_bw_update) { if (stream_update->mst_bw_update->is_increase) - link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw); + dc->link_srv->increase_mst_payload(pipe_ctx, + stream_update->mst_bw_update->mst_stream_bw); else - link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw); + dc->link_srv->reduce_mst_payload(pipe_ctx, + stream_update->mst_bw_update->mst_stream_bw); } if (stream_update->pending_test_pattern) { @@ -3248,7 +3255,7 @@ static void commit_planes_do_stream_update(struct dc *dc, if (stream_update->dpms_off) { if (*stream_update->dpms_off) { - link_set_dpms_off(pipe_ctx); + dc->link_srv->set_dpms_off(pipe_ctx); /* for dpms, keep acquired resources*/ if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only) pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); @@ -3258,7 +3265,7 @@ static void commit_planes_do_stream_update(struct dc *dc, } else { if (get_seamless_boot_stream_count(context) == 0) dc->hwss.prepare_bandwidth(dc, dc->current_state); - link_set_dpms_on(dc->current_state, pipe_ctx); + dc->link_srv->set_dpms_on(dc->current_state, pipe_ctx); } } @@ -4322,7 +4329,7 @@ void dc_resume(struct dc *dc) uint32_t i; for (i = 0; i < dc->link_count; i++) - link_resume(dc->links[i]); + dc->link_srv->resume(dc->links[i]); } bool dc_is_dmcu_initialized(struct dc *dc) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c index 74e465ba158d..41198c729d90 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c @@ -48,7 +48,7 @@ static bool is_dig_link_enc_stream(struct dc_stream_state *stream) /* DIGs do not support DP2.0 streams with 128b/132b encoding. */ struct dc_link_settings link_settings = {0}; - link_decide_link_settings(stream, &link_settings); + stream->ctx->dc->link_srv->dp_decide_link_settings(stream, &link_settings); if ((link_settings.link_rate >= LINK_RATE_LOW) && link_settings.link_rate <= LINK_RATE_HIGH3) { is_dig_stream = true; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c index 217c80db190d..58fa911b1417 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c @@ -80,67 +80,63 @@ bool dc_get_edp_link_panel_inst(const struct dc *dc, bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) { - return link_detect(link, reason); + return link->dc->link_srv->detect_link(link, reason); } bool dc_link_detect_connection_type(struct dc_link *link, enum dc_connection_type *type) { - return link_detect_connection_type(link, type); + return link->dc->link_srv->detect_connection_type(link, type); } const struct dc_link_status *dc_link_get_status(const struct dc_link *link) { - return link_get_status(link); + return link->dc->link_srv->get_status(link); } /* return true if the connected receiver supports the hdcp version */ bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal) { - return link_is_hdcp14(link, signal); + return link->dc->link_srv->is_hdcp1x_supported(link, signal); } bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal) { - return link_is_hdcp22(link, signal); + return link->dc->link_srv->is_hdcp2x_supported(link, signal); } void dc_link_clear_dprx_states(struct dc_link *link) { - link_clear_dprx_states(link); + link->dc->link_srv->clear_dprx_states(link); } bool dc_link_reset_cur_dp_mst_topology(struct dc_link *link) { - return link_reset_cur_dp_mst_topology(link); + return link->dc->link_srv->reset_cur_dp_mst_topology(link); } uint32_t dc_link_bandwidth_kbps( const struct dc_link *link, const struct dc_link_settings *link_settings) { - return dp_link_bandwidth_kbps(link, link_settings); -} - -uint32_t dc_bandwidth_in_kbps_from_timing( - const struct dc_crtc_timing *timing) -{ - return link_timing_bandwidth_kbps(timing); + return link->dc->link_srv->dp_link_bandwidth_kbps(link, link_settings); } void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map) { - link_get_cur_res_map(dc, map); + dc->link_srv->get_cur_res_map(dc, map); } void dc_restore_link_res_map(const struct dc *dc, uint32_t *map) { - link_restore_res_map(dc, map); + dc->link_srv->restore_res_map(dc, map); } bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx) { - return link_update_dsc_config(pipe_ctx); + struct dc_link *link = pipe_ctx->stream->link; + + return link->dc->link_srv->update_dsc_config(pipe_ctx); } bool dc_is_oem_i2c_device_present( @@ -210,8 +206,8 @@ void dc_link_set_drive_settings(struct dc *dc, { struct link_resource link_res; - link_get_cur_link_res(link, &link_res); - dp_set_drive_settings(link, &link_res, lt_settings); + dc->link_srv->get_cur_link_res(link, &link_res); + dc->link_srv->dp_set_drive_settings(link, &link_res, lt_settings); } void dc_link_set_preferred_link_settings(struct dc *dc, diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 2e3b2fd23b56..85d54bfb595c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -2213,7 +2213,7 @@ enum dc_status dc_remove_stream_from_ctx( del_pipe->stream_res.stream_enc, false); - if (link_is_dp_128b_132b_signal(del_pipe)) { + if (dc->link_srv->dp_is_128b_132b_signal(del_pipe)) { update_hpo_dp_stream_engine_usage( &new_ctx->res_ctx, dc->res_pool, del_pipe->stream_res.hpo_dp_stream_enc, @@ -2513,9 +2513,10 @@ enum dc_status resource_map_pool_resources( * and link settings */ if (dc_is_dp_signal(stream->signal)) { - if (!link_decide_link_settings(stream, &pipe_ctx->link_config.dp_link_settings)) + if (!dc->link_srv->dp_decide_link_settings(stream, &pipe_ctx->link_config.dp_link_settings)) return DC_FAIL_DP_LINK_BANDWIDTH; - if (link_dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) { + if (dc->link_srv->dp_get_encoding_format( + &pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) { pipe_ctx->stream_res.hpo_dp_stream_enc = find_first_free_match_hpo_dp_stream_enc_for_link( &context->res_ctx, pool, stream); @@ -3685,7 +3686,7 @@ enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) /* TODO: validate audio ASIC caps, encoder */ if (res == DC_OK) - res = link_validate_mode_timing(stream, + res = dc->link_srv->validate_mode_timing(stream, link, &stream->timing); @@ -3812,7 +3813,7 @@ bool get_temp_dp_link_res(struct dc_link *link, memset(link_res, 0, sizeof(*link_res)); - if (link_dp_get_encoding_format(link_settings) == DP_128b_132b_ENCODING) { + if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_128b_132b_ENCODING) { link_res->hpo_dp_link_enc = get_temp_hpo_dp_link_enc(res_ctx, dc->res_pool, link); if (!link_res->hpo_dp_link_enc) @@ -4046,7 +4047,7 @@ enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx) { - if (link_dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) { + if (dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) { if (pipe_ctx->stream_res.hpo_dp_stream_enc == NULL) { pipe_ctx->stream_res.hpo_dp_stream_enc = find_first_free_match_hpo_dp_stream_enc_for_link( diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index ccc27d482640..3f25a1620f4f 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -889,7 +889,7 @@ struct dc { uint8_t link_count; struct dc_link *links[MAX_PIPES * 2]; - const struct link_service *link_srv; + struct link_service *link_srv; struct dc_state *current_state; struct resource_pool *res_pool; @@ -1370,6 +1370,11 @@ struct dc_plane_state *dc_get_surface_for_mpcc(struct dc *dc, uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane); +/* The function returns minimum bandwidth required to drive a given timing + * return - minimum required timing bandwidth in kbps. + */ +uint32_t dc_bandwidth_in_kbps_from_timing(const struct dc_crtc_timing *timing); + /* Link Interfaces */ /* * A link contains one or more sinks and their connected status. @@ -1724,12 +1729,6 @@ uint32_t dc_link_bandwidth_kbps( const struct dc_link *link, const struct dc_link_settings *link_setting); -/* The function returns minimum bandwidth required to drive a given timing - * return - minimum required timing bandwidth in kbps. - */ -uint32_t dc_bandwidth_in_kbps_from_timing( - const struct dc_crtc_timing *timing); - /* The function takes a snapshot of current link resource allocation state * @dc: pointer to dc of the dm calling this * @map: a dc link resource snapshot defined internally to dc. diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index cb3bb5402c52..9fe0ce91db00 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -741,7 +741,7 @@ void dce110_edp_wait_for_hpd_ready( /* obtain HPD */ /* TODO what to do with this? */ - hpd = link_get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service); + hpd = ctx->dc->link_srv->get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service); if (!hpd) { BREAK_TO_DEBUGGER(); @@ -809,19 +809,19 @@ void dce110_edp_power_control( div64_u64(dm_get_elapse_time_in_ns( ctx, current_ts, - link_dp_trace_get_edp_poweroff_timestamp(link)), 1000000); + ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link)), 1000000); unsigned long long time_since_edp_poweron_ms = div64_u64(dm_get_elapse_time_in_ns( ctx, current_ts, - link_dp_trace_get_edp_poweron_timestamp(link)), 1000000); + ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link)), 1000000); DC_LOG_HW_RESUME_S3( "%s: transition: power_up=%d current_ts=%llu edp_poweroff=%llu edp_poweron=%llu time_since_edp_poweroff_ms=%llu time_since_edp_poweron_ms=%llu", __func__, power_up, current_ts, - link_dp_trace_get_edp_poweroff_timestamp(link), - link_dp_trace_get_edp_poweron_timestamp(link), + ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link), + ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link), time_since_edp_poweroff_ms, time_since_edp_poweron_ms); @@ -836,7 +836,7 @@ void dce110_edp_power_control( link->panel_config.pps.extra_t12_ms; /* Adjust remaining_min_edp_poweroff_time_ms if this is not the first time. */ - if (link_dp_trace_get_edp_poweroff_timestamp(link) != 0) { + if (ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link) != 0) { if (time_since_edp_poweroff_ms < remaining_min_edp_poweroff_time_ms) remaining_min_edp_poweroff_time_ms = remaining_min_edp_poweroff_time_ms - time_since_edp_poweroff_ms; @@ -896,13 +896,13 @@ void dce110_edp_power_control( __func__, (power_up ? "On":"Off"), bp_result); - link_dp_trace_set_edp_power_timestamp(link, power_up); + ctx->dc->link_srv->dp_trace_set_edp_power_timestamp(link, power_up); DC_LOG_HW_RESUME_S3( "%s: updated values: edp_poweroff=%llu edp_poweron=%llu\n", __func__, - link_dp_trace_get_edp_poweroff_timestamp(link), - link_dp_trace_get_edp_poweron_timestamp(link)); + ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link), + ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link)); if (bp_result != BP_RESULT_OK) DC_LOG_ERROR( @@ -930,14 +930,14 @@ void dce110_edp_wait_for_T12( return; if (!link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl) && - link_dp_trace_get_edp_poweroff_timestamp(link) != 0) { + ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link) != 0) { unsigned int t12_duration = 500; // Default T12 as per spec unsigned long long current_ts = dm_get_timestamp(ctx); unsigned long long time_since_edp_poweroff_ms = div64_u64(dm_get_elapse_time_in_ns( ctx, current_ts, - link_dp_trace_get_edp_poweroff_timestamp(link)), 1000000); + ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link)), 1000000); t12_duration += link->panel_config.pps.extra_t12_ms; // Add extra T12 @@ -1018,7 +1018,7 @@ void dce110_edp_backlight_control( * we shouldn't be doing power-sequencing, hence we can skip * waiting for T7-ready. */ - link_edp_receiver_ready_T7(link); + ctx->dc->link_srv->edp_receiver_ready_T7(link); else DC_LOG_DC("edp_receiver_ready_T7 skipped\n"); } @@ -1049,7 +1049,7 @@ void dce110_edp_backlight_control( if (link->dpcd_sink_ext_caps.bits.oled || link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1) - link_backlight_enable_aux(link, enable); + ctx->dc->link_srv->edp_backlight_enable_aux(link, enable); /*edp 1.2*/ if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) { @@ -1061,7 +1061,7 @@ void dce110_edp_backlight_control( * we shouldn't be doing power-sequencing, hence we can skip * waiting for T9-ready. */ - link_edp_add_delay_for_T9(link); + ctx->dc->link_srv->edp_add_delay_for_T9(link); else DC_LOG_DC("edp_receiver_ready_T9 skipped\n"); } @@ -1161,7 +1161,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) pipe_ctx->stream_res.stream_enc); } - if (link_is_dp_128b_132b_signal(pipe_ctx)) { + if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->stop_dp_info_packets( pipe_ctx->stream_res.hpo_dp_stream_enc); } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) @@ -1172,7 +1172,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) link_hwss->reset_stream_encoder(pipe_ctx); - if (link_is_dp_128b_132b_signal(pipe_ctx)) { + if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { dto_params.otg_inst = tg->inst; dto_params.timing = &pipe_ctx->stream->timing; dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; @@ -1181,7 +1181,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst); } - if (link_is_dp_128b_132b_signal(pipe_ctx)) { + if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { /* TODO: This looks like a bug to me as we are disabling HPO IO when * we are just disabling a single HPO stream. Shouldn't we disable HPO * HW control only when HPOs for all streams are disabled? @@ -1223,7 +1223,7 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx) link->dc->hwss.set_abm_immediate_disable(pipe_ctx); } - if (link_is_dp_128b_132b_signal(pipe_ctx)) { + if (link->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */ pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_blank( pipe_ctx->stream_res.hpo_dp_stream_enc); @@ -1245,7 +1245,7 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx) * we shouldn't be doing power-sequencing, hence we can skip * waiting for T9-ready. */ - link_edp_receiver_ready_T9(link); + link->dc->link_srv->edp_receiver_ready_T9(link); } } } @@ -1428,7 +1428,7 @@ static enum dc_status dce110_enable_stream_timing( if (false == pipe_ctx->clock_source->funcs->program_pix_clk( pipe_ctx->clock_source, &pipe_ctx->stream_res.pix_clk_params, - link_dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings), + dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings), &pipe_ctx->pll_settings)) { BREAK_TO_DEBUGGER(); return DC_ERROR_UNEXPECTED; @@ -1532,7 +1532,7 @@ static enum dc_status apply_single_controller_ctx_to_hw( * To do so, move calling function enable_stream_timing to only be done AFTER calling * function core_link_enable_stream */ - if (!(hws->wa.dp_hpo_and_otg_sequence && link_is_dp_128b_132b_signal(pipe_ctx))) + if (!(hws->wa.dp_hpo_and_otg_sequence && dc->link_srv->dp_is_128b_132b_signal(pipe_ctx))) /* */ /* Do not touch stream timing on seamless boot optimization. */ if (!pipe_ctx->stream->apply_seamless_boot_optimization) @@ -1564,17 +1564,17 @@ static enum dc_status apply_single_controller_ctx_to_hw( pipe_ctx->stream_res.tg->inst); if (dc_is_dp_signal(pipe_ctx->stream->signal)) - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG); + dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG); if (!stream->dpms_off) - link_set_dpms_on(context, pipe_ctx); + dc->link_srv->set_dpms_on(context, pipe_ctx); /* DCN3.1 FPGA Workaround * Need to enable HPO DP Stream Encoder before setting OTG master enable. * To do so, move calling function enable_stream_timing to only be done AFTER calling * function core_link_enable_stream */ - if (hws->wa.dp_hpo_and_otg_sequence && link_is_dp_128b_132b_signal(pipe_ctx)) { + if (hws->wa.dp_hpo_and_otg_sequence && dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { if (!pipe_ctx->stream->apply_seamless_boot_optimization) hws->funcs.enable_stream_timing(pipe_ctx, context, dc); } @@ -1600,7 +1600,7 @@ static void power_down_encoders(struct dc *dc) for (i = 0; i < dc->link_count; i++) { enum signal_type signal = dc->links[i]->connector_signal; - link_blank_dp_stream(dc->links[i], false); + dc->link_srv->blank_dp_stream(dc->links[i], false); if (signal != SIGNAL_TYPE_EDP) signal = SIGNAL_TYPE_NONE; @@ -2083,7 +2083,7 @@ static void dce110_reset_hw_ctx_wrap( * disabled already, no need to disable again. */ if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) { - link_set_dpms_off(pipe_ctx_old); + dc->link_srv->set_dpms_off(pipe_ctx_old); /* free acquired resources*/ if (pipe_ctx_old->stream_res.audio) { @@ -3054,13 +3054,13 @@ void dce110_enable_dp_link_output( pipes[i].clock_source->funcs->program_pix_clk( pipes[i].clock_source, &pipes[i].stream_res.pix_clk_params, - link_dp_get_encoding_format(link_settings), + dc->link_srv->dp_get_encoding_format(link_settings), &pipes[i].pll_settings); } } } - if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) { + if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) { if (dc->clk_mgr->funcs->notify_link_rate_change) dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link); } @@ -3077,7 +3077,7 @@ void dce110_enable_dp_link_output( if (dmcu != NULL && dmcu->funcs->unlock_phy) dmcu->funcs->unlock_phy(dmcu); - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY); + dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY); } void dce110_disable_link_output(struct dc_link *link, @@ -3102,7 +3102,7 @@ void dce110_disable_link_output(struct dc_link *link, link->dc->hwss.edp_power_control(link, false); else if (dmcu != NULL && dmcu->funcs->lock_phy) dmcu->funcs->unlock_phy(dmcu); - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY); + dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY); } static const struct hw_sequencer_funcs dce110_funcs = { 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 5b34066ffcf6..7f9cceb49f4e 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 @@ -919,7 +919,7 @@ enum dc_status dcn10_enable_stream_timing( if (false == pipe_ctx->clock_source->funcs->program_pix_clk( pipe_ctx->clock_source, &pipe_ctx->stream_res.pix_clk_params, - link_dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings), + dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings), &pipe_ctx->pll_settings)) { BREAK_TO_DEBUGGER(); return DC_ERROR_UNEXPECTED; @@ -1017,7 +1017,7 @@ static void dcn10_reset_back_end_for_pipe( * VBIOS lit up eDP, so check link status too. */ if (!pipe_ctx->stream->dpms_off || link->link_status.link_active) - link_set_dpms_off(pipe_ctx); + dc->link_srv->set_dpms_off(pipe_ctx); else if (pipe_ctx->stream_res.audio) dc->hwss.disable_audio_stream(pipe_ctx); @@ -1564,7 +1564,7 @@ void dcn10_init_hw(struct dc *dc) } /* we want to turn off all dp displays before doing detection */ - link_blank_all_dp_displays(dc); + dc->link_srv->blank_all_dp_displays(dc); if (hws->funcs.enable_power_gating_plane) hws->funcs.enable_power_gating_plane(dc->hwseq, true); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c index 2e5f8dc401ff..f496e952ceec 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c @@ -933,7 +933,7 @@ void enc1_stream_encoder_dp_blank( /* disable DP stream */ REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0); - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_DP_VID_STREAM); + link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_DP_VID_STREAM); /* the encoder stops sending the video stream * at the start of the vertical blanking. @@ -952,7 +952,7 @@ void enc1_stream_encoder_dp_blank( REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, true); - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_FIFO_STEER_RESET); + link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_FIFO_STEER_RESET); } /* output video stream to link encoder */ @@ -1025,7 +1025,8 @@ void enc1_stream_encoder_dp_unblank( REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true); - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM); + link->dc->link_srv->dp_trace_source_sequence(link, + DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM); } void enc1_stream_encoder_set_avmute( 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 8b5181f3d13a..53669f832ba5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -720,7 +720,7 @@ enum dc_status dcn20_enable_stream_timing( if (false == pipe_ctx->clock_source->funcs->program_pix_clk( pipe_ctx->clock_source, &pipe_ctx->stream_res.pix_clk_params, - link_dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings), + dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings), &pipe_ctx->pll_settings)) { BREAK_TO_DEBUGGER(); return DC_ERROR_UNEXPECTED; @@ -2405,7 +2405,7 @@ void dcn20_unblank_stream(struct pipe_ctx *pipe_ctx, params.link_settings.link_rate = link_settings->link_rate; - if (link_is_dp_128b_132b_signal(pipe_ctx)) { + if (link->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */ pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_unblank( pipe_ctx->stream_res.hpo_dp_stream_enc, @@ -2458,7 +2458,7 @@ static void dcn20_reset_back_end_for_pipe( * VBIOS lit up eDP, so check link status too. */ if (!pipe_ctx->stream->dpms_off || link->link_status.link_active) - link_set_dpms_off(pipe_ctx); + dc->link_srv->set_dpms_off(pipe_ctx); else if (pipe_ctx->stream_res.audio) dc->hwss.disable_audio_stream(pipe_ctx); @@ -2478,7 +2478,7 @@ static void dcn20_reset_back_end_for_pipe( } } else if (pipe_ctx->stream_res.dsc) { - link_set_dsc_enable(pipe_ctx, false); + dc->link_srv->set_dsc_enable(pipe_ctx, false); } /* by upper caller loop, parent pipe: pipe0, will be reset last. @@ -2713,12 +2713,12 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) unsigned int k1_div = PIXEL_RATE_DIV_NA; unsigned int k2_div = PIXEL_RATE_DIV_NA; - if (link_is_dp_128b_132b_signal(pipe_ctx)) { + if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { if (dc->hwseq->funcs.setup_hpo_hw_control) dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, true); } - if (link_is_dp_128b_132b_signal(pipe_ctx)) { + if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, dp_hpo_inst); @@ -2752,7 +2752,7 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) dc->hwss.update_info_frame(pipe_ctx); if (dc_is_dp_signal(pipe_ctx->stream->signal)) - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME); + dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME); /* enable early control to avoid corruption on DP monitor*/ active_total_with_borders = 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 00668df0938e..77ef474ced07 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -1211,8 +1211,11 @@ static void dcn20_resource_destruct(struct dcn20_resource_pool *pool) if (pool->base.pp_smu != NULL) dcn20_pp_smu_destroy(&pool->base.pp_smu); - if (pool->base.oem_device != NULL) - link_destroy_ddc_service(&pool->base.oem_device); + if (pool->base.oem_device != NULL) { + struct dc *dc = pool->base.oem_device->ctx->dc; + + dc->link_srv->destroy_ddc_service(&pool->base.oem_device); + } } struct hubp *dcn20_hubp_create( @@ -2763,7 +2766,7 @@ static bool dcn20_resource_construct( ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id; ddc_init_data.id.enum_id = 0; ddc_init_data.id.type = OBJECT_TYPE_GENERIC; - pool->base.oem_device = link_create_ddc_service(&ddc_init_data); + pool->base.oem_device = dc->link_srv->create_ddc_service(&ddc_init_data); } else { pool->base.oem_device = NULL; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c index 42865d6c0cdd..0b47aeb60e79 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c @@ -546,7 +546,8 @@ void enc2_stream_encoder_dp_unblank( REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true); - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM); + link->dc->link_srv->dp_trace_source_sequence(link, + DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM); } static void enc2_dp_set_odm_combine( diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c index 15475c7e2cf9..2a182c2f57d6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c @@ -132,8 +132,8 @@ void dcn21_PLAT_58856_wa(struct dc_state *context, struct pipe_ctx *pipe_ctx) return; pipe_ctx->stream->dpms_off = false; - link_set_dpms_on(context, pipe_ctx); - link_set_dpms_off(pipe_ctx); + pipe_ctx->stream->ctx->dc->link_srv->set_dpms_on(context, pipe_ctx); + pipe_ctx->stream->ctx->dc->link_srv->set_dpms_off(pipe_ctx); pipe_ctx->stream->dpms_off = true; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index f8733ff6970e..586de81fc2da 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -532,7 +532,7 @@ void dcn30_init_hw(struct dc *dc) } /* we want to turn off all dp displays before doing detection */ - link_blank_all_dp_displays(dc); + dc->link_srv->blank_all_dp_displays(dc); if (hws->funcs.enable_power_gating_plane) hws->funcs.enable_power_gating_plane(dc->hwseq, true); diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index d60c17d5a0d8..c9e45da6ccd1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -1205,8 +1205,11 @@ static void dcn30_resource_destruct(struct dcn30_resource_pool *pool) if (pool->base.dccg != NULL) dcn_dccg_destroy(&pool->base.dccg); - if (pool->base.oem_device != NULL) - link_destroy_ddc_service(&pool->base.oem_device); + if (pool->base.oem_device != NULL) { + struct dc *dc = pool->base.oem_device->ctx->dc; + + dc->link_srv->destroy_ddc_service(&pool->base.oem_device); + } } static struct hubp *dcn30_hubp_create( @@ -2590,7 +2593,7 @@ static bool dcn30_resource_construct( ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id; ddc_init_data.id.enum_id = 0; ddc_init_data.id.type = OBJECT_TYPE_GENERIC; - pool->base.oem_device = link_create_ddc_service(&ddc_init_data); + pool->base.oem_device = dc->link_srv->create_ddc_service(&ddc_init_data); } else { pool->base.oem_device = NULL; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c index 6ccad53f1e49..9f93c43115ba 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c @@ -1125,8 +1125,11 @@ static void dcn302_resource_destruct(struct resource_pool *pool) if (pool->dccg != NULL) dcn_dccg_destroy(&pool->dccg); - if (pool->oem_device != NULL) - link_destroy_ddc_service(&pool->oem_device); + if (pool->oem_device != NULL) { + struct dc *dc = pool->oem_device->ctx->dc; + + dc->link_srv->destroy_ddc_service(&pool->oem_device); + } } static void dcn302_destroy_resource_pool(struct resource_pool **pool) @@ -1506,7 +1509,7 @@ static bool dcn302_resource_construct( ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id; ddc_init_data.id.enum_id = 0; ddc_init_data.id.type = OBJECT_TYPE_GENERIC; - pool->oem_device = link_create_ddc_service(&ddc_init_data); + pool->oem_device = dc->link_srv->create_ddc_service(&ddc_init_data); } else { pool->oem_device = NULL; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c index 5c28f7151d13..7f72ef882ca4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c @@ -1051,8 +1051,11 @@ static void dcn303_resource_destruct(struct resource_pool *pool) if (pool->dccg != NULL) dcn_dccg_destroy(&pool->dccg); - if (pool->oem_device != NULL) - link_destroy_ddc_service(&pool->oem_device); + if (pool->oem_device != NULL) { + struct dc *dc = pool->oem_device->ctx->dc; + + dc->link_srv->destroy_ddc_service(&pool->oem_device); + } } static void dcn303_destroy_resource_pool(struct resource_pool **pool) @@ -1417,7 +1420,7 @@ static bool dcn303_resource_construct( ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id; ddc_init_data.id.enum_id = 0; ddc_init_data.id.type = OBJECT_TYPE_GENERIC; - pool->oem_device = link_create_ddc_service(&ddc_init_data); + pool->oem_device = dc->link_srv->create_ddc_service(&ddc_init_data); } else { pool->oem_device = NULL; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c index 80a0c5a575a9..10e3cc17f71a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c @@ -202,7 +202,7 @@ void dcn31_init_hw(struct dc *dc) dmub_enable_outbox_notification(dc->ctx->dmub_srv); /* we want to turn off all dp displays before doing detection */ - link_blank_all_dp_displays(dc); + dc->link_srv->blank_all_dp_displays(dc); if (hws->funcs.enable_power_gating_plane) hws->funcs.enable_power_gating_plane(dc->hwseq, true); @@ -230,7 +230,7 @@ void dcn31_init_hw(struct dc *dc) } if (num_opps > 1) { - link_blank_all_edp_displays(dc); + dc->link_srv->blank_all_edp_displays(dc); break; } } @@ -414,7 +414,7 @@ void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx) pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets( pipe_ctx->stream_res.stream_enc, &pipe_ctx->stream_res.encoder_info_frame); - else if (link_is_dp_128b_132b_signal(pipe_ctx)) { + else if (pipe_ctx->stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->update_dp_info_packets( pipe_ctx->stream_res.hpo_dp_stream_enc, &pipe_ctx->stream_res.encoder_info_frame); @@ -565,7 +565,7 @@ static void dcn31_reset_back_end_for_pipe( * VBIOS lit up eDP, so check link status too. */ if (!pipe_ctx->stream->dpms_off || link->link_status.link_active) - link_set_dpms_off(pipe_ctx); + dc->link_srv->set_dpms_off(pipe_ctx); else if (pipe_ctx->stream_res.audio) dc->hwss.disable_audio_stream(pipe_ctx); @@ -584,7 +584,7 @@ static void dcn31_reset_back_end_for_pipe( } } } else if (pipe_ctx->stream_res.dsc) { - link_set_dsc_enable(pipe_ctx, false); + dc->link_srv->set_dsc_enable(pipe_ctx, false); } pipe_ctx->stream = NULL; diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c index 742e43cb8880..467509a65fa7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c @@ -372,7 +372,7 @@ static void enc314_stream_encoder_dp_unblank( */ enc314_enable_fifo(enc); - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM); + link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM); } /* Set DSC-related configuration. diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c index 575d3501c848..bcc03426fc3e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c @@ -346,7 +346,7 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing); odm_combine_factor = get_odm_config(pipe_ctx, NULL); - if (link_is_dp_128b_132b_signal(pipe_ctx)) { + if (stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { *k1_div = PIXEL_RATE_DIV_BY_1; *k2_div = PIXEL_RATE_DIV_BY_1; } else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c index ccf6b181c349..c72448125976 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c @@ -371,7 +371,7 @@ static void enc32_stream_encoder_dp_unblank( REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true); - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM); + link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM); } /* Set DSC-related configuration. diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index f87db2271924..5016b1313f3d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -801,7 +801,7 @@ void dcn32_init_hw(struct dc *dc) hws->funcs.enable_power_gating_plane(dc->hwseq, true); /* we want to turn off all dp displays before doing detection */ - link_blank_all_dp_displays(dc); + dc->link_srv->blank_all_dp_displays(dc); /* If taking control over from VBIOS, we may want to optimize our first * mode set, so we need to skip powering down pipes until we know which @@ -1102,7 +1102,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing); odm_combine_factor = get_odm_config(pipe_ctx, NULL); - if (link_is_dp_128b_132b_signal(pipe_ctx)) { + if (stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { *k1_div = PIXEL_RATE_DIV_BY_1; *k2_div = PIXEL_RATE_DIV_BY_1; } else if (dc_is_hdmi_tmds_signal(stream->signal) || dc_is_dvi_signal(stream->signal)) { @@ -1166,7 +1166,7 @@ void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx, params.link_settings.link_rate = link_settings->link_rate; - if (link_is_dp_128b_132b_signal(pipe_ctx)) { + if (link->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */ pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_unblank( pipe_ctx->stream_res.hpo_dp_stream_enc, @@ -1193,7 +1193,7 @@ bool dcn32_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx) if (!is_h_timing_divisible_by_2(pipe_ctx->stream)) return false; - if (dc_is_dp_signal(pipe_ctx->stream->signal) && !link_is_dp_128b_132b_signal(pipe_ctx) && + if (dc_is_dp_signal(pipe_ctx->stream->signal) && !dc->link_srv->dp_is_128b_132b_signal(pipe_ctx) && dc->debug.enable_dp_dig_pixel_rate_div_policy) return true; return false; @@ -1227,7 +1227,8 @@ static void apply_symclk_on_tx_off_wa(struct dc_link *link) pipe_ctx->clock_source->funcs->program_pix_clk( pipe_ctx->clock_source, &pipe_ctx->stream_res.pix_clk_params, - link_dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings), + dc->link_srv->dp_get_encoding_format( + &pipe_ctx->link_config.dp_link_settings), &pipe_ctx->pll_settings); link->phy_state.symclk_state = SYMCLK_ON_TX_OFF; break; @@ -1259,7 +1260,7 @@ void dcn32_disable_link_output(struct dc_link *link, else if (dmcu != NULL && dmcu->funcs->lock_phy) dmcu->funcs->unlock_phy(dmcu); - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY); + dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY); apply_symclk_on_tx_off_wa(link); } diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index 100b6df33b33..f6f72e7c9e86 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -1505,8 +1505,11 @@ static void dcn32_resource_destruct(struct dcn32_resource_pool *pool) if (pool->base.dccg != NULL) dcn_dccg_destroy(&pool->base.dccg); - if (pool->base.oem_device != NULL) - link_destroy_ddc_service(&pool->base.oem_device); + if (pool->base.oem_device != NULL) { + struct dc *dc = pool->base.oem_device->ctx->dc; + + dc->link_srv->destroy_ddc_service(&pool->base.oem_device); + } } @@ -2451,7 +2454,7 @@ static bool dcn32_resource_construct( ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id; ddc_init_data.id.enum_id = 0; ddc_init_data.id.type = OBJECT_TYPE_GENERIC; - pool->base.oem_device = link_create_ddc_service(&ddc_init_data); + pool->base.oem_device = dc->link_srv->create_ddc_service(&ddc_init_data); } else { pool->base.oem_device = NULL; } 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 0f477d50e935..c6a0e84885a2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c @@ -1490,8 +1490,11 @@ static void dcn321_resource_destruct(struct dcn321_resource_pool *pool) if (pool->base.dccg != NULL) dcn_dccg_destroy(&pool->base.dccg); - if (pool->base.oem_device != NULL) - link_destroy_ddc_service(&pool->base.oem_device); + if (pool->base.oem_device != NULL) { + struct dc *dc = pool->base.oem_device->ctx->dc; + + dc->link_srv->destroy_ddc_service(&pool->base.oem_device); + } } @@ -1995,7 +1998,7 @@ static bool dcn321_resource_construct( ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id; ddc_init_data.id.enum_id = 0; ddc_init_data.id.type = OBJECT_TYPE_GENERIC; - pool->base.oem_device = link_create_ddc_service(&ddc_init_data); + pool->base.oem_device = dc->link_srv->create_ddc_service(&ddc_init_data); } else { pool->base.oem_device = NULL; } 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 f3cfc144e358..38d1f2be8cf3 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 @@ -938,7 +938,7 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context) for (i = 0; i < dc->res_pool->pipe_count; i++) { if (!context->res_ctx.pipe_ctx[i].stream) continue; - if (link_is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i])) + if (dc->link_srv->dp_is_128b_132b_signal(&context->res_ctx.pipe_ctx[i])) return true; } return false; @@ -1341,7 +1341,7 @@ int dcn20_populate_dml_pipes_from_context( case SIGNAL_TYPE_DISPLAY_PORT_MST: case SIGNAL_TYPE_DISPLAY_PORT: pipes[pipe_cnt].dout.output_type = dm_dp; - if (link_is_dp_128b_132b_signal(&res_ctx->pipe_ctx[i])) + if (dc->link_srv->dp_is_128b_132b_signal(&res_ctx->pipe_ctx[i])) pipes[pipe_cnt].dout.output_type = dm_dp2p0; break; case SIGNAL_TYPE_EDP: 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 077674be452b..6b29d3a9520f 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 @@ -1270,7 +1270,7 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context) for (i = 0; i < dc->res_pool->pipe_count; i++) { if (!context->res_ctx.pipe_ctx[i].stream) continue; - if (link_is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i])) + if (dc->link_srv->dp_is_128b_132b_signal(&context->res_ctx.pipe_ctx[i])) return true; } return false; diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c index d9622a0f448a..2bdc47615543 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c @@ -47,6 +47,59 @@ static bool dsc_policy_disable_dsc_stream_overhead; #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) #endif +uint32_t dc_bandwidth_in_kbps_from_timing( + const struct dc_crtc_timing *timing) +{ + uint32_t bits_per_channel = 0; + uint32_t kbps; + + if (timing->flags.DSC) + return dc_dsc_stream_bandwidth_in_kbps(timing, + timing->dsc_cfg.bits_per_pixel, + timing->dsc_cfg.num_slices_h, + timing->dsc_cfg.is_dp); + + switch (timing->display_color_depth) { + case COLOR_DEPTH_666: + bits_per_channel = 6; + break; + case COLOR_DEPTH_888: + bits_per_channel = 8; + break; + case COLOR_DEPTH_101010: + bits_per_channel = 10; + break; + case COLOR_DEPTH_121212: + bits_per_channel = 12; + break; + case COLOR_DEPTH_141414: + bits_per_channel = 14; + break; + case COLOR_DEPTH_161616: + bits_per_channel = 16; + break; + default: + ASSERT(bits_per_channel != 0); + bits_per_channel = 8; + break; + } + + kbps = timing->pix_clk_100hz / 10; + kbps *= bits_per_channel; + + if (timing->flags.Y_ONLY != 1) { + /*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/ + kbps *= 3; + if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) + kbps /= 2; + else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) + kbps = kbps * 2 / 3; + } + + return kbps; +} + + /* Forward Declerations */ static bool decide_dsc_bandwidth_range( const uint32_t min_bpp_x16, diff --git a/drivers/gpu/drm/amd/display/dc/inc/link.h b/drivers/gpu/drm/amd/display/dc/inc/link.h index 45cdf3bce2d3..11aaa7a9518a 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link.h @@ -28,13 +28,58 @@ /* FILE POLICY AND INTENDED USAGE: * - * This header declares link functions exposed to dc. All functions must use - * function pointers. This header is strictly private in dc and should never be - * included by DM. If DM needs to call a new link function, it needs to be - * translated by dc_link_exports.c. + * This header defines link component function interfaces aka link_service. + * link_service provides the only entry point to link functions with function + * pointer style. This header is strictly private in dc and should never be + * included by DM because it exposes too much dc detail including all dc + * private types defined in core_types.h. Otherwise it will break DM - DC + * encapsulation and turn DM into a maintenance nightmare. + * + * The following shows a link component relation map. + * + * DM to DC: + * DM includes dc.h + * dc_link_exports.c or other dc files implement dc.h + * + * DC to Link: + * dc_link_exports.c or other dc files include link.h + * link_factory.c implements link.h + * + * Link sub-component to Link sub-component: + * link_factory.c includes --> link_xxx.h + * link_xxx.c implements link_xxx.h + + * As you can see if you ever need to add a new dc link function and call it on + * DM/dc side, it is very difficult because you will need layers of translation. + * The most appropriate approach to implement new requirements on DM/dc side is + * to extend or generalize the functionality of existing link function + * interfaces so minimal modification is needed outside link component to + * achieve your new requirements. This approach reduces or even eliminates the + * effort needed outside link component to support a new link feature. This also + * reduces code discrepancy among DMs to support the same link feature. If we + * test full code path on one version of DM, and there is no feature specific + * modification required on other DMs, then we can have higher confidence that + * the feature will run on other DMs and produce the same result. The following + * are some good examples to start with: + * + * - detect_link --> to add new link detection or capability retrieval routines + * + * - validate_mode_timing --> to add new timing validation conditions + * + * - set_dpms_on/set_dpms_off --> to include new link enablement sequences + * + * If you must add new link functions, you will need to: + * 1. declare the function pointer here under the suitable commented category. + * 2. Implement your function in the suitable link_xxx.c file. + * 3. Assign the function to link_service in link_factory.c + * 4. NEVER include link_xxx.h headers outside link component. + * 5. NEVER include link.h on DM side. */ #include "core_types.h" +struct link_service *link_create_link_service(void); +void link_destroy_link_service(struct link_service **link_srv); + struct link_init_data { const struct dc *dc; struct dc_context *ctx; /* TODO: remove 'dal' when DC is complete. */ @@ -44,8 +89,24 @@ struct link_init_data { bool is_dpia_link; }; +struct ddc_service_init_data { + struct graphics_object_id id; + struct dc_context *ctx; + struct dc_link *link; + bool is_dpia_link; +}; + struct link_service { - /* Detection */ + /************************** Factory ***********************************/ + struct dc_link *(*create_link)( + const struct link_init_data *init_params); + void (*destroy_link)(struct dc_link **link); + + + /************************** Detection *********************************/ + bool (*detect_link)(struct dc_link *link, enum dc_detect_reason reason); + bool (*detect_connection_type)(struct dc_link *link, + enum dc_connection_type *type); struct dc_sink *(*add_remote_sink)( struct dc_link *link, const uint8_t *edid, @@ -53,24 +114,90 @@ struct link_service { struct dc_sink_init_data *init_data); void (*remove_remote_sink)(struct dc_link *link, struct dc_sink *sink); bool (*get_hpd_state)(struct dc_link *link); + struct gpio *(*get_hpd_gpio)(struct dc_bios *dcb, + struct graphics_object_id link_id, + struct gpio_service *gpio_service); void (*enable_hpd)(const struct dc_link *link); void (*disable_hpd)(const struct dc_link *link); void (*enable_hpd_filter)(struct dc_link *link, bool enable); + bool (*reset_cur_dp_mst_topology)(struct dc_link *link); + const struct dc_link_status *(*get_status)(const struct dc_link *link); + bool (*is_hdcp1x_supported)(struct dc_link *link, + enum signal_type signal); + bool (*is_hdcp2x_supported)(struct dc_link *link, + enum signal_type signal); + void (*clear_dprx_states)(struct dc_link *link); + + + /*************************** Resource *********************************/ + void (*get_cur_res_map)(const struct dc *dc, uint32_t *map); + void (*restore_res_map)(const struct dc *dc, uint32_t *map); + void (*get_cur_link_res)(const struct dc_link *link, + struct link_resource *link_res); + + + /*************************** Validation *******************************/ + enum dc_status (*validate_mode_timing)( + const struct dc_stream_state *stream, + struct dc_link *link, + const struct dc_crtc_timing *timing); + uint32_t (*dp_link_bandwidth_kbps)( + const struct dc_link *link, + const struct dc_link_settings *link_settings); + + + /*************************** DPMS *************************************/ + void (*set_dpms_on)(struct dc_state *state, struct pipe_ctx *pipe_ctx); + void (*set_dpms_off)(struct pipe_ctx *pipe_ctx); + void (*resume)(struct dc_link *link); + void (*blank_all_dp_displays)(struct dc *dc); + void (*blank_all_edp_displays)(struct dc *dc); + void (*blank_dp_stream)(struct dc_link *link, bool hw_init); + enum dc_status (*increase_mst_payload)( + struct pipe_ctx *pipe_ctx, uint32_t req_pbn); + enum dc_status (*reduce_mst_payload)( + struct pipe_ctx *pipe_ctx, uint32_t req_pbn); + void (*set_dsc_on_stream)(struct pipe_ctx *pipe_ctx, bool enable); + bool (*set_dsc_enable)(struct pipe_ctx *pipe_ctx, bool enable); + bool (*update_dsc_config)(struct pipe_ctx *pipe_ctx); - /* DDC */ + + /*************************** DDC **************************************/ + struct ddc_service *(*create_ddc_service)( + struct ddc_service_init_data *ddc_init_data); + void (*destroy_ddc_service)(struct ddc_service **ddc); + bool (*query_ddc_data)( + struct ddc_service *ddc, + uint32_t address, + uint8_t *write_buf, + uint32_t write_size, + uint8_t *read_buf, + uint32_t read_size); int (*aux_transfer_raw)(struct ddc_service *ddc, struct aux_payload *payload, enum aux_return_code_type *operation_result); + bool (*aux_transfer_with_retries_no_mutex)(struct ddc_service *ddc, + struct aux_payload *payload); + bool (*is_in_aux_transaction_mode)(struct ddc_service *ddc); + uint32_t (*get_aux_defer_delay)(struct ddc_service *ddc); + - /* DP Capability */ + /*************************** DP Capability ****************************/ bool (*dp_is_sink_present)(struct dc_link *link); bool (*dp_is_fec_supported)(const struct dc_link *link); + bool (*dp_is_128b_132b_signal)(struct pipe_ctx *pipe_ctx); bool (*dp_get_max_link_enc_cap)(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap); const struct dc_link_settings *(*dp_get_verified_link_cap)( const struct dc_link *link); + enum dp_link_encoding (*dp_get_encoding_format)( + const struct dc_link_settings *link_settings); bool (*dp_should_enable_fec)(const struct dc_link *link); - enum dp_link_encoding (*mst_decide_link_encoding_format)(const struct dc_link *link); + bool (*dp_decide_link_settings)( + struct dc_stream_state *stream, + struct dc_link_settings *link_setting); + enum dp_link_encoding (*mst_decide_link_encoding_format)( + const struct dc_link *link); bool (*edp_decide_link_settings)(struct dc_link *link, struct dc_link_settings *link_setting, uint32_t req_bw); uint32_t (*bw_kbps_from_raw_frl_link_rate_data)(uint8_t bw); @@ -78,12 +205,20 @@ struct link_service { enum lttpr_mode (*dp_decide_lttpr_mode)(struct dc_link *link, struct dc_link_settings *link_setting); - /* DP DPIA/PHY */ - int (*dpia_handle_usb4_bandwidth_allocation_for_link)(struct dc_link *link, int peak_bw); - void (*dpia_handle_bw_alloc_response)(struct dc_link *link, uint8_t bw, uint8_t result); + + /*************************** DP DPIA/PHY ******************************/ + int (*dpia_handle_usb4_bandwidth_allocation_for_link)( + struct dc_link *link, int peak_bw); + void (*dpia_handle_bw_alloc_response)( + struct dc_link *link, uint8_t bw, uint8_t result); + void (*dp_set_drive_settings)( + struct dc_link *link, + const struct link_resource *link_res, + struct link_training_settings *lt_settings); void (*dpcd_write_rx_power_ctrl)(struct dc_link *link, bool on); - /* DP IRQ Handler */ + + /*************************** DP IRQ Handler ***************************/ bool (*dp_parse_link_loss_status)( struct dc_link *link, union hpd_irq_data *hpd_irq_dpcd_data); @@ -93,11 +228,14 @@ struct link_service { struct dc_link *link, union hpd_irq_data *irq_data); bool (*dp_handle_hpd_rx_irq)(struct dc_link *link, - union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss, + union hpd_irq_data *out_hpd_irq_dpcd_data, + bool *out_link_loss, bool defer_handling, bool *has_left_work); - /* eDP Panel Control */ - void (*edp_panel_backlight_power_on)(struct dc_link *link, bool wait_for_hpd); + + /*************************** eDP Panel Control ************************/ + void (*edp_panel_backlight_power_on)( + struct dc_link *link, bool wait_for_hpd); int (*edp_get_backlight_level)(const struct dc_link *link); bool (*edp_get_backlight_level_nits)(struct dc_link *link, uint32_t *backlight_millinits_avg, @@ -110,16 +248,35 @@ struct link_service { uint32_t backlight_millinits, uint32_t transition_time_in_ms); int (*edp_get_target_backlight_pwm)(const struct dc_link *link); - bool (*edp_get_psr_state)(const struct dc_link *link, enum dc_psr_state *state); - bool (*edp_set_psr_allow_active)(struct dc_link *link, const bool *allow_active, - bool wait, bool force_static, const unsigned int *power_opts); + bool (*edp_get_psr_state)( + const struct dc_link *link, enum dc_psr_state *state); + bool (*edp_set_psr_allow_active)( + struct dc_link *link, + const bool *allow_active, + bool wait, + bool force_static, + const unsigned int *power_opts); bool (*edp_setup_psr)(struct dc_link *link, const struct dc_stream_state *stream, struct psr_config *psr_config, struct psr_context *psr_context); + bool (*edp_set_sink_vtotal_in_psr_active)( + const struct dc_link *link, + uint16_t psr_vtotal_idle, + uint16_t psr_vtotal_su); + void (*edp_get_psr_residency)( + const struct dc_link *link, uint32_t *residency); bool (*edp_wait_for_t12)(struct dc_link *link); + bool (*edp_is_ilr_optimization_required)(struct dc_link *link, + struct dc_crtc_timing *crtc_timing); + bool (*edp_backlight_enable_aux)(struct dc_link *link, bool enable); + void (*edp_add_delay_for_T9)(struct dc_link *link); + bool (*edp_receiver_ready_T9)(struct dc_link *link); + bool (*edp_receiver_ready_T7)(struct dc_link *link); + bool (*edp_power_alpm_dpcd_enable)(struct dc_link *link, bool enable); - /* DP CTS */ + + /*************************** DP CTS ************************************/ void (*dp_handle_automated_test)(struct dc_link *link); bool (*dp_set_test_pattern)( struct dc_link *link, @@ -137,7 +294,8 @@ struct link_service { struct dc_link *link, bool skip_immediate_retrain); - /* DP Trace */ + + /*************************** DP Trace *********************************/ bool (*dp_trace_is_initialized)(struct dc_link *link); void (*dp_trace_set_is_logged_flag)(struct dc_link *link, bool in_detection, @@ -148,115 +306,11 @@ struct link_service { const struct dp_trace_lt_counts *(*dp_trace_get_lt_counts)( struct dc_link *link, bool in_detection); unsigned int (*dp_trace_get_link_loss_count)(struct dc_link *link); + void (*dp_trace_set_edp_power_timestamp)(struct dc_link *link, + bool power_up); + uint64_t (*dp_trace_get_edp_poweron_timestamp)(struct dc_link *link); + uint64_t (*dp_trace_get_edp_poweroff_timestamp)(struct dc_link *link); + void (*dp_trace_source_sequence)( + struct dc_link *link, uint8_t dp_test_mode); }; - -struct dc_link *link_create(const struct link_init_data *init_params); -void link_destroy(struct dc_link **link); -const struct link_service *link_get_link_service(void); - -// TODO - convert any function declarations below to function pointers -struct gpio *link_get_hpd_gpio(struct dc_bios *dcb, - struct graphics_object_id link_id, - struct gpio_service *gpio_service); - -struct ddc_service_init_data { - struct graphics_object_id id; - struct dc_context *ctx; - struct dc_link *link; - bool is_dpia_link; -}; - -struct ddc_service *link_create_ddc_service( - struct ddc_service_init_data *ddc_init_data); - -void link_destroy_ddc_service(struct ddc_service **ddc); - -bool link_is_in_aux_transaction_mode(struct ddc_service *ddc); - -bool link_query_ddc_data( - struct ddc_service *ddc, - uint32_t address, - uint8_t *write_buf, - uint32_t write_size, - uint8_t *read_buf, - uint32_t read_size); - - -/* Attempt to submit an aux payload, retrying on timeouts, defers, and busy - * states as outlined in the DP spec. Returns true if the request was - * successful. - * - * NOTE: The function requires explicit mutex on DM side in order to prevent - * potential race condition. DC components should call the dpcd read/write - * function in dm_helpers in order to access dpcd safely - */ -bool link_aux_transfer_with_retries_no_mutex(struct ddc_service *ddc, - struct aux_payload *payload); - -uint32_t link_get_aux_defer_delay(struct ddc_service *ddc); - -bool link_is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx); - -enum dp_link_encoding link_dp_get_encoding_format( - const struct dc_link_settings *link_settings); - -bool link_decide_link_settings( - struct dc_stream_state *stream, - struct dc_link_settings *link_setting); - -void link_dp_trace_set_edp_power_timestamp(struct dc_link *link, - bool power_up); -uint64_t link_dp_trace_get_edp_poweron_timestamp(struct dc_link *link); -uint64_t link_dp_trace_get_edp_poweroff_timestamp(struct dc_link *link); - -bool link_is_edp_ilr_optimization_required(struct dc_link *link, - struct dc_crtc_timing *crtc_timing); - -bool link_backlight_enable_aux(struct dc_link *link, bool enable); -void link_edp_add_delay_for_T9(struct dc_link *link); -bool link_edp_receiver_ready_T9(struct dc_link *link); -bool link_edp_receiver_ready_T7(struct dc_link *link); -bool link_power_alpm_dpcd_enable(struct dc_link *link, bool enable); -bool link_set_sink_vtotal_in_psr_active(const struct dc_link *link, - uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su); -void link_get_psr_residency(const struct dc_link *link, uint32_t *residency); -enum dc_status link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn); -enum dc_status link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn); -void link_blank_all_dp_displays(struct dc *dc); -void link_blank_all_edp_displays(struct dc *dc); -void link_blank_dp_stream(struct dc_link *link, bool hw_init); -void link_resume(struct dc_link *link); -void link_set_dpms_on( - struct dc_state *state, - struct pipe_ctx *pipe_ctx); -void link_set_dpms_off(struct pipe_ctx *pipe_ctx); -void link_dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode); -void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable); -bool link_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable); -bool link_update_dsc_config(struct pipe_ctx *pipe_ctx); -enum dc_status link_validate_mode_timing( - const struct dc_stream_state *stream, - struct dc_link *link, - const struct dc_crtc_timing *timing); -bool link_detect(struct dc_link *link, enum dc_detect_reason reason); -bool link_detect_connection_type(struct dc_link *link, - enum dc_connection_type *type); -const struct dc_link_status *link_get_status(const struct dc_link *link); -/* return true if the connected receiver supports the hdcp version */ -bool link_is_hdcp14(struct dc_link *link, enum signal_type signal); -bool link_is_hdcp22(struct dc_link *link, enum signal_type signal); -void link_clear_dprx_states(struct dc_link *link); -bool link_reset_cur_dp_mst_topology(struct dc_link *link); -uint32_t dp_link_bandwidth_kbps( - const struct dc_link *link, - const struct dc_link_settings *link_settings); -uint32_t link_timing_bandwidth_kbps(const struct dc_crtc_timing *timing); -void link_get_cur_res_map(const struct dc *dc, uint32_t *map); -void link_restore_res_map(const struct dc *dc, uint32_t *map); -void link_get_cur_link_res(const struct dc_link *link, - struct link_resource *link_res); -void dp_set_drive_settings( - struct dc_link *link, - const struct link_resource *link_res, - struct link_training_settings *lt_settings); #endif /* __DC_LINK_HPD_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c index 704373d4d110..db9f1baa27e5 100644 --- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c +++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c @@ -28,6 +28,7 @@ #include "link/protocols/link_dp_training.h" #include "link/protocols/link_dp_phy.h" #include "link/protocols/link_dp_training_fixed_vs_pe_retimer.h" +#include "link/protocols/link_dp_capability.h" #include "link/link_dpms.h" #include "resource.h" #include "dm_helpers.h" diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.c index 277fe9137a97..fbcd8fb58ea8 100644 --- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.c +++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.c @@ -145,7 +145,7 @@ unsigned int dp_trace_get_link_loss_count(struct dc_link *link) return link->dp_trace.link_loss_count; } -void link_dp_trace_set_edp_power_timestamp(struct dc_link *link, +void dp_trace_set_edp_power_timestamp(struct dc_link *link, bool power_up) { if (!power_up) @@ -155,17 +155,17 @@ void link_dp_trace_set_edp_power_timestamp(struct dc_link *link, link->dp_trace.edp_trace_power_timestamps.poweron = dm_get_timestamp(link->dc->ctx); } -uint64_t link_dp_trace_get_edp_poweron_timestamp(struct dc_link *link) +uint64_t dp_trace_get_edp_poweron_timestamp(struct dc_link *link) { return link->dp_trace.edp_trace_power_timestamps.poweron; } -uint64_t link_dp_trace_get_edp_poweroff_timestamp(struct dc_link *link) +uint64_t dp_trace_get_edp_poweroff_timestamp(struct dc_link *link) { return link->dp_trace.edp_trace_power_timestamps.poweroff; } -void link_dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode) +void dp_trace_source_sequence(struct dc_link *link, uint8_t dp_test_mode) { if (link != NULL && link->dc->debug.enable_driver_sequence_debug) core_link_write_dpcd(link, DP_SOURCE_SEQUENCE, diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.h b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.h index 9a0aff81a251..ab437a0c9101 100644 --- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.h +++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.h @@ -54,5 +54,10 @@ unsigned long long dp_trace_get_lt_end_timestamp(struct dc_link *link, const struct dp_trace_lt_counts *dp_trace_get_lt_counts(struct dc_link *link, bool in_detection); unsigned int dp_trace_get_link_loss_count(struct dc_link *link); +void dp_trace_set_edp_power_timestamp(struct dc_link *link, + bool power_up); +uint64_t dp_trace_get_edp_poweron_timestamp(struct dc_link *link); +uint64_t dp_trace_get_edp_poweroff_timestamp(struct dc_link *link); +void dp_trace_source_sequence(struct dc_link *link, uint8_t dp_test_mode); #endif /* __LINK_DP_TRACE_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c index b092b00b3599..bebf9c4c8702 100644 --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c @@ -44,7 +44,7 @@ void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx) link_enc->funcs->connect_dig_be_to_fe(link_enc, pipe_ctx->stream_res.stream_enc->id, true); if (dc_is_dp_signal(pipe_ctx->stream->signal)) - link_dp_source_sequence_trace(pipe_ctx->stream->link, + pipe_ctx->stream->ctx->dc->link_srv->dp_trace_source_sequence(pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE); if (stream_enc->funcs->enable_fifo) stream_enc->funcs->enable_fifo(stream_enc); @@ -63,7 +63,8 @@ void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx) pipe_ctx->stream_res.stream_enc->id, false); if (dc_is_dp_signal(pipe_ctx->stream->signal)) - link_dp_source_sequence_trace(pipe_ctx->stream->link, + pipe_ctx->stream->ctx->dc->link_srv->dp_trace_source_sequence( + pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_DISCONNECT_DIG_FE_BE); } @@ -105,7 +106,8 @@ void setup_dio_stream_attribute(struct pipe_ctx *pipe_ctx) &stream->timing); if (dc_is_dp_signal(stream->signal)) - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR); + link->dc->link_srv->dp_trace_source_sequence(link, + DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR); } void enable_dio_dp_link_output(struct dc_link *link, @@ -126,7 +128,8 @@ void enable_dio_dp_link_output(struct dc_link *link, link_enc, link_settings, clock_source); - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY); + link->dc->link_srv->dp_trace_source_sequence(link, + DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY); } void disable_dio_link_output(struct dc_link *link, @@ -136,7 +139,8 @@ void disable_dio_link_output(struct dc_link *link, struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link); link_enc->funcs->disable_output(link_enc, signal); - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY); + link->dc->link_srv->dp_trace_source_sequence(link, + DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY); } void set_dio_dp_link_test_pattern(struct dc_link *link, @@ -146,7 +150,7 @@ void set_dio_dp_link_test_pattern(struct dc_link *link, struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link); link_enc->funcs->dp_set_phy_pattern(link_enc, tp_params); - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN); + link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN); } void set_dio_dp_lane_settings(struct dc_link *link, @@ -195,7 +199,8 @@ void enable_dio_audio_packet(struct pipe_ctx *pipe_ctx) pipe_ctx->stream_res.stream_enc, false); if (dc_is_dp_signal(pipe_ctx->stream->signal)) - link_dp_source_sequence_trace(pipe_ctx->stream->link, + pipe_ctx->stream->ctx->dc->link_srv->dp_trace_source_sequence( + pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_ENABLE_AUDIO_STREAM); } @@ -214,7 +219,8 @@ void disable_dio_audio_packet(struct pipe_ctx *pipe_ctx) } if (dc_is_dp_signal(pipe_ctx->stream->signal)) - link_dp_source_sequence_trace(pipe_ctx->stream->link, + pipe_ctx->stream->ctx->dc->link_srv->dp_trace_source_sequence( + pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_DISABLE_AUDIO_STREAM); } diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c index aa1c5e253b43..edd7d026a762 100644 --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c @@ -68,7 +68,8 @@ static void set_hpo_dp_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx, struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; struct fixed31_32 h_blank_in_ms, time_slot_in_ms, mtp_cnt_per_h_blank; uint32_t link_bw_in_kbps = - dc_link_bandwidth_kbps(pipe_ctx->stream->link, link_settings); + hpo_dp_stream_encoder->ctx->dc->link_srv->dp_link_bandwidth_kbps( + pipe_ctx->stream->link, link_settings); uint16_t hblank_min_symbol_width = 0; if (link_bw_in_kbps > 0) { @@ -115,7 +116,8 @@ static void setup_hpo_dp_stream_attribute(struct pipe_ctx *pipe_ctx) stream->use_vsc_sdp_for_colorimetry, stream->timing.flags.DSC, false); - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR); + link->dc->link_srv->dp_trace_source_sequence(link, + DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR); } static void enable_hpo_dp_fpga_link_output(struct dc_link *link, @@ -201,7 +203,7 @@ static void set_hpo_dp_link_test_pattern(struct dc_link *link, { link_res->hpo_dp_link_enc->funcs->set_link_test_pattern( link_res->hpo_dp_link_enc, tp_params); - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN); + link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN); } static void set_hpo_dp_lane_settings(struct dc_link *link, diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index a51f761ba018..13e5222249ec 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -876,7 +876,7 @@ static bool detect_link_and_local_sink(struct dc_link *link, return true; } - if (!dc_link_detect_connection_type(link, &new_connection_type)) { + if (!link_detect_connection_type(link, &new_connection_type)) { BREAK_TO_DEBUGGER(); return false; } diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.h b/drivers/gpu/drm/amd/display/dc/link/link_detection.h index 4b1731c4fd3d..7da05078721e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.h +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.h @@ -26,11 +26,18 @@ #ifndef __DC_LINK_DETECTION_H__ #define __DC_LINK_DETECTION_H__ #include "link.h" +bool link_detect(struct dc_link *link, enum dc_detect_reason reason); +bool link_detect_connection_type(struct dc_link *link, + enum dc_connection_type *type); struct dc_sink *link_add_remote_sink( struct dc_link *link, const uint8_t *edid, int len, struct dc_sink_init_data *init_data); void link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink); - +bool link_reset_cur_dp_mst_topology(struct dc_link *link); +const struct dc_link_status *link_get_status(const struct dc_link *link); +bool link_is_hdcp14(struct dc_link *link, enum signal_type signal); +bool link_is_hdcp22(struct dc_link *link, enum signal_type signal); +void link_clear_dprx_states(struct dc_link *link); #endif /* __DC_LINK_DETECTION_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index 00d441cacbff..020d668ce09e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -37,6 +37,7 @@ #include "link_dpms.h" #include "link_hwss.h" +#include "link_validation.h" #include "accessories/link_fpga.h" #include "accessories/link_dp_trace.h" #include "protocols/link_dpcd.h" @@ -672,7 +673,7 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off) /* stream encoder index */ config.stream_enc_idx = pipe_ctx->stream_res.stream_enc->id - ENGINE_ID_DIGA; - if (link_is_dp_128b_132b_signal(pipe_ctx)) + if (dp_is_128b_132b_signal(pipe_ctx)) config.stream_enc_idx = pipe_ctx->stream_res.hpo_dp_stream_enc->id - ENGINE_ID_HPO_DP_0; @@ -681,7 +682,7 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off) /* link encoder index */ config.link_enc_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A; - if (link_is_dp_128b_132b_signal(pipe_ctx)) + if (dp_is_128b_132b_signal(pipe_ctx)) config.link_enc_idx = pipe_ctx->link_res.hpo_dp_link_enc->inst; /* dio output index is dpia index for DPIA endpoint & dcio index by default */ @@ -702,7 +703,7 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off) config.assr_enabled = (panel_mode == DP_PANEL_MODE_EDP) ? 1 : 0; config.mst_enabled = (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) ? 1 : 0; - config.dp2_enabled = link_is_dp_128b_132b_signal(pipe_ctx) ? 1 : 0; + config.dp2_enabled = dp_is_128b_132b_signal(pipe_ctx) ? 1 : 0; config.usb4_enabled = (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) ? 1 : 0; config.dpms_off = dpms_off; @@ -816,7 +817,7 @@ void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) /* Enable DSC in encoder */ if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) - && !link_is_dp_128b_132b_signal(pipe_ctx)) { + && !dp_is_128b_132b_signal(pipe_ctx)) { DC_LOG_DSC("Setting stream encoder DSC config for engine %d:", (int)pipe_ctx->stream_res.stream_enc->id); dsc_optc_config_log(dsc, &dsc_optc_cfg); pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc, @@ -842,7 +843,7 @@ void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) /* disable DSC in stream encoder */ if (dc_is_dp_signal(stream->signal)) { - if (link_is_dp_128b_132b_signal(pipe_ctx)) + if (dp_is_128b_132b_signal(pipe_ctx)) pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet( pipe_ctx->stream_res.hpo_dp_stream_enc, false, @@ -901,7 +902,7 @@ bool link_set_dsc_pps_packet(struct pipe_ctx *pipe_ctx, bool enable, bool immedi memcpy(&stream->dsc_packed_pps[0], &dsc_packed_pps[0], sizeof(stream->dsc_packed_pps)); if (dc_is_dp_signal(stream->signal)) { DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id); - if (link_is_dp_128b_132b_signal(pipe_ctx)) + if (dp_is_128b_132b_signal(pipe_ctx)) pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet( pipe_ctx->stream_res.hpo_dp_stream_enc, true, @@ -918,7 +919,7 @@ bool link_set_dsc_pps_packet(struct pipe_ctx *pipe_ctx, bool enable, bool immedi /* disable DSC PPS in stream encoder */ memset(&stream->dsc_packed_pps[0], 0, sizeof(stream->dsc_packed_pps)); if (dc_is_dp_signal(stream->signal)) { - if (link_is_dp_128b_132b_signal(pipe_ctx)) + if (dp_is_128b_132b_signal(pipe_ctx)) pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet( pipe_ctx->stream_res.hpo_dp_stream_enc, false, @@ -1043,7 +1044,7 @@ static void log_vcp_x_y(const struct dc_link *link, struct fixed31_32 avg_time_s static struct fixed31_32 get_pbn_per_slot(struct dc_stream_state *stream) { struct fixed31_32 mbytes_per_sec; - uint32_t link_rate_in_mbytes_per_sec = dc_link_bandwidth_kbps(stream->link, + uint32_t link_rate_in_mbytes_per_sec = dp_link_bandwidth_kbps(stream->link, &stream->link->cur_link_settings); link_rate_in_mbytes_per_sec /= 8000; /* Kbits to MBytes */ @@ -1534,7 +1535,7 @@ struct fixed31_32 link_calculate_sst_avg_time_slots_per_mtp( { struct fixed31_32 link_bw_effective = dc_fixpt_from_int( - dc_link_bandwidth_kbps(link, &link->cur_link_settings)); + dp_link_bandwidth_kbps(link, &link->cur_link_settings)); struct fixed31_32 timeslot_bw_effective = dc_fixpt_div_int(link_bw_effective, MAX_MTP_SLOT_COUNT); struct fixed31_32 timing_bw = @@ -2122,7 +2123,7 @@ static enum dc_status enable_link_dp(struct dc_state *state, set_default_brightness_aux(link); // TODO: use cached if known if (link->dpcd_sink_ext_caps.bits.oled == 1) msleep(bl_oled_enable_delay); - link_backlight_enable_aux(link, true); + edp_backlight_enable_aux(link, true); } return status; @@ -2242,7 +2243,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx) ASSERT(is_master_pipe_for_link(link, pipe_ctx)); - if (link_is_dp_128b_132b_signal(pipe_ctx)) + if (dp_is_128b_132b_signal(pipe_ctx)) vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg; DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); @@ -2273,7 +2274,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx) if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) deallocate_mst_payload(pipe_ctx); else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT && - link_is_dp_128b_132b_signal(pipe_ctx)) + dp_is_128b_132b_signal(pipe_ctx)) update_sst_payload(pipe_ctx, false); if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) { @@ -2302,7 +2303,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx) } if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT && - !link_is_dp_128b_132b_signal(pipe_ctx)) { + !dp_is_128b_132b_signal(pipe_ctx)) { /* In DP1.x SST mode, our encoder will go to TPS1 * when link is on but stream is off. @@ -2322,7 +2323,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx) if (dc_is_dp_signal(pipe_ctx->stream->signal)) link_set_dsc_enable(pipe_ctx, false); } - if (link_is_dp_128b_132b_signal(pipe_ctx)) { + if (dp_is_128b_132b_signal(pipe_ctx)) { if (pipe_ctx->stream_res.tg->funcs->set_out_mux) pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, OUT_MUX_DIO); } @@ -2346,7 +2347,7 @@ void link_set_dpms_on( ASSERT(is_master_pipe_for_link(link, pipe_ctx)); - if (link_is_dp_128b_132b_signal(pipe_ctx)) + if (dp_is_128b_132b_signal(pipe_ctx)) vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg; DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); @@ -2368,7 +2369,7 @@ void link_set_dpms_on( ASSERT(link_enc); if (!dc_is_virtual_signal(pipe_ctx->stream->signal) - && !link_is_dp_128b_132b_signal(pipe_ctx)) { + && !dp_is_128b_132b_signal(pipe_ctx)) { if (link_enc) link_enc->funcs->setup( link_enc, @@ -2378,7 +2379,7 @@ void link_set_dpms_on( pipe_ctx->stream->link->link_state_valid = true; if (pipe_ctx->stream_res.tg->funcs->set_out_mux) { - if (link_is_dp_128b_132b_signal(pipe_ctx)) + if (dp_is_128b_132b_signal(pipe_ctx)) otg_out_dest = OUT_MUX_HPO_DP; else otg_out_dest = OUT_MUX_DIO; @@ -2401,7 +2402,7 @@ void link_set_dpms_on( dc->hwss.update_info_frame(pipe_ctx); if (dc_is_dp_signal(pipe_ctx->stream->signal)) - link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME); + dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME); /* Do not touch link on seamless boot optimization. */ if (pipe_ctx->stream->apply_seamless_boot_optimization) { @@ -2476,7 +2477,7 @@ void link_set_dpms_on( * from transmitter control. */ if (!(dc_is_virtual_signal(pipe_ctx->stream->signal) || - link_is_dp_128b_132b_signal(pipe_ctx))) + dp_is_128b_132b_signal(pipe_ctx))) if (link_enc) link_enc->funcs->setup( link_enc, @@ -2496,7 +2497,7 @@ void link_set_dpms_on( if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) allocate_mst_payload(pipe_ctx); else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT && - link_is_dp_128b_132b_signal(pipe_ctx)) + dp_is_128b_132b_signal(pipe_ctx)) update_sst_payload(pipe_ctx, true); dc->hwss.unblank_stream(pipe_ctx, @@ -2512,7 +2513,7 @@ void link_set_dpms_on( dc->hwss.enable_audio_stream(pipe_ctx); } else { // if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) - if (link_is_dp_128b_132b_signal(pipe_ctx)) + if (dp_is_128b_132b_signal(pipe_ctx)) dp_fpga_hpo_enable_link_and_stream(state, pipe_ctx); if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.h b/drivers/gpu/drm/amd/display/dc/link/link_dpms.h index 33d312dabdb8..9398f9c1666a 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.h +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.h @@ -27,14 +27,27 @@ #define __DC_LINK_DPMS_H__ #include "link.h" -bool link_set_dsc_pps_packet(struct pipe_ctx *pipe_ctx, - bool enable, bool immediate_update); -struct fixed31_32 link_calculate_sst_avg_time_slots_per_mtp( - const struct dc_stream_state *stream, - const struct dc_link *link); +void link_set_dpms_on( + struct dc_state *state, + struct pipe_ctx *pipe_ctx); +void link_set_dpms_off(struct pipe_ctx *pipe_ctx); +void link_resume(struct dc_link *link); +void link_blank_all_dp_displays(struct dc *dc); +void link_blank_all_edp_displays(struct dc *dc); +void link_blank_dp_stream(struct dc_link *link, bool hw_init); void link_set_all_streams_dpms_off_for_link(struct dc_link *link); void link_get_master_pipes_with_dpms_on(const struct dc_link *link, struct dc_state *state, uint8_t *count, struct pipe_ctx *pipes[MAX_PIPES]); +enum dc_status link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn); +enum dc_status link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn); +bool link_set_dsc_pps_packet(struct pipe_ctx *pipe_ctx, + bool enable, bool immediate_update); +struct fixed31_32 link_calculate_sst_avg_time_slots_per_mtp( + const struct dc_stream_state *stream, + const struct dc_link *link); +void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable); +bool link_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable); +bool link_update_dsc_config(struct pipe_ctx *pipe_ctx); #endif /* __DC_LINK_DPMS_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index d9ce83f0bbef..995032a341b3 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -28,6 +28,9 @@ */ #include "link_factory.h" #include "link_detection.h" +#include "link_resource.h" +#include "link_validation.h" +#include "link_dpms.h" #include "accessories/link_dp_cts.h" #include "accessories/link_dp_trace.h" #include "accessories/link_fpga.h" @@ -49,69 +52,248 @@ DC_LOG_HW_HOTPLUG( \ __VA_ARGS__) -static struct link_service link_srv = { - /* Detection */ - .add_remote_sink = link_add_remote_sink, - .remove_remote_sink = link_remove_remote_sink, - .get_hpd_state = link_get_hpd_state, - .enable_hpd = link_enable_hpd, - .disable_hpd = link_disable_hpd, - .enable_hpd_filter = link_enable_hpd_filter, - - /* DDC */ - .aux_transfer_raw = link_aux_transfer_raw, - - /* DP Capability */ - .dp_is_sink_present = dp_is_sink_present, - .dp_is_fec_supported = dp_is_fec_supported, - .dp_get_max_link_enc_cap = dp_get_max_link_enc_cap, - .dp_get_verified_link_cap = dp_get_verified_link_cap, - .dp_should_enable_fec = dp_should_enable_fec, - .mst_decide_link_encoding_format = mst_decide_link_encoding_format, - .edp_decide_link_settings = edp_decide_link_settings, - .bw_kbps_from_raw_frl_link_rate_data = link_bw_kbps_from_raw_frl_link_rate_data, - .dp_overwrite_extended_receiver_cap = dp_overwrite_extended_receiver_cap, - .dp_decide_lttpr_mode = dp_decide_lttpr_mode, - - /* DP DPIA/PHY */ - .dpia_handle_usb4_bandwidth_allocation_for_link = dpia_handle_usb4_bandwidth_allocation_for_link, - .dpia_handle_bw_alloc_response = dpia_handle_bw_alloc_response, - /* DP IRQ Handler */ - .dp_parse_link_loss_status = dp_parse_link_loss_status, - .dp_should_allow_hpd_rx_irq = dp_should_allow_hpd_rx_irq, - .dp_handle_link_loss = dp_handle_link_loss, - .dp_read_hpd_rx_irq_data = dp_read_hpd_rx_irq_data, - .dp_handle_hpd_rx_irq = dp_handle_hpd_rx_irq, - .dpcd_write_rx_power_ctrl = dpcd_write_rx_power_ctrl, - - /* eDP Panel Control */ - .edp_panel_backlight_power_on = edp_panel_backlight_power_on, - .edp_get_backlight_level = edp_get_backlight_level, - .edp_get_backlight_level_nits = edp_get_backlight_level_nits, - .edp_set_backlight_level = edp_set_backlight_level, - .edp_set_backlight_level_nits = edp_set_backlight_level_nits, - .edp_get_target_backlight_pwm = edp_get_target_backlight_pwm, - .edp_get_psr_state = edp_get_psr_state, - .edp_set_psr_allow_active = edp_set_psr_allow_active, - .edp_setup_psr = edp_setup_psr, - .edp_wait_for_t12 = edp_wait_for_t12, - - /* DP CTS */ - .dp_handle_automated_test = dp_handle_automated_test, - .dp_set_test_pattern = dp_set_test_pattern, - .dp_set_preferred_link_settings = dp_set_preferred_link_settings, - .dp_set_preferred_training_settings = dp_set_preferred_training_settings, - - /* DP Trace */ - .dp_trace_is_initialized = dp_trace_is_initialized, - .dp_trace_set_is_logged_flag = dp_trace_set_is_logged_flag, - .dp_trace_is_logged = dp_trace_is_logged, - .dp_trace_get_lt_end_timestamp = dp_trace_get_lt_end_timestamp, - .dp_trace_get_lt_counts = dp_trace_get_lt_counts, - .dp_trace_get_link_loss_count = dp_trace_get_link_loss_count, -}; - -static enum transmitter translate_encoder_to_transmitter(struct graphics_object_id encoder) +/* link factory owns the creation/destruction of link structures. */ +static void construct_link_service_factory(struct link_service *link_srv) +{ + + link_srv->create_link = link_create; + link_srv->destroy_link = link_destroy; +} + +/* link_detection manages link detection states and receiver states by using + * various link protocols. It also provides helper functions to interpret + * certain capabilities or status based on the states it manages or retrieve + * them directly from connected receivers. + */ +static void construct_link_service_detection(struct link_service *link_srv) +{ + link_srv->detect_link = link_detect; + link_srv->detect_connection_type = link_detect_connection_type; + link_srv->add_remote_sink = link_add_remote_sink; + link_srv->remove_remote_sink = link_remove_remote_sink; + link_srv->get_hpd_state = link_get_hpd_state; + link_srv->get_hpd_gpio = link_get_hpd_gpio; + link_srv->enable_hpd = link_enable_hpd; + link_srv->disable_hpd = link_disable_hpd; + link_srv->enable_hpd_filter = link_enable_hpd_filter; + link_srv->reset_cur_dp_mst_topology = link_reset_cur_dp_mst_topology; + link_srv->get_status = link_get_status; + link_srv->is_hdcp1x_supported = link_is_hdcp14; + link_srv->is_hdcp2x_supported = link_is_hdcp22; + link_srv->clear_dprx_states = link_clear_dprx_states; +} + +/* link resource implements accessors to link resource. */ +static void construct_link_service_resource(struct link_service *link_srv) +{ + link_srv->get_cur_res_map = link_get_cur_res_map; + link_srv->restore_res_map = link_restore_res_map; + link_srv->get_cur_link_res = link_get_cur_link_res; +} + +/* link validation owns timing validation against various link limitations. (ex. + * link bandwidth, receiver capability or our hardware capability) It also + * provides helper functions exposing bandwidth formulas used in validation. + */ +static void construct_link_service_validation(struct link_service *link_srv) +{ + link_srv->validate_mode_timing = link_validate_mode_timing; + link_srv->dp_link_bandwidth_kbps = dp_link_bandwidth_kbps; +} + +/* link dpms owns the programming sequence of stream's dpms state associated + * with the link and link's enable/disable sequences as result of the stream's + * dpms state change. + */ +static void construct_link_service_dpms(struct link_service *link_srv) +{ + link_srv->set_dpms_on = link_set_dpms_on; + link_srv->set_dpms_off = link_set_dpms_off; + link_srv->resume = link_resume; + link_srv->blank_all_dp_displays = link_blank_all_dp_displays; + link_srv->blank_all_edp_displays = link_blank_all_edp_displays; + link_srv->blank_dp_stream = link_blank_dp_stream; + link_srv->increase_mst_payload = link_increase_mst_payload; + link_srv->reduce_mst_payload = link_reduce_mst_payload; + link_srv->set_dsc_on_stream = link_set_dsc_on_stream; + link_srv->set_dsc_enable = link_set_dsc_enable; + link_srv->update_dsc_config = link_update_dsc_config; +} + +/* link ddc implements generic display communication protocols such as i2c, aux + * and scdc. It should not contain any specific applications of these + * protocols such as display capability query, detection, or handshaking such as + * link training. + */ +static void construct_link_service_ddc(struct link_service *link_srv) +{ + link_srv->create_ddc_service = link_create_ddc_service; + link_srv->destroy_ddc_service = link_destroy_ddc_service; + link_srv->query_ddc_data = link_query_ddc_data; + link_srv->aux_transfer_raw = link_aux_transfer_raw; + link_srv->aux_transfer_with_retries_no_mutex = + link_aux_transfer_with_retries_no_mutex; + link_srv->is_in_aux_transaction_mode = link_is_in_aux_transaction_mode; + link_srv->get_aux_defer_delay = link_get_aux_defer_delay; +} + +/* link dp capability implements dp specific link capability retrieval sequence. + * It is responsible for retrieving, parsing, overriding, deciding capability + * obtained from dp link. Link capability consists of encoders, DPRXs, cables, + * retimers, usb and all other possible backend capabilities. + */ +static void construct_link_service_dp_capability(struct link_service *link_srv) +{ + link_srv->dp_is_sink_present = dp_is_sink_present; + link_srv->dp_is_fec_supported = dp_is_fec_supported; + link_srv->dp_is_128b_132b_signal = dp_is_128b_132b_signal; + link_srv->dp_get_max_link_enc_cap = dp_get_max_link_enc_cap; + link_srv->dp_get_verified_link_cap = dp_get_verified_link_cap; + link_srv->dp_get_encoding_format = link_dp_get_encoding_format; + link_srv->dp_should_enable_fec = dp_should_enable_fec; + link_srv->dp_decide_link_settings = link_decide_link_settings; + link_srv->mst_decide_link_encoding_format = + mst_decide_link_encoding_format; + link_srv->edp_decide_link_settings = edp_decide_link_settings; + link_srv->bw_kbps_from_raw_frl_link_rate_data = + link_bw_kbps_from_raw_frl_link_rate_data; + link_srv->dp_overwrite_extended_receiver_cap = + dp_overwrite_extended_receiver_cap; + link_srv->dp_decide_lttpr_mode = dp_decide_lttpr_mode; +} + +/* link dp phy/dpia implements basic dp phy/dpia functionality such as + * enable/disable output and set lane/drive settings. It is responsible for + * maintaining and update software state representing current phy/dpia status + * such as current link settings. + */ +static void construct_link_service_dp_phy_or_dpia(struct link_service *link_srv) +{ + link_srv->dpia_handle_usb4_bandwidth_allocation_for_link = + dpia_handle_usb4_bandwidth_allocation_for_link; + link_srv->dpia_handle_bw_alloc_response = dpia_handle_bw_alloc_response; + link_srv->dp_set_drive_settings = dp_set_drive_settings; + link_srv->dpcd_write_rx_power_ctrl = dpcd_write_rx_power_ctrl; +} + +/* link dp irq handler implements DP HPD short pulse handling sequence according + * to DP specifications + */ +static void construct_link_service_dp_irq_handler(struct link_service *link_srv) +{ + link_srv->dp_parse_link_loss_status = dp_parse_link_loss_status; + link_srv->dp_should_allow_hpd_rx_irq = dp_should_allow_hpd_rx_irq; + link_srv->dp_handle_link_loss = dp_handle_link_loss; + link_srv->dp_read_hpd_rx_irq_data = dp_read_hpd_rx_irq_data; + link_srv->dp_handle_hpd_rx_irq = dp_handle_hpd_rx_irq; +} + +/* link edp panel control implements retrieval and configuration of eDP panel + * features such as PSR and ABM and it also manages specs defined eDP panel + * power sequences. + */ +static void construct_link_service_edp_panel_control(struct link_service *link_srv) +{ + link_srv->edp_panel_backlight_power_on = edp_panel_backlight_power_on; + link_srv->edp_get_backlight_level = edp_get_backlight_level; + link_srv->edp_get_backlight_level_nits = edp_get_backlight_level_nits; + link_srv->edp_set_backlight_level = edp_set_backlight_level; + link_srv->edp_set_backlight_level_nits = edp_set_backlight_level_nits; + link_srv->edp_get_target_backlight_pwm = edp_get_target_backlight_pwm; + link_srv->edp_get_psr_state = edp_get_psr_state; + link_srv->edp_set_psr_allow_active = edp_set_psr_allow_active; + link_srv->edp_setup_psr = edp_setup_psr; + link_srv->edp_set_sink_vtotal_in_psr_active = + edp_set_sink_vtotal_in_psr_active; + link_srv->edp_get_psr_residency = edp_get_psr_residency; + link_srv->edp_wait_for_t12 = edp_wait_for_t12; + link_srv->edp_is_ilr_optimization_required = + edp_is_ilr_optimization_required; + link_srv->edp_backlight_enable_aux = edp_backlight_enable_aux; + link_srv->edp_add_delay_for_T9 = edp_add_delay_for_T9; + link_srv->edp_receiver_ready_T9 = edp_receiver_ready_T9; + link_srv->edp_receiver_ready_T7 = edp_receiver_ready_T7; + link_srv->edp_power_alpm_dpcd_enable = edp_power_alpm_dpcd_enable; +} + +/* link dp cts implements dp compliance test automation protocols and manual + * testing interfaces for debugging and certification purpose. + */ +static void construct_link_service_dp_cts(struct link_service *link_srv) +{ + link_srv->dp_handle_automated_test = dp_handle_automated_test; + link_srv->dp_set_test_pattern = dp_set_test_pattern; + link_srv->dp_set_preferred_link_settings = + dp_set_preferred_link_settings; + link_srv->dp_set_preferred_training_settings = + dp_set_preferred_training_settings; +} + +/* link dp trace implements tracing interfaces for tracking major dp sequences + * including execution status and timestamps + */ +static void construct_link_service_dp_trace(struct link_service *link_srv) +{ + link_srv->dp_trace_is_initialized = dp_trace_is_initialized; + link_srv->dp_trace_set_is_logged_flag = dp_trace_set_is_logged_flag; + link_srv->dp_trace_is_logged = dp_trace_is_logged; + link_srv->dp_trace_get_lt_end_timestamp = dp_trace_get_lt_end_timestamp; + link_srv->dp_trace_get_lt_counts = dp_trace_get_lt_counts; + link_srv->dp_trace_get_link_loss_count = dp_trace_get_link_loss_count; + link_srv->dp_trace_set_edp_power_timestamp = + dp_trace_set_edp_power_timestamp; + link_srv->dp_trace_get_edp_poweron_timestamp = + dp_trace_get_edp_poweron_timestamp; + link_srv->dp_trace_get_edp_poweroff_timestamp = + dp_trace_get_edp_poweroff_timestamp; + link_srv->dp_trace_source_sequence = dp_trace_source_sequence; +} + +static void construct_link_service(struct link_service *link_srv) +{ + /* All link service functions should fall under some sub categories. + * If a new function doesn't perfectly fall under an existing sub + * category, it must be that you are either adding a whole new aspect of + * responsibility to link service or something doesn't belong to link + * service. In that case please contact the arch owner to arrange a + * design review meeting. + */ + construct_link_service_factory(link_srv); + construct_link_service_detection(link_srv); + construct_link_service_resource(link_srv); + construct_link_service_validation(link_srv); + construct_link_service_dpms(link_srv); + construct_link_service_ddc(link_srv); + construct_link_service_dp_capability(link_srv); + construct_link_service_dp_phy_or_dpia(link_srv); + construct_link_service_dp_irq_handler(link_srv); + construct_link_service_edp_panel_control(link_srv); + construct_link_service_dp_cts(link_srv); + construct_link_service_dp_trace(link_srv); +} + +struct link_service *link_create_link_service(void) +{ + struct link_service *link_srv = kzalloc(sizeof(*link_srv), GFP_KERNEL); + + if (link_srv == NULL) + goto fail; + + construct_link_service(link_srv); + + return link_srv; +fail: + return NULL; +} + +void link_destroy_link_service(struct link_service **link_srv) +{ + kfree(*link_srv); + *link_srv = NULL; +} + +static enum transmitter translate_encoder_to_transmitter( + struct graphics_object_id encoder) { switch (encoder.id) { case ENCODER_ID_INTERNAL_UNIPHY: @@ -646,8 +828,3 @@ void link_destroy(struct dc_link **link) kfree(*link); *link = NULL; } - -const struct link_service *link_get_link_service(void) -{ - return &link_srv; -} diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.h b/drivers/gpu/drm/amd/display/dc/link/link_factory.h index 5b846147c4a6..e96220d48d03 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.h +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.h @@ -25,5 +25,7 @@ #ifndef __LINK_FACTORY_H__ #define __LINK_FACTORY_H__ #include "link.h" +struct dc_link *link_create(const struct link_init_data *init_params); +void link_destroy(struct dc_link **link); #endif /* __LINK_FACTORY_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_resource.h b/drivers/gpu/drm/amd/display/dc/link/link_resource.h index 68dfbfc973cc..1907bda3cb6e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_resource.h +++ b/drivers/gpu/drm/amd/display/dc/link/link_resource.h @@ -25,4 +25,8 @@ #ifndef __LINK_RESOURCE_H__ #define __LINK_RESOURCE_H__ #include "link.h" +void link_get_cur_res_map(const struct dc *dc, uint32_t *map); +void link_restore_res_map(const struct dc *dc, uint32_t *map); +void link_get_cur_link_res(const struct dc_link *link, + struct link_resource *link_res); #endif /* __LINK_RESOURCE_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_validation.c b/drivers/gpu/drm/amd/display/dc/link/link_validation.c index 62aa5f6b1f0c..9a5010f86003 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_validation.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_validation.c @@ -255,8 +255,7 @@ uint32_t dp_link_bandwidth_kbps( return link_rate_per_lane_kbps * link_settings->lane_count / 10000 * total_data_bw_efficiency_x10000; } -uint32_t link_timing_bandwidth_kbps( - const struct dc_crtc_timing *timing) +uint32_t link_timing_bandwidth_kbps(const struct dc_crtc_timing *timing) { uint32_t bits_per_channel = 0; uint32_t kbps; @@ -337,7 +336,7 @@ static bool dp_validate_mode_timing( */ req_bw = dc_bandwidth_in_kbps_from_timing(timing); - max_bw = dc_link_bandwidth_kbps(link, link_setting); + max_bw = dp_link_bandwidth_kbps(link, link_setting); if (req_bw <= max_bw) { /* remember the biggest mode here, during diff --git a/drivers/gpu/drm/amd/display/dc/link/link_validation.h b/drivers/gpu/drm/amd/display/dc/link/link_validation.h index ab6a44f50032..2191d3a4950c 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_validation.h +++ b/drivers/gpu/drm/amd/display/dc/link/link_validation.h @@ -25,4 +25,11 @@ #ifndef __LINK_VALIDATION_H__ #define __LINK_VALIDATION_H__ #include "link.h" +enum dc_status link_validate_mode_timing( + const struct dc_stream_state *stream, + struct dc_link *link, + const struct dc_crtc_timing *timing); +uint32_t dp_link_bandwidth_kbps( + const struct dc_link *link, + const struct dc_link_settings *link_settings); #endif /* __LINK_VALIDATION_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h index f002fa01508e..860ef15d7f1b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h @@ -37,13 +37,41 @@ #define EDID_SEGMENT_SIZE 256 +struct ddc_service *link_create_ddc_service( + struct ddc_service_init_data *ddc_init_data); + +void link_destroy_ddc_service(struct ddc_service **ddc); + void set_ddc_transaction_type( struct ddc_service *ddc, enum ddc_transaction_type type); +uint32_t link_get_aux_defer_delay(struct ddc_service *ddc); + +bool link_is_in_aux_transaction_mode(struct ddc_service *ddc); + bool try_to_configure_aux_timeout(struct ddc_service *ddc, uint32_t timeout); +bool link_query_ddc_data( + struct ddc_service *ddc, + uint32_t address, + uint8_t *write_buf, + uint32_t write_size, + uint8_t *read_buf, + uint32_t read_size); + +/* Attempt to submit an aux payload, retrying on timeouts, defers, and busy + * states as outlined in the DP spec. Returns true if the request was + * successful. + * + * NOTE: The function requires explicit mutex on DM side in order to prevent + * potential race condition. DC components should call the dpcd read/write + * function in dm_helpers in order to access dpcd safely + */ +bool link_aux_transfer_with_retries_no_mutex(struct ddc_service *ddc, + struct aux_payload *payload); + void write_scdc_data( struct ddc_service *ddc_service, uint32_t pix_clk, diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index 75e1a687608a..e9bcb35ae185 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -347,7 +347,7 @@ bool dp_should_enable_fec(const struct dc_link *link) return !force_disable && dp_is_fec_supported(link); } -bool link_is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx) +bool dp_is_128b_132b_signal(struct pipe_ctx *pipe_ctx) { /* If this assert is hit then we have a link encoder dynamic management issue */ ASSERT(pipe_ctx->stream_res.hpo_dp_stream_enc ? pipe_ctx->link_res.hpo_dp_link_enc != NULL : true); @@ -656,7 +656,7 @@ static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_setting */ while (current_link_setting.link_rate <= link->verified_link_cap.link_rate) { - link_bw = dc_link_bandwidth_kbps( + link_bw = dp_link_bandwidth_kbps( link, ¤t_link_setting); if (req_bw <= link_bw) { @@ -712,7 +712,7 @@ bool edp_decide_link_settings(struct dc_link *link, */ while (current_link_setting.link_rate <= link->verified_link_cap.link_rate) { - link_bw = dc_link_bandwidth_kbps( + link_bw = dp_link_bandwidth_kbps( link, ¤t_link_setting); if (req_bw <= link_bw) { @@ -891,7 +891,7 @@ bool link_decide_link_settings(struct dc_stream_state *stream, struct dc_link_settings *link_setting) { struct dc_link *link = stream->link; - uint32_t req_bw = link_timing_bandwidth_kbps(&stream->timing); + uint32_t req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing); memset(link_setting, 0, sizeof(*link_setting)); @@ -924,7 +924,7 @@ bool link_decide_link_settings(struct dc_stream_state *stream, tmp_link_setting.link_rate = LINK_RATE_UNKNOWN; tmp_timing.flags.DSC = 0; - orig_req_bw = link_timing_bandwidth_kbps(&tmp_timing); + orig_req_bw = dc_bandwidth_in_kbps_from_timing(&tmp_timing); edp_decide_link_settings(link, &tmp_link_setting, orig_req_bw); max_link_rate = tmp_link_setting.link_rate; } diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h index 62980ae17d41..8f0ce97f2362 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h @@ -40,6 +40,9 @@ bool dp_get_max_link_enc_cap(const struct dc_link *link, const struct dc_link_settings *dp_get_verified_link_cap( const struct dc_link *link); +enum dp_link_encoding link_dp_get_encoding_format( + const struct dc_link_settings *link_settings); + enum dc_status dp_retrieve_lttpr_cap(struct dc_link *link); /* Convert PHY repeater count read from DPCD uint8_t. */ @@ -59,12 +62,18 @@ void dpcd_write_cable_id_to_dprx(struct dc_link *link); bool dp_should_enable_fec(const struct dc_link *link); +bool dp_is_128b_132b_signal(struct pipe_ctx *pipe_ctx); + /* Initialize output parameter lt_settings. */ void dp_decide_training_settings( struct dc_link *link, const struct dc_link_settings *link_setting, struct link_training_settings *lt_settings); +bool link_decide_link_settings( + struct dc_stream_state *stream, + struct dc_link_settings *link_setting); + bool edp_decide_link_settings(struct dc_link *link, struct dc_link_settings *link_setting, uint32_t req_bw); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h index 207bff2ec32e..1eb0619d6710 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h @@ -44,6 +44,11 @@ void dp_set_hw_lane_settings( const struct link_training_settings *link_settings, uint32_t offset); +void dp_set_drive_settings( + struct dc_link *link, + const struct link_resource *link_res, + struct link_training_settings *lt_settings); + enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index eee1853f6b32..a9025671ee4a 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -42,6 +42,7 @@ #include "link_dp_capability.h" #include "link_edp_panel_control.h" #include "link/link_detection.h" +#include "link/link_validation.h" #include "atomfirmware.h" #include "link_enc_cfg.h" #include "resource.h" @@ -861,8 +862,9 @@ static enum dc_status configure_lttpr_mode_non_transparent( uint8_t repeater_id; enum dc_status result = DC_ERROR_UNEXPECTED; uint8_t repeater_mode = DP_PHY_REPEATER_MODE_TRANSPARENT; + const struct dc *dc = link->dc; - enum dp_link_encoding encoding = link_dp_get_encoding_format(<_settings->link_settings); + enum dp_link_encoding encoding = dc->link_srv->dp_get_encoding_format(<_settings->link_settings); if (encoding == DP_8b_10b_ENCODING) { DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Transparent Mode\n", __func__); @@ -1675,7 +1677,7 @@ bool perform_link_training_with_retries( /* Flag if reduced link bandwidth no longer meets stream requirements or fallen back to * minimum link bandwidth. */ - req_bw = link_timing_bandwidth_kbps(&stream->timing); + req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing); link_bw = dp_link_bandwidth_kbps(link, &cur_link_settings); is_link_bw_low = (req_bw > link_bw); is_link_bw_min = ((cur_link_settings.link_rate <= LINK_RATE_LOW) && diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index 4d78ac932845..93a6bbe954bb 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -201,7 +201,7 @@ bool edp_get_backlight_level_nits(struct dc_link *link, return true; } -bool link_backlight_enable_aux(struct dc_link *link, bool enable) +bool edp_backlight_enable_aux(struct dc_link *link, bool enable) { uint8_t backlight_enable = enable ? 1 : 0; @@ -249,7 +249,7 @@ bool set_default_brightness_aux(struct dc_link *link) return false; } -bool link_is_edp_ilr_optimization_required(struct dc_link *link, +bool edp_is_ilr_optimization_required(struct dc_link *link, struct dc_crtc_timing *crtc_timing) { struct dc_link_settings link_setting; @@ -282,7 +282,7 @@ bool link_is_edp_ilr_optimization_required(struct dc_link *link, core_link_read_dpcd(link, DP_LANE_COUNT_SET, &lane_count_set.raw, sizeof(lane_count_set)); - req_bw = link_timing_bandwidth_kbps(crtc_timing); + req_bw = dc_bandwidth_in_kbps_from_timing(crtc_timing); if (!crtc_timing->flags.DSC) edp_decide_link_settings(link, &link_setting, req_bw); @@ -322,13 +322,13 @@ bool edp_wait_for_t12(struct dc_link *link) return false; } -void link_edp_add_delay_for_T9(struct dc_link *link) +void edp_add_delay_for_T9(struct dc_link *link) { if (link && link->panel_config.pps.extra_delay_backlight_off > 0) fsleep(link->panel_config.pps.extra_delay_backlight_off * 1000); } -bool link_edp_receiver_ready_T9(struct dc_link *link) +bool edp_receiver_ready_T9(struct dc_link *link) { unsigned int tries = 0; unsigned char sinkstatus = 0; @@ -353,7 +353,7 @@ bool link_edp_receiver_ready_T9(struct dc_link *link) return result; } -bool link_edp_receiver_ready_T7(struct dc_link *link) +bool edp_receiver_ready_T7(struct dc_link *link) { unsigned char sinkstatus = 0; unsigned char edpRev = 0; @@ -388,7 +388,7 @@ bool link_edp_receiver_ready_T7(struct dc_link *link) return result; } -bool link_power_alpm_dpcd_enable(struct dc_link *link, bool enable) +bool edp_power_alpm_dpcd_enable(struct dc_link *link, bool enable) { bool ret = false; union dpcd_alpm_configuration alpm_config; @@ -623,7 +623,7 @@ bool edp_setup_psr(struct dc_link *link, sizeof(psr_configuration.raw)); if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) { - link_power_alpm_dpcd_enable(link, true); + edp_power_alpm_dpcd_enable(link, true); psr_context->su_granularity_required = psr_config->su_granularity_required; psr_context->su_y_granularity = @@ -752,7 +752,7 @@ bool edp_setup_psr(struct dc_link *link, } -void link_get_psr_residency(const struct dc_link *link, uint32_t *residency) +void edp_get_psr_residency(const struct dc_link *link, uint32_t *residency) { struct dc *dc = link->ctx->dc; struct dmub_psr *psr = dc->res_pool->psr; @@ -767,7 +767,7 @@ void link_get_psr_residency(const struct dc_link *link, uint32_t *residency) else *residency = 0; } -bool link_set_sink_vtotal_in_psr_active(const struct dc_link *link, uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su) +bool edp_set_sink_vtotal_in_psr_active(const struct dc_link *link, uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su) { struct dc *dc = link->ctx->dc; struct dmub_psr *psr = dc->res_pool->psr; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h index 4439598f9f7d..28f552080558 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h @@ -49,5 +49,15 @@ bool edp_set_psr_allow_active(struct dc_link *link, const bool *allow_active, bool edp_setup_psr(struct dc_link *link, const struct dc_stream_state *stream, struct psr_config *psr_config, struct psr_context *psr_context); +bool edp_set_sink_vtotal_in_psr_active(const struct dc_link *link, + uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su); +void edp_get_psr_residency(const struct dc_link *link, uint32_t *residency); bool edp_wait_for_t12(struct dc_link *link); +bool edp_is_ilr_optimization_required(struct dc_link *link, + struct dc_crtc_timing *crtc_timing); +bool edp_backlight_enable_aux(struct dc_link *link, bool enable); +void edp_add_delay_for_T9(struct dc_link *link); +bool edp_receiver_ready_T9(struct dc_link *link); +bool edp_receiver_ready_T7(struct dc_link *link); +bool edp_power_alpm_dpcd_enable(struct dc_link *link, bool enable); #endif /* __DC_LINK_EDP_POWER_CONTROL_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.h index bd471b63476e..4fb526b264f9 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.h @@ -45,6 +45,9 @@ bool program_hpd_filter(const struct dc_link *link); bool dpia_query_hpd_status(struct dc_link *link); bool query_hpd_status(struct dc_link *link, uint32_t *is_hpd_high); bool link_get_hpd_state(struct dc_link *link); +struct gpio *link_get_hpd_gpio(struct dc_bios *dcb, + struct graphics_object_id link_id, + struct gpio_service *gpio_service); void link_enable_hpd(const struct dc_link *link); void link_disable_hpd(const struct dc_link *link); void link_enable_hpd_filter(struct dc_link *link, bool enable); -- cgit From 5d04d13954479292dd45e38a46dfa31abb8dc2e0 Mon Sep 17 00:00:00 2001 From: Saaem Rizvi Date: Mon, 27 Feb 2023 18:55:07 -0500 Subject: drm/amd/display: Remove OTG DIV register write for Virtual signals. [WHY] Hot plugging and then hot unplugging leads to k1 and k2 values to change, as signal is detected as a virtual signal on hot unplug. Writing these values to OTG_PIXEL_RATE_DIV register might cause primary display to blank (known hw bug). [HOW] No longer write k1 and k2 values to register if signal is virtual, we have safe guards in place in the case that k1 and k2 is unassigned so that an unknown value is not written to the register either. Cc: stable@vger.kernel.org Cc: Mario Limonciello Reviewed-by: Samson Tam Reviewed-by: Alvin Lee Acked-by: Qingqing Zhuo Signed-off-by: Saaem Rizvi Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index 5016b1313f3d..f9073b722b36 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -1111,7 +1111,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign *k2_div = PIXEL_RATE_DIV_BY_2; else *k2_div = PIXEL_RATE_DIV_BY_4; - } else if (dc_is_dp_signal(stream->signal) || dc_is_virtual_signal(stream->signal)) { + } else if (dc_is_dp_signal(stream->signal)) { if (two_pix_per_container) { *k1_div = PIXEL_RATE_DIV_BY_1; *k2_div = PIXEL_RATE_DIV_BY_2; -- cgit From d142d4113fd5c3f7afdb48dff4703ae7edddf53d Mon Sep 17 00:00:00 2001 From: Mustapha Ghaddar Date: Mon, 27 Feb 2023 08:04:39 -0500 Subject: drm/amd/display: Add Validate BW for USB4 Links [WHY] To validate the BW used for DPIAs per HostRouter [HOW] Add the Validate function in C source file Reviewed-by: Wenjing Liu Acked-by: Qingqing Zhuo Signed-off-by: Mustapha Ghaddar Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../display/dc/link/protocols/link_dp_dpia_bw.c | 34 ++++++++++++++++++++++ .../display/dc/link/protocols/link_dp_dpia_bw.h | 14 +++++++++ 2 files changed, 48 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index 2f0311c42f90..2e251dcbb022 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -33,6 +33,10 @@ #define DC_LOGGER \ link->ctx->logger +/* Number of Host Routers per motherboard is 2 */ +#define MAX_HR_NUM 2 +/* Number of DPIA per host router is 2 */ +#define MAX_DPIA_NUM (MAX_HR_NUM * 2) #define Kbps_TO_Gbps (1000 * 1000) // ------------------------------------------------------------------ @@ -458,3 +462,33 @@ int link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int re out: return ret; } +bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed_per_dpia, uint8_t num_dpias) +{ + bool ret = true; + int bw_needed_per_hr[MAX_HR_NUM] = { 0, 0 }; + uint8_t lowest_dpia_index = 0, dpia_index = 0; + + if (!num_dpias || num_dpias > MAX_DPIA_NUM) + return ret; + + //Get total Host Router BW & Validate against each Host Router max BW + for (uint8_t i = 0; i < num_dpias; ++i) { + + if (!link[i]->dpia_bw_alloc_config.bw_alloc_enabled) + continue; + + lowest_dpia_index = get_lowest_dpia_index(link[i]); + if (link[i]->link_index < lowest_dpia_index) + continue; + + dpia_index = (link[i]->link_index - lowest_dpia_index) / 2; + bw_needed_per_hr[dpia_index] += bw_needed_per_dpia[i]; + if (bw_needed_per_hr[dpia_index] > get_host_router_total_bw(link[i], HOST_ROUTER_BW_ALLOCATED)) { + + ret = false; + break; + } + } + + return ret; +} 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 cfb255b63dd1..382616c8b698 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 @@ -25,7 +25,9 @@ #ifndef DC_INC_LINK_DP_DPIA_BW_H_ #define DC_INC_LINK_DP_DPIA_BW_H_ + #include "link.h" + /* * Host Router BW type */ @@ -80,4 +82,16 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea */ void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result); +/* + * Handle the validation of total BW here and confirm that the bw used by each + * DPIA doesn't exceed available BW for each host router (HR) + * + * @link[]: array of link pointer to all possible DPIA links + * @bw_needed[]: bw needed for each DPIA link based on timing + * @num_dpias: Number of DPIAs for the above 2 arrays. Should always be <= MAX_DPIA_NUM + * + * return: TRUE if bw used by DPIAs doesn't exceed available BW else return FALSE + */ +bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed, uint8_t num_dpias); + #endif /* DC_INC_LINK_DP_DPIA_BW_H_ */ -- cgit From 2792f98cdb1c8fa43bf4ee5ae00349b823a823b7 Mon Sep 17 00:00:00 2001 From: Fangzhi Zuo Date: Tue, 28 Feb 2023 21:34:58 -0500 Subject: drm/amd/display: Take FEC Overhead into Timeslot Calculation 8b/10b encoding needs to add 3% fec overhead into the pbn. In the Synapcis Cascaded MST hub, the first stage MST branch device needs the information to determine the timeslot count for the second stage MST branch device. Missing this overhead will leads to insufficient timeslot allocation. Cc: stable@vger.kernel.org Cc: Mario Limonciello Reviewed-by: Hersen Wu Acked-by: Qingqing Zhuo Signed-off-by: Fangzhi Zuo Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 32 ++++++++++++++++------ .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.h | 3 ++ 2 files changed, 27 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 9241d48e9d98..6378352346c8 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 @@ -670,12 +670,25 @@ struct dsc_mst_fairness_params { struct amdgpu_dm_connector *aconnector; }; -static int kbps_to_peak_pbn(int kbps) +static uint16_t get_fec_overhead_multiplier(struct dc_link *dc_link) +{ + u8 link_coding_cap; + uint16_t fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B; + + link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(dc_link); + if (link_coding_cap == DP_128b_132b_ENCODING) + fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B; + + return fec_overhead_multiplier_x1000; +} + +static int kbps_to_peak_pbn(int kbps, uint16_t fec_overhead_multiplier_x1000) { u64 peak_kbps = kbps; peak_kbps *= 1006; - peak_kbps = div_u64(peak_kbps, 1000); + peak_kbps *= fec_overhead_multiplier_x1000; + peak_kbps = div_u64(peak_kbps, 1000 * 1000); return (int) DIV64_U64_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000)); } @@ -773,11 +786,12 @@ static int increase_dsc_bpp(struct drm_atomic_state *state, int link_timeslots_used; int fair_pbn_alloc; int ret = 0; + uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link); for (i = 0; i < count; i++) { if (vars[i + k].dsc_enabled) { initial_slack[i] = - kbps_to_peak_pbn(params[i].bw_range.max_kbps) - vars[i + k].pbn; + kbps_to_peak_pbn(params[i].bw_range.max_kbps, fec_overhead_multiplier_x1000) - vars[i + k].pbn; bpp_increased[i] = false; remaining_to_increase += 1; } else { @@ -873,6 +887,7 @@ static int try_disable_dsc(struct drm_atomic_state *state, int next_index; int remaining_to_try = 0; int ret; + uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link); for (i = 0; i < count; i++) { if (vars[i + k].dsc_enabled @@ -902,7 +917,7 @@ static int try_disable_dsc(struct drm_atomic_state *state, if (next_index == -1) break; - vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps); + vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000); ret = drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port, @@ -915,7 +930,7 @@ static int try_disable_dsc(struct drm_atomic_state *state, vars[next_index].dsc_enabled = false; vars[next_index].bpp_x16 = 0; } else { - vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps); + vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps, fec_overhead_multiplier_x1000); ret = drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port, @@ -944,6 +959,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, int count = 0; int i, k, ret; bool debugfs_overwrite = false; + uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link); memset(params, 0, sizeof(params)); @@ -1005,7 +1021,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, /* Try no compression */ for (i = 0; i < count; i++) { vars[i + k].aconnector = params[i].aconnector; - vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); + vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000); vars[i + k].dsc_enabled = false; vars[i + k].bpp_x16 = 0; ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port, @@ -1024,7 +1040,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, /* Try max compression */ for (i = 0; i < count; i++) { if (params[i].compression_possible && params[i].clock_force_enable != DSC_CLK_FORCE_DISABLE) { - vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps); + vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps, fec_overhead_multiplier_x1000); vars[i + k].dsc_enabled = true; vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16; ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, @@ -1032,7 +1048,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, if (ret < 0) return ret; } else { - vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); + vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000); vars[i + k].dsc_enabled = false; vars[i + k].bpp_x16 = 0; ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, diff --git 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 index 0b5750202e73..1e4ede1e57ab 100644 --- 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 @@ -46,6 +46,9 @@ #define SYNAPTICS_CASCADED_HUB_ID 0x5A #define IS_SYNAPTICS_CASCADED_PANAMERA(devName, data) ((IS_SYNAPTICS_PANAMERA(devName) && ((int)data[2] == SYNAPTICS_CASCADED_HUB_ID)) ? 1 : 0) +#define PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B 1031 +#define PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B 1000 + struct amdgpu_display_manager; struct amdgpu_dm_connector; -- cgit From 825b3772a2047bd32ed3b3914234da0de19ef2e0 Mon Sep 17 00:00:00 2001 From: Wesley Chalmers Date: Thu, 3 Nov 2022 22:29:31 -0400 Subject: drm/amd/display: Do not set DRR on pipe Commit [WHY] Writing to DRR registers such as OTG_V_TOTAL_MIN on the same frame as a pipe commit can cause underflow. Cc: stable@vger.kernel.org Cc: Mario Limonciello Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Wesley Chalmers Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index 586de81fc2da..6d328b7e07a8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -990,8 +990,5 @@ void dcn30_prepare_bandwidth(struct dc *dc, dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz); dcn20_prepare_bandwidth(dc, context); - - dc_dmub_srv_p_state_delegate(dc, - context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching, context); } -- cgit From 709671ffb15dcd1b4f6afe2a9d8c67c7c4ead4a1 Mon Sep 17 00:00:00 2001 From: Saaem Rizvi Date: Mon, 27 Feb 2023 18:55:07 -0500 Subject: drm/amd/display: Remove OTG DIV register write for Virtual signals. [WHY] Hot plugging and then hot unplugging leads to k1 and k2 values to change, as signal is detected as a virtual signal on hot unplug. Writing these values to OTG_PIXEL_RATE_DIV register might cause primary display to blank (known hw bug). [HOW] No longer write k1 and k2 values to register if signal is virtual, we have safe guards in place in the case that k1 and k2 is unassigned so that an unknown value is not written to the register either. Cc: stable@vger.kernel.org Cc: Mario Limonciello Reviewed-by: Samson Tam Reviewed-by: Alvin Lee Acked-by: Qingqing Zhuo Signed-off-by: Saaem Rizvi Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index 16f892125b6f..9d14045cccd6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -1104,7 +1104,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign *k2_div = PIXEL_RATE_DIV_BY_2; else *k2_div = PIXEL_RATE_DIV_BY_4; - } else if (dc_is_dp_signal(stream->signal) || dc_is_virtual_signal(stream->signal)) { + } else if (dc_is_dp_signal(stream->signal)) { if (two_pix_per_container) { *k1_div = PIXEL_RATE_DIV_BY_1; *k2_div = PIXEL_RATE_DIV_BY_2; -- cgit From 56574f89dbd84004c3fd6485bcaafb5aa9b8be14 Mon Sep 17 00:00:00 2001 From: Wesley Chalmers Date: Thu, 3 Nov 2022 22:29:31 -0400 Subject: drm/amd/display: Do not set DRR on pipe Commit [WHY] Writing to DRR registers such as OTG_V_TOTAL_MIN on the same frame as a pipe commit can cause underflow. Cc: stable@vger.kernel.org Cc: Mario Limonciello Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Wesley Chalmers Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index 3b4d4d68359b..df787fcf8e86 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -998,8 +998,5 @@ void dcn30_prepare_bandwidth(struct dc *dc, dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz); dcn20_prepare_bandwidth(dc, context); - - dc_dmub_srv_p_state_delegate(dc, - context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching, context); } -- cgit From cbd6c1b17d3b42b7935526a86ad5f66838767d03 Mon Sep 17 00:00:00 2001 From: Cruise Hung Date: Thu, 2 Mar 2023 10:33:51 +0800 Subject: drm/amd/display: Fix DP MST sinks removal issue [Why] In USB4 DP tunneling, it's possible to have this scenario that the path becomes unavailable and CM tears down the path a little bit late. So, in this case, the HPD is high but fails to read any DPCD register. That causes the link connection type to be set to sst. And not all sinks are removed behind the MST branch. [How] Restore the link connection type if it fails to read DPCD register. Cc: stable@vger.kernel.org Cc: Mario Limonciello Reviewed-by: Wenjing Liu Acked-by: Qingqing Zhuo Signed-off-by: Cruise Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/link_detection.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 38216c789d77..f70025ef7b69 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -855,6 +855,7 @@ static bool detect_link_and_local_sink(struct dc_link *link, struct dc_sink *prev_sink = NULL; struct dpcd_caps prev_dpcd_caps; enum dc_connection_type new_connection_type = dc_connection_none; + enum dc_connection_type pre_connection_type = link->type; const uint32_t post_oui_delay = 30; // 30ms DC_LOGGER_INIT(link->ctx->logger); @@ -957,6 +958,8 @@ static bool detect_link_and_local_sink(struct dc_link *link, } if (!detect_dp(link, &sink_caps, reason)) { + link->type = pre_connection_type; + if (prev_sink) dc_sink_release(prev_sink); return false; @@ -1244,11 +1247,16 @@ bool link_detect(struct dc_link *link, enum dc_detect_reason reason) bool is_delegated_to_mst_top_mgr = false; enum dc_connection_type pre_link_type = link->type; + DC_LOGGER_INIT(link->ctx->logger); + is_local_sink_detect_success = detect_link_and_local_sink(link, reason); if (is_local_sink_detect_success && link->local_sink) verify_link_capability(link, link->local_sink, reason); + DC_LOG_DC("%s: link_index=%d is_local_sink_detect_success=%d pre_link_type=%d link_type=%d\n", __func__, + link->link_index, is_local_sink_detect_success, pre_link_type, link->type); + if (is_local_sink_detect_success && link->local_sink && dc_is_dp_signal(link->local_sink->sink_signal) && link->dpcd_caps.is_mst_capable) -- cgit From 7304ee979b6b6422f41a1312391a5e505fc29ccd Mon Sep 17 00:00:00 2001 From: Ayush Gupta Date: Thu, 2 Mar 2023 09:58:05 -0500 Subject: drm/amd/display: disconnect MPCC only on OTG change [Why] Framedrops are observed while playing Vp9 and Av1 10 bit video on 8k resolution using VSR while playback controls are disappeared/appeared [How] Now ODM 2 to 1 is disabled for 5k or greater resolutions on VSR. Cc: stable@vger.kernel.org Cc: Mario Limonciello Reviewed-by: Alvin Lee Acked-by: Qingqing Zhuo Signed-off-by: Ayush Gupta Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index 74e50c09bb62..d024007f0f65 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -1915,6 +1915,7 @@ int dcn32_populate_dml_pipes_from_context( bool subvp_in_use = false; uint8_t is_pipe_split_expected[MAX_PIPES] = {0}; struct dc_crtc_timing *timing; + bool vsr_odm_support = false; dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate); @@ -1932,12 +1933,15 @@ int dcn32_populate_dml_pipes_from_context( timing = &pipe->stream->timing; pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal; + vsr_odm_support = (res_ctx->pipe_ctx[i].stream->src.width >= 5120 && + res_ctx->pipe_ctx[i].stream->src.width > res_ctx->pipe_ctx[i].stream->dst.width); if (context->stream_count == 1 && context->stream_status[0].plane_count == 1 && !dc_is_hdmi_signal(res_ctx->pipe_ctx[i].stream->signal) && is_h_timing_divisible_by_2(res_ctx->pipe_ctx[i].stream) && pipe->stream->timing.pix_clk_100hz * 100 > DCN3_2_VMIN_DISPCLK_HZ && - dc->debug.enable_single_display_2to1_odm_policy) { + dc->debug.enable_single_display_2to1_odm_policy && + !vsr_odm_support) { //excluding 2to1 ODM combine on >= 5k vsr pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1; } pipe_cnt++; -- cgit From eeefe7c4820b6baa0462a8b723ea0a3b5846ccae Mon Sep 17 00:00:00 2001 From: Robin Chen Date: Fri, 17 Feb 2023 20:47:57 +0800 Subject: drm/amd/display: hpd rx irq not working with eDP interface [Why] This is the fix for the defect of commit ab144f0b4ad6 ("drm/amd/display: Allow individual control of eDP hotplug support"). [How] To revise the default eDP hotplug setting and use the enum to git rid of the magic number for different options. Fixes: ab144f0b4ad6 ("drm/amd/display: Allow individual control of eDP hotplug support") Cc: stable@vger.kernel.org Cc: Mario Limonciello Reviewed-by: Wenjing Liu Acked-by: Qingqing Zhuo Signed-off-by: Robin Chen Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_types.h | 7 +++++++ drivers/gpu/drm/amd/display/dc/link/link_factory.c | 9 +++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 4b47fa00610b..45ab48fe5d00 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -1080,4 +1080,11 @@ struct dc_dpia_bw_alloc { }; #define MAX_SINKS_PER_LINK 4 + +enum dc_hpd_enable_select { + HPD_EN_FOR_ALL_EDP = 0, + HPD_EN_FOR_PRIMARY_EDP_ONLY, + HPD_EN_FOR_SECONDARY_EDP_ONLY, +}; + #endif /* DC_TYPES_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index 995032a341b3..3951d48118c4 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -528,14 +528,18 @@ static bool construct_phy(struct dc_link *link, link->irq_source_hpd = DC_IRQ_SOURCE_INVALID; switch (link->dc->config.allow_edp_hotplug_detection) { - case 1: // only the 1st eDP handles hotplug + case HPD_EN_FOR_ALL_EDP: + link->irq_source_hpd_rx = + dal_irq_get_rx_source(link->hpd_gpio); + break; + case HPD_EN_FOR_PRIMARY_EDP_ONLY: if (link->link_index == 0) link->irq_source_hpd_rx = dal_irq_get_rx_source(link->hpd_gpio); else link->irq_source_hpd = DC_IRQ_SOURCE_INVALID; break; - case 2: // only the 2nd eDP handles hotplug + case HPD_EN_FOR_SECONDARY_EDP_ONLY: if (link->link_index == 1) link->irq_source_hpd_rx = dal_irq_get_rx_source(link->hpd_gpio); @@ -543,6 +547,7 @@ static bool construct_phy(struct dc_link *link, link->irq_source_hpd = DC_IRQ_SOURCE_INVALID; break; default: + link->irq_source_hpd = DC_IRQ_SOURCE_INVALID; break; } } -- cgit From deaccddaf4921faa5dfc71e8936dd8daa98ba33d Mon Sep 17 00:00:00 2001 From: Cruise Hung Date: Thu, 2 Mar 2023 10:33:51 +0800 Subject: drm/amd/display: Fix DP MST sinks removal issue [Why] In USB4 DP tunneling, it's possible to have this scenario that the path becomes unavailable and CM tears down the path a little bit late. So, in this case, the HPD is high but fails to read any DPCD register. That causes the link connection type to be set to sst. And not all sinks are removed behind the MST branch. [How] Restore the link connection type if it fails to read DPCD register. Cc: stable@vger.kernel.org Cc: Mario Limonciello Reviewed-by: Wenjing Liu Acked-by: Qingqing Zhuo Signed-off-by: Cruise Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/link_detection.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 13e5222249ec..fee71ebdfc73 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -853,6 +853,7 @@ static bool detect_link_and_local_sink(struct dc_link *link, struct dc_sink *prev_sink = NULL; struct dpcd_caps prev_dpcd_caps; enum dc_connection_type new_connection_type = dc_connection_none; + enum dc_connection_type pre_connection_type = link->type; const uint32_t post_oui_delay = 30; // 30ms DC_LOGGER_INIT(link->ctx->logger); @@ -955,6 +956,8 @@ static bool detect_link_and_local_sink(struct dc_link *link, } if (!detect_dp(link, &sink_caps, reason)) { + link->type = pre_connection_type; + if (prev_sink) dc_sink_release(prev_sink); return false; @@ -1236,11 +1239,16 @@ bool link_detect(struct dc_link *link, enum dc_detect_reason reason) bool is_delegated_to_mst_top_mgr = false; enum dc_connection_type pre_link_type = link->type; + DC_LOGGER_INIT(link->ctx->logger); + is_local_sink_detect_success = detect_link_and_local_sink(link, reason); if (is_local_sink_detect_success && link->local_sink) verify_link_capability(link, link->local_sink, reason); + DC_LOG_DC("%s: link_index=%d is_local_sink_detect_success=%d pre_link_type=%d link_type=%d\n", __func__, + link->link_index, is_local_sink_detect_success, pre_link_type, link->type); + if (is_local_sink_detect_success && link->local_sink && dc_is_dp_signal(link->local_sink->sink_signal) && link->dpcd_caps.is_mst_capable) -- cgit From 562e08223a85f315122cd65e8f99b8c0a42b8771 Mon Sep 17 00:00:00 2001 From: Ayush Gupta Date: Thu, 2 Mar 2023 09:58:05 -0500 Subject: drm/amd/display: disconnect MPCC only on OTG change [Why] Framedrops are observed while playing Vp9 and Av1 10 bit video on 8k resolution using VSR while playback controls are disappeared/appeared [How] Now ODM 2 to 1 is disabled for 5k or greater resolutions on VSR. Cc: stable@vger.kernel.org Cc: Mario Limonciello Reviewed-by: Alvin Lee Acked-by: Qingqing Zhuo Signed-off-by: Ayush Gupta Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index f6f72e7c9e86..633491331722 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -1914,6 +1914,7 @@ int dcn32_populate_dml_pipes_from_context( struct pipe_ctx *pipe; bool subvp_in_use = false; struct dc_crtc_timing *timing; + bool vsr_odm_support = false; dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate); @@ -1931,12 +1932,15 @@ int dcn32_populate_dml_pipes_from_context( timing = &pipe->stream->timing; pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal; + vsr_odm_support = (res_ctx->pipe_ctx[i].stream->src.width >= 5120 && + res_ctx->pipe_ctx[i].stream->src.width > res_ctx->pipe_ctx[i].stream->dst.width); if (context->stream_count == 1 && context->stream_status[0].plane_count == 1 && !dc_is_hdmi_signal(res_ctx->pipe_ctx[i].stream->signal) && is_h_timing_divisible_by_2(res_ctx->pipe_ctx[i].stream) && pipe->stream->timing.pix_clk_100hz * 100 > DCN3_2_VMIN_DISPCLK_HZ && - dc->debug.enable_single_display_2to1_odm_policy) { + dc->debug.enable_single_display_2to1_odm_policy && + !vsr_odm_support) { //excluding 2to1 ODM combine on >= 5k vsr pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1; } pipe_cnt++; -- cgit From 5f3401eeb064fab5ce50728cce46532cce7a85c5 Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Tue, 28 Feb 2023 14:33:00 -0500 Subject: drm/amd/display: reallocate DET for dual displays with high pixel rate ratio [Why] For dual displays where pixel rate is much higher on one display, we may get underflow when DET is evenly allocated. [How] Allocate less DET segments for the lower pixel rate display and more DET segments for the higher pixel rate display Reviewed-by: Alvin Lee Acked-by: Qingqing Zhuo Signed-off-by: Samson Tam Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/dc/dcn32/dcn32_resource_helpers.c | 43 +++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c index a616cf078cf4..adaf330716c2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c @@ -257,6 +257,8 @@ bool dcn32_is_psr_capable(struct pipe_ctx *pipe) return psr_capable; } +#define DCN3_2_NEW_DET_OVERRIDE_MIN_MULTIPLIER 7 + /** * ******************************************************************************************* * dcn32_determine_det_override: Determine DET allocation for each pipe @@ -268,7 +270,6 @@ bool dcn32_is_psr_capable(struct pipe_ctx *pipe) * If there is a plane that's driven by more than 1 pipe (i.e. pipe split), then the * number of DET for that given plane will be split among the pipes driving that plane. * - * * High level algorithm: * 1. Split total DET among number of streams * 2. For each stream, split DET among the planes @@ -276,6 +277,18 @@ bool dcn32_is_psr_capable(struct pipe_ctx *pipe) * among those pipes. * 4. Assign the DET override to the DML pipes. * + * Special cases: + * + * For two displays that have a large difference in pixel rate, we may experience + * underflow on the larger display when we divide the DET equally. For this, we + * will implement a modified algorithm to assign more DET to larger display. + * + * 1. Calculate difference in pixel rates ( multiplier ) between two displays + * 2. If the multiplier exceeds DCN3_2_NEW_DET_OVERRIDE_MIN_MULTIPLIER, then + * implement the modified DET override algorithm. + * 3. Assign smaller DET size for lower pixel display and higher DET size for + * higher pixel display + * * @param [in]: dc: Current DC state * @param [in]: context: New DC state to be programmed * @param [in]: pipes: Array of DML pipes @@ -295,18 +308,46 @@ void dcn32_determine_det_override(struct dc *dc, struct dc_plane_state *current_plane = NULL; uint8_t stream_count = 0; + int phy_pix_clk_mult, lower_mode_stream_index; + int phy_pix_clk[MAX_PIPES] = {0}; + bool use_new_det_override_algorithm = false; + for (i = 0; i < context->stream_count; i++) { /* Don't count SubVP streams for DET allocation */ if (context->streams[i]->mall_stream_config.type != SUBVP_PHANTOM) { + phy_pix_clk[i] = context->streams[i]->phy_pix_clk; stream_count++; } } + /* Check for special case with two displays, one with much higher pixel rate */ + if (stream_count == 2) { + ASSERT(!phy_pix_clk[0] || !phy_pix_clk[1]); + if (phy_pix_clk[0] < phy_pix_clk[1]) { + lower_mode_stream_index = 0; + phy_pix_clk_mult = phy_pix_clk[1] / phy_pix_clk[0]; + } else { + lower_mode_stream_index = 1; + phy_pix_clk_mult = phy_pix_clk[0] / phy_pix_clk[1]; + } + + if (phy_pix_clk_mult >= DCN3_2_NEW_DET_OVERRIDE_MIN_MULTIPLIER) + use_new_det_override_algorithm = true; + } + if (stream_count > 0) { stream_segments = 18 / stream_count; for (i = 0; i < context->stream_count; i++) { if (context->streams[i]->mall_stream_config.type == SUBVP_PHANTOM) continue; + + if (use_new_det_override_algorithm) { + if (i == lower_mode_stream_index) + stream_segments = 4; + else + stream_segments = 14; + } + if (context->stream_status[i].plane_count > 0) plane_segments = stream_segments / context->stream_status[i].plane_count; else -- cgit From 7108a1c1271dc4d26789002c1a6858b52f237cf5 Mon Sep 17 00:00:00 2001 From: Wesley Chalmers Date: Mon, 27 Feb 2023 13:21:17 -0500 Subject: drm/amd/display: Make DCN32 functions available to future DCNs [Why & How] Make DCN32 functions available for more DCNs. Reviewed-by: Chris Park Acked-by: Qingqing Zhuo Signed-off-by: Wesley Chalmers Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c | 8 ++++---- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.h | 13 +++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c index 206a5ddbaf6d..c8041cfd594d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c @@ -42,7 +42,7 @@ mpc30->mpc_shift->field_name, mpc30->mpc_mask->field_name -static void mpc32_mpc_init(struct mpc *mpc) +void mpc32_mpc_init(struct mpc *mpc) { struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); int mpcc_id; @@ -254,7 +254,7 @@ static void mpc32_program_post1dlut_pwl( } } -static bool mpc32_program_post1dlut( +bool mpc32_program_post1dlut( struct mpc *mpc, const struct pwl_params *params, uint32_t mpcc_id) @@ -701,7 +701,7 @@ static void mpc32_power_on_shaper_3dlut( } -static bool mpc32_program_shaper( +bool mpc32_program_shaper( struct mpc *mpc, const struct pwl_params *params, uint32_t mpcc_id) @@ -897,7 +897,7 @@ static void mpc32_set_3dlut_mode( } -static bool mpc32_program_3dlut( +bool mpc32_program_3dlut( struct mpc *mpc, const struct tetrahedral_params *params, int mpcc_id) diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.h index 61f33c0d8e59..2c2ecd053806 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.h @@ -310,6 +310,19 @@ struct dcn32_mpc_registers { MPC_REG_VARIABLE_LIST_DCN3_0; MPC_REG_VARIABLE_LIST_DCN32; }; +void mpc32_mpc_init(struct mpc *mpc); +bool mpc32_program_3dlut( + struct mpc *mpc, + const struct tetrahedral_params *params, + int mpcc_id); +bool mpc32_program_post1dlut( + struct mpc *mpc, + const struct pwl_params *params, + uint32_t mpcc_id); +bool mpc32_program_shaper( + struct mpc *mpc, + const struct pwl_params *params, + uint32_t mpcc_id); void dcn32_mpc_construct(struct dcn30_mpc *mpc30, struct dc_context *ctx, -- cgit From c416a9e4e31eaec5a35417b056a22c73652db544 Mon Sep 17 00:00:00 2001 From: Stylon Wang Date: Wed, 1 Mar 2023 23:56:51 +0800 Subject: drm/amd/display: Clearly states if long or short HPD event in dmesg logs [Why] The log "DMUB HPD callback" is crucial to identify when DP tunneling is been established and driver is notified of this event from DMUB. Same log is shared for long and short hotplug event and we need to check trailing DC debug log to distinguish between them two, making debugging on DPIA related issues a bit more troublesome. [How] Clearly states in dmesg logs whether this is a long or short hotplug event. Reviewed-by: Hamza Mahfooz Acked-by: Qingqing Zhuo Signed-off-by: Stylon Wang Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 e0b7ef6d1a62..eeaeca8b51f4 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -713,7 +713,14 @@ static void dmub_hpd_callback(struct amdgpu_device *adev, drm_for_each_connector_iter(connector, &iter) { aconnector = to_amdgpu_dm_connector(connector); if (link && aconnector->dc_link == link) { - DRM_INFO("DMUB HPD callback: link_index=%u\n", link_index); + if (notify->type == DMUB_NOTIFICATION_HPD) + DRM_INFO("DMUB HPD callback: link_index=%u\n", link_index); + else if (notify->type == DMUB_NOTIFICATION_HPD_IRQ) + DRM_INFO("DMUB HPD IRQ callback: link_index=%u\n", link_index); + else + DRM_WARN("DMUB Unknown HPD callback type %d, link_index=%u\n", + notify->type, link_index); + hpd_aconnector = aconnector; break; } -- cgit From 05cff51055c1050bf3a730748db15eb84f34b31d Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Fri, 3 Mar 2023 17:30:25 -0500 Subject: drm/amd/display: fix assert condition [Why & How] Reversed assert condition when checking that phy_pix_clk[] is not 0 Reviewed-by: Alvin Lee Acked-by: Qingqing Zhuo Signed-off-by: Samson Tam Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c index adaf330716c2..47fa51c1d3f4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c @@ -322,7 +322,7 @@ void dcn32_determine_det_override(struct dc *dc, /* Check for special case with two displays, one with much higher pixel rate */ if (stream_count == 2) { - ASSERT(!phy_pix_clk[0] || !phy_pix_clk[1]); + ASSERT((phy_pix_clk[0] > 0) && (phy_pix_clk[1] > 0)); if (phy_pix_clk[0] < phy_pix_clk[1]) { lower_mode_stream_index = 0; phy_pix_clk_mult = phy_pix_clk[1] / phy_pix_clk[0]; -- cgit From c79503dc2ec2378d08cccb6b53da408d6bd6cf9e Mon Sep 17 00:00:00 2001 From: Anthony Koo Date: Sun, 5 Mar 2023 01:35:03 -0500 Subject: drm/amd/display: [FW Promotion] Release 0.0.158.0 [Why & How] Add boot control bit to control dispclk and dppclk deep sleep Acked-by: Qingqing Zhuo Signed-off-by: Anthony Koo Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 734b34902fa7..3175a4fe4d52 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -410,8 +410,8 @@ union dmub_fw_boot_options { uint32_t usb4_cm_version: 1; /**< 1 CM support */ uint32_t dpia_hpd_int_enable_supported: 1; /* 1 if dpia hpd int enable supported */ uint32_t usb4_dpia_bw_alloc_supported: 1; /* 1 if USB4 dpia BW allocation supported */ - - uint32_t reserved : 15; /**< reserved */ + uint32_t disable_clk_ds: 1; /* 1 if disallow dispclk_ds and dppclk_ds*/ + uint32_t reserved : 14; /**< reserved */ } bits; /**< boot bits */ uint32_t all; /**< 32-bit access to bits */ }; -- cgit From 3726b6e7c0f1842a2ffdfd5921c95f69c0524808 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Sun, 5 Mar 2023 20:48:26 -0500 Subject: drm/amd/display: 3.2.227 This version brings along the following: - FW Release 0.0.158.0 - Fixes to HDCP, DP MST and more - Improvements on USB4 links and more - Code re-architecture on link.h Reviewed-by: Aric Cyr Acked-by: Qingqing Zhuo 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(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 3f25a1620f4f..2818483964dd 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -45,7 +45,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.226" +#define DC_VER "3.2.227" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- cgit From 0bad3200dffa26943ce2b561e5446cc3ac018bc9 Mon Sep 17 00:00:00 2001 From: bobzhou Date: Wed, 15 Mar 2023 15:23:48 +0800 Subject: drm/amd: fix compilation issue with legacy gcc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch is used to fix following compilation issue with legacy gcc error: ‘for’ loop initial declarations are only allowed in C99 mode Signed-off-by: bobzhou Reviewed-by: Guchun Chen Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index 2e251dcbb022..931f7c6446de 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -137,8 +137,9 @@ static uint8_t get_lowest_dpia_index(struct dc_link *link) { const struct dc *dc_struct = link->dc; uint8_t idx = 0xFF; + int i; - for (int i = 0; i < MAX_PIPES * 2; ++i) { + for (i = 0; i < MAX_PIPES * 2; ++i) { if (!dc_struct->links[i] || dc_struct->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) @@ -165,8 +166,9 @@ static int get_host_router_total_bw(struct dc_link *link, uint8_t type) uint8_t idx = (link->link_index - lowest_dpia_index) / 2, idx_temp = 0; struct dc_link *link_temp; int total_bw = 0; + int i; - for (int i = 0; i < MAX_PIPES * 2; ++i) { + for (i = 0; i < MAX_PIPES * 2; ++i) { if (!dc_struct->links[i] || dc_struct->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) continue; @@ -467,12 +469,13 @@ bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed_per_dpia, uint8 bool ret = true; int bw_needed_per_hr[MAX_HR_NUM] = { 0, 0 }; uint8_t lowest_dpia_index = 0, dpia_index = 0; + uint8_t i; if (!num_dpias || num_dpias > MAX_DPIA_NUM) return ret; //Get total Host Router BW & Validate against each Host Router max BW - for (uint8_t i = 0; i < num_dpias; ++i) { + for (i = 0; i < num_dpias; ++i) { if (!link[i]->dpia_bw_alloc_config.bw_alloc_enabled) continue; -- cgit From 4db231d7dd80163fd251635f81280f1c93a393ab Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 12 Mar 2023 20:17:46 +0100 Subject: drm/amd/display/amdgpu_dm: Fix backlight_device_register() error handling backlight_device_register() returns an ERR_PTR on error, but other code such as amdgpu_dm_connector_destroy() assumes dm->backlight_dev[i] is NULL if no backlight is registered. Clear dm->backlight_dev[i] on registration failure, to avoid other code trying to deref an ERR_PTR pointer. Reviewed-by: Rodrigo Siqueira Signed-off-by: Hans de Goede Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 eeaeca8b51f4..1c69353defb5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4218,9 +4218,10 @@ amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm) &amdgpu_dm_backlight_ops, &props); - if (IS_ERR(dm->backlight_dev[dm->num_of_edps])) + if (IS_ERR(dm->backlight_dev[dm->num_of_edps])) { DRM_ERROR("DM: Backlight registration failed!\n"); - else + dm->backlight_dev[dm->num_of_edps] = NULL; + } else DRM_DEBUG_DRIVER("DM: Registered Backlight device: %s\n", bl_name); } -- cgit From ceb4a5619c734ea679bf5a2446e6869056e353d4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 12 Mar 2023 20:17:47 +0100 Subject: drm/amd/display/amdgpu_dm: Refactor register_backlight_device() Refactor register_backlight_device(): 1) Turn the connector-type + signal check into an early exit condition to avoid the indentation level of the rest of the code 2) Add an array bounds check for the arrays indexed by dm->num_of_edps 3) register_backlight_device() always increases dm->num_of_edps if amdgpu_dm_register_backlight_device() has assigned a backlight_dev to the current dm->backlight_link[dm->num_of_edps] slot. So on its next call dm->backlight_dev[dm->num_of_edps] always point to the next empty slot and the "if (!dm->backlight_dev[dm->num_of_edps])" check will thus always succeed and can be removed. 4) Add a bl_idx local variable to use as array index, rather then using dm->num_of_edps to improve the code readability. Reviewed-by: Rodrigo Siqueira Signed-off-by: Hans de Goede Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 ++++++++++++----------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 1c69353defb5..cbf36131cdd0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4269,21 +4269,23 @@ static int initialize_plane(struct amdgpu_display_manager *dm, static void register_backlight_device(struct amdgpu_display_manager *dm, struct dc_link *link) { - if ((link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) && - link->type != dc_connection_none) { - /* - * Event if registration failed, we should continue with - * DM initialization because not having a backlight control - * is better then a black screen. - */ - if (!dm->backlight_dev[dm->num_of_edps]) - amdgpu_dm_register_backlight_device(dm); + int bl_idx = dm->num_of_edps; - if (dm->backlight_dev[dm->num_of_edps]) { - dm->backlight_link[dm->num_of_edps] = link; - dm->num_of_edps++; - } + if (!(link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) || + link->type == dc_connection_none) + return; + + if (dm->num_of_edps >= AMDGPU_DM_MAX_NUM_EDP) { + drm_warn(adev_to_drm(dm->adev), "Too much eDP connections, skipping backlight setup for additional eDPs\n"); + return; } + + amdgpu_dm_register_backlight_device(dm); + if (!dm->backlight_dev[bl_idx]) + return; + + dm->backlight_link[bl_idx] = link; + dm->num_of_edps++; } static void amdgpu_set_panel_orientation(struct drm_connector *connector); -- cgit From 6091693a4bd1ba52e406cff44a4a9959e755c986 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Thu, 16 Mar 2023 17:51:42 +0800 Subject: drm/amd/display: make is_synaptics_cascaded_panamera static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This symbol is not used outside of amdgpu_dm_mst_types.c, so marks it static. drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_mst_types.c:211:6: warning: no previous prototype for ‘is_synaptics_cascaded_panamera’. Reported-by: Abaci Robot Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=4548 Signed-off-by: Jiapeng Chong Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 6378352346c8..994ba426ca66 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 @@ -208,7 +208,7 @@ bool needs_dsc_aux_workaround(struct dc_link *link) return false; } -bool is_synaptics_cascaded_panamera(struct dc_link *link, struct drm_dp_mst_port *port) +static bool is_synaptics_cascaded_panamera(struct dc_link *link, struct drm_dp_mst_port *port) { u8 branch_vendor_data[4] = { 0 }; // Vendor data 0x50C ~ 0x50F -- cgit From 7d67285e84f62fb5fd00405432ecf1b64f921091 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Thu, 16 Mar 2023 17:51:43 +0800 Subject: drm/amd/display: Remove the unused function link_timing_bandwidth_kbps() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function link_timing_bandwidth_kbps is defined in the link_validation.c file, but not called elsewhere, so remove this unused function. drivers/gpu/drm/amd/amdgpu/../display/dc/link/link_validation.c:258:10: warning: no previous prototype for ‘link_timing_bandwidth_kbps’. Reported-by: Abaci Robot Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=4547 Signed-off-by: Jiapeng Chong Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/link/link_validation.c | 51 ---------------------- 1 file changed, 51 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/link_validation.c b/drivers/gpu/drm/amd/display/dc/link/link_validation.c index 9a5010f86003..afbd22631721 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_validation.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_validation.c @@ -255,57 +255,6 @@ uint32_t dp_link_bandwidth_kbps( return link_rate_per_lane_kbps * link_settings->lane_count / 10000 * total_data_bw_efficiency_x10000; } -uint32_t link_timing_bandwidth_kbps(const struct dc_crtc_timing *timing) -{ - uint32_t bits_per_channel = 0; - uint32_t kbps; - - if (timing->flags.DSC) - return dc_dsc_stream_bandwidth_in_kbps(timing, - timing->dsc_cfg.bits_per_pixel, - timing->dsc_cfg.num_slices_h, - timing->dsc_cfg.is_dp); - - switch (timing->display_color_depth) { - case COLOR_DEPTH_666: - bits_per_channel = 6; - break; - case COLOR_DEPTH_888: - bits_per_channel = 8; - break; - case COLOR_DEPTH_101010: - bits_per_channel = 10; - break; - case COLOR_DEPTH_121212: - bits_per_channel = 12; - break; - case COLOR_DEPTH_141414: - bits_per_channel = 14; - break; - case COLOR_DEPTH_161616: - bits_per_channel = 16; - break; - default: - ASSERT(bits_per_channel != 0); - bits_per_channel = 8; - break; - } - - kbps = timing->pix_clk_100hz / 10; - kbps *= bits_per_channel; - - if (timing->flags.Y_ONLY != 1) { - /*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/ - kbps *= 3; - if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) - kbps /= 2; - else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) - kbps = kbps * 2 / 3; - } - - return kbps; -} - static bool dp_validate_mode_timing( struct dc_link *link, const struct dc_crtc_timing *timing) -- cgit From f825fead3570d7b7a13dd13b8d63209dc1acfe5e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 17 Mar 2023 08:16:42 +0000 Subject: drm/amd/display/dc/dc_hdmi_types: Move string definition to the only file it's used in MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/gpu/drm/amd/amdgpu/../display/dc/dc_hdmi_types.h:53:22: warning: ‘dp_hdmi_dongle_signature_str’ defined but not used [-Wunused-const-variable=] [snipped 400 similar lines for brevity] Cc: Harry Wentland Cc: Leo Li Cc: Rodrigo Siqueira Cc: Alex Deucher Cc: "Christian König" Cc: "Pan, Xinhui" Cc: David Airlie Cc: Daniel Vetter Cc: Wenjing Liu Cc: amd-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h | 1 - drivers/gpu/drm/amd/display/dc/link/link_detection.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h index c364744b4c83..b015e80672ec 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h @@ -50,7 +50,6 @@ struct dp_hdmi_dongle_signature_data { /* DP-HDMI dongle slave address for retrieving dongle signature*/ #define DP_HDMI_DONGLE_ADDRESS 0x40 -static const uint8_t dp_hdmi_dongle_signature_str[] = "DP-HDMI ADAPTOR"; #define DP_HDMI_DONGLE_SIGNATURE_EOT 0x04 diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index fee71ebdfc73..8cfeddfb65c8 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -60,6 +60,8 @@ */ #define LINK_TRAINING_MAX_VERIFY_RETRY 2 +static const uint8_t dp_hdmi_dongle_signature_str[] = "DP-HDMI ADAPTOR"; + static enum ddc_transaction_type get_ddc_transaction_type(enum signal_type sink_signal) { enum ddc_transaction_type transaction_type = DDC_TRANSACTION_TYPE_NONE; -- cgit From bc517825c5d6c388cc7c668615a0b8f1b26ce513 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 17 Mar 2023 08:17:01 +0000 Subject: drm/amd/display/amdgpu_dm/amdgpu_dm_helpers: Move defines out to where they are actually used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h: At top level: drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:143:22: warning: ‘SYNAPTICS_DEVICE_ID’ defined but not used [-Wunused-const-variable=] drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:140:22: warning: ‘DP_VGA_LVDS_CONVERTER_ID_3’ defined but not used [-Wunused-const-variable=] drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:138:22: warning: ‘DP_VGA_LVDS_CONVERTER_ID_2’ defined but not used [-Wunused-const-variable=] drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:133:22: warning: ‘DP_SINK_DEVICE_STR_ID_2’ defined but not used [-Wunused-const-variable=] drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:132:22: warning: ‘DP_SINK_DEVICE_STR_ID_1’ defined but not used [-Wunused-const-variable=] [snip 400 similar lines brevity] Cc: Harry Wentland Cc: Leo Li Cc: Rodrigo Siqueira Cc: Alex Deucher Cc: "Christian König" Cc: "Pan, Xinhui" Cc: David Airlie Cc: Daniel Vetter Cc: amd-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 3 +++ drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 3 +++ drivers/gpu/drm/amd/display/dc/link/link_detection.c | 2 ++ .../amd/display/dc/link/protocols/link_edp_panel_control.c | 5 +++++ drivers/gpu/drm/amd/display/include/ddc_service_types.h | 13 ------------- 5 files changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 9c1e91c2179e..330ab036c830 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 @@ -44,6 +44,9 @@ #include "dm_helpers.h" #include "ddc_service_types.h" +/* MST Dock */ +static const uint8_t SYNAPTICS_DEVICE_ID[] = "SYNA"; + /* dm_helpers_parse_edid_caps * * Parse edid caps diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c index 19440bdf6344..27b8f3435d86 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -33,6 +33,9 @@ #define MAX_PIPES 6 +static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3}; +static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5}; + /* * Convert dmcub psr state to dmcu psr state. */ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 8cfeddfb65c8..9177b146a80a 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -60,6 +60,8 @@ */ #define LINK_TRAINING_MAX_VERIFY_RETRY 2 +static const u8 DP_SINK_BRANCH_DEV_NAME_7580[] = "7580\x80u"; + static const uint8_t dp_hdmi_dongle_signature_str[] = "DP-HDMI ADAPTOR"; static enum ddc_transaction_type get_ddc_transaction_type(enum signal_type sink_signal) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index 93a6bbe954bb..d895046787bc 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -37,6 +37,11 @@ #include "abm.h" #define DC_LOGGER_INIT(logger) +/* Travis */ +static const uint8_t DP_VGA_LVDS_CONVERTER_ID_2[] = "sivarT"; +/* Nutmeg */ +static const uint8_t DP_VGA_LVDS_CONVERTER_ID_3[] = "dnomlA"; + void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode) { union dpcd_edp_config edp_config_set; 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 31a12ce79a8e..f843fc497855 100644 --- a/drivers/gpu/drm/amd/display/include/ddc_service_types.h +++ b/drivers/gpu/drm/amd/display/include/ddc_service_types.h @@ -129,17 +129,4 @@ struct av_sync_data { uint8_t aud_del_ins3;/* DPCD 0002Dh */ }; -static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3}; -static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5}; - -static const u8 DP_SINK_BRANCH_DEV_NAME_7580[] = "7580\x80u"; - -/*Travis*/ -static const uint8_t DP_VGA_LVDS_CONVERTER_ID_2[] = "sivarT"; -/*Nutmeg*/ -static const uint8_t DP_VGA_LVDS_CONVERTER_ID_3[] = "dnomlA"; - -/*MST Dock*/ -static const uint8_t SYNAPTICS_DEVICE_ID[] = "SYNA"; - #endif /* __DAL_DDC_SERVICE_TYPES_H__ */ -- cgit From b8c6b225d9d82b5245479960f62f0e95d611cc18 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 17 Mar 2023 08:17:08 +0000 Subject: drm/amd/display/dc/dce/dmub_psr: Demote kerneldoc abuse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dmub_psr.c:257: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst Cc: Harry Wentland Cc: Leo Li Cc: Rodrigo Siqueira Cc: Alex Deucher Cc: "Christian König" Cc: "Pan, Xinhui" Cc: David Airlie Cc: Daniel Vetter Cc: David Zhang Cc: amd-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c index 27b8f3435d86..9705d8f88382 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -253,7 +253,7 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level, uint8_ dc_dmub_srv_wait_idle(dc->dmub_srv); } -/** +/* * Set PSR vtotal requirement for FreeSync PSR. */ static void dmub_psr_set_sink_vtotal_in_psr_active(struct dmub_psr *dmub, -- cgit From c54011512965ab221573b4d31ce1f5a279e15c15 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 17 Mar 2023 08:17:10 +0000 Subject: drm/amd/display/dc/link/link_detection: Remove unused variable 'status' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/gpu/drm/amd/amdgpu/../display/dc/link/link_detection.c: In function ‘query_hdcp_capability’: drivers/gpu/drm/amd/amdgpu/../display/dc/link/link_detection.c:501:42: warning: variable ‘status’ set but not used [-Wunused-but-set-variable] Cc: Harry Wentland Cc: Leo Li Cc: Rodrigo Siqueira Cc: Alex Deucher Cc: "Christian König" Cc: "Pan, Xinhui" Cc: David Airlie Cc: Daniel Vetter Cc: Wenjing Liu Cc: amd-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/link_detection.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 9177b146a80a..9a4cfa777622 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -498,8 +498,6 @@ static void query_hdcp_capability(enum signal_type signal, struct dc_link *link) dc_process_hdcp_msg(signal, link, &msg22); if (signal == SIGNAL_TYPE_DISPLAY_PORT || signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { - enum hdcp_message_status status = HDCP_MESSAGE_UNSUPPORTED; - msg14.data = &link->hdcp_caps.bcaps.raw; msg14.length = sizeof(link->hdcp_caps.bcaps.raw); msg14.msg_id = HDCP_MESSAGE_ID_READ_BCAPS; @@ -507,7 +505,7 @@ static void query_hdcp_capability(enum signal_type signal, struct dc_link *link) msg14.link = HDCP_LINK_PRIMARY; msg14.max_retries = 5; - status = dc_process_hdcp_msg(signal, link, &msg14); + dc_process_hdcp_msg(signal, link, &msg14); } } -- cgit From 7afe3521bd405d878bc5f9b98d5db4682bcdf3a5 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 17 Mar 2023 08:17:11 +0000 Subject: drm/amd/display/dc/link/protocols/link_dp_training: Remove set but unused variable 'result' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/gpu/drm/amd/amdgpu/../display/dc/link/protocols/link_dp_training.c: In function ‘perform_link_training_with_retries’: drivers/gpu/drm/amd/amdgpu/../display/dc/link/protocols/link_dp_training.c:1586:38: warning: variable ‘result’ set but not used [-Wunused-but-set-variable] Cc: Harry Wentland Cc: Leo Li Cc: Rodrigo Siqueira Cc: Alex Deucher Cc: "Christian König" Cc: "Pan, Xinhui" Cc: David Airlie Cc: Daniel Vetter Cc: Wenjing Liu Cc: amd-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index a9025671ee4a..10261764a0ce 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -1580,8 +1580,7 @@ bool perform_link_training_with_retries( * Report and continue with eDP panel mode to * perform eDP link training with right settings */ - bool result; - result = cp_psp->funcs.enable_assr(cp_psp->handle, link); + cp_psp->funcs.enable_assr(cp_psp->handle, link); } } -- cgit From 14af917998a6126494423f8820a93982025c6963 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 17 Mar 2023 08:17:13 +0000 Subject: drm/amd/display/dc/link/protocols/link_dp_capability: Remove unused variable and mark another as __maybe_unused MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ‘ds_port’ is clearly not used anywhere and ‘result_write_min_hblank’ is only utilised when debugging is enabled. The alternative would be to allocate the variable under the same clause as the debugging code, but that would become very messy, very quickly. Fixes the following W=1 kernel build warning(s): drivers/gpu/drm/amd/amdgpu/../display/dc/link/protocols/link_dp_capability.c: In function ‘dp_wa_power_up_0010FA’: drivers/gpu/drm/amd/amdgpu/../display/dc/link/protocols/link_dp_capability.c:280:42: warning: variable ‘ds_port’ set but not used [-Wunused-but-set-variable] drivers/gpu/drm/amd/amdgpu/../display/dc/link/protocols/link_dp_capability.c: In function ‘dpcd_set_source_specific_data’: drivers/gpu/drm/amd/amdgpu/../display/dc/link/protocols/link_dp_capability.c:1296:32: warning: variable ‘result_write_min_hblank’ set but not used [-Wunused-but-set-variable] Cc: Harry Wentland Cc: Leo Li Cc: Rodrigo Siqueira Cc: Alex Deucher Cc: "Christian König" Cc: "Pan, Xinhui" Cc: David Airlie Cc: Daniel Vetter Cc: Wenjing Liu Cc: amd-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index e9bcb35ae185..51427f508164 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -1284,7 +1284,7 @@ bool dp_overwrite_extended_receiver_cap(struct dc_link *link) void dpcd_set_source_specific_data(struct dc_link *link) { if (!link->dc->vendor_signature.is_valid) { - enum dc_status result_write_min_hblank = DC_NOT_SUPPORTED; + enum dc_status __maybe_unused result_write_min_hblank = DC_NOT_SUPPORTED; struct dpcd_amd_signature amd_signature = {0}; struct dpcd_amd_device_id amd_device_id = {0}; -- cgit From 16a7004a2d7a2f8953daa5196d68766cfa120fcb Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 17 Mar 2023 08:17:14 +0000 Subject: drm/amd/display/dc/link/protocols/link_dp_capability: Demote non-compliant kerneldoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/gpu/drm/amd/amdgpu/../display/dc/link/protocols/link_dp_capability.c:2190: warning: Function parameter or member 'link' not described in 'dc_link_is_dp_sink_present' Cc: Harry Wentland Cc: Leo Li Cc: Rodrigo Siqueira Cc: Alex Deucher Cc: "Christian König" Cc: "Pan, Xinhui" Cc: David Airlie Cc: Daniel Vetter Cc: amd-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index 51427f508164..2a2443535b67 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -2177,7 +2177,7 @@ bool dp_verify_link_cap_with_retries( return success; } -/** +/* * Check if there is a native DP or passive DP-HDMI dongle connected */ bool dp_is_sink_present(struct dc_link *link) -- cgit From 4082b9f5ead4966797dddcfef0905d59e5a83873 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 17 Mar 2023 08:17:16 +0000 Subject: drm/amd/display/dc/dce60/Makefile: Fix previous attempt to silence known override-init warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/gpu/drm/amd/amdgpu/../display/dc/dce60/dce60_resource.c:157:21: note: in expansion of macro ‘mmCRTC1_DCFE_MEM_LIGHT_SLEEP_CNTL’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_transform.h:170:9: note: in expansion of macro ‘SRI’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce60/dce60_resource.c:183:17: note: in expansion of macro ‘XFM_COMMON_REG_LIST_DCE60’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce60/dce60_resource.c:188:17: note: in expansion of macro ‘transform_regs’ drivers/gpu/drm/amd/amdgpu/../include/asic_reg/dce/dce_6_0_d.h:722:43: warning: initialized field overwritten [-Woverride-init] drivers/gpu/drm/amd/amdgpu/../display/dc/dce60/dce60_resource.c:157:21: note: in expansion of macro ‘mmCRTC2_DCFE_MEM_LIGHT_SLEEP_CNTL’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_transform.h:170:9: note: in expansion of macro ‘SRI’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce60/dce60_resource.c:183:17: note: in expansion of macro ‘XFM_COMMON_REG_LIST_DCE60’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce60/dce60_resource.c:189:17: note: in expansion of macro ‘transform_regs’ drivers/gpu/drm/amd/amdgpu/../include/asic_reg/dce/dce_6_0_d.h:722:43: note: (near initialization for ‘xfm_regs[2].DCFE_MEM_LIGHT_SLEEP_CN [100 lines snipped for brevity] Fixes: ceb3cf476a441 ("drm/amd/display/dc/dce60/Makefile: Ignore -Woverride-init warning") Cc: Harry Wentland Cc: Leo Li Cc: Rodrigo Siqueira Cc: Alex Deucher Cc: "Christian König" Cc: "Pan, Xinhui" Cc: David Airlie Cc: Daniel Vetter Cc: Mauro Rossi Cc: amd-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce60/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dce60/Makefile b/drivers/gpu/drm/amd/display/dc/dce60/Makefile index dda596fa1cd7..fee331accc0e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce60/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dce60/Makefile @@ -23,7 +23,7 @@ # Makefile for the 'controller' sub-component of DAL. # It provides the control and status of HW CRTC block. -CFLAGS_AMDDALPATH)/dc/dce60/dce60_resource.o = $(call cc-disable-warning, override-init) +CFLAGS_$(AMDDALPATH)/dc/dce60/dce60_resource.o = $(call cc-disable-warning, override-init) DCE60 = dce60_timing_generator.o dce60_hw_sequencer.o \ dce60_resource.o -- cgit From 1a593aa09000c513a912f250ddbe1dd191e871c4 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 17 Mar 2023 08:17:17 +0000 Subject: drm/amd/display/dc/link/link_detection: Demote a couple of kerneldoc abuses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/gpu/drm/amd/amdgpu/../display/dc/link/link_detection.c:877: warning: Function parameter or member 'link' not described in 'detect_link_and_local_sink' drivers/gpu/drm/amd/amdgpu/../display/dc/link/link_detection.c:877: warning: Function parameter or member 'reason' not described in 'detect_link_and_local_sink' drivers/gpu/drm/amd/amdgpu/../display/dc/link/link_detection.c:1232: warning: Function parameter or member 'link' not described in 'dc_link_detect_connection_type' Cc: Harry Wentland Cc: Leo Li Cc: Rodrigo Siqueira Cc: Alex Deucher Cc: "Christian König" Cc: "Pan, Xinhui" Cc: David Airlie Cc: Daniel Vetter Cc: Lee Jones Cc: Wenjing Liu Cc: amd-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/link_detection.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 9a4cfa777622..67addedd8956 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -832,7 +832,7 @@ static void verify_link_capability(struct dc_link *link, struct dc_sink *sink, verify_link_capability_non_destructive(link); } -/** +/* * detect_link_and_local_sink() - Detect if a sink is attached to a given link * * link->local_sink is created or destroyed as needed. @@ -1185,7 +1185,7 @@ static bool detect_link_and_local_sink(struct dc_link *link, return true; } -/** +/* * link_detect_connection_type() - Determine if there is a sink connected * * @type: Returned connection type -- cgit From 74fa4c81aadf418341f0d073c864ea7dca730a2e Mon Sep 17 00:00:00 2001 From: Saaem Rizvi Date: Mon, 6 Mar 2023 15:10:13 -0500 Subject: drm/amd/display: Implement workaround for writing to OTG_PIXEL_RATE_DIV register [Why and How] Current implementation requires FPGA builds to take a different code path from DCN32 to write to OTG_PIXEL_RATE_DIV. Now that we have a workaround to write to OTG_PIXEL_RATE_DIV register without blanking display on hotplug on DCN32, we can allow the code paths for FPGA to be exactly the same allowing for more consistent testing. Reviewed-by: Alvin Lee Acked-by: Qingqing Zhuo Signed-off-by: Saaem Rizvi Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h | 3 ++- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c | 22 ++++++++++++++++++++++ drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h | 3 ++- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 2 +- .../gpu/drm/amd/display/dc/dcn32/dcn32_resource.h | 3 ++- 5 files changed, 29 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h index 915a20461c77..893c0809cd4e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h @@ -230,7 +230,8 @@ type DTBCLK_P2_SRC_SEL;\ type DTBCLK_P2_EN;\ type DTBCLK_P3_SRC_SEL;\ - type DTBCLK_P3_EN; + type DTBCLK_P3_EN;\ + type DENTIST_DISPCLK_CHG_DONE; struct dccg_shift { DCCG_REG_FIELD_LIST(uint8_t) diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c index e4472c6be6c3..5dbef498580b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c @@ -42,6 +42,20 @@ #define DC_LOGGER \ dccg->ctx->logger +/* This function is a workaround for writing to OTG_PIXEL_RATE_DIV + * without the probability of causing a DIG FIFO error. + */ +static void dccg32_wait_for_dentist_change_done( + struct dccg *dccg) +{ + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + uint32_t dentist_dispclk_value = REG_READ(DENTIST_DISPCLK_CNTL); + + REG_WRITE(DENTIST_DISPCLK_CNTL, dentist_dispclk_value); + REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000); +} + static void dccg32_get_pixel_rate_div( struct dccg *dccg, uint32_t otg_inst, @@ -110,21 +124,29 @@ static void dccg32_set_pixel_rate_div( REG_UPDATE_2(OTG_PIXEL_RATE_DIV, OTG0_PIXEL_RATE_DIVK1, k1, OTG0_PIXEL_RATE_DIVK2, k2); + + dccg32_wait_for_dentist_change_done(dccg); break; case 1: REG_UPDATE_2(OTG_PIXEL_RATE_DIV, OTG1_PIXEL_RATE_DIVK1, k1, OTG1_PIXEL_RATE_DIVK2, k2); + + dccg32_wait_for_dentist_change_done(dccg); break; case 2: REG_UPDATE_2(OTG_PIXEL_RATE_DIV, OTG2_PIXEL_RATE_DIVK1, k1, OTG2_PIXEL_RATE_DIVK2, k2); + + dccg32_wait_for_dentist_change_done(dccg); break; case 3: REG_UPDATE_2(OTG_PIXEL_RATE_DIV, OTG3_PIXEL_RATE_DIVK1, k1, OTG3_PIXEL_RATE_DIVK2, k2); + + dccg32_wait_for_dentist_change_done(dccg); break; default: BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h index 271c163e4844..8071ab98d708 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h @@ -111,7 +111,8 @@ DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P3_SRC_SEL, mask_sh),\ DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P3_EN, mask_sh),\ DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, mask_sh),\ - DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh) + DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh),\ + DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh) struct dccg *dccg32_create( diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index f9073b722b36..5016b1313f3d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -1111,7 +1111,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign *k2_div = PIXEL_RATE_DIV_BY_2; else *k2_div = PIXEL_RATE_DIV_BY_4; - } else if (dc_is_dp_signal(stream->signal)) { + } else if (dc_is_dp_signal(stream->signal) || dc_is_virtual_signal(stream->signal)) { if (two_pix_per_container) { *k1_div = PIXEL_RATE_DIV_BY_1; *k2_div = PIXEL_RATE_DIV_BY_2; diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h index aca928edc4e3..10a3350376e4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h @@ -1276,7 +1276,8 @@ double dcn32_determine_max_vratio_prefetch(struct dc *dc, struct dc_state *conte DCCG_SRII(PHASE, DTBCLK_DTO, 0), DCCG_SRII(PHASE, DTBCLK_DTO, 1), \ DCCG_SRII(PHASE, DTBCLK_DTO, 2), DCCG_SRII(PHASE, DTBCLK_DTO, 3), \ SR(DCCG_AUDIO_DTBCLK_DTO_MODULO), SR(DCCG_AUDIO_DTBCLK_DTO_PHASE), \ - SR(OTG_PIXEL_RATE_DIV), SR(DTBCLK_P_CNTL), SR(DCCG_AUDIO_DTO_SOURCE) \ + SR(OTG_PIXEL_RATE_DIV), SR(DTBCLK_P_CNTL), \ + SR(DCCG_AUDIO_DTO_SOURCE), SR(DENTIST_DISPCLK_CNTL) \ ) /* VMID */ -- cgit From 97cbcae3ff20234f6a59240df0b5d5fa238b3f9e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 17 Mar 2023 08:17:09 +0000 Subject: drm/amd/display/dc/core/dc_stat: Convert a couple of doc headers to kerneldoc format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_stat.c:38: warning: Cannot understand ***************************************************************************** drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_stat.c:76: warning: Cannot understand ***************************************************************************** Cc: Harry Wentland Cc: Leo Li Cc: Rodrigo Siqueira Cc: Alex Deucher Cc: "Christian König" Cc: "Pan, Xinhui" Cc: David Airlie Cc: Daniel Vetter Cc: Mustapha Ghaddar Cc: Nicholas Kazlauskas Cc: Jasdeep Dhillon Cc: amd-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Reviewed-by: Harry Wentland Signed-off-by: Lee Jones Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_stat.c | 28 ++++++++++----------------- 1 file changed, 10 insertions(+), 18 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stat.c b/drivers/gpu/drm/amd/display/dc/core/dc_stat.c index 6c06587dd88c..5f6392ae31a6 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stat.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stat.c @@ -35,19 +35,15 @@ */ /** - ***************************************************************************** - * Function: dc_stat_get_dmub_notification + * dc_stat_get_dmub_notification * - * @brief - * Calls dmub layer to retrieve dmub notification + * Calls dmub layer to retrieve dmub notification * - * @param - * [in] dc: dc structure - * [in] notify: dmub notification structure + * @dc: dc structure + * @notify: dmub notification structure * - * @return + * Returns * None - ***************************************************************************** */ void dc_stat_get_dmub_notification(const struct dc *dc, struct dmub_notification *notify) { @@ -73,19 +69,15 @@ void dc_stat_get_dmub_notification(const struct dc *dc, struct dmub_notification } /** - ***************************************************************************** - * Function: dc_stat_get_dmub_dataout + * dc_stat_get_dmub_dataout * - * @brief - * Calls dmub layer to retrieve dmub gpint dataout + * Calls dmub layer to retrieve dmub gpint dataout * - * @param - * [in] dc: dc structure - * [in] dataout: dmub gpint dataout + * @dc: dc structure + * @dataout: dmub gpint dataout * - * @return + * Returns * None - ***************************************************************************** */ void dc_stat_get_dmub_dataout(const struct dc *dc, uint32_t *dataout) { -- cgit From 52b29307a98789853d87ed0a68031ec18063cba4 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Mon, 6 Mar 2023 11:39:51 +0800 Subject: drm/amd/display: remove outdated 8bpc comments [Why] The commit c76e483cd916 ("drm/amd/display: Don't restrict bpc to 8 bpc") removes the historical 8bpc dependency and sets max_bpc to 16. [How] The comment that states "8bpc for non-edp" needs to be removed as well. Reviewed-by: Harry Wentland Acked-by: Qingqing Zhuo Signed-off-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 cbf36131cdd0..5bac5781a06b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7284,7 +7284,6 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, if (!aconnector->mst_root) drm_connector_attach_max_bpc_property(&aconnector->base, 8, 16); - /* This defaults to the max in the range, but we want 8bpc for non-edp. */ aconnector->base.state->max_bpc = 16; aconnector->base.state->max_requested_bpc = aconnector->base.state->max_bpc; -- cgit From 28e5c9d601fb8c2f387516b095a9cf6ddf7c00d5 Mon Sep 17 00:00:00 2001 From: Wesley Chalmers Date: Fri, 3 Mar 2023 14:44:53 -0500 Subject: drm/amd/display: Make DCN32 3dlut function available to future DCNs [Why & How] Make DCN32 3dlut function non-static and thus available for future DCNs. Reviewed-by: Chris Park Acked-by: Qingqing Zhuo Signed-off-by: Wesley Chalmers Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index 5016b1313f3d..42255c22605d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -414,7 +414,7 @@ void dcn32_subvp_pipe_control_lock(struct dc *dc, } -static bool dcn32_set_mpc_shaper_3dlut( +bool dcn32_set_mpc_shaper_3dlut( struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream) { struct dpp *dpp_base = pipe_ctx->plane_res.dpp; diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h index 84c1f36c3fa6..2a5376eb9d66 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h @@ -54,6 +54,9 @@ bool dcn32_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state); +bool dcn32_set_mpc_shaper_3dlut( + struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream); + bool dcn32_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream); -- cgit From c964b86e322f91f409aead79b1b497b74ae0f795 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Tue, 28 Feb 2023 15:53:10 -0700 Subject: drm/amd/display: Add const to a function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When calling the dc_link_bw_kbps_from_raw_frl_link_rate_data from amdgpu_dm, GCC highlighted the following issue: In function ‘get_conv_frl_bw’: error: passing argument 1 of ‘dc_link_bw_kbps_from_raw_frl_link_rate_data’ discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers] 997 | aconnector->dc_link->dc, This commit fix this issue by making DC a constant variable since we only use it to invoke the function bw_kbps_from_raw_frl_link_rate_data(). Reviewed-by: Chris Park Acked-by: Qingqing Zhuo Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c | 3 +-- drivers/gpu/drm/amd/display/dc/dc.h | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c index 58fa911b1417..d24bc0a0b1d4 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c @@ -285,8 +285,7 @@ int dc_link_aux_transfer_raw(struct ddc_service *ddc, ddc, payload, operation_result); } -uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data( - struct dc *dc, uint8_t bw) +uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(const struct dc *dc, uint8_t bw) { return dc->link_srv->bw_kbps_from_raw_frl_link_rate_data(bw); } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 2818483964dd..624acd402eae 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1768,8 +1768,7 @@ void dc_restore_link_res_map(const struct dc *dc, uint32_t *map); bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx); /* translate a raw link rate data to bandwidth in kbps */ -uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data( - struct dc *dc, uint8_t bw); +uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(const struct dc *dc, uint8_t bw); /* determine the optimal bandwidth given link and required bw. * @link - current detected link -- cgit From ac84304d68c4b310e61b275317c0ddee1b746cb8 Mon Sep 17 00:00:00 2001 From: Zhikai Zhai Date: Thu, 2 Mar 2023 18:04:12 +0800 Subject: drm/amd/display: skip wait vblank [WHY] There is no need to wait vblank in the vupdate locked region at a full type update [HOW] skip wait vblank when global sync change Reviewed-by: Alvin Lee Acked-by: Qingqing Zhuo Signed-off-by: Zhikai Zhai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 53669f832ba5..69ea1f4ea749 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1720,10 +1720,8 @@ static void dcn20_program_pipe( pipe_ctx->pipe_dlg_param.vupdate_offset, pipe_ctx->pipe_dlg_param.vupdate_width); - if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) { - pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK); + if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE); - } pipe_ctx->stream_res.tg->funcs->set_vtg_params( pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, true); -- cgit From e89d890c1b4a29fd1871f9ce21e9a94720a10e98 Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Thu, 9 Mar 2023 17:05:47 -0500 Subject: drm/amd/display: update dio for two pixel per container case [why] Processing rate of the DP encoder, must be programmed to be the same as DIG_FIFO_OUTPUT_ PROCESSING_MODE in DP mode 0: 1 pixel per cycle 1: 2 pixel per cycle Reviewed-by: Alvin Lee Acked-by: Qingqing Zhuo Signed-off-by: Charlene Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c index c72448125976..89de64f18040 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c @@ -286,6 +286,7 @@ static void enc32_stream_encoder_dp_unblank( uint32_t n_vid = 0x8000; uint32_t m_vid; uint32_t n_multiply = 0; + uint32_t pix_per_cycle = 0; uint64_t m_vid_l = n_vid; /* YCbCr 4:2:0 : Computed VID_M will be 2X the input rate */ @@ -320,6 +321,10 @@ static void enc32_stream_encoder_dp_unblank( REG_UPDATE_2(DP_VID_TIMING, DP_VID_M_N_GEN_EN, 1, DP_VID_N_MUL, n_multiply); + + REG_UPDATE(DP_PIXEL_FORMAT, + DP_PIXEL_PER_CYCLE_PROCESSING_MODE, + pix_per_cycle); } /* make sure stream is disabled before resetting steer fifo */ -- cgit From 426714f89f7081ce8bf83546219eed6ea1511891 Mon Sep 17 00:00:00 2001 From: Paul Hsieh Date: Tue, 7 Mar 2023 21:04:28 +0800 Subject: drm/amd/display: power down eDP if eDP not present [Why] When init, driver will power up eDP to check eDP present or not. If eDP not present, driver doesn't power off eDP VDD cause power consumption. [How] If eDP is not present when detection, power off eDP VDD. Reviewed-by: Wenjing Liu Acked-by: Qingqing Zhuo Signed-off-by: Paul Hsieh Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/link_detection.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 67addedd8956..a131e30fd7d6 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -1227,6 +1227,11 @@ bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type * /* TODO: need to do the actual detection */ } else { *type = dc_connection_none; + if (link->connector_signal == SIGNAL_TYPE_EDP) { + /* eDP is not connected, power down it */ + if (!link->dc->config.edp_no_power_sequencing) + link->dc->hwss.edp_power_control(link, false); + } } return true; -- cgit From b5006f873b99a26f8bd36d691c09083495bc0a03 Mon Sep 17 00:00:00 2001 From: Martin Leung Date: Thu, 9 Mar 2023 22:42:14 -0500 Subject: drm/amd/display: initialize link_srv in virtual env [why] when refactoring to link_srv, we did not include the virtual environment case where dc_construct_ctx gets called instead of dc_construct [how] add initialize link_srv to dc_construct_ctx as well Reviewed-by: Leo Ma Acked-by: Qingqing Zhuo Signed-off-by: Martin Leung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index ae5f1b7b4fef..dc67256f565d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -887,6 +887,7 @@ static bool dc_construct_ctx(struct dc *dc, } dc->ctx = dc_ctx; + dc->link_srv = link_create_link_service(); return true; } -- cgit From a8b537605e22bfe277e666727fa0e9e01f2c729b Mon Sep 17 00:00:00 2001 From: Mustapha Ghaddar Date: Wed, 8 Mar 2023 10:27:17 -0500 Subject: drm/amd/display: Add function pointer for validate bw usb4 [WHY] In order to follow the new protocol of calling link functions [HOW] Add the function pointer to the link_srv Reviewed-by: Kshitij Bhardwaj Acked-by: Qingqing Zhuo Signed-off-by: Mustapha Ghaddar Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c | 5 +++++ drivers/gpu/drm/amd/display/dc/dc.h | 13 +++++++++++++ drivers/gpu/drm/amd/display/dc/inc/link.h | 3 +++ drivers/gpu/drm/amd/display/dc/link/link_factory.c | 1 + drivers/gpu/drm/amd/display/dc/link/link_validation.c | 18 ++++++++++++++++++ drivers/gpu/drm/amd/display/dc/link/link_validation.h | 4 ++++ .../amd/display/dc/link/protocols/link_dp_dpia_bw.c | 9 ++------- .../amd/display/dc/link/protocols/link_dp_dpia_bw.h | 7 ++++++- 8 files changed, 52 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c index d24bc0a0b1d4..18e098568cb4 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c @@ -473,3 +473,8 @@ void dc_link_enable_hpd_filter(struct dc_link *link, bool enable) { link->dc->link_srv->enable_hpd_filter(link, enable); } + +bool dc_link_validate(struct dc *dc, const struct dc_stream_state *streams, const unsigned int count) +{ + return dc->link_srv->validate_dpia_bandwidth(streams, count); +} diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 624acd402eae..1e6fa2d387f7 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -2028,6 +2028,19 @@ void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link( struct dc_link *link, int peak_bw); +/* + * Validate the BW of all the valid DPIA links to make sure it doesn't exceed + * available BW for each host router + * + * @dc: pointer to dc struct + * @stream: pointer to all possible streams + * @num_streams: number of valid DPIA streams + * + * return: TRUE if bw used by DPIAs doesn't exceed available BW else return FALSE + */ +bool dc_link_validate(struct dc *dc, const struct dc_stream_state *streams, + const unsigned int count); + /* Sink Interfaces - A sink corresponds to a display output device */ struct dc_container_id { diff --git a/drivers/gpu/drm/amd/display/dc/inc/link.h b/drivers/gpu/drm/amd/display/dc/inc/link.h index 11aaa7a9518a..f839494d59d8 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link.h @@ -144,6 +144,9 @@ struct link_service { uint32_t (*dp_link_bandwidth_kbps)( const struct dc_link *link, const struct dc_link_settings *link_settings); + bool (*validate_dpia_bandwidth)( + const struct dc_stream_state *stream, + const unsigned int num_streams); /*************************** DPMS *************************************/ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index 3951d48118c4..1515c817f03b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -99,6 +99,7 @@ static void construct_link_service_validation(struct link_service *link_srv) { link_srv->validate_mode_timing = link_validate_mode_timing; link_srv->dp_link_bandwidth_kbps = dp_link_bandwidth_kbps; + link_srv->validate_dpia_bandwidth = link_validate_dpia_bandwidth; } /* link dpms owns the programming sequence of stream's dpms state associated diff --git a/drivers/gpu/drm/amd/display/dc/link/link_validation.c b/drivers/gpu/drm/amd/display/dc/link/link_validation.c index afbd22631721..d4b7da526f0a 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_validation.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_validation.c @@ -30,6 +30,7 @@ */ #include "link_validation.h" #include "protocols/link_dp_capability.h" +#include "protocols/link_dp_dpia_bw.h" #include "resource.h" #define DC_LOGGER_INIT(logger) @@ -343,3 +344,20 @@ enum dc_status link_validate_mode_timing( return DC_OK; } + +bool link_validate_dpia_bandwidth(const struct dc_stream_state *stream, const unsigned int num_streams) +{ + bool ret = true; + int bw_needed[MAX_DPIA_NUM]; + struct dc_link *link[MAX_DPIA_NUM]; + + if (!num_streams || num_streams > MAX_DPIA_NUM) + return ret; + + for (uint8_t i = 0; i < num_streams; ++i) { + + link[i] = stream[i].link; + bw_needed[i] = dc_bandwidth_in_kbps_from_timing(&stream[i].timing); + } + return ret; +} diff --git a/drivers/gpu/drm/amd/display/dc/link/link_validation.h b/drivers/gpu/drm/amd/display/dc/link/link_validation.h index 2191d3a4950c..4a954317d0da 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_validation.h +++ b/drivers/gpu/drm/amd/display/dc/link/link_validation.h @@ -29,7 +29,11 @@ enum dc_status link_validate_mode_timing( const struct dc_stream_state *stream, struct dc_link *link, const struct dc_crtc_timing *timing); +bool link_validate_dpia_bandwidth( + const struct dc_stream_state *stream, + const unsigned int num_streams); uint32_t dp_link_bandwidth_kbps( const struct dc_link *link, const struct dc_link_settings *link_settings); + #endif /* __LINK_VALIDATION_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index 931f7c6446de..7581023daa47 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -33,10 +33,6 @@ #define DC_LOGGER \ link->ctx->logger -/* Number of Host Routers per motherboard is 2 */ -#define MAX_HR_NUM 2 -/* Number of DPIA per host router is 2 */ -#define MAX_DPIA_NUM (MAX_HR_NUM * 2) #define Kbps_TO_Gbps (1000 * 1000) // ------------------------------------------------------------------ @@ -379,9 +375,8 @@ void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t res // 1. If due to unplug of other sink if (estimated == host_router_total_estimated_bw) { // First update the estimated & max_bw fields - if (link->dpia_bw_alloc_config.estimated_bw < estimated) { + if (link->dpia_bw_alloc_config.estimated_bw < estimated) link->dpia_bw_alloc_config.estimated_bw = estimated; - } } // 2. If due to realloc bw btw 2 dpia due to plug OR realloc unused Bw else { @@ -464,7 +459,7 @@ int link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int re out: return ret; } -bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed_per_dpia, uint8_t num_dpias) +bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed_per_dpia, const unsigned int num_dpias) { bool ret = true; int bw_needed_per_hr[MAX_HR_NUM] = { 0, 0 }; 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 382616c8b698..7292690383ae 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 @@ -28,6 +28,11 @@ #include "link.h" +/* Number of Host Routers per motherboard is 2 */ +#define MAX_HR_NUM 2 +/* Number of DPIA per host router is 2 */ +#define MAX_DPIA_NUM (MAX_HR_NUM * 2) + /* * Host Router BW type */ @@ -92,6 +97,6 @@ void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t res * * return: TRUE if bw used by DPIAs doesn't exceed available BW else return FALSE */ -bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed, uint8_t num_dpias); +bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed, const unsigned int num_dpias); #endif /* DC_INC_LINK_DP_DPIA_BW_H_ */ -- cgit From a36f72547e0eb623912957aeb68465e3c9f7effe Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Thu, 9 Mar 2023 15:03:50 -0500 Subject: drm/amd/display: Add CRC and DMUB test support [Why & How] - Add CRC for test support - Add params to allow control into to DMUB. Reviewed-by: Chris Park Acked-by: Qingqing Zhuo Signed-off-by: Charlene Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h | 29 +++++++++++++++++++++++ drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 2 ++ drivers/gpu/drm/amd/display/include/dal_asic_id.h | 1 + 3 files changed, 32 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h index 0b37bb0e184b..db766689af58 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h @@ -161,10 +161,20 @@ struct dcn_optc_registers { uint32_t OTG_CRC_CNTL2; uint32_t OTG_CRC0_DATA_RG; uint32_t OTG_CRC0_DATA_B; + uint32_t OTG_CRC1_DATA_B; + uint32_t OTG_CRC2_DATA_B; + uint32_t OTG_CRC3_DATA_B; + uint32_t OTG_CRC1_DATA_RG; + uint32_t OTG_CRC2_DATA_RG; + uint32_t OTG_CRC3_DATA_RG; uint32_t OTG_CRC0_WINDOWA_X_CONTROL; uint32_t OTG_CRC0_WINDOWA_Y_CONTROL; uint32_t OTG_CRC0_WINDOWB_X_CONTROL; uint32_t OTG_CRC0_WINDOWB_Y_CONTROL; + uint32_t OTG_CRC1_WINDOWA_X_CONTROL; + uint32_t OTG_CRC1_WINDOWA_Y_CONTROL; + uint32_t OTG_CRC1_WINDOWB_X_CONTROL; + uint32_t OTG_CRC1_WINDOWB_Y_CONTROL; uint32_t GSL_SOURCE_SELECT; uint32_t DWB_SOURCE_SELECT; uint32_t OTG_DSC_START_POSITION; @@ -464,6 +474,15 @@ struct dcn_optc_registers { type CRC0_R_CR;\ type CRC0_G_Y;\ type CRC0_B_CB;\ + type CRC1_R_CR;\ + type CRC1_G_Y;\ + type CRC1_B_CB;\ + type CRC2_R_CR;\ + type CRC2_G_Y;\ + type CRC2_B_CB;\ + type CRC3_R_CR;\ + type CRC3_G_Y;\ + type CRC3_B_CB;\ type OTG_CRC0_WINDOWA_X_START;\ type OTG_CRC0_WINDOWA_X_END;\ type OTG_CRC0_WINDOWA_Y_START;\ @@ -472,6 +491,15 @@ struct dcn_optc_registers { type OTG_CRC0_WINDOWB_X_END;\ type OTG_CRC0_WINDOWB_Y_START;\ type OTG_CRC0_WINDOWB_Y_END;\ + type OTG_CRC_WINDOW_DB_EN;\ + type OTG_CRC1_WINDOWA_X_START;\ + type OTG_CRC1_WINDOWA_X_END;\ + type OTG_CRC1_WINDOWA_Y_START;\ + type OTG_CRC1_WINDOWA_Y_END;\ + type OTG_CRC1_WINDOWB_X_START;\ + type OTG_CRC1_WINDOWB_X_END;\ + type OTG_CRC1_WINDOWB_Y_START;\ + type OTG_CRC1_WINDOWB_Y_END;\ type GSL0_READY_SOURCE_SEL;\ type GSL1_READY_SOURCE_SEL;\ type GSL2_READY_SOURCE_SEL;\ @@ -525,6 +553,7 @@ struct dcn_optc_registers { #define TG_REG_FIELD_LIST_DCN3_2(type) \ type OTG_H_TIMING_DIV_MODE_MANUAL; + struct dcn_optc_shift { TG_REG_FIELD_LIST(uint8_t) TG_REG_FIELD_LIST_DCN3_2(uint8_t) diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h index a391b939d709..ba1715e2d25a 100644 --- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h @@ -261,6 +261,8 @@ struct dmub_srv_hw_params { bool usb4_cm_version; bool fw_in_system_memory; bool dpia_hpd_int_enable_supported; + bool disable_clock_gate; + bool disallow_dispclk_dppclk_ds; }; /** diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h index c3089c673975..e317089cf6ee 100644 --- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h +++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h @@ -246,6 +246,7 @@ enum { #define AMDGPU_FAMILY_GC_11_0_0 145 #define AMDGPU_FAMILY_GC_11_0_1 148 +#define AMDGPU_FAMILY_GC_11_5_0 150 #define GC_11_0_0_A0 0x1 #define GC_11_0_2_A0 0x10 #define GC_11_0_3_A0 0x20 -- cgit From 63bb1064a71d9372a643dbf1d00b736f203c867f Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Fri, 10 Mar 2023 14:32:26 -0500 Subject: drm/amd/display: add missing code change init pix_per_cycle [why] missing change when port to these two dcn version. Reviewed-by: Chris Park Reviewed-by: Leo Ma Reviewed-by: Nicholas Kazlauskas Acked-by: Qingqing Zhuo Signed-off-by: Charlene Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c index 89de64f18040..d05e7655f603 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c @@ -294,6 +294,7 @@ static void enc32_stream_encoder_dp_unblank( || is_dp_dig_pixel_rate_div_policy(dc, ¶m->timing)) { /*this logic should be the same in get_pixel_clock_parameters() */ n_multiply = 1; + pix_per_cycle = 1; } /* M / N = Fstream / Flink * m_vid / n_vid = pixel rate / link rate -- cgit From ea2b852b656afaf6d45597abbcac8425fa6ab02d Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Thu, 9 Mar 2023 10:30:32 -0700 Subject: drm/amd/display: Set MPC_SPLIT_DYNAMIC for DCN10 Since DC version 3.2.226, DC started to use a new internal commit sequence that better deals with multiple hardware constraints. One of the improvements is a more reliable sequence for pipe split. Due to the transition made in version 3.2.226, it should be more reliable to use the pipe policy as MPC_SPLIT_DYNAMIC, and this commit makes this change. Acked-by: Qingqing Zhuo Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 2bb8e11f26e0..21ec1ba5ed75 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -542,8 +542,8 @@ static const struct dc_debug_options debug_defaults_drv = { .disable_pplib_clock_request = false, .disable_pplib_wm_range = false, .pplib_wm_report_mode = WM_REPORT_DEFAULT, - .pipe_split_policy = MPC_SPLIT_AVOID, - .force_single_disp_pipe_split = false, + .pipe_split_policy = MPC_SPLIT_DYNAMIC, + .force_single_disp_pipe_split = true, .disable_dcc = DCC_ENABLE, .voltage_align_fclk = true, .disable_stereo_support = true, -- cgit From 75b204ee6cac4595cc663daf59b40162bbf411fb Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Thu, 9 Mar 2023 11:18:38 -0700 Subject: drm/amd/display: Set MPC_SPLIT_DYNAMIC for DCN301 Since DC version 3.2.226, DC started to use a new internal commit sequence that better deals with hardware limitations. Usually, DC adopts split pipe dynamics to improve the display bandwidth and, in some cases, to save power. This commit sets MPC_SPLIT_DYNAMIC for DCN301, improving the bandwidth and fixing the cursor bug on KDE when it tries hardware rotation. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2247 Cc: Melissa Wen Cc: Xaver Hugl Reviewed-by: Melissa Wen Acked-by: Qingqing Zhuo Acked-by: Hamza Mahfooz Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c index b93b4498dba4..5ac2a272c380 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c @@ -687,7 +687,7 @@ static const struct dc_debug_options debug_defaults_drv = { .disable_clock_gate = true, .disable_pplib_clock_request = true, .disable_pplib_wm_range = true, - .pipe_split_policy = MPC_SPLIT_AVOID, + .pipe_split_policy = MPC_SPLIT_DYNAMIC, .force_single_disp_pipe_split = false, .disable_dcc = DCC_ENABLE, .vsr_support = true, -- cgit From 27dd79c00aeab36cd7542c7a4481a32549038659 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 28 Feb 2023 14:46:46 -0500 Subject: Revert "drm/amdgpu/display: change pipe policy for DCN 2.0" This reverts commit bcfab8e35ce81e2fd3230c1575024bfde0d28c8b. Hopefully this is fixed by the previous patch to enable TEMP_DEPENDENT_VMIN for navi1x or otherwise and we can re-enable MPC_SPLIT_DYNAMIC for DCN 2.0 for better power savings. Reviewed-by: Rodrigo Siqueira Acked-by: Qingqing Zhuo Signed-off-by: Alex Deucher Tested-by: Daniel Wheeler --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 77ef474ced07..1d8c5805ef20 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -712,7 +712,7 @@ static const struct dc_debug_options debug_defaults_drv = { .timing_trace = false, .clock_trace = true, .disable_pplib_clock_request = true, - .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, + .pipe_split_policy = MPC_SPLIT_DYNAMIC, .force_single_disp_pipe_split = false, .disable_dcc = DCC_ENABLE, .vsr_support = true, -- cgit From 1c1f61057c10107d15093522c097d9bf54703ae3 Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Thu, 9 Mar 2023 14:43:12 -0500 Subject: drm/amd/display: align commit_planes_for_stream to latest dc code [Why & How] Due to historic issues, commit_planes_for_stream() has grown differently compared to latest dc code. Apply missed changes to make it aligned. Acked-by: Qingqing Zhuo Signed-off-by: Hersen Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index dc67256f565d..40f2e174c524 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -3493,22 +3493,6 @@ static void commit_planes_for_stream(struct dc *dc, dc_dmub_update_dirty_rect(dc, surface_count, stream, srf_updates, context); - if (update_type != UPDATE_TYPE_FAST) { - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; - - if ((new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) || - subvp_prev_use) { - // If old context or new context has phantom pipes, apply - // the phantom timings now. We can't change the phantom - // pipe configuration safely without driver acquiring - // the DMCUB lock first. - dc->hwss.apply_ctx_to_hw(dc, context); - break; - } - } - } - // Stream updates if (stream_update) commit_planes_do_stream_update(dc, stream, stream_update, update_type, context); @@ -3724,6 +3708,9 @@ static void commit_planes_for_stream(struct dc *dc, } } + if (update_type != UPDATE_TYPE_FAST) + dc->hwss.post_unlock_program_front_end(dc, context); + if (subvp_prev_use && !subvp_curr_use) { /* If disabling subvp, disable phantom streams after front end * programming has completed (we turn on phantom OTG in order @@ -3732,16 +3719,9 @@ static void commit_planes_for_stream(struct dc *dc, dc->hwss.apply_ctx_to_hw(dc, context); } - if (update_type != UPDATE_TYPE_FAST) - dc->hwss.post_unlock_program_front_end(dc, context); if (update_type != UPDATE_TYPE_FAST) if (dc->hwss.commit_subvp_config) dc->hwss.commit_subvp_config(dc, context); - - if (update_type != UPDATE_TYPE_FAST) - if (dc->hwss.commit_subvp_config) - dc->hwss.commit_subvp_config(dc, context); - /* Since phantom pipe programming is moved to post_unlock_program_front_end, * move the SubVP lock to after the phantom pipes have been setup */ -- cgit From 2fedafc7ef071979b07fe9e9ccb7af210b65da0e Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Thu, 9 Mar 2023 16:14:08 -0500 Subject: drm/amd/display: fix wrong index used in dccg32_set_dpstreamclk [Why & How] When merging commit 9af611f29034 ("drm/amd/display: Fix DCN32 DPSTREAMCLK_CNTL programming"), index change was not picked up. Cc: stable@vger.kernel.org Cc: Mario Limonciello Fixes: 9af611f29034 ("drm/amd/display: Fix DCN32 DPSTREAMCLK_CNTL programming") Reviewed-by: Qingqing Zhuo Acked-by: Qingqing Zhuo Signed-off-by: Hersen Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c index 5dbef498580b..ffbb739d85b6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c @@ -293,8 +293,7 @@ static void dccg32_set_dpstreamclk( dccg32_set_dtbclk_p_src(dccg, src, otg_inst); /* enabled to select one of the DTBCLKs for pipe */ - switch (otg_inst) - { + switch (dp_hpo_inst) { case 0: REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK0_EN, -- cgit From ae8df8c9f630403bb74d3c6e9768fe3991d547f6 Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Thu, 9 Mar 2023 15:58:54 -0500 Subject: drm/amd/display: Set dcn32 caps.seamless_odm [Why & How] seamless_odm set was not picked up while merging commit 2d017189e2b3 ("drm/amd/display: Blank eDP on enable drv if odm enabled") Fixes: 2d017189e2b3 ("drm/amd/display: Blank eDP on enable drv if odm enabled") Reviewed-by: Qingqing Zhuo Acked-by: Qingqing Zhuo Signed-off-by: Hersen Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index 633491331722..1715909b1225 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -2185,6 +2185,7 @@ static bool dcn32_resource_construct( dc->caps.edp_dsc_support = true; dc->caps.extended_aux_timeout_support = true; dc->caps.dmcub_support = true; + dc->caps.seamless_odm = true; /* Color pipeline capabilities */ dc->caps.color.dpp.dcn_arch = 1; -- cgit From 2a867a85ee0251cf55abca75e745c5f66f76c125 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Mon, 13 Mar 2023 01:09:20 -0400 Subject: drm/amd/display: 3.2.228 This DC version brings along: - Power down eDP if eDP not present - Set MPC_SPLIT_DYNAMIC for DCN10 and DCN301 - Initialize link_srv in virtual env - Code cleanup and alignment Acked-by: Qingqing Zhuo 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(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 1e6fa2d387f7..475128db02bb 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -45,7 +45,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.227" +#define DC_VER "3.2.228" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- cgit From 6d457ca162da98a6a1a381320e936d7448177de9 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Mon, 6 Mar 2023 11:39:51 +0800 Subject: drm/amd/display: remove outdated 8bpc comments [Why] The commit c76e483cd916 ("drm/amd/display: Don't restrict bpc to 8 bpc") removes the historical 8bpc dependency and sets max_bpc to 16. [How] The comment that states "8bpc for non-edp" needs to be removed as well. Reviewed-by: Harry Wentland Acked-by: Qingqing Zhuo Signed-off-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 32abbafd43fa..a01fd41643fc 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7244,7 +7244,6 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, if (!aconnector->mst_root) drm_connector_attach_max_bpc_property(&aconnector->base, 8, 16); - /* This defaults to the max in the range, but we want 8bpc for non-edp. */ aconnector->base.state->max_bpc = 16; aconnector->base.state->max_requested_bpc = aconnector->base.state->max_bpc; -- cgit From 4c94e57c258cb7800aa5f3a9d9597d91291407a9 Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Thu, 9 Mar 2023 16:14:08 -0500 Subject: drm/amd/display: fix wrong index used in dccg32_set_dpstreamclk [Why & How] When merging commit 9af611f29034 ("drm/amd/display: Fix DCN32 DPSTREAMCLK_CNTL programming"), index change was not picked up. Cc: stable@vger.kernel.org Cc: Mario Limonciello Fixes: 9af611f29034 ("drm/amd/display: Fix DCN32 DPSTREAMCLK_CNTL programming") Reviewed-by: Qingqing Zhuo Acked-by: Qingqing Zhuo Signed-off-by: Hersen Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c index e4472c6be6c3..3fb4bcc34353 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c @@ -271,8 +271,7 @@ static void dccg32_set_dpstreamclk( dccg32_set_dtbclk_p_src(dccg, src, otg_inst); /* enabled to select one of the DTBCLKs for pipe */ - switch (otg_inst) - { + switch (dp_hpo_inst) { case 0: REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK0_EN, -- cgit From f9537b1fa7fb51c2162bc15ce469cbbf1ca0fbfe Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Thu, 9 Mar 2023 15:58:54 -0500 Subject: drm/amd/display: Set dcn32 caps.seamless_odm [Why & How] seamless_odm set was not picked up while merging commit 2d017189e2b3 ("drm/amd/display: Blank eDP on enable drv if odm enabled") Fixes: 2d017189e2b3 ("drm/amd/display: Blank eDP on enable drv if odm enabled") Reviewed-by: Qingqing Zhuo Acked-by: Qingqing Zhuo Signed-off-by: Hersen Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index d024007f0f65..4b7abb4af623 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -2186,6 +2186,7 @@ static bool dcn32_resource_construct( dc->caps.edp_dsc_support = true; dc->caps.extended_aux_timeout_support = true; dc->caps.dmcub_support = true; + dc->caps.seamless_odm = true; /* Color pipeline capabilities */ dc->caps.color.dpp.dcn_arch = 1; -- cgit From 4cf3ae9d8e9a5f77e8a1f69f17c92dc59ba15154 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Wed, 22 Mar 2023 11:14:19 +0800 Subject: drm/amd/display: Clean up some inconsistent indenting No functional modification involved. Reported-by: Abaci Robot Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=4585 Signed-off-by: Jiapeng Chong Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/modules/power/power_helpers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c index fa469de3e935..0d3a983cb9ec 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -758,8 +758,8 @@ bool dmcu_load_iram(struct dmcu *dmcu, if (dmcu->dmcu_version.abm_version == 0x24) { fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params, true); - result = dmcu->funcs->load_iram( - dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2); + result = dmcu->funcs->load_iram(dmcu, 0, (char *)(&ram_table), + IRAM_RESERVE_AREA_START_V2_2); } else if (dmcu->dmcu_version.abm_version == 0x23) { fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params, true); -- cgit From a76766664a9f91dfde906fecd1409ba596a30e33 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Wed, 22 Mar 2023 09:59:17 +0800 Subject: drm/amd/display: Remove the unused variable dppclk_delay_subtotal Variable dppclk_delay_subtotal is not effectively used, so delete it. drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn314/display_rq_dlg_calc_314.c:1004:15: warning: variable 'dppclk_delay_subtotal' set but not used. Reported-by: Abaci Robot Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=4584 Signed-off-by: Jiapeng Chong Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dml/dcn314/display_rq_dlg_calc_314.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_rq_dlg_calc_314.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_rq_dlg_calc_314.c index 6576b897a512..d1c2693a2e28 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_rq_dlg_calc_314.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_rq_dlg_calc_314.c @@ -1001,7 +1001,6 @@ static void dml_rq_dlg_get_dlg_params( unsigned int vupdate_width; unsigned int vready_offset; - unsigned int dppclk_delay_subtotal; unsigned int dispclk_delay_subtotal; unsigned int vstartup_start; @@ -1130,17 +1129,8 @@ static void dml_rq_dlg_get_dlg_params( vupdate_offset = dst->vupdate_offset; vupdate_width = dst->vupdate_width; vready_offset = dst->vready_offset; - - dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal; dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal; - if (scl_enable) - dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl; - else - dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl_lb_only; - - dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_cnvc_formatter + src->num_cursors * mode_lib->ip.dppclk_delay_cnvc_cursor; - if (dout->dsc_enable) { double dsc_delay = get_dsc_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); // FROM VBA -- cgit From 0e909e4fa8895bcef1b1ef2e39b9f1a158933ffe Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Tue, 21 Mar 2023 18:58:50 +0100 Subject: drm/amd/display: Slightly optimize dm_dmub_outbox1_low_irq() A kzalloc()+memcpy() can be optimized in a single kmemdup(). This saves a few cycles because some memory doesn't need to be zeroed. Signed-off-by: Christophe JAILLET Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 5bac5781a06b..57a5fbdab890 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -820,15 +820,14 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params) DRM_ERROR("Failed to allocate dmub_hpd_wrk"); return; } - dmub_hpd_wrk->dmub_notify = kzalloc(sizeof(struct dmub_notification), GFP_ATOMIC); + dmub_hpd_wrk->dmub_notify = kmemdup(¬ify, sizeof(struct dmub_notification), + GFP_ATOMIC); if (!dmub_hpd_wrk->dmub_notify) { kfree(dmub_hpd_wrk); DRM_ERROR("Failed to allocate dmub_hpd_wrk->dmub_notify"); return; } INIT_WORK(&dmub_hpd_wrk->handle_hpd_work, dm_handle_hpd_work); - if (dmub_hpd_wrk->dmub_notify) - memcpy(dmub_hpd_wrk->dmub_notify, ¬ify, sizeof(struct dmub_notification)); dmub_hpd_wrk->adev = adev; if (notify.type == DMUB_NOTIFICATION_HPD) { plink = adev->dm.dc->links[notify.link_index]; -- cgit From f4f3b7dedbe849e780c779ba67365bb1db0d8637 Mon Sep 17 00:00:00 2001 From: Fangzhi Zuo Date: Fri, 24 Feb 2023 13:45:21 -0500 Subject: drm/amd/display: Add DSC Support for Synaptics Cascaded MST Hub Traditional synaptics hub has one MST branch device without virtual dpcd. Synaptics cascaded hub has two chained MST branch devices. DSC decoding is performed via root MST branch device, instead of the second MST branch device. Reviewed-by: Hersen Wu Acked-by: Qingqing Zhuo Signed-off-by: Fangzhi Zuo Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 19 +++++++++++++++++++ .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h | 12 ++++++++++++ 2 files changed, 31 insertions(+) (limited to 'drivers/gpu/drm/amd/display') 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 e25e1b2bf194..30de0aa084d8 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 @@ -212,6 +212,21 @@ bool needs_dsc_aux_workaround(struct dc_link *link) return false; } +bool is_synaptics_cascaded_panamera(struct dc_link *link, struct drm_dp_mst_port *port) +{ + u8 branch_vendor_data[4] = { 0 }; // Vendor data 0x50C ~ 0x50F + + if (drm_dp_dpcd_read(port->mgr->aux, DP_BRANCH_VENDOR_SPECIFIC_START, &branch_vendor_data, 4) == 4) { + if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 && + IS_SYNAPTICS_CASCADED_PANAMERA(link->dpcd_caps.branch_dev_name, branch_vendor_data)) { + DRM_INFO("Synaptics Cascaded MST hub\n"); + return true; + } + } + + return false; +} + static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector) { struct dc_sink *dc_sink = aconnector->dc_sink; @@ -235,6 +250,10 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto needs_dsc_aux_workaround(aconnector->dc_link)) aconnector->dsc_aux = &aconnector->mst_root->dm_dp_aux.aux; + /* synaptics cascaded MST hub case */ + if (!aconnector->dsc_aux && is_synaptics_cascaded_panamera(aconnector->dc_link, port)) + aconnector->dsc_aux = port->mgr->aux; + if (!aconnector->dsc_aux) return false; diff --git 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 index 97fd70df531b..0b5750202e73 100644 --- 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 @@ -34,6 +34,18 @@ #define SYNAPTICS_RC_OFFSET 0x4BC #define SYNAPTICS_RC_DATA 0x4C0 +#define DP_BRANCH_VENDOR_SPECIFIC_START 0x50C + +/** + * Panamera MST Hub detection + * Offset DPCD 050Eh == 0x5A indicates cascaded MST hub case + * Check from beginning of branch device vendor specific field (050Ch) + */ +#define IS_SYNAPTICS_PANAMERA(branchDevName) (((int)branchDevName[4] & 0xF0) == 0x50 ? 1 : 0) +#define BRANCH_HW_REVISION_PANAMERA_A2 0x10 +#define SYNAPTICS_CASCADED_HUB_ID 0x5A +#define IS_SYNAPTICS_CASCADED_PANAMERA(devName, data) ((IS_SYNAPTICS_PANAMERA(devName) && ((int)data[2] == SYNAPTICS_CASCADED_HUB_ID)) ? 1 : 0) + struct amdgpu_display_manager; struct amdgpu_dm_connector; -- cgit From 68dc1846c3a44d5e633be145c169ce2fd5420695 Mon Sep 17 00:00:00 2001 From: Fangzhi Zuo Date: Tue, 28 Feb 2023 21:34:58 -0500 Subject: drm/amd/display: Take FEC Overhead into Timeslot Calculation 8b/10b encoding needs to add 3% fec overhead into the pbn. In the Synapcis Cascaded MST hub, the first stage MST branch device needs the information to determine the timeslot count for the second stage MST branch device. Missing this overhead will leads to insufficient timeslot allocation. Cc: stable@vger.kernel.org Cc: Mario Limonciello Reviewed-by: Hersen Wu Acked-by: Qingqing Zhuo Signed-off-by: Fangzhi Zuo Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 32 ++++++++++++++++------ .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.h | 3 ++ 2 files changed, 27 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 30de0aa084d8..8dc442f90eaf 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 @@ -681,12 +681,25 @@ struct dsc_mst_fairness_params { struct amdgpu_dm_connector *aconnector; }; -static int kbps_to_peak_pbn(int kbps) +static uint16_t get_fec_overhead_multiplier(struct dc_link *dc_link) +{ + u8 link_coding_cap; + uint16_t fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B; + + link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(dc_link); + if (link_coding_cap == DP_128b_132b_ENCODING) + fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B; + + return fec_overhead_multiplier_x1000; +} + +static int kbps_to_peak_pbn(int kbps, uint16_t fec_overhead_multiplier_x1000) { u64 peak_kbps = kbps; peak_kbps *= 1006; - peak_kbps = div_u64(peak_kbps, 1000); + peak_kbps *= fec_overhead_multiplier_x1000; + peak_kbps = div_u64(peak_kbps, 1000 * 1000); return (int) DIV64_U64_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000)); } @@ -780,11 +793,12 @@ static int increase_dsc_bpp(struct drm_atomic_state *state, int link_timeslots_used; int fair_pbn_alloc; int ret = 0; + uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link); for (i = 0; i < count; i++) { if (vars[i + k].dsc_enabled) { initial_slack[i] = - kbps_to_peak_pbn(params[i].bw_range.max_kbps) - vars[i + k].pbn; + kbps_to_peak_pbn(params[i].bw_range.max_kbps, fec_overhead_multiplier_x1000) - vars[i + k].pbn; bpp_increased[i] = false; remaining_to_increase += 1; } else { @@ -880,6 +894,7 @@ static int try_disable_dsc(struct drm_atomic_state *state, int next_index; int remaining_to_try = 0; int ret; + uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link); for (i = 0; i < count; i++) { if (vars[i + k].dsc_enabled @@ -909,7 +924,7 @@ static int try_disable_dsc(struct drm_atomic_state *state, if (next_index == -1) break; - vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps); + vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000); ret = drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port, @@ -922,7 +937,7 @@ static int try_disable_dsc(struct drm_atomic_state *state, vars[next_index].dsc_enabled = false; vars[next_index].bpp_x16 = 0; } else { - vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps); + vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps, fec_overhead_multiplier_x1000); ret = drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port, @@ -951,6 +966,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, int count = 0; int i, k, ret; bool debugfs_overwrite = false; + uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link); memset(params, 0, sizeof(params)); @@ -1012,7 +1028,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, /* Try no compression */ for (i = 0; i < count; i++) { vars[i + k].aconnector = params[i].aconnector; - vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); + vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000); vars[i + k].dsc_enabled = false; vars[i + k].bpp_x16 = 0; ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port, @@ -1031,7 +1047,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, /* Try max compression */ for (i = 0; i < count; i++) { if (params[i].compression_possible && params[i].clock_force_enable != DSC_CLK_FORCE_DISABLE) { - vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps); + vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps, fec_overhead_multiplier_x1000); vars[i + k].dsc_enabled = true; vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16; ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, @@ -1039,7 +1055,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, if (ret < 0) return ret; } else { - vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); + vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000); vars[i + k].dsc_enabled = false; vars[i + k].bpp_x16 = 0; ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, diff --git 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 index 0b5750202e73..1e4ede1e57ab 100644 --- 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 @@ -46,6 +46,9 @@ #define SYNAPTICS_CASCADED_HUB_ID 0x5A #define IS_SYNAPTICS_CASCADED_PANAMERA(devName, data) ((IS_SYNAPTICS_PANAMERA(devName) && ((int)data[2] == SYNAPTICS_CASCADED_HUB_ID)) ? 1 : 0) +#define PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B 1031 +#define PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B 1000 + struct amdgpu_display_manager; struct amdgpu_dm_connector; -- cgit From f196198cafb8f0f2bedf1d8abc755f791fc03648 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 12 Mar 2023 20:17:48 +0100 Subject: drm/amd/display/amdgpu_dm: Add a bl_idx to amdgpu_dm_connector Currently functions like update_connector_ext_caps() and amdgpu_dm_connector_destroy() are iterating over dm->backlight_link[i] to find the index of the (optional) backlight_dev associated with the connector. Instead make register_backlight_device() store the dm->backlight_dev[] index used for the connector inside the amdgpu_dm_connector struct. This removes the need to iterate over the dm->backlight_link[] array and this is necessary as a preparation patch for moving the actual backlight_device_register() call to drm_connector_funcs.late_register. While reworking update_connector_ext_caps() also remove the aconnector and aconnector->dc_link NULL checks in this function. These are both never NULL and are unconditionally derefed in its callers. Reviewed-by: Rodrigo Siqueira Signed-off-by: Hans de Goede Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 42 +++++++++-------------- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 1 + 2 files changed, 17 insertions(+), 26 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 57a5fbdab890..ee252158ef87 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2975,30 +2975,18 @@ static struct drm_mode_config_helper_funcs amdgpu_dm_mode_config_helperfuncs = { static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) { struct amdgpu_dm_backlight_caps *caps; - struct amdgpu_display_manager *dm; struct drm_connector *conn_base; struct amdgpu_device *adev; - struct dc_link *link = NULL; struct drm_luminance_range_info *luminance_range; - int i; - - if (!aconnector || !aconnector->dc_link) - return; - link = aconnector->dc_link; - if (link->connector_signal != SIGNAL_TYPE_EDP) + if (aconnector->bl_idx == -1 || + aconnector->dc_link->connector_signal != SIGNAL_TYPE_EDP) return; conn_base = &aconnector->base; adev = drm_to_adev(conn_base->dev); - dm = &adev->dm; - for (i = 0; i < dm->num_of_edps; i++) { - if (link == dm->backlight_link[i]) - break; - } - if (i >= dm->num_of_edps) - return; - caps = &dm->backlight_caps[i]; + + caps = &adev->dm.backlight_caps[aconnector->bl_idx]; caps->ext_caps = &aconnector->dc_link->dpcd_sink_ext_caps; caps->aux_support = false; @@ -4266,8 +4254,9 @@ static int initialize_plane(struct amdgpu_display_manager *dm, static void register_backlight_device(struct amdgpu_display_manager *dm, - struct dc_link *link) + struct amdgpu_dm_connector *aconnector) { + struct dc_link *link = aconnector->dc_link; int bl_idx = dm->num_of_edps; if (!(link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) || @@ -4279,9 +4268,13 @@ static void register_backlight_device(struct amdgpu_display_manager *dm, return; } + aconnector->bl_idx = bl_idx; + amdgpu_dm_register_backlight_device(dm); - if (!dm->backlight_dev[bl_idx]) + if (!dm->backlight_dev[bl_idx]) { + aconnector->bl_idx = -1; return; + } dm->backlight_link[bl_idx] = link; dm->num_of_edps++; @@ -4464,7 +4457,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) if (ret) { amdgpu_dm_update_connector_after_detect(aconnector); - register_backlight_device(dm, link); + register_backlight_device(dm, aconnector); if (dm->num_of_edps) update_connector_ext_caps(aconnector); @@ -6243,10 +6236,8 @@ static void amdgpu_dm_connector_unregister(struct drm_connector *connector) static void amdgpu_dm_connector_destroy(struct drm_connector *connector) { struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); - const struct dc_link *link = aconnector->dc_link; struct amdgpu_device *adev = drm_to_adev(connector->dev); struct amdgpu_display_manager *dm = &adev->dm; - int i; /* * Call only if mst_mgr was initialized before since it's not done @@ -6255,11 +6246,9 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector) if (aconnector->mst_mgr.dev) drm_dp_mst_topology_mgr_destroy(&aconnector->mst_mgr); - for (i = 0; i < dm->num_of_edps; i++) { - if ((link == dm->backlight_link[i]) && dm->backlight_dev[i]) { - backlight_device_unregister(dm->backlight_dev[i]); - dm->backlight_dev[i] = NULL; - } + if (aconnector->bl_idx != -1) { + backlight_device_unregister(dm->backlight_dev[aconnector->bl_idx]); + dm->backlight_dev[aconnector->bl_idx] = NULL; } if (aconnector->dc_em_sink) @@ -7229,6 +7218,7 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, aconnector->base.funcs->reset(&aconnector->base); aconnector->connector_id = link_index; + aconnector->bl_idx = -1; aconnector->dc_link = link; aconnector->base.interlace_allowed = false; aconnector->base.doublescan_allowed = false; 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 904f9e2fd35b..2e2413fd73a4 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -610,6 +610,7 @@ struct amdgpu_dm_connector { struct drm_connector base; uint32_t connector_id; + int bl_idx; /* we need to mind the EDID between detect and get modes due to analog/digital/tvencoder */ -- cgit From 618e51cd526cbbb2ea9ad01ef1f67719b775f792 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 12 Mar 2023 20:17:49 +0100 Subject: drm/amd/display/amdgpu_dm: Move most backlight setup into setup_backlight_device() Rename register_backlight_device() to setup_backlight_device() and move all backlight setup related calls from amdgpu_dm_register_backlight_device() and from amdgpu_dm_initialize_drm_device() there. This leaves amdgpu_dm_register_backlight_device() dealing purely with registering the actual backlight class device. This is a preparation patch for moving the actual backlight class device registering to drm_connector_funcs.late_register. Reviewed-by: Rodrigo Siqueira Signed-off-by: Hans de Goede Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 ee252158ef87..52248616c737 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4182,9 +4182,6 @@ amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm) char bl_name[16]; struct backlight_properties props = { 0 }; - amdgpu_dm_update_backlight_caps(dm, dm->num_of_edps); - dm->brightness[dm->num_of_edps] = AMDGPU_MAX_BL_LEVEL; - if (!acpi_video_backlight_use_native()) { drm_info(adev_to_drm(dm->adev), "Skipping amdgpu DM backlight registration\n"); /* Try registering an ACPI video backlight device instead. */ @@ -4253,8 +4250,8 @@ static int initialize_plane(struct amdgpu_display_manager *dm, } -static void register_backlight_device(struct amdgpu_display_manager *dm, - struct amdgpu_dm_connector *aconnector) +static void setup_backlight_device(struct amdgpu_display_manager *dm, + struct amdgpu_dm_connector *aconnector) { struct dc_link *link = aconnector->dc_link; int bl_idx = dm->num_of_edps; @@ -4270,6 +4267,9 @@ static void register_backlight_device(struct amdgpu_display_manager *dm, aconnector->bl_idx = bl_idx; + amdgpu_dm_update_backlight_caps(dm, bl_idx); + dm->brightness[bl_idx] = AMDGPU_MAX_BL_LEVEL; + amdgpu_dm_register_backlight_device(dm); if (!dm->backlight_dev[bl_idx]) { aconnector->bl_idx = -1; @@ -4278,6 +4278,8 @@ static void register_backlight_device(struct amdgpu_display_manager *dm, dm->backlight_link[bl_idx] = link; dm->num_of_edps++; + + update_connector_ext_caps(aconnector); } static void amdgpu_set_panel_orientation(struct drm_connector *connector); @@ -4457,10 +4459,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) if (ret) { amdgpu_dm_update_connector_after_detect(aconnector); - register_backlight_device(dm, aconnector); - - if (dm->num_of_edps) - update_connector_ext_caps(aconnector); + setup_backlight_device(dm, aconnector); if (psr_feature_enabled) amdgpu_dm_set_psr_caps(link); -- cgit From 213eca2b0c042b024bf9697a278619f887bab4e5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 12 Mar 2023 20:17:50 +0100 Subject: drm/amd/display/amdgpu_dm: Make amdgpu_dm_register_backlight_device() take an amdgpu_dm_connector Make amdgpu_dm_register_backlight_device() take an amdgpu_dm_connector pointer to the connector for which it should register the backlight as its only argument. This is a preparation patch for moving the actual backlight class device registering to drm_connector_funcs.late_register. Reviewed-by: Rodrigo Siqueira Signed-off-by: Hans de Goede Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 52248616c737..aee79506a969 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4177,13 +4177,15 @@ static const struct backlight_ops amdgpu_dm_backlight_ops = { }; static void -amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm) +amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) { - char bl_name[16]; + struct drm_device *drm = aconnector->base.dev; + struct amdgpu_display_manager *dm = &drm_to_adev(drm)->dm; struct backlight_properties props = { 0 }; + char bl_name[16]; if (!acpi_video_backlight_use_native()) { - drm_info(adev_to_drm(dm->adev), "Skipping amdgpu DM backlight registration\n"); + drm_info(drm, "Skipping amdgpu DM backlight registration\n"); /* Try registering an ACPI video backlight device instead. */ acpi_video_register_backlight(); return; @@ -4194,17 +4196,15 @@ amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm) props.type = BACKLIGHT_RAW; snprintf(bl_name, sizeof(bl_name), "amdgpu_bl%d", - adev_to_drm(dm->adev)->primary->index + dm->num_of_edps); + drm->primary->index + aconnector->bl_idx); - dm->backlight_dev[dm->num_of_edps] = backlight_device_register(bl_name, - adev_to_drm(dm->adev)->dev, - dm, - &amdgpu_dm_backlight_ops, - &props); + dm->backlight_dev[aconnector->bl_idx] = + backlight_device_register(bl_name, drm->dev, dm, + &amdgpu_dm_backlight_ops, &props); - if (IS_ERR(dm->backlight_dev[dm->num_of_edps])) { + if (IS_ERR(dm->backlight_dev[aconnector->bl_idx])) { DRM_ERROR("DM: Backlight registration failed!\n"); - dm->backlight_dev[dm->num_of_edps] = NULL; + dm->backlight_dev[aconnector->bl_idx] = NULL; } else DRM_DEBUG_DRIVER("DM: Registered Backlight device: %s\n", bl_name); } @@ -4270,7 +4270,7 @@ static void setup_backlight_device(struct amdgpu_display_manager *dm, amdgpu_dm_update_backlight_caps(dm, bl_idx); dm->brightness[bl_idx] = AMDGPU_MAX_BL_LEVEL; - amdgpu_dm_register_backlight_device(dm); + amdgpu_dm_register_backlight_device(aconnector); if (!dm->backlight_dev[bl_idx]) { aconnector->bl_idx = -1; return; -- cgit From 62f03dad76441ee3a58c26a0bbe703028e846db0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 12 Mar 2023 20:17:51 +0100 Subject: drm/amd/display/amdgpu_dm: Pass proper parent for backlight device registration v3 The parent for the backlight device should be the drm-connector object, not the PCI device. Userspace relies on this to be able to detect which backlight class device to use on hybrid gfx devices where there may be multiple native (raw) backlight devices registered. Specifically gnome-settings-daemon expects the parent device to have an "enabled" sysfs attribute (as drm_connector devices do) and tests that this returns "enabled" when read. This aligns the parent of the backlight device with i915, nouveau, radeon. Note that drivers/gpu/drm/amd/amdgpu/atombios_encoders.c also already uses the drm_connector as parent, only amdgpu_dm.c used the PCI device as parent before this change. Changes in v3: Make amdgpu_dm_register_backlight_device() check bl_idx != 1 before registering the backlight since amdgpu_dm_connector_late_register() now calls it for _all_ connectors. Changes in v2: Together with changing the parent, also move the registration to drm_connector_funcs.late_register() this is necessary because the parent device (which now is the drm_connector) must be registered before the backlight class device is, otherwise the backlight class device ends up without any parent set at all. This brings the backlight class device registration timing inline with nouveau and i915 which also use drm_connector_funcs.late_register() for this. Note this slightly changes backlight_device_register() error handling, instead of not increasing dm->num_of_edps and re-using the current bl_idx for a potential other backlight device, dm->backlight_dev[bl_idx] is now simply left NULL on failure. This is ok because all code looking at dm->backlight_dev[i] also checks it is not NULL. Link: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/730 Reviewed-by: Rodrigo Siqueira Signed-off-by: Hans de Goede Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 aee79506a969..5d0069f383d4 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4184,6 +4184,9 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) struct backlight_properties props = { 0 }; char bl_name[16]; + if (aconnector->bl_idx == -1) + return; + if (!acpi_video_backlight_use_native()) { drm_info(drm, "Skipping amdgpu DM backlight registration\n"); /* Try registering an ACPI video backlight device instead. */ @@ -4199,7 +4202,7 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) drm->primary->index + aconnector->bl_idx); dm->backlight_dev[aconnector->bl_idx] = - backlight_device_register(bl_name, drm->dev, dm, + backlight_device_register(bl_name, aconnector->base.kdev, dm, &amdgpu_dm_backlight_ops, &props); if (IS_ERR(dm->backlight_dev[aconnector->bl_idx])) { @@ -4269,13 +4272,6 @@ static void setup_backlight_device(struct amdgpu_display_manager *dm, amdgpu_dm_update_backlight_caps(dm, bl_idx); dm->brightness[bl_idx] = AMDGPU_MAX_BL_LEVEL; - - amdgpu_dm_register_backlight_device(aconnector); - if (!dm->backlight_dev[bl_idx]) { - aconnector->bl_idx = -1; - return; - } - dm->backlight_link[bl_idx] = link; dm->num_of_edps++; @@ -6329,6 +6325,8 @@ amdgpu_dm_connector_late_register(struct drm_connector *connector) to_amdgpu_dm_connector(connector); int r; + amdgpu_dm_register_backlight_device(amdgpu_dm_connector); + if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) || (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { amdgpu_dm_connector->dm_dp_aux.aux.dev = connector->kdev; -- cgit From d29fb7baab09b6a1dc484c9c67933253883e770a Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Sat, 11 Mar 2023 09:11:29 -0500 Subject: drm/amd/display: Add NULL plane_state check for cursor disable logic [Why] While scanning the top_pipe connections we can run into a case where the bottom pipe is still connected to a top_pipe but with a NULL plane_state. [How] Treat a NULL plane_state the same as the plane being invisible for pipe cursor disable logic. Cc: stable@vger.kernel.org Cc: Mario Limonciello Reviewed-by: Charlene Liu Acked-by: Qingqing Zhuo Signed-off-by: Nicholas Kazlauskas Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 7f9cceb49f4e..46ca88741cb8 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 @@ -3385,7 +3385,9 @@ static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) for (test_pipe = pipe_ctx->top_pipe; test_pipe; test_pipe = test_pipe->top_pipe) { // Skip invisible layer and pipe-split plane on same layer - if (!test_pipe->plane_state->visible || test_pipe->plane_state->layer_index == cur_layer) + if (!test_pipe->plane_state || + !test_pipe->plane_state->visible || + test_pipe->plane_state->layer_index == cur_layer) continue; r2 = test_pipe->plane_res.scl_data.recout; -- cgit From ac18b610fd95762125cd6a7194cc7e2e3b94e3ed Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Mon, 13 Mar 2023 12:54:49 -0400 Subject: drm/amd/display: Enable FPO for configs that could reduce vlevel [Description] - On high refresh rate DRR displays that support VBLANK naturally, UCLK could be idling at DPM1 instead of DPM0 since it doesn't use FPO - To achieve DPM0, enable FPO on these configs even though it can support P-State without FPO - Default disable for now, have debug option to enable Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 1 + .../drm/amd/display/dc/dcn321/dcn321_resource.c | 1 + .../gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 23 ++++++++++++++++------ 4 files changed, 20 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 475128db02bb..2d2621abf012 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -873,6 +873,7 @@ struct dc_debug_options { bool dig_fifo_off_in_blank; bool temp_mst_deallocation_sequence; bool override_dispclk_programming; + bool disable_fpo_optimizations; }; struct gpu_info_soc_bounding_box_v1_0; diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index 1715909b1225..b8c1de357e5f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -725,6 +725,7 @@ static const struct dc_debug_options debug_defaults_drv = { .min_prefetch_in_strobe_ns = 60000, // 60us .disable_unbounded_requesting = false, .override_dispclk_programming = true, + .disable_fpo_optimizations = true, }; static const struct dc_debug_options debug_defaults_diags = { 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 c6a0e84885a2..5e0b1484dc18 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c @@ -723,6 +723,7 @@ static const struct dc_debug_options debug_defaults_drv = { .min_prefetch_in_strobe_ns = 60000, // 60us .disable_unbounded_requesting = false, .override_dispclk_programming = true, + .disable_fpo_optimizations = true, }; static const struct dc_debug_options debug_defaults_diags = { 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 6b29d3a9520f..4e17f2c8d2b7 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 @@ -1961,7 +1961,8 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = false; - if (!pstate_en) { + if (!pstate_en || (!dc->debug.disable_fpo_optimizations && + pstate_en && vlevel != 0)) { /* only when the mclk switch can not be natural, is the fw based vblank stretch attempted */ context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch(dc, context); @@ -1985,11 +1986,21 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, context->bw_ctx.dml.soc.fclk_change_latency_us = dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us; } - dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false); - maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb; - dcfclk_from_fw_based_mclk_switching = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb]; - pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] != - dm_dram_clock_change_unsupported; + dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel_temp, false); + if (vlevel_temp < vlevel) { + vlevel = vlevel_temp; + maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb; + dcfclk_from_fw_based_mclk_switching = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb]; + pstate_en = true; + } else { + /* Restore FCLK latency and re-run validation to go back to original validation + * output if we find that enabling FPO does not give us any benefit (i.e. lower + * voltage level) + */ + context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = false; + context->bw_ctx.dml.soc.fclk_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.fclk_change_latency_us; + dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false); + } } } -- cgit From 1991481828a84dcc5168f1e9b818311cbde86876 Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Mon, 13 Mar 2023 18:06:34 -0400 Subject: drm/amd/display: Update FCLK change latency [Descrtipion] - Driver hardcoded FCLK P-State latency was incorrect - Use the value provided by PMFW header instead Reviewed-by: Nevenko Stupar Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 4e17f2c8d2b7..6ab60facc091 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 @@ -131,7 +131,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = { .urgent_latency_pixel_data_only_us = 4.0, .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, .urgent_latency_vm_data_only_us = 4.0, - .fclk_change_latency_us = 20, + .fclk_change_latency_us = 25, .usr_retraining_latency_us = 2, .smn_latency_us = 2, .mall_allocated_for_dcn_mbytes = 64, -- cgit From bf224e00a9f54e2bf14b4d720a09c3d2f4aa4aa8 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Mon, 13 Mar 2023 13:23:45 -0400 Subject: drm/amd/display: Fix 4to1 MPC black screen with DPP RCO [Why] DPP Root clock optimization when combined with 4to1 MPC combine results in the screen turning black. This is because the DPPCLK is stopped during the middle of an optimize_bandwidth sequence during commit_minimal_transition without going through plane power down/power up. [How] The intent of a 0Hz DPP clock through update_clocks is to disable the DTO. This differs from the behavior of stopping the DPPCLK entirely (utilizing a 0Hz clock on some ASIC) so it's better to move this logic to reside next to plane power up/power down where we gate the HUBP/DPP DOMAIN. The new sequence should be: Power down: PG enabled -> RCO on Power up: RCO off -> PG disabled Rename power_on_plane to power_on_plane_resources to reflect the actual operation that's occurring. Cc: stable@vger.kernel.org Cc: Mario Limonciello Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Nicholas Kazlauskas Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 12 +++++++++-- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 8 +++++-- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c | 13 ++--------- .../gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c | 23 ++++++++++++++++++++ .../gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c | 10 +++++++++ .../gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h | 2 ++ .../gpu/drm/amd/display/dc/dcn314/dcn314_init.c | 1 + drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h | 25 ++++++++++++---------- .../drm/amd/display/dc/inc/hw_sequencer_private.h | 4 ++++ 9 files changed, 72 insertions(+), 26 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 46ca88741cb8..1c3b6f25a782 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 @@ -726,11 +726,15 @@ void dcn10_hubp_pg_control( } } -static void power_on_plane( +static void power_on_plane_resources( struct dce_hwseq *hws, int plane_id) { DC_LOGGER_INIT(hws->ctx->logger); + + if (hws->funcs.dpp_root_clock_control) + hws->funcs.dpp_root_clock_control(hws, plane_id, true); + if (REG(DC_IP_REQUEST_CNTL)) { REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); @@ -1237,11 +1241,15 @@ void dcn10_plane_atomic_power_down(struct dc *dc, hws->funcs.hubp_pg_control(hws, hubp->inst, false); dpp->funcs->dpp_reset(dpp); + REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); DC_LOG_DEBUG( "Power gated front end %d\n", hubp->inst); } + + if (hws->funcs.dpp_root_clock_control) + hws->funcs.dpp_root_clock_control(hws, dpp->inst, false); } /* disable HW used by plane. @@ -2462,7 +2470,7 @@ static void dcn10_enable_plane( undo_DEGVIDCN10_253_wa(dc); - power_on_plane(dc->hwseq, + power_on_plane_resources(dc->hwseq, pipe_ctx->plane_res.hubp->inst); /* enable DCFCLK current DCHUB */ 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 69ea1f4ea749..9ca162ea0d07 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1130,11 +1130,15 @@ void dcn20_blank_pixel_data( } -static void dcn20_power_on_plane( +static void dcn20_power_on_plane_resources( struct dce_hwseq *hws, struct pipe_ctx *pipe_ctx) { DC_LOGGER_INIT(hws->ctx->logger); + + if (hws->funcs.dpp_root_clock_control) + hws->funcs.dpp_root_clock_control(hws, pipe_ctx->plane_res.dpp->inst, true); + if (REG(DC_IP_REQUEST_CNTL)) { REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); @@ -1158,7 +1162,7 @@ static void dcn20_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx, //if (dc->debug.sanity_checks) { // dcn10_verify_allow_pstate_change_high(dc); //} - dcn20_power_on_plane(dc->hwseq, pipe_ctx); + dcn20_power_on_plane_resources(dc->hwseq, pipe_ctx); /* enable DCFCLK current DCHUB */ pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true); diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c index 7f34418e6308..7d2b982506fd 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c @@ -66,17 +66,8 @@ void dccg31_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk) REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_ENABLE[dpp_inst], 1); } else { - //DTO must be enabled to generate a 0Hz clock output - if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) { - REG_UPDATE(DPPCLK_DTO_CTRL, - DPPCLK_DTO_ENABLE[dpp_inst], 1); - REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, - DPPCLK0_DTO_PHASE, 0, - DPPCLK0_DTO_MODULO, 1); - } else { - REG_UPDATE(DPPCLK_DTO_CTRL, - DPPCLK_DTO_ENABLE[dpp_inst], 0); - } + REG_UPDATE(DPPCLK_DTO_CTRL, + DPPCLK_DTO_ENABLE[dpp_inst], 0); } dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c index 0b769ee71405..081ce168f621 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c @@ -289,8 +289,31 @@ static void dccg314_set_valid_pixel_rate( dccg314_set_dtbclk_dto(dccg, &dto_params); } +static void dccg314_dpp_root_clock_control( + struct dccg *dccg, + unsigned int dpp_inst, + bool clock_on) +{ + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + if (clock_on) { + /* turn off the DTO and leave phase/modulo at max */ + REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_ENABLE[dpp_inst], 0); + REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, + DPPCLK0_DTO_PHASE, 0xFF, + DPPCLK0_DTO_MODULO, 0xFF); + } else { + /* turn on the DTO to generate a 0hz clock */ + REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_ENABLE[dpp_inst], 1); + REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, + DPPCLK0_DTO_PHASE, 0, + DPPCLK0_DTO_MODULO, 1); + } +} + static const struct dccg_funcs dccg314_funcs = { .update_dpp_dto = dccg31_update_dpp_dto, + .dpp_root_clock_control = dccg314_dpp_root_clock_control, .get_dccg_ref_freq = dccg31_get_dccg_ref_freq, .dccg_init = dccg31_init, .set_dpstreamclk = dccg314_set_dpstreamclk, diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c index bcc03426fc3e..40c488b26901 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c @@ -390,6 +390,16 @@ void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx) pix_per_cycle); } +void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on) +{ + if (!hws->ctx->dc->debug.root_clock_optimization.bits.dpp) + return; + + if (hws->ctx->dc->res_pool->dccg->funcs->dpp_root_clock_control) + hws->ctx->dc->res_pool->dccg->funcs->dpp_root_clock_control( + hws->ctx->dc->res_pool->dccg, dpp_inst, clock_on); +} + void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on) { struct dc_context *ctx = hws->ctx; diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h index c419d3dbdfee..c786d5e6a428 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h @@ -43,4 +43,6 @@ void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx); void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on); +void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on); + #endif /* __DC_HWSS_DCN314_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c index 343f4d9dd5e3..5267e901a35c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c @@ -137,6 +137,7 @@ static const struct hwseq_private_funcs dcn314_private_funcs = { .plane_atomic_disable = dcn20_plane_atomic_disable, .plane_atomic_power_down = dcn10_plane_atomic_power_down, .enable_power_gating_plane = dcn314_enable_power_gating_plane, + .dpp_root_clock_control = dcn314_dpp_root_clock_control, .hubp_pg_control = dcn314_hubp_pg_control, .program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree, .update_odm = dcn314_update_odm, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h index ce006762f257..ad6acd1b34e1 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h @@ -148,18 +148,21 @@ struct dccg_funcs { struct dccg *dccg, int inst); -void (*set_pixel_rate_div)( - struct dccg *dccg, - uint32_t otg_inst, - enum pixel_rate_div k1, - enum pixel_rate_div k2); - -void (*set_valid_pixel_rate)( - struct dccg *dccg, - int ref_dtbclk_khz, - int otg_inst, - int pixclk_khz); + void (*set_pixel_rate_div)(struct dccg *dccg, + uint32_t otg_inst, + enum pixel_rate_div k1, + enum pixel_rate_div k2); + void (*set_valid_pixel_rate)( + struct dccg *dccg, + int ref_dtbclk_khz, + int otg_inst, + int pixclk_khz); + + void (*dpp_root_clock_control)( + struct dccg *dccg, + unsigned int dpp_inst, + bool clock_on); }; #endif //__DAL_DCCG_H__ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h index 45d37c584551..5f63b67975cf 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h @@ -115,6 +115,10 @@ struct hwseq_private_funcs { void (*plane_atomic_disable)(struct dc *dc, struct pipe_ctx *pipe_ctx); void (*enable_power_gating_plane)(struct dce_hwseq *hws, bool enable); + void (*dpp_root_clock_control)( + struct dce_hwseq *hws, + unsigned int dpp_inst, + bool clock_on); void (*dpp_pg_control)(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on); -- cgit From f5442b35e69e42015ef3082008c0d85cdcc0ca05 Mon Sep 17 00:00:00 2001 From: Martin Leung Date: Tue, 14 Mar 2023 09:27:20 -0400 Subject: drm/amd/display: fix double memory allocation [Why & How] when trying to fix a nullptr dereference on VMs, accidentally doubly allocated memory for the non VM case. removed the extra link_srv creation since dc_construct_ctx is called in both VM and non VM cases Also added a proper fail check for if kzalloc fails Cc: stable@vger.kernel.org Cc: Mario Limonciello Reviewed-by: Leo Ma Acked-by: Qingqing Zhuo Signed-off-by: Martin Leung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 40f2e174c524..52564b93f7eb 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -887,7 +887,10 @@ static bool dc_construct_ctx(struct dc *dc, } dc->ctx = dc_ctx; + dc->link_srv = link_create_link_service(); + if (!dc->link_srv) + return false; return true; } @@ -986,8 +989,6 @@ static bool dc_construct(struct dc *dc, goto fail; } - dc->link_srv = link_create_link_service(); - dc->res_pool = dc_create_resource_pool(dc, init_params, dc_ctx->dce_version); if (!dc->res_pool) goto fail; -- cgit From 7b1b3f5818c33da2ab78fe62d34ee7bacc93cef0 Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Fri, 10 Mar 2023 21:18:06 -0500 Subject: drm/amd/display: update dig enable sequence [why] HW delta follow up Reviewed-by: Chris Park Reviewed-by: Jun Lei Reviewed-by: Jerry Zuo Acked-by: Qingqing Zhuo Signed-off-by: Charlene Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c | 10 +++++----- .../gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h | 8 ++++++++ drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 11 ++++++----- 3 files changed, 19 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c index d05e7655f603..2fef1419ae91 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c @@ -274,10 +274,10 @@ static bool is_dp_dig_pixel_rate_div_policy(struct dc *dc, const struct dc_crtc_ dc->debug.enable_dp_dig_pixel_rate_div_policy; } -static void enc32_stream_encoder_dp_unblank( - struct dc_link *link, - struct stream_encoder *enc, - const struct encoder_unblank_param *param) +void enc32_stream_encoder_dp_unblank( + struct dc_link *link, + struct stream_encoder *enc, + const struct encoder_unblank_param *param) { struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); struct dc *dc = enc->ctx->dc; @@ -440,7 +440,7 @@ static void enc32_reset_fifo(struct stream_encoder *enc, bool reset) udelay(10); } -static void enc32_enable_fifo(struct stream_encoder *enc) +void enc32_enable_fifo(struct stream_encoder *enc) { struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h index 875b1cd46056..1be5410cce97 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h @@ -194,4 +194,12 @@ void dcn32_dio_stream_encoder_construct( const struct dcn10_stream_encoder_shift *se_shift, const struct dcn10_stream_encoder_mask *se_mask); + +void enc32_enable_fifo(struct stream_encoder *enc); + +void enc32_stream_encoder_dp_unblank( + struct dc_link *link, + struct stream_encoder *enc, + const struct encoder_unblank_param *param); + #endif /* __DC_DIO_STREAM_ENCODER_DCN32_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index 020d668ce09e..aa08925d54c9 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -2477,11 +2477,12 @@ void link_set_dpms_on( * from transmitter control. */ if (!(dc_is_virtual_signal(pipe_ctx->stream->signal) || - dp_is_128b_132b_signal(pipe_ctx))) - if (link_enc) - link_enc->funcs->setup( - link_enc, - pipe_ctx->stream->signal); + dp_is_128b_132b_signal(pipe_ctx))) { + if (link_enc) + link_enc->funcs->setup( + link_enc, + pipe_ctx->stream->signal); + } dc->hwss.enable_stream(pipe_ctx); -- cgit From 79978cc76f050d6cf24880645519f54aa6843da3 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Tue, 14 Mar 2023 10:20:33 -0400 Subject: drm/amd/display: w/a for dcn315 inconsistent smu clock table [Why & How] w/a for dcn315 inconsistent smu clock. Reviewed-by: Nicholas Kazlauskas Acked-by: Qingqing Zhuo Signed-off-by: Dmytro Laktyushkin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/amd/display') 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 a737782b2840..b737cbc468f5 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 @@ -522,6 +522,11 @@ static void dcn315_clk_mgr_helper_populate_bw_params( bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[0]; bw_params->clk_table.entries[i].wck_ratio = 1; i++; + } else if (clock_table->NumDcfClkLevelsEnabled != clock_table->NumSocClkLevelsEnabled) { + bw_params->clk_table.entries[i-1].voltage = clock_table->SocVoltage[clock_table->NumSocClkLevelsEnabled - 1]; + bw_params->clk_table.entries[i-1].socclk_mhz = clock_table->SocClocks[clock_table->NumSocClkLevelsEnabled - 1]; + bw_params->clk_table.entries[i-1].dispclk_mhz = clock_table->DispClocks[clock_table->NumDispClkLevelsEnabled - 1]; + bw_params->clk_table.entries[i-1].dppclk_mhz = clock_table->DppClocks[clock_table->NumDispClkLevelsEnabled - 1]; } bw_params->clk_table.num_entries = i; -- cgit From 8ef23f9268fc4364fc79bd017c2ed6a6495133ec Mon Sep 17 00:00:00 2001 From: Taimur Hassan Date: Tue, 14 Mar 2023 17:39:03 -0400 Subject: drm/amd/display: Add 90Mhz to video_optimized_pixel_rates [Why & How] Needed to get certain EDID to light up during TMDS compliance. Reviewed-by: Charlene Liu Acked-by: Qingqing Zhuo Signed-off-by: Taimur Hassan Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c index 67e3df7e1b05..462c7a3ec3cc 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c @@ -1157,6 +1157,7 @@ const struct pixel_rate_range_table_entry video_optimized_pixel_rates[] = { {25170, 25180, 25200, 1000, 1001}, //25.2MHz -> 25.17 {59340, 59350, 59400, 1000, 1001}, //59.4Mhz -> 59.340 {74170, 74180, 74250, 1000, 1001}, //74.25Mhz -> 74.1758 + {89910, 90000, 90000, 1000, 1001}, //90Mhz -> 89.91 {125870, 125880, 126000, 1000, 1001}, //126Mhz -> 125.87 {148350, 148360, 148500, 1000, 1001}, //148.5Mhz -> 148.3516 {167830, 167840, 168000, 1000, 1001}, //168Mhz -> 167.83 -- cgit From e8e5cc645b2d6cfcff58d02743543eeb37e2795e Mon Sep 17 00:00:00 2001 From: Qingqing Zhuo Date: Mon, 20 Mar 2023 05:24:41 -0400 Subject: drm/amd/display: Add infrastructure for enabling FAMS for DCN30 As part of the FAMS work, we need code infrastructure in DC. dcn30_fpu.c changes went missing during previous upstream activity. Reviewed-by: Rodrigo Siqueira Acked-by: Qingqing Zhuo Signed-off-by: Qingqing Zhuo Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c | 53 +++++++++++++++++++--- 1 file changed, 46 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c index 4fa636364793..ecfa395f5fa8 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c @@ -384,9 +384,34 @@ void dcn30_fpu_calculate_wm_and_dlg( int i, pipe_idx; double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][maxMpcComb]; bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] != dm_dram_clock_change_unsupported; + unsigned int dummy_latency_index = 0; dc_assert_fp_enabled(); + context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = false; + + if (!pstate_en) { + /* only when the mclk switch can not be natural, is the fw based vblank stretch attempted */ + context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = + dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch(dc, context); + + if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) { + dummy_latency_index = dcn30_find_dummy_latency_index_for_fw_based_mclk_switch(dc, + context, pipes, pipe_cnt, vlevel); + + /* After calling dcn30_find_dummy_latency_index_for_fw_based_mclk_switch + * we reinstate the original dram_clock_change_latency_us on the context + * and all variables that may have changed up to this point, except the + * newly found dummy_latency_index + */ + context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; + dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false, true); + maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb; + dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb]; + pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] != dm_dram_clock_change_unsupported; + } + } + if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk) dcfclk = context->bw_ctx.dml.soc.min_dcfclk; @@ -449,15 +474,29 @@ void dcn30_fpu_calculate_wm_and_dlg( unsigned int min_dram_speed_mts = context->bw_ctx.dml.vba.DRAMSpeed; unsigned int min_dram_speed_mts_margin = 160; - if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] == dm_dram_clock_change_unsupported) - min_dram_speed_mts = dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz * 16; + context->bw_ctx.dml.soc.dram_clock_change_latency_us = + dc->clk_mgr->bw_params->dummy_pstate_table[0].dummy_pstate_latency_us; - /* find largest table entry that is lower than dram speed, but lower than DPM0 still uses DPM0 */ - for (i = 3; i > 0; i--) - if (min_dram_speed_mts + min_dram_speed_mts_margin > dc->clk_mgr->bw_params->dummy_pstate_table[i].dram_speed_mts) - break; + if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] == + dm_dram_clock_change_unsupported) { + int min_dram_speed_mts_offset = dc->clk_mgr->bw_params->clk_table.num_entries - 1; - context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->dummy_pstate_table[i].dummy_pstate_latency_us; + min_dram_speed_mts = + dc->clk_mgr->bw_params->clk_table.entries[min_dram_speed_mts_offset].memclk_mhz * 16; + } + + if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) { + /* find largest table entry that is lower than dram speed, + * but lower than DPM0 still uses DPM0 + */ + for (dummy_latency_index = 3; dummy_latency_index > 0; dummy_latency_index--) + if (min_dram_speed_mts + min_dram_speed_mts_margin > + dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dram_speed_mts) + break; + } + + context->bw_ctx.dml.soc.dram_clock_change_latency_us = + dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us; context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us; context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us; -- cgit From 4ed793083afc2bbf22a7fb5993efccf3b5bcde25 Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Wed, 15 Mar 2023 17:40:49 -0400 Subject: drm/amd/display: Use per pipe P-State force for FPO [Description] * Pass in pipe index for FPO cmd to DMCUB - This change will pass in the pipe index for each stream that is using FPO - This change is in preparation to enable FPO + VActive * Use per pipe P-State force for FPO - For FPO, instead of using max watermarks value for P-State disallow, use per pipe p-state force instead - This is in preparation to enable FPO + VActive Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 46 +++++++++++++--------- drivers/gpu/drm/amd/display/dc/dc_stream.h | 1 + drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 10 +++++ .../gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 2 + drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c | 10 +++++ drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.h | 2 + drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 41 +++++++++++-------- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h | 2 +- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c | 2 +- .../gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c | 4 ++ .../gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 8 ++-- drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h | 1 + .../drm/amd/display/dc/inc/hw_sequencer_private.h | 2 +- 13 files changed, 88 insertions(+), 43 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index b5c6501c28fc..8f26f7245104 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -302,27 +302,31 @@ static uint8_t dc_dmub_srv_get_pipes_for_stream(struct dc *dc, struct dc_stream_ return pipes; } -static int dc_dmub_srv_get_timing_generator_offset(struct dc *dc, struct dc_stream_state *stream) +static void dc_dmub_srv_populate_fams_pipe_info(struct dc *dc, struct dc_state *context, + struct pipe_ctx *head_pipe, + struct dmub_cmd_fw_assisted_mclk_switch_pipe_data *fams_pipe_data) { - int tg_inst = 0; - int i = 0; + int j; - for (i = 0; i < MAX_PIPES; i++) { - struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; + // TODO: Uncomment once FW headers are updated in driver + //fams_pipe_data->pipe_index[pipe_idx++] = head_pipe->plane_res.hubp->inst; + for (j = 0; j < dc->res_pool->pipe_count; j++) { + struct pipe_ctx *split_pipe = &context->res_ctx.pipe_ctx[j]; - if (pipe->stream == stream && pipe->stream_res.tg) { - tg_inst = pipe->stream_res.tg->inst; - break; + if (split_pipe->stream == head_pipe->stream && (split_pipe->top_pipe || split_pipe->prev_odm_pipe)) { + // TODO: Uncomment once FW headers are updated in driver + //fams_pipe_data->pipe_index[pipe_idx++] = split_pipe->plane_res.hubp->inst; } } - return tg_inst; + // TODO: Uncomment once FW headers are updated in driver + //fams_pipe_data->pipe_count = pipe_idx; } bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, struct dc_state *context) { union dmub_rb_cmd cmd = { 0 }; struct dmub_cmd_fw_assisted_mclk_switch_config *config_data = &cmd.fw_assisted_mclk_switch.config_data; - int i = 0; + int i = 0, k = 0; int ramp_up_num_steps = 1; // TODO: Ramp is currently disabled. Reenable it. uint8_t visual_confirm_enabled; @@ -337,17 +341,21 @@ bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, stru cmd.fw_assisted_mclk_switch.config_data.fams_enabled = should_manage_pstate; cmd.fw_assisted_mclk_switch.config_data.visual_confirm_enabled = visual_confirm_enabled; - for (i = 0; context && i < context->stream_count; i++) { - struct dc_stream_state *stream = context->streams[i]; - uint8_t min_refresh_in_hz = (stream->timing.min_refresh_in_uhz + 999999) / 1000000; - int tg_inst = dc_dmub_srv_get_timing_generator_offset(dc, stream); + for (i = 0, k = 0; context && i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - config_data->pipe_data[tg_inst].pix_clk_100hz = stream->timing.pix_clk_100hz; - config_data->pipe_data[tg_inst].min_refresh_in_hz = min_refresh_in_hz; - config_data->pipe_data[tg_inst].max_ramp_step = ramp_up_num_steps; - config_data->pipe_data[tg_inst].pipes = dc_dmub_srv_get_pipes_for_stream(dc, stream); + if (!pipe->top_pipe && !pipe->prev_odm_pipe && pipe->stream && pipe->stream->fpo_in_use) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + uint8_t min_refresh_in_hz = (pipe->stream->timing.min_refresh_in_uhz + 999999) / 1000000; + + config_data->pipe_data[k].pix_clk_100hz = pipe->stream->timing.pix_clk_100hz; + config_data->pipe_data[k].min_refresh_in_hz = min_refresh_in_hz; + config_data->pipe_data[k].max_ramp_step = ramp_up_num_steps; + config_data->pipe_data[k].pipes = dc_dmub_srv_get_pipes_for_stream(dc, pipe->stream); + dc_dmub_srv_populate_fams_pipe_info(dc, context, pipe, &config_data->pipe_data[k]); + k++; + } } - cmd.fw_assisted_mclk_switch.header.payload_bytes = sizeof(cmd.fw_assisted_mclk_switch) - sizeof(cmd.fw_assisted_mclk_switch.header); diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index 567452599659..181a3408cc61 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -293,6 +293,7 @@ struct dc_stream_state { bool has_non_synchronizable_pclk; bool vblank_synchronized; + bool fpo_in_use; struct mall_stream_config mall_stream_config; }; 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 9ca162ea0d07..5403e9399a46 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1993,6 +1993,16 @@ void dcn20_post_unlock_program_front_end( } } + /* P-State support transitions: + * Natural -> FPO: P-State disabled in prepare, force disallow anytime is safe + * FPO -> Natural: Unforce anytime after FW disable is safe (P-State will assert naturally) + * Unsupported -> FPO: P-State enabled in optimize, force disallow anytime is safe + * FPO -> Unsupported: P-State disabled in prepare, unforce disallow anytime is safe + * FPO <-> SubVP: Force disallow is maintained on the FPO / SubVP pipes + */ + if (hwseq && hwseq->funcs.update_force_pstate) + dc->hwseq->funcs.update_force_pstate(dc, context); + /* Only program the MALL registers after all the main and phantom pipes * are done programming. */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index c9e45da6ccd1..965f5ceb33f7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -2016,6 +2016,8 @@ bool dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch(struct dc *dc, if (context->streams[0]->vrr_active_variable) return false; + context->streams[0]->fpo_in_use = true; + return true; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c index fe0cd177744c..2d604f7ee782 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c @@ -47,6 +47,15 @@ void hubp32_update_force_pstate_disallow(struct hubp *hubp, bool pstate_disallow DATA_UCLK_PSTATE_FORCE_VALUE, 0); } +void hubp32_update_force_cursor_pstate_disallow(struct hubp *hubp, bool pstate_disallow) +{ + struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); + + REG_UPDATE_2(UCLK_PSTATE_FORCE, + CURSOR_UCLK_PSTATE_FORCE_EN, pstate_disallow, + CURSOR_UCLK_PSTATE_FORCE_VALUE, 0); +} + void hubp32_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor) { struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); @@ -188,6 +197,7 @@ static struct hubp_funcs dcn32_hubp_funcs = { .hubp_set_flip_int = hubp1_set_flip_int, .hubp_in_blank = hubp1_in_blank, .hubp_update_force_pstate_disallow = hubp32_update_force_pstate_disallow, + .hubp_update_force_cursor_pstate_disallow = hubp32_update_force_cursor_pstate_disallow, .phantom_hubp_post_enable = hubp32_phantom_hubp_post_enable, .hubp_update_mall_sel = hubp32_update_mall_sel, .hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.h index d5e5ed8ab869..d2acbc129609 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.h @@ -46,6 +46,8 @@ void hubp32_update_force_pstate_disallow(struct hubp *hubp, bool pstate_disallow); +void hubp32_update_force_cursor_pstate_disallow(struct hubp *hubp, bool pstate_disallow); + void hubp32_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor); void hubp32_prepare_subvp_buffering(struct hubp *hubp, bool enable); diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index 42255c22605d..5ee9c5a74ecb 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -571,39 +571,50 @@ bool dcn32_set_output_transfer_func(struct dc *dc, return ret; } -/* Program P-State force value according to if pipe is using SubVP or not: +/* Program P-State force value according to if pipe is using SubVP / FPO or not: * 1. Reset P-State force on all pipes first * 2. For each main pipe, force P-State disallow (P-State allow moderated by DMUB) */ -void dcn32_subvp_update_force_pstate(struct dc *dc, struct dc_state *context) +void dcn32_update_force_pstate(struct dc *dc, struct dc_state *context) { int i; - int num_subvp = 0; - /* Unforce p-state for each pipe + + /* Unforce p-state for each pipe if it is not FPO or SubVP. + * For FPO and SubVP, if it's already forced disallow, leave + * it as disallow. */ for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; struct hubp *hubp = pipe->plane_res.hubp; - if (hubp && hubp->funcs->hubp_update_force_pstate_disallow) - hubp->funcs->hubp_update_force_pstate_disallow(hubp, false); - if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_MAIN) - num_subvp++; + if (!pipe->stream || (pipe->stream && !(pipe->stream->mall_stream_config.type == SUBVP_MAIN || + pipe->stream->fpo_in_use))) { + if (hubp && hubp->funcs->hubp_update_force_pstate_disallow) + hubp->funcs->hubp_update_force_pstate_disallow(hubp, false); + if (hubp && hubp->funcs->hubp_update_force_cursor_pstate_disallow) + hubp->funcs->hubp_update_force_cursor_pstate_disallow(hubp, false); + } } - if (num_subvp == 0) - return; - /* Loop through each pipe -- for each subvp main pipe force p-state allow equal to false. */ for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + struct hubp *hubp = pipe->plane_res.hubp; - if (pipe->stream && pipe->plane_state && (pipe->stream->mall_stream_config.type == SUBVP_MAIN)) { - struct hubp *hubp = pipe->plane_res.hubp; + if (pipe->stream && pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_MAIN) { + if (hubp && hubp->funcs->hubp_update_force_pstate_disallow) + hubp->funcs->hubp_update_force_pstate_disallow(hubp, true); + } + if (pipe->stream && pipe->stream->fpo_in_use) { if (hubp && hubp->funcs->hubp_update_force_pstate_disallow) hubp->funcs->hubp_update_force_pstate_disallow(hubp, true); + /* For now only force cursor p-state disallow for FPO + * Needs to be added for subvp once FW side gets updated + */ + if (hubp && hubp->funcs->hubp_update_force_cursor_pstate_disallow) + hubp->funcs->hubp_update_force_cursor_pstate_disallow(hubp, true); } } } @@ -677,10 +688,6 @@ void dcn32_program_mall_pipe_config(struct dc *dc, struct dc_state *context) if (hws && hws->funcs.update_mall_sel) hws->funcs.update_mall_sel(dc, context); - //update subvp force pstate - if (hws && hws->funcs.subvp_update_force_pstate) - dc->hwseq->funcs.subvp_update_force_pstate(dc, context); - // Program FORCE_ONE_ROW_FOR_FRAME and CURSOR_REQ_MODE for main subvp pipes for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h index 2a5376eb9d66..6694c1d14aa3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h @@ -67,7 +67,7 @@ void dcn32_program_mall_pipe_config(struct dc *dc, struct dc_state *context); void dcn32_update_mall_sel(struct dc *dc, struct dc_state *context); -void dcn32_subvp_update_force_pstate(struct dc *dc, struct dc_state *context); +void dcn32_update_force_pstate(struct dc *dc, struct dc_state *context); void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx); 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 dcb81662884f..8085f2acb1a9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c @@ -149,7 +149,7 @@ static const struct hwseq_private_funcs dcn32_private_funcs = { .dccg_init = dcn20_dccg_init, .set_mcm_luts = dcn32_set_mcm_luts, .program_mall_pipe_config = dcn32_program_mall_pipe_config, - .subvp_update_force_pstate = dcn32_subvp_update_force_pstate, + .update_force_pstate = dcn32_update_force_pstate, .update_mall_sel = dcn32_update_mall_sel, .calculate_dccg_k1_k2_values = dcn32_calculate_dccg_k1_k2_values, .set_pixels_per_cycle = dcn32_set_pixels_per_cycle, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c index ecfa395f5fa8..80972ee5e55b 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c @@ -389,6 +389,10 @@ void dcn30_fpu_calculate_wm_and_dlg( dc_assert_fp_enabled(); context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = false; + for (i = 0; i < context->stream_count; i++) { + if (context->streams[i]) + context->streams[i]->fpo_in_use = false; + } if (!pstate_en) { /* only when the mclk switch can not be natural, is the fw based vblank stretch attempted */ 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 6ab60facc091..1e26adf987cc 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 @@ -1960,6 +1960,10 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, } context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = false; + for (i = 0; i < context->stream_count; i++) { + if (context->streams[i]) + context->streams[i]->fpo_in_use = false; + } if (!pstate_en || (!dc->debug.disable_fpo_optimizations && pstate_en && vlevel != 0)) { @@ -2199,10 +2203,6 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; - if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) { - dcn30_setup_mclk_switch_using_fw_based_vblank_stretch(dc, context); - } - /* revert fclk lat changes if required */ if (need_fclk_lat_as_dummy) context->bw_ctx.dml.soc.fclk_change_latency_us = diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h index b5d353c41aa9..7f3f9b69e903 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h @@ -203,6 +203,7 @@ struct hubp_funcs { void (*hubp_soft_reset)(struct hubp *hubp, bool reset); void (*hubp_update_force_pstate_disallow)(struct hubp *hubp, bool allow); + void (*hubp_update_force_cursor_pstate_disallow)(struct hubp *hubp, bool allow); void (*hubp_update_mall_sel)(struct hubp *hubp, uint32_t mall_sel, bool c_cursor); void (*hubp_prepare_subvp_buffering)(struct hubp *hubp, bool enable); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h index 5f63b67975cf..4513544559be 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h @@ -154,7 +154,7 @@ struct hwseq_private_funcs { void (*setup_hpo_hw_control)(const struct dce_hwseq *hws, bool enable); #ifdef CONFIG_DRM_AMD_DC_FP void (*program_mall_pipe_config)(struct dc *dc, struct dc_state *context); - void (*subvp_update_force_pstate)(struct dc *dc, struct dc_state *context); + void (*update_force_pstate)(struct dc *dc, struct dc_state *context); void (*update_mall_sel)(struct dc *dc, struct dc_state *context); unsigned int (*calculate_dccg_k1_k2_values)(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, -- cgit From 37403ced9f2873fab7f39ab4ac963bbb33fb0bc0 Mon Sep 17 00:00:00 2001 From: Ayush Gupta Date: Thu, 16 Mar 2023 15:57:30 -0400 Subject: drm/amd/display: fixed dcn30+ underflow issue [Why] Observing underflow on dcn30+ system config at 4k144hz [How] We set the UCLK hardmax on AC/DC switch if softmax is enabled and also on boot. While booting up the UCLK Hardmax is set to softmax before the init sequence and the init sequence resets the hardmax to UCLK max which enables P-state switching. Just added a conditional check to avoid setting hardmax on init. Reviewed-by: Alvin Lee Reviewed-by: Martin Leung Acked-by: Qingqing Zhuo Signed-off-by: Ayush Gupta Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 3 ++- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index 586de81fc2da..d0ef23bfb9e6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -621,7 +621,8 @@ void dcn30_init_hw(struct dc *dc) if (dc->clk_mgr->funcs->notify_wm_ranges) dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr); - if (dc->clk_mgr->funcs->set_hard_max_memclk) + //if softmax is enabled then hardmax will be set by a different call + if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled) dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr); if (dc->res_pool->hubbub->funcs->force_pstate_change_control) diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c index 10e3cc17f71a..7ac6e69cff37 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c @@ -285,7 +285,7 @@ void dcn31_init_hw(struct dc *dc) if (dc->clk_mgr->funcs->notify_wm_ranges) dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr); - if (dc->clk_mgr->funcs->set_hard_max_memclk) + if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled) dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr); if (dc->res_pool->hubbub->funcs->force_pstate_change_control) diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index 5ee9c5a74ecb..b2919104ffc7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -909,7 +909,7 @@ void dcn32_init_hw(struct dc *dc) if (dc->clk_mgr->funcs->notify_wm_ranges) dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr); - if (dc->clk_mgr->funcs->set_hard_max_memclk) + if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled) dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr); if (dc->res_pool->hubbub->funcs->force_pstate_change_control) -- cgit From a78d43738ead68a40acf7da8a873f47a9f6e6eb3 Mon Sep 17 00:00:00 2001 From: Artem Grishin Date: Tue, 14 Mar 2023 16:11:39 -0400 Subject: drm/amd/display: Add support for 6.75 GBps link rate [Why] The latest eDP spec version 1.5 defines a new generic link rate of 6.75 Gbps/Lane, which needs to be supported in the driver. [How] Added new element to the dc_link_rate enum Reviewed-by: Charlene Liu Acked-by: Qingqing Zhuo Signed-off-by: Artem Grishin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_dp_types.h | 17 +++++++++-------- .../amd/display/dc/link/protocols/link_dp_capability.c | 5 ++++- .../amd/display/dc/link/protocols/link_dp_training.c | 3 +++ 3 files changed, 16 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h index af53278662ec..49aab1924665 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h @@ -47,14 +47,15 @@ enum dc_lane_count { */ enum dc_link_rate { LINK_RATE_UNKNOWN = 0, - LINK_RATE_LOW = 0x06, // Rate_1 (RBR) - 1.62 Gbps/Lane - LINK_RATE_RATE_2 = 0x08, // Rate_2 - 2.16 Gbps/Lane - LINK_RATE_RATE_3 = 0x09, // Rate_3 - 2.43 Gbps/Lane - LINK_RATE_HIGH = 0x0A, // Rate_4 (HBR) - 2.70 Gbps/Lane - LINK_RATE_RBR2 = 0x0C, // Rate_5 (RBR2)- 3.24 Gbps/Lane - LINK_RATE_RATE_6 = 0x10, // Rate_6 - 4.32 Gbps/Lane - LINK_RATE_HIGH2 = 0x14, // Rate_7 (HBR2)- 5.40 Gbps/Lane - LINK_RATE_HIGH3 = 0x1E, // Rate_8 (HBR3)- 8.10 Gbps/Lane + LINK_RATE_LOW = 0x06, // Rate_1 (RBR) - 1.62 Gbps/Lane + LINK_RATE_RATE_2 = 0x08, // Rate_2 - 2.16 Gbps/Lane + LINK_RATE_RATE_3 = 0x09, // Rate_3 - 2.43 Gbps/Lane + LINK_RATE_HIGH = 0x0A, // Rate_4 (HBR) - 2.70 Gbps/Lane + LINK_RATE_RBR2 = 0x0C, // Rate_5 (RBR2) - 3.24 Gbps/Lane + LINK_RATE_RATE_6 = 0x10, // Rate_6 - 4.32 Gbps/Lane + LINK_RATE_HIGH2 = 0x14, // Rate_7 (HBR2) - 5.40 Gbps/Lane + LINK_RATE_RATE_8 = 0x19, // Rate_8 - 6.75 Gbps/Lane + LINK_RATE_HIGH3 = 0x1E, // Rate_9 (HBR3) - 8.10 Gbps/Lane /* Starting from DP2.0 link rate enum directly represents actual * link rate value in unit of 10 mbps */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index 2a2443535b67..7d7edbb2cf52 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -203,8 +203,11 @@ static enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in case 5400000: link_rate = LINK_RATE_HIGH2; // Rate_7 (HBR2)- 5.40 Gbps/Lane break; + case 6750000: + link_rate = LINK_RATE_RATE_8; // Rate_8 - 6.75 Gbps/Lane + break; case 8100000: - link_rate = LINK_RATE_HIGH3; // Rate_8 (HBR3)- 8.10 Gbps/Lane + link_rate = LINK_RATE_HIGH3; // Rate_9 (HBR3)- 8.10 Gbps/Lane break; default: link_rate = LINK_RATE_UNKNOWN; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index 10261764a0ce..f301c9eaf2f9 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -86,6 +86,9 @@ void dp_log_training_result( case LINK_RATE_HIGH2: link_rate = "HBR2"; break; + case LINK_RATE_RATE_8: + link_rate = "R8"; + break; case LINK_RATE_HIGH3: link_rate = "HBR3"; break; -- cgit From 53c8ed46e81636c39528aeb7c3db353a906ecee3 Mon Sep 17 00:00:00 2001 From: Artem Grishin Date: Wed, 15 Mar 2023 18:17:59 -0400 Subject: drm/amd/display: Conditionally enable 6.75 GBps link rate [Why] The 6.75 GBps link rate is part of the new eDP specification version 1.5 is going to be supported in the future. Since this standard is very new and there are no existing 6.75 GBps panels on the market yet, we should put a condition in the driver on enabling this feature until we can validate it with real hardware. [How] - Add boolean flag support_eDP1_5 in struct dc_debug_options. - Enable the 6.75 link rate in reduce_link_rate(...) only when the flag is true. Reviewed-by: Charlene Liu Acked-by: Qingqing Zhuo Signed-off-by: Artem Grishin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../display/dc/link/protocols/link_dp_capability.c | 23 +++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 2d2621abf012..1b77d50cfd89 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -874,6 +874,7 @@ struct dc_debug_options { bool temp_mst_deallocation_sequence; bool override_dispclk_programming; bool disable_fpo_optimizations; + bool support_eDP1_5; }; struct gpu_info_soc_bounding_box_v1_0; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index 7d7edbb2cf52..c840ef17802e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -447,8 +447,12 @@ static enum dc_lane_count reduce_lane_count(enum dc_lane_count lane_count) } } -static enum dc_link_rate reduce_link_rate(enum dc_link_rate link_rate) +static enum dc_link_rate reduce_link_rate(const struct dc_link *link, enum dc_link_rate link_rate) { + // NEEDSWORK: provide some details about why this function never returns some of the + // obscure link rates such as 4.32 Gbps or 3.24 Gbps and if such behavior is intended. + // + switch (link_rate) { case LINK_RATE_UHBR20: return LINK_RATE_UHBR13_5; @@ -457,13 +461,22 @@ static enum dc_link_rate reduce_link_rate(enum dc_link_rate link_rate) case LINK_RATE_UHBR10: return LINK_RATE_HIGH3; case LINK_RATE_HIGH3: + if (link->connector_signal == SIGNAL_TYPE_EDP && link->dc->debug.support_eDP1_5) + return LINK_RATE_RATE_8; + return LINK_RATE_HIGH2; + case LINK_RATE_RATE_8: return LINK_RATE_HIGH2; case LINK_RATE_HIGH2: return LINK_RATE_HIGH; + case LINK_RATE_RATE_6: + case LINK_RATE_RBR2: + return LINK_RATE_HIGH; case LINK_RATE_HIGH: return LINK_RATE_LOW; + case LINK_RATE_RATE_3: + case LINK_RATE_RATE_2: + return LINK_RATE_LOW; case LINK_RATE_LOW: - return LINK_RATE_UNKNOWN; default: return LINK_RATE_UNKNOWN; } @@ -586,7 +599,7 @@ bool decide_fallback_link_setting( case LINK_TRAINING_LQA_FAIL: { if (!reached_minimum_link_rate(cur->link_rate)) { - cur->link_rate = reduce_link_rate(cur->link_rate); + cur->link_rate = reduce_link_rate(link, cur->link_rate); } else if (!reached_minimum_lane_count(cur->lane_count)) { cur->link_rate = max->link_rate; if (training_result == LINK_TRAINING_CR_FAIL_LANE0) @@ -608,7 +621,7 @@ bool decide_fallback_link_setting( if (!reached_minimum_lane_count(cur->lane_count)) { cur->lane_count = reduce_lane_count(cur->lane_count); } else if (!reached_minimum_link_rate(cur->link_rate)) { - cur->link_rate = reduce_link_rate(cur->link_rate); + cur->link_rate = reduce_link_rate(link, cur->link_rate); /* Reduce max link rate to avoid potential infinite loop. * Needed so that any subsequent CR_FAIL fallback can't * re-set the link rate higher than the link rate from @@ -624,7 +637,7 @@ bool decide_fallback_link_setting( case LINK_TRAINING_EQ_FAIL_CR: { if (!reached_minimum_link_rate(cur->link_rate)) { - cur->link_rate = reduce_link_rate(cur->link_rate); + cur->link_rate = reduce_link_rate(link, cur->link_rate); /* Reduce max link rate to avoid potential infinite loop. * Needed so that any subsequent CR_FAIL fallback can't * re-set the link rate higher than the link rate from -- cgit From cf31994d0b7c2489d0b83a53b510fdc1e4c731a9 Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Fri, 17 Mar 2023 14:08:55 -0400 Subject: drm/amd/display: Only keep cursor p-state force for FPO [Description] If transitioning from an FPO config -> FPO config, we want to keep cursor P-State force disallowed. Any other transition from FPO config -> non FPO config should unforce the cursor P-State disallow Reviewed-by: Wesley Chalmers Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index b2919104ffc7..b3824287c224 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -591,6 +591,12 @@ void dcn32_update_force_pstate(struct dc *dc, struct dc_state *context) pipe->stream->fpo_in_use))) { if (hubp && hubp->funcs->hubp_update_force_pstate_disallow) hubp->funcs->hubp_update_force_pstate_disallow(hubp, false); + } + + /* Today only FPO uses cursor P-State force. Only clear cursor P-State force + * if it's not FPO. + */ + if (!pipe->stream || (pipe->stream && !pipe->stream->fpo_in_use)) { if (hubp && hubp->funcs->hubp_update_force_cursor_pstate_disallow) hubp->funcs->hubp_update_force_cursor_pstate_disallow(hubp, false); } -- cgit From 0cdf91bf67b782bf3548cb3cce8ab923a13ca6fe Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Fri, 17 Mar 2023 15:18:03 -0400 Subject: drm/amd/display: Enable FPO optimization [Description] Enable optimization for preferring FPO if it achieves a lower voltage level Reviewed-by: George Shen Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index b8c1de357e5f..502f990346b1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -725,7 +725,7 @@ static const struct dc_debug_options debug_defaults_drv = { .min_prefetch_in_strobe_ns = 60000, // 60us .disable_unbounded_requesting = false, .override_dispclk_programming = true, - .disable_fpo_optimizations = true, + .disable_fpo_optimizations = false, }; static const struct dc_debug_options debug_defaults_diags = { 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 5e0b1484dc18..79664ba7e7af 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c @@ -723,7 +723,7 @@ static const struct dc_debug_options debug_defaults_drv = { .min_prefetch_in_strobe_ns = 60000, // 60us .disable_unbounded_requesting = false, .override_dispclk_programming = true, - .disable_fpo_optimizations = true, + .disable_fpo_optimizations = false, }; static const struct dc_debug_options debug_defaults_diags = { -- cgit From a1c9a1e27022d13c70a14c4faeab6ce293ad043b Mon Sep 17 00:00:00 2001 From: Peichen Huang Date: Mon, 20 Mar 2023 09:34:23 +0800 Subject: drm/amd/display: skip CLEAR_PAYLOAD_ID_TABLE if device mst_en is 0 [Why] Some dock and mst monitor don't like to receive CLEAR_PAYLOAD_ID_TABLE when mst_en is set to 0. It doesn't make sense to do so in source side, either. [How] Don't send CLEAR_PAYLOAD_ID_TABLE if mst_en is 0 Reviewed-by: George Shen Acked-by: Qingqing Zhuo Signed-off-by: Peichen Huang Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index aa08925d54c9..f6c5ee2d639b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -2160,6 +2160,7 @@ static enum dc_status enable_link_dp_mst( struct pipe_ctx *pipe_ctx) { struct dc_link *link = pipe_ctx->stream->link; + unsigned char mstm_cntl; /* sink signal type after MST branch is MST. Multiple MST sinks * share one link. Link DP PHY is enable or training only once. @@ -2168,7 +2169,9 @@ static enum dc_status enable_link_dp_mst( return DC_OK; /* clear payload table */ - dm_helpers_dp_mst_clear_payload_allocation_table(link->ctx, link); + core_link_read_dpcd(link, DP_MSTM_CTRL, &mstm_cntl, 1); + if (mstm_cntl & DP_MST_EN) + dm_helpers_dp_mst_clear_payload_allocation_table(link->ctx, link); /* to make sure the pending down rep can be processed * before enabling the link -- cgit From d3981ee76dda3370d2f51ac0c528dd4dfb45cb97 Mon Sep 17 00:00:00 2001 From: Anthony Koo Date: Sat, 18 Mar 2023 11:17:16 -0400 Subject: drm/amd/display: [FW Promotion] Release 0.0.160.0 - New parameter to define extra vblank stretch required when doing FPO + Vactive - Pass in pipe index for FPO Reviewed-by: Alvin Lee Acked-by: Qingqing Zhuo Signed-off-by: Anthony Koo Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 3175a4fe4d52..15d26222597a 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -95,6 +95,13 @@ /* Maximum number of SubVP streams */ #define DMUB_MAX_SUBVP_STREAMS 2 +/* Define max FPO streams as 4 for now. Current implementation today + * only supports 1, but could be more in the future. Reduce array + * size to ensure the command size remains less than 64 bytes if + * adding new fields. + */ +#define DMUB_MAX_FPO_STREAMS 4 + /* Maximum number of streams on any ASIC. */ #define DMUB_MAX_STREAMS 6 @@ -3084,14 +3091,15 @@ struct dmub_cmd_fw_assisted_mclk_switch_pipe_data { uint8_t max_ramp_step; uint8_t pipes; uint8_t min_refresh_in_hz; - uint8_t padding[1]; + uint8_t pipe_count; + uint8_t pipe_index[4]; }; struct dmub_cmd_fw_assisted_mclk_switch_config { uint8_t fams_enabled; uint8_t visual_confirm_enabled; - uint8_t padding[2]; - struct dmub_cmd_fw_assisted_mclk_switch_pipe_data pipe_data[DMUB_MAX_STREAMS]; + uint16_t vactive_stretch_margin_us; // Extra vblank stretch required when doing FPO + Vactive + struct dmub_cmd_fw_assisted_mclk_switch_pipe_data pipe_data[DMUB_MAX_FPO_STREAMS]; }; struct dmub_rb_cmd_fw_assisted_mclk_switch { -- cgit From b0d58d1147b8b08241f4a0de018241dad804b1db Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Fri, 17 Mar 2023 17:56:39 -0400 Subject: drm/amd/display: Uncomment assignments after HW headers are promoted [Description] Assign the correct info now that FW headers are promoted Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 8f26f7245104..dd6f643254fe 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -307,19 +307,17 @@ static void dc_dmub_srv_populate_fams_pipe_info(struct dc *dc, struct dc_state * struct dmub_cmd_fw_assisted_mclk_switch_pipe_data *fams_pipe_data) { int j; + int pipe_idx = 0; - // TODO: Uncomment once FW headers are updated in driver - //fams_pipe_data->pipe_index[pipe_idx++] = head_pipe->plane_res.hubp->inst; + fams_pipe_data->pipe_index[pipe_idx++] = head_pipe->plane_res.hubp->inst; for (j = 0; j < dc->res_pool->pipe_count; j++) { struct pipe_ctx *split_pipe = &context->res_ctx.pipe_ctx[j]; if (split_pipe->stream == head_pipe->stream && (split_pipe->top_pipe || split_pipe->prev_odm_pipe)) { - // TODO: Uncomment once FW headers are updated in driver - //fams_pipe_data->pipe_index[pipe_idx++] = split_pipe->plane_res.hubp->inst; + fams_pipe_data->pipe_index[pipe_idx++] = split_pipe->plane_res.hubp->inst; } } - // TODO: Uncomment once FW headers are updated in driver - //fams_pipe_data->pipe_count = pipe_idx; + fams_pipe_data->pipe_count = pipe_idx; } bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, struct dc_state *context) -- cgit From a2f00188137940432e898952fa61e45adaaa68ff Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Mon, 20 Mar 2023 01:26:59 -0400 Subject: drm/amd/display: Promote DAL to 3.2.229 This DC version brings along: - Enable FPO optimization - Support for 6.75 GBps link rate - Fixes to underflow, black screen and more Acked-by: Qingqing Zhuo 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(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 1b77d50cfd89..e363a3c88250 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -45,7 +45,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.228" +#define DC_VER "3.2.229" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- cgit From 3335a13535312c9fad4d8d1307a621e6617d6ed8 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 27 Mar 2023 18:07:54 +0200 Subject: drm/amd/display: Whitespace cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 075e2099c32c ("drm/amd/display: Fix race condition in DPIA AUX transfer") was backported to stable, which I noticed because of git saying linux-6.1/.git/rebase-apply/patch:37154: space before tab in indent. while applying patch-6.1.21. While fixing the code location that issued that warning, improve in few more places. Signed-off-by: Uwe Kleine-König Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 26 +++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 5d0069f383d4..e29655a26dd4 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2299,9 +2299,9 @@ static int dm_late_init(void *handle) */ params.min_abm_backlight = 0x28F; /* In the case where abm is implemented on dmcub, - * dmcu object will be null. - * ABM 2.4 and up are implemented on dmcub. - */ + * dmcu object will be null. + * ABM 2.4 and up are implemented on dmcub. + */ if (dmcu) { if (!dmcu_load_iram(dmcu, params)) return -EINVAL; @@ -7091,13 +7091,13 @@ static uint add_fs_modes(struct amdgpu_dm_connector *aconnector) /* Standard FPS values * * 23.976 - TV/NTSC - * 24 - Cinema - * 25 - TV/PAL + * 24 - Cinema + * 25 - TV/PAL * 29.97 - TV/NTSC - * 30 - TV/NTSC - * 48 - Cinema HFR - * 50 - TV/PAL - * 60 - Commonly used + * 30 - TV/NTSC + * 48 - Cinema HFR + * 50 - TV/PAL + * 60 - Commonly used * 48,72,96,120 - Multiples of 24 */ static const u32 common_rates[] = { @@ -7726,7 +7726,7 @@ static void update_freesync_state_on_stream( return; spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); - vrr_params = acrtc->dm_irq_params.vrr_params; + vrr_params = acrtc->dm_irq_params.vrr_params; if (surface) { mod_freesync_handle_preflip( @@ -8307,7 +8307,7 @@ static void amdgpu_dm_commit_audio(struct drm_device *dev, if (!drm_atomic_crtc_needs_modeset(new_crtc_state)) continue; - notify: +notify: aconnector = to_amdgpu_dm_connector(connector); mutex_lock(&adev->dm.audio_lock); @@ -9323,7 +9323,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, skip_modeset: /* Release extra reference */ if (new_stream) - dc_stream_release(new_stream); + dc_stream_release(new_stream); /* * We want to do dc stream updates that do not require a @@ -10657,7 +10657,7 @@ int amdgpu_dm_process_dmub_aux_transfer_sync( if (!dc_process_dmub_aux_transfer_async(ctx->dc, link_index, payload)) { *operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE; goto out; - } + } if (!wait_for_completion_timeout(&adev->dm.dmub_aux_transfer_done, 10 * HZ)) { DRM_ERROR("wait_for_completion_timeout timeout!"); -- cgit From 16b34622f7b18d017c59bd648415cfb64a842d96 Mon Sep 17 00:00:00 2001 From: Caio Novais Date: Tue, 28 Mar 2023 19:09:46 -0300 Subject: drm/amd/display: Remove unused variable 'scl_enable' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compiling AMD GPU drivers displays a warning: drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn314/display_rq_dlg_calc_314.c: In function ‘dml_rq_dlg_get_dlg_params’: drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn314/display_rq_dlg_calc_314.c:991:14: warning: variable ‘scl_enable’ set but not used [-Wunused-but-set-variable] Get rid of it by removing the variable 'scl_enable'. Signed-off-by: Caio Novais Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn314/display_rq_dlg_calc_314.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_rq_dlg_calc_314.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_rq_dlg_calc_314.c index d1c2693a2e28..ea4eb66066c4 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_rq_dlg_calc_314.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_rq_dlg_calc_314.c @@ -988,7 +988,6 @@ static void dml_rq_dlg_get_dlg_params( double hratio_c; double vratio_l; double vratio_c; - bool scl_enable; unsigned int swath_width_ub_l; unsigned int dpte_groups_per_row_ub_l; @@ -1117,7 +1116,6 @@ static void dml_rq_dlg_get_dlg_params( hratio_c = scl->hscl_ratio_c; vratio_l = scl->vscl_ratio; vratio_c = scl->vscl_ratio_c; - scl_enable = scl->scl_enable; swath_width_ub_l = rq_dlg_param->rq_l.swath_width_ub; dpte_groups_per_row_ub_l = rq_dlg_param->rq_l.dpte_groups_per_row_ub; -- cgit From fac7c51d62f3536a66e47f3da076803016cc355f Mon Sep 17 00:00:00 2001 From: Caio Novais Date: Wed, 29 Mar 2023 15:05:34 -0300 Subject: drm/amd/display: Mark function 'optc3_wait_drr_doublebuffer_pending_clear' as static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compiling AMD GPU drivers displays a warning: drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_optc.c:294:6: warning: no previous prototype for ‘optc3_wait_drr_doublebuffer_pending_clear’ [-Wmissing-prototypes] Get rid of it by marking the function as static Signed-off-by: Caio Novais Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c index 08b92715e2e6..c95f000b63b2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c @@ -291,7 +291,7 @@ static void optc3_set_timing_double_buffer(struct timing_generator *optc, bool e OTG_DRR_TIMING_DBUF_UPDATE_MODE, mode); } -void optc3_wait_drr_doublebuffer_pending_clear(struct timing_generator *optc) +static void optc3_wait_drr_doublebuffer_pending_clear(struct timing_generator *optc) { struct optc *optc1 = DCN10TG_FROM_TG(optc); -- cgit From 78f0929884d4811c225fd2c57ecc602c84c07392 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 4 Apr 2023 20:28:47 +1000 Subject: powerpc/64: Always build with 128-bit long double The amdgpu driver builds some of its code with hard-float enabled, whereas the rest of the kernel is built with soft-float. When building with 64-bit long double, if soft-float and hard-float objects are linked together, the build fails due to incompatible ABI tags. In the past there have been build errors in the amdgpu driver caused by this, some of those were due to bad intermingling of soft & hard-float code, but those issues have now all been fixed since commit 58ddbecb14c7 ("drm/amd/display: move remaining FPU code to dml folder"). However it's still possible for soft & hard-float objects to end up linked together, if the amdgpu driver is built-in to the kernel along with the test_emulate_step.c code, which uses soft-float. That happens in an allyesconfig build. Currently those build errors are avoided because the amdgpu driver is gated on 128-bit long double being enabled. But that's not a detail the amdgpu driver should need to be aware of, and if another driver starts using hard-float the same problem would occur. All versions of the 64-bit ABI specify that long-double is 128-bits. However some compilers, notably the kernel.org ones, are built to use 64-bit long double by default. Apart from this issue of soft vs hard-float, the kernel doesn't care what size long double is. In particular the kernel using 128-bit long double doesn't impact userspace's ability to use 64-bit long double, as musl does. So always build the 64-bit kernel with 128-bit long double. That should avoid any build errors due to the incompatible ABI tags. Excluding the code that uses soft/hard-float, the vmlinux is identical with/without the flag. It does mean any code which is incorrectly intermingling soft & hard-float code will build without error, so those bugs will need to be caught by testing rather than at build time. For more background see: - commit d11219ad53dc ("amdgpu: disable powerpc support for the newer display engine") - commit c653c591789b ("drm/amdgpu: Re-enable DCN for 64-bit powerpc") - https://lore.kernel.org/r/dab9cbd8-2626-4b99-8098-31fe76397d2d@app.fastmail.com Signed-off-by: Michael Ellerman Reviewed-by: Segher Boessenkool Link: https://msgid.link/20230404102847.3303623-1-mpe@ellerman.id.au --- drivers/gpu/drm/amd/display/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig index 0c9bd0a53e60..e36261d546af 100644 --- a/drivers/gpu/drm/amd/display/Kconfig +++ b/drivers/gpu/drm/amd/display/Kconfig @@ -8,7 +8,7 @@ config DRM_AMD_DC depends on BROKEN || !CC_IS_CLANG || X86_64 || SPARC64 || ARM64 select SND_HDA_COMPONENT if SND_HDA_CORE # !CC_IS_CLANG: https://github.com/ClangBuiltLinux/linux/issues/1752 - select DRM_AMD_DC_DCN if (X86 || PPC_LONG_DOUBLE_128 || (ARM64 && KERNEL_MODE_NEON && !CC_IS_CLANG)) + select DRM_AMD_DC_DCN if (X86 || (PPC64 && ALTIVEC) || (ARM64 && KERNEL_MODE_NEON && !CC_IS_CLANG)) help Choose this option if you want to use the new display engine support for AMDGPU. This adds required support for Vega and -- cgit From 67abe9c6a8077819aae490dcd3b9629c2e87bfc2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 4 Apr 2023 13:02:50 +0200 Subject: ACPI: video: Remove register_backlight_delay module option and code Since commit 5aa9d943e9b6 ("ACPI: video: Don't enable fallback path for creating ACPI backlight by default"), the delayed registering of acpi_video# backlight devices has been disabled by default. The few bugreports where this option was used as a workaround were all cases where the GPU driver did not call acpi_video_register_backlight() and the workaround was to pass video.register_backlight_delay=1. With the recent "ACPI: video: Make acpi_backlight=video work independent from GPU driver" changes acpi_backlight=video can be used to achieve the same result. So there is no need for the register_backlight_delay option + code anymore. Reviewed-by: Mario Limonciello Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 a01fd41643fc..d8b3e1224ec2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4445,10 +4445,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) amdgpu_set_panel_orientation(&aconnector->base); } - /* If we didn't find a panel, notify the acpi video detection */ - if (dm->adev->flags & AMD_IS_APU && dm->num_of_edps == 0) - acpi_video_report_nolcd(); - /* Software is initialized. Now we can register interrupt handlers. */ switch (adev->asic_type) { #if defined(CONFIG_DRM_AMD_DC_SI) -- cgit From 583da1b82ac51f0631b6ab699153f16b241dd40e Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Thu, 30 Mar 2023 20:10:32 -0400 Subject: drm/amd/display: remove unused average_render_time_in_us and i variables clang with W=1 reports drivers/gpu/drm/amd/amdgpu/../display/modules/freesync/freesync.c:1132:15: error: variable 'average_render_time_in_us' set but not used [-Werror,-Wunused-but-set-variable] unsigned int average_render_time_in_us = 0; ^ This variable is not used so remove it, which caused i to be unused so remove that as well. Signed-off-by: Tom Rix Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index 315da61ee897..5c41a4751db4 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -1129,7 +1129,6 @@ void mod_freesync_handle_preflip(struct mod_freesync *mod_freesync, { struct core_freesync *core_freesync = NULL; unsigned int last_render_time_in_us = 0; - unsigned int average_render_time_in_us = 0; if (mod_freesync == NULL) return; @@ -1138,7 +1137,6 @@ void mod_freesync_handle_preflip(struct mod_freesync *mod_freesync, if (in_out_vrr->supported && in_out_vrr->state == VRR_STATE_ACTIVE_VARIABLE) { - unsigned int i = 0; unsigned int oldest_index = plane->time.index + 1; if (oldest_index >= DC_PLANE_UPDATE_TIMES_MAX) @@ -1147,18 +1145,6 @@ void mod_freesync_handle_preflip(struct mod_freesync *mod_freesync, last_render_time_in_us = curr_time_stamp_in_us - plane->time.prev_update_time_in_us; - /* Sum off all entries except oldest one */ - for (i = 0; i < DC_PLANE_UPDATE_TIMES_MAX; i++) { - average_render_time_in_us += - plane->time.time_elapsed_in_us[i]; - } - average_render_time_in_us -= - plane->time.time_elapsed_in_us[oldest_index]; - - /* Add render time for current flip */ - average_render_time_in_us += last_render_time_in_us; - average_render_time_in_us /= DC_PLANE_UPDATE_TIMES_MAX; - if (in_out_vrr->btr.btr_enabled) { apply_below_the_range(core_freesync, stream, -- cgit From abaeafb1b1fbeeb9e18638c6edbe9db31750c163 Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Tue, 21 Mar 2023 13:35:44 -0400 Subject: drm/amd/display: Clear FAMS flag if FAMS doesn't reduce vlevel [Description] - If we find that applying FAMS doesn't reduce the voltage level, we will not use it - Ensure to clear the stream flags indicating FAMS if we hit this case Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee 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(+) (limited to 'drivers/gpu/drm/amd/display') 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 1e26adf987cc..c252fdf2c0e8 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 @@ -2002,6 +2002,10 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, * voltage level) */ context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = false; + for (i = 0; i < context->stream_count; i++) { + if (context->streams[i]) + context->streams[i]->fpo_in_use = false; + } context->bw_ctx.dml.soc.fclk_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.fclk_change_latency_us; dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false); } -- cgit From 0efa70356882ec2a843122f02892391ae61fc4d3 Mon Sep 17 00:00:00 2001 From: Zhikai Zhai Date: Wed, 15 Mar 2023 11:16:12 +0800 Subject: drm/amd/display: add scaler control for dcn32 [WHY] It will introduce the extra warnning log on some asic that doesn't register [HOW] Add the register on dcn32 Reviewed-by: Dmytro Laktyushkin Acked-by: Qingqing Zhuo Signed-off-by: Zhikai Zhai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h index 10a3350376e4..3f5e92ef0c99 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h @@ -472,6 +472,7 @@ double dcn32_determine_max_vratio_prefetch(struct dc *dc, struct dc_state *conte SRI_ARR(OTG_H_BLANK, DSCL, id), SRI_ARR(OTG_V_BLANK, DSCL, id), \ SRI_ARR(SCL_MODE, DSCL, id), SRI_ARR(LB_DATA_FORMAT, DSCL, id), \ SRI_ARR(LB_MEMORY_CTRL, DSCL, id), SRI_ARR(DSCL_AUTOCAL, DSCL, id), \ + SRI_ARR(DSCL_CONTROL, DSCL, id), \ SRI_ARR(SCL_TAP_CONTROL, DSCL, id), \ SRI_ARR(SCL_COEF_RAM_TAP_SELECT, DSCL, id), \ SRI_ARR(SCL_COEF_RAM_TAP_DATA, DSCL, id), \ -- cgit From 6f6869dcf415f7c222057a3f07c23667e1758585 Mon Sep 17 00:00:00 2001 From: Hamza Mahfooz Date: Tue, 21 Mar 2023 16:35:28 -0400 Subject: drm/amd/display: prep work for root clock optimization enablement for DCN314 To enable root clock optimizations, we need a number of register writes and need to account for the difference in DPSTREAMCLK between DCN31 and DCN314. To prevent issues, add a number of register writes to DCCG_MASK_SH_LIST_DCN314_COMMON(), and define dccg314_init() which is mostly in alignment with dccg31_init() but accounts for the new DPSTREAMCLK sequence. Reviewed-by: Nicholas Kazlauskas Acked-by: Qingqing Zhuo Signed-off-by: Hamza Mahfooz Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c | 28 +++++++++++++++++++++- .../gpu/drm/amd/display/dc/dcn314/dcn314_dccg.h | 6 +++++ 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c index 081ce168f621..6f879265ad9c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c @@ -274,6 +274,32 @@ static void dccg314_set_dpstreamclk( } } +void dccg314_init(struct dccg *dccg) +{ + int otg_inst; + + /* Set HPO stream encoder to use refclk to avoid case where PHY is + * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which + * will cause DCN to hang. + */ + for (otg_inst = 0; otg_inst < 4; otg_inst++) + dccg31_disable_symclk32_se(dccg, otg_inst); + + if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) + for (otg_inst = 0; otg_inst < 2; otg_inst++) + dccg31_disable_symclk32_le(dccg, otg_inst); + + if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) + for (otg_inst = 0; otg_inst < 4; otg_inst++) + dccg314_set_dpstreamclk(dccg, REFCLK, otg_inst, + otg_inst); + + if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) + for (otg_inst = 0; otg_inst < 5; otg_inst++) + dccg31_set_physymclk(dccg, otg_inst, + PHYSYMCLK_FORCE_SRC_SYMCLK, false); +} + static void dccg314_set_valid_pixel_rate( struct dccg *dccg, int ref_dtbclk_khz, @@ -315,7 +341,7 @@ static const struct dccg_funcs dccg314_funcs = { .update_dpp_dto = dccg31_update_dpp_dto, .dpp_root_clock_control = dccg314_dpp_root_clock_control, .get_dccg_ref_freq = dccg31_get_dccg_ref_freq, - .dccg_init = dccg31_init, + .dccg_init = dccg314_init, .set_dpstreamclk = dccg314_set_dpstreamclk, .enable_symclk32_se = dccg31_enable_symclk32_se, .disable_symclk32_se = dccg31_disable_symclk32_se, diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.h index 6a35986307af..f62631ab53a2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.h @@ -155,6 +155,12 @@ DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE3_GATE_DISABLE, mask_sh),\ DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_LE0_GATE_DISABLE, mask_sh),\ DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_LE1_GATE_DISABLE, mask_sh),\ + DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_SE0_GATE_DISABLE, mask_sh),\ + DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_SE1_GATE_DISABLE, mask_sh),\ + DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_SE2_GATE_DISABLE, mask_sh),\ + DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_SE3_GATE_DISABLE, mask_sh),\ + DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_LE0_GATE_DISABLE, mask_sh),\ + DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_LE1_GATE_DISABLE, mask_sh),\ DCCG_SF(HDMISTREAMCLK0_DTO_PARAM, HDMISTREAMCLK0_DTO_PHASE, mask_sh),\ DCCG_SF(HDMISTREAMCLK0_DTO_PARAM, HDMISTREAMCLK0_DTO_MODULO, mask_sh) -- cgit From 385c3e4c29e1d4ce8f68687a8c84621e4c0e0416 Mon Sep 17 00:00:00 2001 From: Paul Hsieh Date: Wed, 22 Mar 2023 17:46:31 +0800 Subject: drm/amd/display: Correct DML calculation to follow HW SPEC [Why] In 2560x1600@240p eDP panel, driver use lowest voltage level to play 1080p video cause underflow. According to HW SPEC, the senario should use high voltage level. [How] ChromaPre value is zero when bandwidth validation. Correct ChromaPre calculation. Reviewed-by: Nicholas Kazlauskas Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Paul Hsieh Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c | 2 +- drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c | 2 +- drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c | 2 +- drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c index d0303173ce80..7d0626e42ea6 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c @@ -4864,7 +4864,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l v->DETBufferSizeCThisState[k], &v->UrgentBurstFactorCursorPre[k], &v->UrgentBurstFactorLumaPre[k], - &v->UrgentBurstFactorChroma[k], + &v->UrgentBurstFactorChromaPre[k], &v->NoUrgentLatencyHidingPre[k]); } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c index 536a63624595..bd674dc30df3 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c @@ -5191,7 +5191,7 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l v->DETBufferSizeCThisState[k], &v->UrgentBurstFactorCursorPre[k], &v->UrgentBurstFactorLumaPre[k], - &v->UrgentBurstFactorChroma[k], + &v->UrgentBurstFactorChromaPre[k], &v->NotUrgentLatencyHidingPre[k]); } 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 daf319370190..7eb2173b7691 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 @@ -5288,7 +5288,7 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_ v->DETBufferSizeCThisState[k], &v->UrgentBurstFactorCursorPre[k], &v->UrgentBurstFactorLumaPre[k], - &v->UrgentBurstFactorChroma[k], + &v->UrgentBurstFactorChromaPre[k], &v->NotUrgentLatencyHidingPre[k]); } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c index f74730c2abbd..13c7e7394b1c 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c @@ -3354,7 +3354,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l /* Output */ &mode_lib->vba.UrgentBurstFactorCursorPre[k], &mode_lib->vba.UrgentBurstFactorLumaPre[k], - &mode_lib->vba.UrgentBurstFactorChroma[k], + &mode_lib->vba.UrgentBurstFactorChromaPre[k], &mode_lib->vba.NotUrgentLatencyHidingPre[k]); } -- cgit From 0289e0ed1b9ae20e7b682fc7ca30d2d324a47618 Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Thu, 23 Mar 2023 15:48:41 -0400 Subject: drm/amd/display: Add FPO + VActive support [Description] - When determining FPO support, include FPO + VActive support - Support FPO + VActive if one display meets regular requirements for FPO and the second display is able to switch in VACTIVE with a given amount of margin Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 + drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 20 +++ .../gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 2 + .../gpu/drm/amd/display/dc/dcn32/dcn32_resource.h | 3 + .../amd/display/dc/dcn32/dcn32_resource_helpers.c | 156 +++++++++++++++++++++ .../drm/amd/display/dc/dcn321/dcn321_resource.c | 2 + .../gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 81 ++++++++++- .../gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h | 4 + 8 files changed, 267 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index e363a3c88250..719727a2f939 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -875,6 +875,8 @@ struct dc_debug_options { bool override_dispclk_programming; bool disable_fpo_optimizations; bool support_eDP1_5; + uint32_t fpo_vactive_margin_us; + bool disable_fpo_vactive; }; struct gpu_info_soc_bounding_box_v1_0; diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index dd6f643254fe..a9b9490a532c 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -327,6 +327,7 @@ bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, stru int i = 0, k = 0; int ramp_up_num_steps = 1; // TODO: Ramp is currently disabled. Reenable it. uint8_t visual_confirm_enabled; + int pipe_idx = 0; if (dc == NULL) return false; @@ -339,6 +340,25 @@ bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, stru cmd.fw_assisted_mclk_switch.config_data.fams_enabled = should_manage_pstate; cmd.fw_assisted_mclk_switch.config_data.visual_confirm_enabled = visual_confirm_enabled; + if (should_manage_pstate) { + for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + + if (!pipe->stream) + continue; + + /* If FAMS is being used to support P-State and there is a stream + * that does not use FAMS, we are in an FPO + VActive scenario. + * Assign vactive stretch margin in this case. + */ + if (!pipe->stream->fpo_in_use) { + cmd.fw_assisted_mclk_switch.config_data.vactive_stretch_margin_us = dc->debug.fpo_vactive_margin_us; + break; + } + pipe_idx++; + } + } + for (i = 0, k = 0; context && i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index 502f990346b1..99d417fa6458 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -726,6 +726,8 @@ static const struct dc_debug_options debug_defaults_drv = { .disable_unbounded_requesting = false, .override_dispclk_programming = true, .disable_fpo_optimizations = false, + .fpo_vactive_margin_us = 2000, // 2000us + .disable_fpo_vactive = true, }; static const struct dc_debug_options debug_defaults_diags = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h index 3f5e92ef0c99..3937dbc1e552 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h @@ -39,6 +39,7 @@ #define DCN3_2_MBLK_HEIGHT_8BPE 64 #define DCN3_2_VMIN_DISPCLK_HZ 717000000 #define DCN3_2_DCFCLK_DS_INIT_KHZ 10000 // Choose 10Mhz for init DCFCLK DS freq +#define DCN3_2_MIN_ACTIVE_SWITCH_MARGIN_FPO_US 100 // Only allow FPO + Vactive if active margin >= 100 #define TO_DCN32_RES_POOL(pool)\ container_of(pool, struct dcn32_resource_pool, base) @@ -146,6 +147,8 @@ void dcn32_restore_mall_state(struct dc *dc, struct dc_state *context, struct mall_temp_config *temp_config); +struct dc_stream_state *dcn32_can_support_mclk_switch_using_fw_based_vblank_stretch(struct dc *dc, const struct dc_state *context); + bool dcn32_allow_subvp_with_active_margin(struct pipe_ctx *pipe); unsigned int dcn32_calc_num_avail_chans_for_mall(struct dc *dc, int num_chans); diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c index 47fa51c1d3f4..eeca16faf31a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c @@ -27,6 +27,7 @@ #include "dcn32_resource.h" #include "dcn20/dcn20_resource.h" #include "dml/dcn32/display_mode_vba_util_32.h" +#include "dml/dcn32/dcn32_fpu.h" static bool is_dual_plane(enum surface_pixel_format format) { @@ -500,3 +501,158 @@ void dcn32_restore_mall_state(struct dc *dc, pipe->plane_state->is_phantom = temp_config->is_phantom_plane[i]; } } + +#define MAX_STRETCHED_V_BLANK 1000 // in micro-seconds (must ensure to match value in FW) +/* + * Scaling factor for v_blank stretch calculations considering timing in + * micro-seconds and pixel clock in 100hz. + * Note: the parenthesis are necessary to ensure the correct order of + * operation where V_SCALE is used. + */ +#define V_SCALE (10000 / MAX_STRETCHED_V_BLANK) + +static int get_frame_rate_at_max_stretch_100hz( + struct dc_stream_state *fpo_candidate_stream, + uint32_t fpo_vactive_margin_us) +{ + struct dc_crtc_timing *timing = NULL; + uint32_t sec_per_100_lines; + uint32_t max_v_blank; + uint32_t curr_v_blank; + uint32_t v_stretch_max; + uint32_t stretched_frame_pix_cnt; + uint32_t scaled_stretched_frame_pix_cnt; + uint32_t scaled_refresh_rate; + uint32_t v_scale; + + if (fpo_candidate_stream == NULL) + return 0; + + /* check if refresh rate at least 120hz */ + timing = &fpo_candidate_stream->timing; + if (timing == NULL) + return 0; + + v_scale = 10000 / (MAX_STRETCHED_V_BLANK + fpo_vactive_margin_us); + + sec_per_100_lines = timing->pix_clk_100hz / timing->h_total + 1; + max_v_blank = sec_per_100_lines / v_scale + 1; + curr_v_blank = timing->v_total - timing->v_addressable; + v_stretch_max = (max_v_blank > curr_v_blank) ? (max_v_blank - curr_v_blank) : (0); + stretched_frame_pix_cnt = (v_stretch_max + timing->v_total) * timing->h_total; + scaled_stretched_frame_pix_cnt = stretched_frame_pix_cnt / 10000; + scaled_refresh_rate = (timing->pix_clk_100hz) / scaled_stretched_frame_pix_cnt + 1; + + return scaled_refresh_rate; + +} + +static bool is_refresh_rate_support_mclk_switch_using_fw_based_vblank_stretch( + struct dc_stream_state *fpo_candidate_stream, uint32_t fpo_vactive_margin_us) +{ + int refresh_rate_max_stretch_100hz; + int min_refresh_100hz; + + if (fpo_candidate_stream == NULL) + return false; + + refresh_rate_max_stretch_100hz = get_frame_rate_at_max_stretch_100hz(fpo_candidate_stream, fpo_vactive_margin_us); + min_refresh_100hz = fpo_candidate_stream->timing.min_refresh_in_uhz / 10000; + + if (refresh_rate_max_stretch_100hz < min_refresh_100hz) + return false; + + return true; +} + +static int get_refresh_rate(struct dc_stream_state *fpo_candidate_stream) +{ + int refresh_rate = 0; + int h_v_total = 0; + struct dc_crtc_timing *timing = NULL; + + if (fpo_candidate_stream == NULL) + return 0; + + /* check if refresh rate at least 120hz */ + timing = &fpo_candidate_stream->timing; + if (timing == NULL) + return 0; + + h_v_total = timing->h_total * timing->v_total; + if (h_v_total == 0) + return 0; + + refresh_rate = ((timing->pix_clk_100hz * 100) / (h_v_total)) + 1; + return refresh_rate; +} + +/** + * dcn32_can_support_mclk_switch_using_fw_based_vblank_stretch - Determines if config can support FPO + * + * @param [in]: dc - current dc state + * @param [in]: context - new dc state + * + * Return: Pointer to FPO stream candidate if config can support FPO, otherwise NULL + */ +struct dc_stream_state *dcn32_can_support_mclk_switch_using_fw_based_vblank_stretch(struct dc *dc, const struct dc_state *context) +{ + int refresh_rate = 0; + const int minimum_refreshrate_supported = 120; + struct dc_stream_state *fpo_candidate_stream = NULL; + bool is_fpo_vactive = false; + uint32_t fpo_vactive_margin_us = 0; + + if (context == NULL) + return NULL; + + if (dc->debug.disable_fams) + return NULL; + + if (!dc->caps.dmub_caps.mclk_sw) + return NULL; + + if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching_shut_down) + return NULL; + + /* For FPO we can support up to 2 display configs if: + * - first display uses FPO + * - Second display switches in VACTIVE */ + if (context->stream_count > 2) + return NULL; + else if (context->stream_count == 2) { + DC_FP_START(); + dcn32_assign_fpo_vactive_candidate(dc, context, &fpo_candidate_stream); + DC_FP_END(); + + DC_FP_START(); + is_fpo_vactive = dcn32_find_vactive_pipe(dc, context, DCN3_2_MIN_ACTIVE_SWITCH_MARGIN_FPO_US); + DC_FP_END(); + if (!is_fpo_vactive || dc->debug.disable_fpo_vactive) + return NULL; + } else + fpo_candidate_stream = context->streams[0]; + + if (!fpo_candidate_stream) + return NULL; + + if (fpo_candidate_stream->sink->edid_caps.panel_patch.disable_fams) + return NULL; + + refresh_rate = get_refresh_rate(fpo_candidate_stream); + if (refresh_rate < minimum_refreshrate_supported) + return NULL; + + fpo_vactive_margin_us = is_fpo_vactive ? dc->debug.fpo_vactive_margin_us : 0; // For now hardcode the FPO + Vactive stretch margin to be 2000us + if (!is_refresh_rate_support_mclk_switch_using_fw_based_vblank_stretch(fpo_candidate_stream, fpo_vactive_margin_us)) + return NULL; + + // check if freesync enabled + if (!fpo_candidate_stream->allow_freesync) + return NULL; + + if (fpo_candidate_stream->vrr_active_variable) + return NULL; + + return fpo_candidate_stream; +} 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 79664ba7e7af..7ebd14fb9698 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c @@ -724,6 +724,8 @@ static const struct dc_debug_options debug_defaults_drv = { .disable_unbounded_requesting = false, .override_dispclk_programming = true, .disable_fpo_optimizations = false, + .fpo_vactive_margin_us = 2000, // 2000us + .disable_fpo_vactive = true, }; static const struct dc_debug_options debug_defaults_diags = { 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 c252fdf2c0e8..4548320217fc 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 @@ -1927,6 +1927,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, unsigned int min_dram_speed_mts_margin; bool need_fclk_lat_as_dummy = false; bool is_subvp_p_drr = false; + struct dc_stream_state *fpo_candidate_stream = NULL; dc_assert_fp_enabled(); @@ -1968,8 +1969,11 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, if (!pstate_en || (!dc->debug.disable_fpo_optimizations && pstate_en && vlevel != 0)) { /* only when the mclk switch can not be natural, is the fw based vblank stretch attempted */ - context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = - dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch(dc, context); + fpo_candidate_stream = dcn32_can_support_mclk_switch_using_fw_based_vblank_stretch(dc, context); + if (fpo_candidate_stream) { + fpo_candidate_stream->fpo_in_use = true; + context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = true; + } if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) { dummy_latency_index = dcn32_find_dummy_latency_index_for_fw_based_mclk_switch(dc, @@ -2161,7 +2165,13 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, * DCFCLK: Min, as reported by PM FW, when available * UCLK: Min, as reported by PM FW, when available */ - dc->res_pool->funcs->update_soc_for_wm_a(dc, context); + + /* For set A set the correct latency values (i.e. non-dummy values) unconditionally + */ + context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; + context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us; + context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us; + context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; @@ -2796,3 +2806,68 @@ double dcn32_determine_max_vratio_prefetch(struct dc *dc, struct dc_state *conte } return max_vratio_pre; } + +/** + * dcn32_assign_fpo_vactive_candidate - Assign the FPO stream candidate for FPO + VActive case + * + * This function chooses the FPO candidate stream for FPO + VActive cases (2 stream config). + * For FPO + VAtive cases, the assumption is that one display has ActiveMargin > 0, and the + * other display has ActiveMargin <= 0. This function will choose the pipe/stream that has + * ActiveMargin <= 0 to be the FPO stream candidate if found. + * + * + * @param [in]: dc - current dc state + * @param [in]: context - new dc state + * @param [out]: fpo_candidate_stream - pointer to FPO stream candidate if one is found + * + * Return: void + */ +void dcn32_assign_fpo_vactive_candidate(struct dc *dc, const struct dc_state *context, struct dc_stream_state **fpo_candidate_stream) +{ + unsigned int i, pipe_idx; + const struct vba_vars_st *vba = &context->bw_ctx.dml.vba; + + for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { + const struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + + if (!pipe->stream) + continue; + + if (vba->ActiveDRAMClockChangeLatencyMarginPerState[vba->VoltageLevel][vba->maxMpcComb][vba->pipe_plane[pipe_idx]] <= 0) { + *fpo_candidate_stream = pipe->stream; + break; + } + pipe_idx++; + } +} + +/** + * dcn32_find_vactive_pipe - Determines if the config has a pipe that can switch in VACTIVE + * + * @param [in]: dc - current dc state + * @param [in]: context - new dc state + * @param [in]: vactive_margin_req_us - The vactive marign required for a vactive pipe to be + * considered "found" + * + * Return: True if VACTIVE display is found, false otherwise + */ +bool dcn32_find_vactive_pipe(struct dc *dc, const struct dc_state *context, uint32_t vactive_margin_req_us) +{ + unsigned int i, pipe_idx; + const struct vba_vars_st *vba = &context->bw_ctx.dml.vba; + bool vactive_found = false; + + for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { + const struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + + if (!pipe->stream) + continue; + + if (vba->ActiveDRAMClockChangeLatencyMarginPerState[vba->VoltageLevel][vba->maxMpcComb][vba->pipe_plane[pipe_idx]] >= vactive_margin_req_us) { + vactive_found = true; + break; + } + pipe_idx++; + } + return vactive_found; +} diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h index ab010e7e840b..9a0806a0e2ef 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h @@ -76,4 +76,8 @@ void dcn32_patch_dpm_table(struct clk_bw_params *bw_params); void dcn32_zero_pipe_dcc_fraction(display_e2e_pipe_params_st *pipes, int pipe_cnt); +void dcn32_assign_fpo_vactive_candidate(struct dc *dc, const struct dc_state *context, struct dc_stream_state **fpo_candidate_stream); + +bool dcn32_find_vactive_pipe(struct dc *dc, const struct dc_state *context, uint32_t vactive_margin_req); + #endif -- cgit From d170e938f01fc8c5c41f8a12f0c12491580829ef Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Fri, 24 Mar 2023 12:01:09 -0400 Subject: drm/amd/display: On clock init, maintain DISPCLK freq [Description] - On init if a display is connected, we need to maintain the DISPCLK frequency - Even though DPG_EN=1, the display still requires the correct timing or it could cause audio corruption (if DISPCLK freq is reduced) - Read the current DISPCLK freq and request the same value to ensure the timing is valid and unchanged - However, add option to do a full pipe power down (including link) which will also avoid audio related issues - Disabled for the time being on dcn32 Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c | 18 +++++++++++++++ drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 26 +++++++++++++++++----- .../gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 1 + .../drm/amd/display/dc/dcn321/dcn321_resource.c | 1 + drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h | 3 +++ 6 files changed, 45 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c index af108f88b112..ea753f8fa175 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c @@ -399,6 +399,23 @@ static void dcn32_update_clocks_update_dentist( } +static int dcn32_get_dispclk_from_dentist(struct clk_mgr *clk_mgr_base) +{ + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); + uint32_t dispclk_wdivider; + int disp_divider; + + REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, &dispclk_wdivider); + disp_divider = dentist_get_divider_from_did(dispclk_wdivider); + + /* Return DISPCLK freq in Khz */ + if (disp_divider) + return (DENTIST_DIVIDER_RANGE_SCALE_FACTOR * clk_mgr->base.dentist_vco_freq_khz) / disp_divider; + + return 0; +} + + static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool safe_to_lower) @@ -852,6 +869,7 @@ static struct clk_mgr_funcs dcn32_funcs = { .are_clock_states_equal = dcn32_are_clock_states_equal, .enable_pme_wa = dcn32_enable_pme_wa, .is_smu_present = dcn32_is_smu_present, + .get_dispclk_from_dentist = dcn32_get_dispclk_from_dentist, }; void dcn32_clk_mgr_construct( diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 719727a2f939..f51b9c265b51 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -877,6 +877,7 @@ struct dc_debug_options { bool support_eDP1_5; uint32_t fpo_vactive_margin_us; bool disable_fpo_vactive; + bool disable_boot_optimizations; }; struct gpu_info_soc_bounding_box_v1_0; diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index b3824287c224..db0974fe58ab 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -721,10 +721,19 @@ static void dcn32_initialize_min_clocks(struct dc *dc) clocks->socclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].socclk_mhz * 1000; clocks->dramclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].memclk_mhz * 1000; clocks->dppclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dppclk_mhz * 1000; - clocks->dispclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dispclk_mhz * 1000; - clocks->ref_dtbclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dtbclk_mhz * 1000; - clocks->fclk_p_state_change_support = true; - clocks->p_state_change_support = true; + if (dc->debug.disable_boot_optimizations) { + clocks->dispclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dispclk_mhz * 1000; + } else { + /* Even though DPG_EN = 1 for the connected display, it still requires the + * correct timing so we cannot set DISPCLK to min freq or it could cause + * audio corruption. Read current DISPCLK from DENTIST and request the same + * freq to ensure that the timing is valid and unchanged. + */ + clocks->dispclk_khz = dc->clk_mgr->funcs->get_dispclk_from_dentist(dc->clk_mgr); + clocks->ref_dtbclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dtbclk_mhz * 1000; + clocks->fclk_p_state_change_support = true; + clocks->p_state_change_support = true; + } dc->clk_mgr->funcs->update_clocks( dc->clk_mgr, @@ -823,7 +832,14 @@ void dcn32_init_hw(struct dc *dc) * everything down. */ if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) { - hws->funcs.init_pipes(dc, dc->current_state); + /* Disable boot optimizations means power down everything including PHY, DIG, + * and OTG (i.e. the boot is not optimized because we do a full power down). + */ + if (dc->hwss.enable_accelerated_mode && dc->debug.disable_boot_optimizations) + dc->hwss.enable_accelerated_mode(dc, dc->current_state); + else + hws->funcs.init_pipes(dc, dc->current_state); + if (dc->res_pool->hubbub->funcs->allow_self_refresh_control) dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub, !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter); diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index 99d417fa6458..e30d1f60695d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -728,6 +728,7 @@ static const struct dc_debug_options debug_defaults_drv = { .disable_fpo_optimizations = false, .fpo_vactive_margin_us = 2000, // 2000us .disable_fpo_vactive = true, + .disable_boot_optimizations = false, }; static const struct dc_debug_options debug_defaults_diags = { 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 7ebd14fb9698..e5ab7f3077c4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c @@ -726,6 +726,7 @@ static const struct dc_debug_options debug_defaults_drv = { .disable_fpo_optimizations = false, .fpo_vactive_margin_us = 2000, // 2000us .disable_fpo_vactive = true, + .disable_boot_optimizations = false, }; static const struct dc_debug_options debug_defaults_diags = { diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h index 591ab1389e3b..bef843cc32a1 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h @@ -293,6 +293,9 @@ struct clk_mgr_funcs { /* Get SMU present */ bool (*is_smu_present)(struct clk_mgr *clk_mgr); + + int (*get_dispclk_from_dentist)(struct clk_mgr *clk_mgr_base); + }; struct clk_mgr { -- cgit From a2a0bdf1989c38ca2fc356edd23a114172ee09a2 Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Fri, 24 Mar 2023 12:31:07 -0400 Subject: drm/amd/display: add dscclk instance offset check [why] based on dscclk instance offset check conditiona program dscclk Reviewed-by: Nicholas Kazlauskas Acked-by: Qingqing Zhuo Signed-off-by: Charlene Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h | 8 ++++++++ drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c | 18 ++++++++++++++++++ drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.h | 4 ++++ 3 files changed, 30 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h index 893c0809cd4e..7bdc146f7cb5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h @@ -205,6 +205,11 @@ type PHYDSYMCLK_GATE_DISABLE; \ type PHYESYMCLK_GATE_DISABLE; +#define DCCG314_REG_FIELD_LIST(type) \ + type DSCCLK3_DTO_PHASE;\ + type DSCCLK3_DTO_MODULO;\ + type DSCCLK3_DTO_ENABLE; + #define DCCG32_REG_FIELD_LIST(type) \ type DPSTREAMCLK0_EN;\ type DPSTREAMCLK1_EN;\ @@ -237,6 +242,7 @@ struct dccg_shift { DCCG_REG_FIELD_LIST(uint8_t) DCCG3_REG_FIELD_LIST(uint8_t) DCCG31_REG_FIELD_LIST(uint8_t) + DCCG314_REG_FIELD_LIST(uint8_t) DCCG32_REG_FIELD_LIST(uint8_t) }; @@ -244,6 +250,7 @@ struct dccg_mask { DCCG_REG_FIELD_LIST(uint32_t) DCCG3_REG_FIELD_LIST(uint32_t) DCCG31_REG_FIELD_LIST(uint32_t) + DCCG314_REG_FIELD_LIST(uint32_t) DCCG32_REG_FIELD_LIST(uint32_t) }; @@ -273,6 +280,7 @@ struct dccg_registers { uint32_t DSCCLK0_DTO_PARAM; uint32_t DSCCLK1_DTO_PARAM; uint32_t DSCCLK2_DTO_PARAM; + uint32_t DSCCLK3_DTO_PARAM; uint32_t DPSTREAMCLK_ROOT_GATE_DISABLE; uint32_t DPSTREAMCLK_GATE_DISABLE; uint32_t DCCG_GATE_DISABLE_CNTL; diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c index 7d2b982506fd..4c2fdfea162f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c @@ -360,6 +360,15 @@ void dccg31_disable_dscclk(struct dccg *dccg, int inst) DSCCLK2_DTO_PHASE, 0, DSCCLK2_DTO_MODULO, 1); break; + case 3: + if (REG(DSCCLK3_DTO_PARAM)) { + REG_UPDATE(DSCCLK_DTO_CTRL, + DSCCLK3_DTO_ENABLE, 1); + REG_UPDATE_2(DSCCLK3_DTO_PARAM, + DSCCLK3_DTO_PHASE, 0, + DSCCLK3_DTO_MODULO, 1); + } + break; default: BREAK_TO_DEBUGGER(); return; @@ -395,6 +404,15 @@ void dccg31_enable_dscclk(struct dccg *dccg, int inst) REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_DTO_ENABLE, 0); break; + case 3: + if (REG(DSCCLK3_DTO_PARAM)) { + REG_UPDATE(DSCCLK_DTO_CTRL, + DSCCLK3_DTO_ENABLE, 0); + REG_UPDATE_2(DSCCLK3_DTO_PARAM, + DSCCLK3_DTO_PHASE, 0, + DSCCLK3_DTO_MODULO, 0); + } + break; default: BREAK_TO_DEBUGGER(); return; diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.h index f62631ab53a2..90687a9e8fdd 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.h @@ -68,6 +68,7 @@ SR(DSCCLK0_DTO_PARAM),\ SR(DSCCLK1_DTO_PARAM),\ SR(DSCCLK2_DTO_PARAM),\ + SR(DSCCLK3_DTO_PARAM),\ SR(DSCCLK_DTO_CTRL),\ SR(DCCG_GATE_DISABLE_CNTL2),\ SR(DCCG_GATE_DISABLE_CNTL3),\ @@ -149,6 +150,8 @@ DCCG_SF(DSCCLK1_DTO_PARAM, DSCCLK1_DTO_MODULO, mask_sh),\ DCCG_SF(DSCCLK2_DTO_PARAM, DSCCLK2_DTO_PHASE, mask_sh),\ DCCG_SF(DSCCLK2_DTO_PARAM, DSCCLK2_DTO_MODULO, mask_sh),\ + DCCG_SF(DSCCLK3_DTO_PARAM, DSCCLK3_DTO_PHASE, mask_sh),\ + DCCG_SF(DSCCLK3_DTO_PARAM, DSCCLK3_DTO_MODULO, mask_sh),\ DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE0_GATE_DISABLE, mask_sh),\ DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE1_GATE_DISABLE, mask_sh),\ DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE2_GATE_DISABLE, mask_sh),\ @@ -184,6 +187,7 @@ DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK0_DTO_ENABLE, mask_sh),\ DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK1_DTO_ENABLE, mask_sh),\ DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK2_DTO_ENABLE, mask_sh),\ + DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK3_DTO_ENABLE, mask_sh),\ DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYASYMCLK_GATE_DISABLE, mask_sh),\ DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYBSYMCLK_GATE_DISABLE, mask_sh),\ DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYCSYMCLK_GATE_DISABLE, mask_sh),\ -- cgit From 7727e7b60f82e8265a1061b81379f5a7bce0dba6 Mon Sep 17 00:00:00 2001 From: Michael Strauss Date: Fri, 24 Mar 2023 10:48:37 -0400 Subject: drm/amd/display: Improve robustness of FIXED_VS link training at DP1 rates [WHY] New sequence for transparent mode DP1.x link training was provided by LTTPR vendor [HOW] Implement new FIXED_VS sequence, increase LT retry count to minimize any potential intermittent lightup failures Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Michael Strauss Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../gpu/drm/amd/display/dc/dcn31/dcn31_resource.c | 2 + drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 8 +- .../display/dc/link/protocols/link_dp_training.c | 5 +- .../link_dp_training_fixed_vs_pe_retimer.c | 378 ++++++++++++++++++++- .../link_dp_training_fixed_vs_pe_retimer.h | 5 + 6 files changed, 396 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index f51b9c265b51..190e6a2e1334 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -405,6 +405,7 @@ struct dc_config { bool force_bios_enable_lttpr; uint8_t force_bios_fixed_vs; int sdpif_request_limit_words_per_umc; + bool use_old_fixed_vs_sequence; bool disable_subvp_drr; }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c index eaaa2e01f6d0..ff8cd5076434 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c @@ -1965,6 +1965,8 @@ static bool dcn31_resource_construct( dc->caps.color.mpc.ogam_rom_caps.hlg = 0; dc->caps.color.mpc.ocsc = 1; + dc->config.use_old_fixed_vs_sequence = true; + /* Use pipe context based otg sync logic */ dc->config.use_pipe_ctx_sync_logic = true; diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index f6c5ee2d639b..027ad1f0144d 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -2035,6 +2035,12 @@ static enum dc_status enable_link_dp(struct dc_state *state, uint32_t post_oui_delay = 30; // 30ms /* Reduce link bandwidth between failed link training attempts. */ bool do_fallback = false; + int lt_attempts = LINK_TRAINING_ATTEMPTS; + + // Increase retry count if attempting DP1.x on FIXED_VS link + if ((link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && + link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) + lt_attempts = 10; // check for seamless boot for (i = 0; i < state->stream_count; i++) { @@ -2099,7 +2105,7 @@ static enum dc_status enable_link_dp(struct dc_state *state, if (perform_link_training_with_retries(link_settings, skip_video_pattern, - LINK_TRAINING_ATTEMPTS, + lt_attempts, pipe_ctx, pipe_ctx->stream->signal, do_fallback)) { diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index f301c9eaf2f9..70fc0ddf2d7e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -1496,7 +1496,10 @@ enum link_training_result dp_perform_link_training( * Non-LT AUX transactions inside training mode. */ if ((link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && encoding == DP_8b_10b_ENCODING) - status = dp_perform_fixed_vs_pe_training_sequence(link, link_res, <_settings); + if (link->dc->config.use_old_fixed_vs_sequence) + status = dp_perform_fixed_vs_pe_training_sequence_legacy(link, link_res, <_settings); + else + status = dp_perform_fixed_vs_pe_training_sequence(link, link_res, <_settings); else if (encoding == DP_8b_10b_ENCODING) status = dp_perform_8b_10b_link_training(link, link_res, <_settings); else if (encoding == DP_128b_132b_ENCODING) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c index a4071d2959a0..5731c4b61f9f 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c @@ -223,7 +223,7 @@ static enum link_training_result perform_fixed_vs_pe_nontransparent_training_seq } -enum link_training_result dp_perform_fixed_vs_pe_training_sequence( +enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( struct dc_link *link, const struct link_resource *link_res, struct link_training_settings *lt_settings) @@ -577,3 +577,379 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( return status; } + +enum link_training_result dp_perform_fixed_vs_pe_training_sequence( + struct dc_link *link, + const struct link_resource *link_res, + struct link_training_settings *lt_settings) +{ + const uint8_t vendor_lttpr_write_data_reset[4] = {0x1, 0x50, 0x63, 0xFF}; + const uint8_t offset = dp_parse_lttpr_repeater_count( + link->dpcd_caps.lttpr_caps.phy_repeater_cnt); + const uint8_t vendor_lttpr_write_data_intercept_en[4] = {0x1, 0x55, 0x63, 0x0}; + const uint8_t vendor_lttpr_write_data_intercept_dis[4] = {0x1, 0x55, 0x63, 0x6E}; + const uint8_t vendor_lttpr_write_data_adicora_eq1[4] = {0x1, 0x55, 0x63, 0x2E}; + const uint8_t vendor_lttpr_write_data_adicora_eq2[4] = {0x1, 0x55, 0x63, 0x01}; + const uint8_t vendor_lttpr_write_data_adicora_eq3[4] = {0x1, 0x55, 0x63, 0x68}; + uint32_t pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa; + uint8_t vendor_lttpr_write_data_vs[4] = {0x1, 0x51, 0x63, 0x0}; + uint8_t vendor_lttpr_write_data_pe[4] = {0x1, 0x52, 0x63, 0x0}; + + uint32_t vendor_lttpr_write_address = 0xF004F; + enum link_training_result status = LINK_TRAINING_SUCCESS; + uint8_t lane = 0; + union down_spread_ctrl downspread = {0}; + union lane_count_set lane_count_set = {0}; + uint8_t toggle_rate; + uint8_t rate; + + /* Only 8b/10b is supported */ + ASSERT(link_dp_get_encoding_format(<_settings->link_settings) == + DP_8b_10b_ENCODING); + + if (lt_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) { + status = perform_fixed_vs_pe_nontransparent_training_sequence(link, link_res, lt_settings); + return status; + } + + if (offset != 0xFF) { + vendor_lttpr_write_address += + ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); + + /* Certain display and cable configuration require extra delay */ + if (offset > 2) + pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa * 2; + } + + /* Vendor specific: Reset lane settings */ + core_link_write_dpcd( + link, + vendor_lttpr_write_address, + &vendor_lttpr_write_data_reset[0], + sizeof(vendor_lttpr_write_data_reset)); + core_link_write_dpcd( + link, + vendor_lttpr_write_address, + &vendor_lttpr_write_data_vs[0], + sizeof(vendor_lttpr_write_data_vs)); + core_link_write_dpcd( + link, + vendor_lttpr_write_address, + &vendor_lttpr_write_data_pe[0], + sizeof(vendor_lttpr_write_data_pe)); + + /* Vendor specific: Enable intercept */ + core_link_write_dpcd( + link, + vendor_lttpr_write_address, + &vendor_lttpr_write_data_intercept_en[0], + sizeof(vendor_lttpr_write_data_intercept_en)); + + /* 1. set link rate, lane count and spread. */ + + downspread.raw = (uint8_t)(lt_settings->link_settings.link_spread); + + lane_count_set.bits.LANE_COUNT_SET = + lt_settings->link_settings.lane_count; + + lane_count_set.bits.ENHANCED_FRAMING = lt_settings->enhanced_framing; + lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0; + + + if (lt_settings->pattern_for_eq < DP_TRAINING_PATTERN_SEQUENCE_4) { + lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = + link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED; + } + + core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL, + &downspread.raw, sizeof(downspread)); + + core_link_write_dpcd(link, DP_LANE_COUNT_SET, + &lane_count_set.raw, 1); + + rate = get_dpcd_link_rate(<_settings->link_settings); + + /* Vendor specific: Toggle link rate */ + toggle_rate = (rate == 0x6) ? 0xA : 0x6; + + if (link->vendor_specific_lttpr_link_rate_wa == rate) { + core_link_write_dpcd( + link, + DP_LINK_BW_SET, + &toggle_rate, + 1); + } + + link->vendor_specific_lttpr_link_rate_wa = rate; + + core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1); + + DC_LOG_HW_LINK_TRAINING("%s\n %x rate = %x\n %x lane = %x framing = %x\n %x spread = %x\n", + __func__, + DP_LINK_BW_SET, + lt_settings->link_settings.link_rate, + DP_LANE_COUNT_SET, + lt_settings->link_settings.lane_count, + lt_settings->enhanced_framing, + DP_DOWNSPREAD_CTRL, + lt_settings->link_settings.link_spread); + + /* 2. Perform link training */ + + /* Perform Clock Recovery Sequence */ + if (status == LINK_TRAINING_SUCCESS) { + const uint8_t max_vendor_dpcd_retries = 10; + uint32_t retries_cr; + uint32_t retry_count; + uint32_t wait_time_microsec; + enum dc_lane_count lane_count = lt_settings->link_settings.lane_count; + union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX]; + union lane_align_status_updated dpcd_lane_status_updated; + union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0}; + enum dc_status dpcd_status = DC_OK; + uint8_t i = 0; + + retries_cr = 0; + retry_count = 0; + + memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status)); + memset(&dpcd_lane_status_updated, '\0', + sizeof(dpcd_lane_status_updated)); + + while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) && + (retry_count < LINK_TRAINING_MAX_CR_RETRY)) { + + + /* 1. call HWSS to set lane settings */ + dp_set_hw_lane_settings( + link, + link_res, + lt_settings, + 0); + + /* 2. update DPCD of the receiver */ + if (!retry_count) { + /* EPR #361076 - write as a 5-byte burst, + * but only for the 1-st iteration. + */ + dpcd_set_lt_pattern_and_lane_settings( + link, + lt_settings, + lt_settings->pattern_for_cr, + 0); + /* Vendor specific: Disable intercept */ + for (i = 0; i < max_vendor_dpcd_retries; i++) { + msleep(pre_disable_intercept_delay_ms); + dpcd_status = core_link_write_dpcd( + link, + vendor_lttpr_write_address, + &vendor_lttpr_write_data_intercept_dis[0], + sizeof(vendor_lttpr_write_data_intercept_dis)); + + if (dpcd_status == DC_OK) + break; + + core_link_write_dpcd( + link, + vendor_lttpr_write_address, + &vendor_lttpr_write_data_intercept_en[0], + sizeof(vendor_lttpr_write_data_intercept_en)); + } + } else { + vendor_lttpr_write_data_vs[3] = 0; + vendor_lttpr_write_data_pe[3] = 0; + + for (lane = 0; lane < lane_count; lane++) { + vendor_lttpr_write_data_vs[3] |= + lt_settings->dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET << (2 * lane); + vendor_lttpr_write_data_pe[3] |= + lt_settings->dpcd_lane_settings[lane].bits.PRE_EMPHASIS_SET << (2 * lane); + } + + /* Vendor specific: Update VS and PE to DPRX requested value */ + core_link_write_dpcd( + link, + vendor_lttpr_write_address, + &vendor_lttpr_write_data_vs[0], + sizeof(vendor_lttpr_write_data_vs)); + core_link_write_dpcd( + link, + vendor_lttpr_write_address, + &vendor_lttpr_write_data_pe[0], + sizeof(vendor_lttpr_write_data_pe)); + + dpcd_set_lane_settings( + link, + lt_settings, + 0); + } + + /* 3. wait receiver to lock-on*/ + wait_time_microsec = lt_settings->cr_pattern_time; + + dp_wait_for_training_aux_rd_interval( + link, + wait_time_microsec); + + /* 4. Read lane status and requested drive + * settings as set by the sink + */ + dp_get_lane_status_and_lane_adjust( + link, + lt_settings, + dpcd_lane_status, + &dpcd_lane_status_updated, + dpcd_lane_adjust, + 0); + + /* 5. check CR done*/ + if (dp_is_cr_done(lane_count, dpcd_lane_status)) { + status = LINK_TRAINING_SUCCESS; + break; + } + + /* 6. max VS reached*/ + if (dp_is_max_vs_reached(lt_settings)) + break; + + /* 7. same lane settings */ + /* Note: settings are the same for all lanes, + * so comparing first lane is sufficient + */ + if (lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET == + dpcd_lane_adjust[0].bits.VOLTAGE_SWING_LANE) + retries_cr++; + else + retries_cr = 0; + + /* 8. update VS/PE/PC2 in lt_settings*/ + dp_decide_lane_settings(lt_settings, dpcd_lane_adjust, + lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); + retry_count++; + } + + if (retry_count >= LINK_TRAINING_MAX_CR_RETRY) { + ASSERT(0); + DC_LOG_ERROR("%s: Link Training Error, could not get CR after %d tries. Possibly voltage swing issue", + __func__, + LINK_TRAINING_MAX_CR_RETRY); + + } + + status = dp_get_cr_failure(lane_count, dpcd_lane_status); + } + + /* Perform Channel EQ Sequence */ + if (status == LINK_TRAINING_SUCCESS) { + enum dc_dp_training_pattern tr_pattern; + uint32_t retries_ch_eq; + uint32_t wait_time_microsec; + enum dc_lane_count lane_count = lt_settings->link_settings.lane_count; + union lane_align_status_updated dpcd_lane_status_updated = {0}; + union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0}; + union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0}; + + core_link_write_dpcd( + link, + vendor_lttpr_write_address, + &vendor_lttpr_write_data_adicora_eq1[0], + sizeof(vendor_lttpr_write_data_adicora_eq1)); + core_link_write_dpcd( + link, + vendor_lttpr_write_address, + &vendor_lttpr_write_data_adicora_eq2[0], + sizeof(vendor_lttpr_write_data_adicora_eq2)); + + /* Note: also check that TPS4 is a supported feature*/ + tr_pattern = lt_settings->pattern_for_eq; + + dp_set_hw_training_pattern(link, link_res, tr_pattern, 0); + + status = LINK_TRAINING_EQ_FAIL_EQ; + + for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT; + retries_ch_eq++) { + + dp_set_hw_lane_settings(link, link_res, lt_settings, 0); + + vendor_lttpr_write_data_vs[3] = 0; + vendor_lttpr_write_data_pe[3] = 0; + + for (lane = 0; lane < lane_count; lane++) { + vendor_lttpr_write_data_vs[3] |= + lt_settings->dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET << (2 * lane); + vendor_lttpr_write_data_pe[3] |= + lt_settings->dpcd_lane_settings[lane].bits.PRE_EMPHASIS_SET << (2 * lane); + } + + /* Vendor specific: Update VS and PE to DPRX requested value */ + core_link_write_dpcd( + link, + vendor_lttpr_write_address, + &vendor_lttpr_write_data_vs[0], + sizeof(vendor_lttpr_write_data_vs)); + core_link_write_dpcd( + link, + vendor_lttpr_write_address, + &vendor_lttpr_write_data_pe[0], + sizeof(vendor_lttpr_write_data_pe)); + + /* 2. update DPCD*/ + if (!retries_ch_eq) { + /* EPR #361076 - write as a 5-byte burst, + * but only for the 1-st iteration + */ + + dpcd_set_lt_pattern_and_lane_settings( + link, + lt_settings, + tr_pattern, 0); + + core_link_write_dpcd( + link, + vendor_lttpr_write_address, + &vendor_lttpr_write_data_adicora_eq3[0], + sizeof(vendor_lttpr_write_data_adicora_eq3)); + } else + dpcd_set_lane_settings(link, lt_settings, 0); + + /* 3. wait for receiver to lock-on*/ + wait_time_microsec = lt_settings->eq_pattern_time; + + dp_wait_for_training_aux_rd_interval( + link, + wait_time_microsec); + + /* 4. Read lane status and requested + * drive settings as set by the sink + */ + dp_get_lane_status_and_lane_adjust( + link, + lt_settings, + dpcd_lane_status, + &dpcd_lane_status_updated, + dpcd_lane_adjust, + 0); + + /* 5. check CR done*/ + if (!dp_is_cr_done(lane_count, dpcd_lane_status)) { + status = LINK_TRAINING_EQ_FAIL_CR; + break; + } + + /* 6. check CHEQ done*/ + if (dp_is_ch_eq_done(lane_count, dpcd_lane_status) && + dp_is_symbol_locked(lane_count, dpcd_lane_status) && + dp_is_interlane_aligned(dpcd_lane_status_updated)) { + status = LINK_TRAINING_SUCCESS; + break; + } + + /* 7. update VS/PE/PC2 in lt_settings*/ + dp_decide_lane_settings(lt_settings, dpcd_lane_adjust, + lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); + } + } + + return status; +} diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.h index e61970e27661..c0d6ea329504 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.h @@ -28,6 +28,11 @@ #define __DC_LINK_DP_FIXED_VS_PE_RETIMER_H__ #include "link_dp_training.h" +enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( + struct dc_link *link, + const struct link_resource *link_res, + struct link_training_settings *lt_settings); + enum link_training_result dp_perform_fixed_vs_pe_training_sequence( struct dc_link *link, const struct link_resource *link_res, -- cgit From 9dce8c2a5f1bf5a304aae39342816f099247d7da Mon Sep 17 00:00:00 2001 From: Anthony Koo Date: Sat, 25 Mar 2023 09:55:13 -0400 Subject: drm/amd/display: [FW Promotion] Release 0.0.161.0 - Add command to idle opt. - Rename d3 entry event and add idle trigger param on notify event. - Add bit to fw boot status to notify status when hardware is powered up. Reviewed-by: Aric Cyr Acked-by: Qingqing Zhuo Signed-off-by: Anthony Koo Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 28 +++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 15d26222597a..598fa1de54ce 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -362,7 +362,7 @@ union dmub_fw_boot_status { uint32_t defer_load : 1; /**< 1 if VBIOS data is deferred programmed */ uint32_t reserved : 1; uint32_t detection_required: 1; /**< if detection need to be triggered by driver */ - + uint32_t hw_power_init_done: 1; /**< 1 if hw power init is completed */ } bits; /**< status bits */ uint32_t all; /**< 32-bit access to status bits */ }; @@ -377,6 +377,7 @@ enum dmub_fw_boot_status_bit { DMUB_FW_BOOT_STATUS_BIT_RESTORE_REQUIRED = (1 << 3), /**< 1 if driver should call restore */ DMUB_FW_BOOT_STATUS_BIT_DEFERRED_LOADED = (1 << 4), /**< 1 if VBIOS data is deferred programmed */ DMUB_FW_BOOT_STATUS_BIT_DETECTION_REQUIRED = (1 << 6), /**< 1 if detection need to be triggered by driver*/ + DMUB_FW_BOOT_STATUS_BIT_HW_POWER_INIT_DONE = (1 << 7), /**< 1 if hw power init is completed */ }; /* Register bit definition for SCRATCH5 */ @@ -1104,7 +1105,12 @@ enum dmub_cmd_idle_opt_type { /** * DCN hardware save. */ - DMUB_CMD__IDLE_OPT_DCN_SAVE_INIT = 1 + DMUB_CMD__IDLE_OPT_DCN_SAVE_INIT = 1, + + /** + * DCN hardware notify idle. + */ + DMUB_CMD__IDLE_OPT_DCN_NOTIFY_IDLE = 2 }; /** @@ -1114,6 +1120,24 @@ struct dmub_rb_cmd_idle_opt_dcn_restore { struct dmub_cmd_header header; /**< header */ }; +/** + * struct dmub_dcn_notify_idle_cntl_data - Data passed to FW in a DMUB_CMD__IDLE_OPT_DCN_NOTIFY_IDLE command. + */ +struct dmub_dcn_notify_idle_cntl_data { + uint8_t driver_idle; + uint8_t d3_entry; + uint8_t trigger; + uint8_t pad[1]; +}; + +/** + * struct dmub_rb_cmd_idle_opt_dcn_notify_idle - Data passed to FW in a DMUB_CMD__IDLE_OPT_DCN_NOTIFY_IDLE command. + */ +struct dmub_rb_cmd_idle_opt_dcn_notify_idle { + struct dmub_cmd_header header; /**< header */ + struct dmub_dcn_notify_idle_cntl_data cntl_data; +}; + /** * struct dmub_clocks - Clock update notification. */ -- cgit From d116db180decec1b21bba31d2ff495ac4d8e1b83 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 23 Mar 2023 14:07:06 -0500 Subject: drm/amd: Fix an out of bounds error in BIOS parser The array is hardcoded to 8 in atomfirmware.h, but firmware provides a bigger one sometimes. Deferencing the larger array causes an out of bounds error. commit 4fc1ba4aa589 ("drm/amd/display: fix array index out of bound error in bios parser") fixed some of this, but there are two other cases not covered by it. Fix those as well. Reported-by: erhard_f@mailbox.org Link: https://bugzilla.kernel.org/show_bug.cgi?id=214853 Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2473 Signed-off-by: Mario Limonciello Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index f0f948501e9a..cce47d3f1a13 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -515,11 +515,8 @@ static enum bp_result get_gpio_i2c_info( info->i2c_slave_address = record->i2c_slave_addr; /* TODO: check how to get register offset for en, Y, etc. */ - info->gpio_info.clk_a_register_index = - le16_to_cpu( - header->gpio_pin[table_index].data_a_reg_index); - info->gpio_info.clk_a_shift = - header->gpio_pin[table_index].gpio_bitshift; + info->gpio_info.clk_a_register_index = le16_to_cpu(pin->data_a_reg_index); + info->gpio_info.clk_a_shift = pin->gpio_bitshift; return BP_RESULT_OK; } -- cgit From e38dddcaed60c0692b77a7af355d34a13183cee1 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Mon, 27 Mar 2023 01:45:02 -0400 Subject: drm/amd/display: 3.2.230 This DC version brings along: - FW Release 0.0.161.0 - Improvements on FPO/FAMS - Correction to DML calculation - Fix to multiple clock related issues Acked-by: Qingqing Zhuo 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(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 190e6a2e1334..23ee63b98dcd 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -45,7 +45,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.229" +#define DC_VER "3.2.230" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- cgit From 52f1783ff4146344342422c1cd94fcb4ce39b6fe Mon Sep 17 00:00:00 2001 From: Igor Artemiev Date: Mon, 3 Apr 2023 16:10:37 +0300 Subject: drm/amd/display: Fix potential null dereference The adev->dm.dc pointer can be NULL and dereferenced in amdgpu_dm_fini() without checking. Add a NULL pointer check before calling dc_dmub_srv_destroy(). Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 9a71c7d31734 ("drm/amd/display: Register DMUB service with DC") Signed-off-by: Igor Artemiev Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 e29655a26dd4..6cacb76f389e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1890,7 +1890,8 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev) if (adev->dm.dc) dc_deinit_callbacks(adev->dm.dc); - dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv); + if (adev->dm.dc) + dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv); if (dc_enable_dmub_notifications(adev->dm.dc)) { kfree(adev->dm.dmub_notify); -- cgit From ff38d974bc2842797d1d75f5060afd1cea4a76a9 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Thu, 6 Apr 2023 14:44:34 -0400 Subject: drm/amd/display: set variable dcn3_14_soc storage-class-specifier to static smatch reports drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn314/dcn314_fpu.c:100:37: warning: symbol 'dcn3_14_soc' was not declared. Should it be static? This variable is only used in one file so should be static. Signed-off-by: Tom Rix Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c index c52b76610bd2..44082f65de1f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c @@ -97,7 +97,7 @@ struct _vcs_dpi_ip_params_st dcn3_14_ip = { .dcc_supported = true, }; -struct _vcs_dpi_soc_bounding_box_st dcn3_14_soc = { +static struct _vcs_dpi_soc_bounding_box_st dcn3_14_soc = { /*TODO: correct dispclk/dppclk voltage level determination*/ .clock_limits = { { -- cgit From 75bf1df75d5e9a22898c5b6c3410ef8ec3a0de70 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Thu, 6 Apr 2023 15:58:18 -0400 Subject: drm/amd/display: set variables aperture_default_system and context0_default_system storage-class-specifier to static smatch reports drivers/gpu/drm/amd/amdgpu/../display/dc/dcn10/dcn10_hubp.c:758:10: warning: symbol 'aperture_default_system' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dcn10/dcn10_hubp.c:759:10: warning: symbol 'context0_default_system' was not declared. Should it be static? These variables are only used in one file so should be static. Signed-off-by: Tom Rix Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c index a142a00bc432..bf399819ca80 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c @@ -755,8 +755,8 @@ bool hubp1_is_flip_pending(struct hubp *hubp) return false; } -uint32_t aperture_default_system = 1; -uint32_t context0_default_system; /* = 0;*/ +static uint32_t aperture_default_system = 1; +static uint32_t context0_default_system; /* = 0;*/ static void hubp1_set_vm_system_aperture_settings(struct hubp *hubp, struct vm_system_aperture_param *apt) -- cgit From 94aec514c872250887e435faee333c9da741cd72 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Sat, 8 Apr 2023 09:43:48 -0400 Subject: drm/amd/display: set variables dml*_funcs storage-class-specifier to static smatch reports drivers/gpu/drm/amd/amdgpu/../display/dc/dml/display_mode_lib.c:44:24: warning: symbol 'dml20_funcs' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dml/display_mode_lib.c:51:24: warning: symbol 'dml20v2_funcs' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dml/display_mode_lib.c:58:24: warning: symbol 'dml21_funcs' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dml/display_mode_lib.c:65:24: warning: symbol 'dml30_funcs' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dml/display_mode_lib.c:72:24: warning: symbol 'dml31_funcs' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dml/display_mode_lib.c:79:24: warning: symbol 'dml314_funcs' was not declared. Should it be static? drivers/gpu/drm/amd/amdgpu/../display/dc/dml/display_mode_lib.c:86:24: warning: symbol 'dml32_funcs' was not declared. Should it be static? These variables are only used in one file so should be static. Cleanup whitespace, use tabs consistently for indents. Signed-off-by: Tom Rix Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dml/display_mode_lib.c | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c index 4125d3d111d1..bdf3ac6cadd5 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c @@ -41,51 +41,51 @@ #include "dcn32/display_rq_dlg_calc_32.h" #include "dml_logger.h" -const struct dml_funcs dml20_funcs = { +static const struct dml_funcs dml20_funcs = { .validate = dml20_ModeSupportAndSystemConfigurationFull, .recalculate = dml20_recalculate, .rq_dlg_get_dlg_reg = dml20_rq_dlg_get_dlg_reg, .rq_dlg_get_rq_reg = dml20_rq_dlg_get_rq_reg }; -const struct dml_funcs dml20v2_funcs = { +static const struct dml_funcs dml20v2_funcs = { .validate = dml20v2_ModeSupportAndSystemConfigurationFull, .recalculate = dml20v2_recalculate, .rq_dlg_get_dlg_reg = dml20v2_rq_dlg_get_dlg_reg, .rq_dlg_get_rq_reg = dml20v2_rq_dlg_get_rq_reg }; -const struct dml_funcs dml21_funcs = { - .validate = dml21_ModeSupportAndSystemConfigurationFull, - .recalculate = dml21_recalculate, - .rq_dlg_get_dlg_reg = dml21_rq_dlg_get_dlg_reg, - .rq_dlg_get_rq_reg = dml21_rq_dlg_get_rq_reg +static const struct dml_funcs dml21_funcs = { + .validate = dml21_ModeSupportAndSystemConfigurationFull, + .recalculate = dml21_recalculate, + .rq_dlg_get_dlg_reg = dml21_rq_dlg_get_dlg_reg, + .rq_dlg_get_rq_reg = dml21_rq_dlg_get_rq_reg }; -const struct dml_funcs dml30_funcs = { +static const struct dml_funcs dml30_funcs = { .validate = dml30_ModeSupportAndSystemConfigurationFull, .recalculate = dml30_recalculate, .rq_dlg_get_dlg_reg = dml30_rq_dlg_get_dlg_reg, .rq_dlg_get_rq_reg = dml30_rq_dlg_get_rq_reg }; -const struct dml_funcs dml31_funcs = { +static const struct dml_funcs dml31_funcs = { .validate = dml31_ModeSupportAndSystemConfigurationFull, .recalculate = dml31_recalculate, .rq_dlg_get_dlg_reg = dml31_rq_dlg_get_dlg_reg, .rq_dlg_get_rq_reg = dml31_rq_dlg_get_rq_reg }; -const struct dml_funcs dml314_funcs = { +static const struct dml_funcs dml314_funcs = { .validate = dml314_ModeSupportAndSystemConfigurationFull, .recalculate = dml314_recalculate, .rq_dlg_get_dlg_reg = dml314_rq_dlg_get_dlg_reg, .rq_dlg_get_rq_reg = dml314_rq_dlg_get_rq_reg }; -const struct dml_funcs dml32_funcs = { +static const struct dml_funcs dml32_funcs = { .validate = dml32_ModeSupportAndSystemConfigurationFull, - .recalculate = dml32_recalculate, + .recalculate = dml32_recalculate, .rq_dlg_get_dlg_reg_v2 = dml32_rq_dlg_get_dlg_reg, .rq_dlg_get_rq_reg_v2 = dml32_rq_dlg_get_rq_reg }; -- cgit From fdf8ea814ae48d7f5670bc7c3bf34101fb58f7c8 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Sat, 25 Mar 2023 09:45:03 -0400 Subject: drm/amd/display: remove unused matching_stream_ptrs variable clang with W=1 reports drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_link_enc_cfg.c:625:6: error: variable 'matching_stream_ptrs' set but not used [-Werror,-Wunused-but-set-variable] int matching_stream_ptrs = 0; ^ This variable is not used so remove it. Reviewed-by: Nick Desaulniers Signed-off-by: Tom Rix Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c index 41198c729d90..30c0644d4418 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c @@ -622,7 +622,6 @@ bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state) int i, j; uint8_t valid_count = 0; uint8_t dig_stream_count = 0; - int matching_stream_ptrs = 0; int eng_ids_per_ep_id[MAX_PIPES] = {0}; int ep_ids_per_eng_id[MAX_PIPES] = {0}; int valid_bitmap = 0; @@ -645,9 +644,7 @@ bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state) struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i]; if (assignment.valid) { - if (assignment.stream == state->streams[i]) - matching_stream_ptrs++; - else + if (assignment.stream != state->streams[i]) valid_stream_ptrs = false; } } -- cgit From aee89b7d0929bfc6530a1468d34e0befc1991389 Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Sun, 9 Apr 2023 22:35:38 +0530 Subject: drm/amd/display : Log DP link training downspread info Update the existing log with DP LT downspread info: [Downstream devices shall support down spreading of the link clock. The down-spread amplitude shall either be disabled (0.0%) or up to 0.5%, as written by the upstream device to the DOWNSPREAD_CTRL register (DPCD 00107h). The modulation frequency range shall be 30 to 33 kHz] Besides, fix checkpatch warning: CHECK: Alignment should match open parenthesis Cc: Mario Limonciello Cc: Harry Wentland Cc: Leo Li Cc: Alex Deucher Signed-off-by: Srinivasan Shanmugam Reviewed-by: Aurabindo Pillai Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/link/protocols/link_dp_training.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index 70fc0ddf2d7e..2d067a4a8517 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -1560,9 +1560,10 @@ bool perform_link_training_with_retries( j = 0; while (j < attempts && fail_count < (attempts * 10)) { - DC_LOG_HW_LINK_TRAINING("%s: Beginning link(%d) training attempt %u of %d @ rate(%d) x lane(%d)\n", - __func__, link->link_index, (unsigned int)j + 1, attempts, cur_link_settings.link_rate, - cur_link_settings.lane_count); + DC_LOG_HW_LINK_TRAINING("%s: Beginning link(%d) training attempt %u of %d @ rate(%d) x lane(%d) @ spread = %x\n", + __func__, link->link_index, (unsigned int)j + 1, attempts, + cur_link_settings.link_rate, cur_link_settings.lane_count, + cur_link_settings.link_spread); dp_enable_link_phy( link, @@ -1640,9 +1641,10 @@ bool perform_link_training_with_retries( break; } - DC_LOG_WARNING("%s: Link(%d) training attempt %u of %d failed @ rate(%d) x lane(%d) : fail reason:(%d)\n", - __func__, link->link_index, (unsigned int)j + 1, attempts, cur_link_settings.link_rate, - cur_link_settings.lane_count, status); + DC_LOG_WARNING("%s: Link(%d) training attempt %u of %d failed @ rate(%d) x lane(%d) @ spread = %x : fail reason:(%d)\n", + __func__, link->link_index, (unsigned int)j + 1, attempts, + cur_link_settings.link_rate, cur_link_settings.lane_count, + cur_link_settings.link_spread, status); dp_disable_link_phy(link, &pipe_ctx->link_res, signal); -- cgit From 3e3320a7d96c1a5c66b60fbabb38af1f4c4fae1a Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Fri, 7 Apr 2023 14:22:53 +0530 Subject: drm/amd/display: Add logging for DP link traning Test Pattern Seqeunces Add some more logging for DP link traning test pattern seqeunces for better debugging. Cc: Fangzhi Zuo Cc: Harry Wentland Cc: Leo Li Cc: Alex Deucher Signed-off-by: Srinivasan Shanmugam Reviewed-by: Fangzhi Zuo Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index 2d067a4a8517..170f33835930 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -212,27 +212,36 @@ enum dpcd_training_patterns switch (pattern) { case DP_TRAINING_PATTERN_SEQUENCE_1: + DC_LOG_HW_LINK_TRAINING("%s: Using DP training pattern TPS1\n", __func__); dpcd_tr_pattern = DPCD_TRAINING_PATTERN_1; break; case DP_TRAINING_PATTERN_SEQUENCE_2: + DC_LOG_HW_LINK_TRAINING("%s: Using DP training pattern TPS2\n", __func__); dpcd_tr_pattern = DPCD_TRAINING_PATTERN_2; break; case DP_TRAINING_PATTERN_SEQUENCE_3: + DC_LOG_HW_LINK_TRAINING("%s: Using DP training pattern TPS3\n", __func__); dpcd_tr_pattern = DPCD_TRAINING_PATTERN_3; break; case DP_TRAINING_PATTERN_SEQUENCE_4: + DC_LOG_HW_LINK_TRAINING("%s: Using DP training pattern TPS4\n", __func__); dpcd_tr_pattern = DPCD_TRAINING_PATTERN_4; break; case DP_128b_132b_TPS1: + DC_LOG_HW_LINK_TRAINING("%s: Using DP 128b/132b training pattern TPS1\n", __func__); dpcd_tr_pattern = DPCD_128b_132b_TPS1; break; case DP_128b_132b_TPS2: + DC_LOG_HW_LINK_TRAINING("%s: Using DP 128b/132b training pattern TPS2\n", __func__); dpcd_tr_pattern = DPCD_128b_132b_TPS2; break; case DP_128b_132b_TPS2_CDS: + DC_LOG_HW_LINK_TRAINING("%s: Using DP 128b/132b training pattern TPS2 CDS\n", + __func__); dpcd_tr_pattern = DPCD_128b_132b_TPS2_CDS; break; case DP_TRAINING_PATTERN_VIDEOIDLE: + DC_LOG_HW_LINK_TRAINING("%s: Using DP training pattern videoidle\n", __func__); dpcd_tr_pattern = DPCD_TRAINING_PATTERN_VIDEOIDLE; break; default: -- cgit From b8ca445f550a9a079134f836466ddda3bfad6108 Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Fri, 17 Feb 2023 13:26:56 +0800 Subject: drm/amd/display: Pass the right info to drm_dp_remove_payload [Why & How] drm_dp_remove_payload() interface was changed. Correct amdgpu dm code to pass the right parameter to the drm helper function. Reviewed-by: Jerry Zuo Acked-by: Qingqing Zhuo Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 57 +++++++++++++++++++--- 1 file changed, 50 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 1583157da355..efd025d8961e 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 @@ -177,6 +177,40 @@ void dm_helpers_dp_update_branch_info( const struct dc_link *link) {} +static void dm_helpers_construct_old_payload( + struct dc_link *link, + int pbn_per_slot, + struct drm_dp_mst_atomic_payload *new_payload, + struct drm_dp_mst_atomic_payload *old_payload) +{ + struct link_mst_stream_allocation_table current_link_table = + link->mst_stream_alloc_table; + struct link_mst_stream_allocation *dc_alloc; + int i; + + *old_payload = *new_payload; + + /* Set correct time_slots/PBN of old payload. + * other fields (delete & dsc_enabled) in + * struct drm_dp_mst_atomic_payload are don't care fields + * while calling drm_dp_remove_payload() + */ + for (i = 0; i < current_link_table.stream_count; i++) { + dc_alloc = + ¤t_link_table.stream_allocations[i]; + + if (dc_alloc->vcp_id == new_payload->vcpi) { + old_payload->time_slots = dc_alloc->slot_count; + old_payload->pbn = dc_alloc->slot_count * pbn_per_slot; + break; + } + } + + /* make sure there is an old payload*/ + ASSERT(i != current_link_table.stream_count); + +} + /* * Writes payload allocation table in immediate downstream device. */ @@ -188,7 +222,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( { struct amdgpu_dm_connector *aconnector; struct drm_dp_mst_topology_state *mst_state; - struct drm_dp_mst_atomic_payload *payload; + struct drm_dp_mst_atomic_payload *target_payload, *new_payload, old_payload; struct drm_dp_mst_topology_mgr *mst_mgr; aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; @@ -204,17 +238,26 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state); /* It's OK for this to fail */ - payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port); - if (enable) - drm_dp_add_payload_part1(mst_mgr, mst_state, payload); - else - drm_dp_remove_payload(mst_mgr, mst_state, payload, payload); + new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port); + + if (enable) { + target_payload = new_payload; + + drm_dp_add_payload_part1(mst_mgr, mst_state, new_payload); + } else { + /* construct old payload by VCPI*/ + dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div, + new_payload, &old_payload); + target_payload = &old_payload; + + drm_dp_remove_payload(mst_mgr, mst_state, &old_payload, new_payload); + } /* mst_mgr->->payloads are VC payload notify MST branch using DPCD or * AUX message. The sequence is slot 1-63 allocated sequence for each * stream. AMD ASIC stream slot allocation should follow the same * sequence. copy DRM MST allocation to dc */ - fill_dc_mst_payload_table_from_drm(stream->link, enable, payload, proposed_table); + fill_dc_mst_payload_table_from_drm(stream->link, enable, target_payload, proposed_table); return true; } -- cgit From ca9beb8aac68468f1778ad0e0fdad4e204f91393 Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Thu, 13 Apr 2023 21:19:15 +0530 Subject: drm/amd/display: Add logging when setting DP sink power state fails Log if we fail to setup sink power states. Cc: Fangzhi Zuo Cc: Aurabindo Pillai Signed-off-by: Srinivasan Shanmugam Reviewed-by: Aurabindo Pillai Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index c840ef17802e..ba98013fecd0 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -1043,6 +1043,9 @@ static enum dc_status wake_up_aux_channel(struct dc_link *link) DP_SET_POWER, &dpcd_power_state, sizeof(dpcd_power_state)); + if (status < 0) + DC_LOG_DC("%s: Failed to power up sink: %s\n", __func__, + dpcd_power_state == DP_SET_POWER_D0 ? "D0" : "D3"); return DC_ERROR_UNEXPECTED; } -- cgit From 88c7ad91e378775a08f54b4a85068d51b5cf52f3 Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Fri, 14 Apr 2023 01:20:18 +0530 Subject: drm/amd/display: Add logging when DP link training Clock recovery is Successful Log when Clock recovery is successful, as part of DP link training process. Cc: Aurabindo Pillai Cc: Fangzhi Zuo Signed-off-by: Srinivasan Shanmugam Reviewed-by: Aurabindo Pillai Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c | 4 +++- drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c index 14b98e096d39..3889ebb2256b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c @@ -225,8 +225,10 @@ enum link_training_result perform_8b_10b_clock_recovery_sequence( offset); /* 5. check CR done*/ - if (dp_is_cr_done(lane_count, dpcd_lane_status)) + if (dp_is_cr_done(lane_count, dpcd_lane_status)) { + DC_LOG_HW_LINK_TRAINING("%s: Clock recovery OK\n", __func__); return LINK_TRAINING_SUCCESS; + } /* 6. max VS reached*/ if ((link_dp_get_encoding_format(<_settings->link_settings) == diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c index ab4aafdb5e5c..4f4e899e5c46 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c @@ -401,6 +401,7 @@ static enum link_training_result dpia_training_cr_non_transparent( /* Check if clock recovery successful. */ if (dp_is_cr_done(lane_count, dpcd_lane_status)) { + DC_LOG_HW_LINK_TRAINING("%s: Clock recovery OK\n", __func__); result = LINK_TRAINING_SUCCESS; break; } @@ -508,6 +509,7 @@ static enum link_training_result dpia_training_cr_transparent( /* Check if clock recovery successful. */ if (dp_is_cr_done(lane_count, dpcd_lane_status)) { + DC_LOG_HW_LINK_TRAINING("%s: Clock recovery OK\n", __func__); result = LINK_TRAINING_SUCCESS; break; } -- cgit From 764ba43d34ac5fd16e0e377643f89a7208f1f67b Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Mon, 3 Apr 2023 14:06:16 -0600 Subject: drm/amd/display: Update bouding box values for DCN32 All clock values came from firmware, but bounding box values can be helpful in some debug situations. This commit updates some of the values associated with clock speed and memory channels. Reviewed-by: Aurabindo Pillai Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 4548320217fc..f0037cb43dca 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 @@ -109,7 +109,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = { { .state = 0, .dcfclk_mhz = 1564.0, - .fabricclk_mhz = 400.0, + .fabricclk_mhz = 2500.0, .dispclk_mhz = 2150.0, .dppclk_mhz = 2150.0, .phyclk_mhz = 810.0, @@ -117,7 +117,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = { .phyclk_d32_mhz = 625.0, .socclk_mhz = 1200.0, .dscclk_mhz = 716.667, - .dram_speed_mts = 16000.0, + .dram_speed_mts = 18000.0, .dtbclk_mhz = 1564.0, }, }, @@ -148,7 +148,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = { .max_avg_fabric_bw_use_normal_percent = 60.0, .max_avg_dram_bw_use_normal_strobe_percent = 50.0, .max_avg_dram_bw_use_normal_percent = 15.0, - .num_chans = 8, + .num_chans = 24, .dram_channel_width_bytes = 2, .fabric_datapath_to_dcn_data_return_bytes = 64, .return_bus_width_bytes = 64, -- cgit From ef3d74aa7e5d0ba4e9fc00f1409652e29f46fc59 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Mon, 3 Apr 2023 14:10:27 -0600 Subject: drm/amd/display: Add missing mclk update When using FPO, there is some misconfiguration that happens for the lack of configuration of the MCLK switch in some circumstances. This commit adds the required field update when using the MCLK switch. Reviewed-by: Aurabindo Pillai Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/amd/display') 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 f0037cb43dca..23a972f2885f 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 @@ -1331,6 +1331,11 @@ static void dcn32_calculate_dlg_params(struct dc *dc, struct dc_state *context, context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != dm_dram_clock_change_unsupported; + /* Pstate change might not be supported by hardware, but it might be + * possible with firmware driven vertical blank stretching. + */ + context->bw_ctx.bw.dcn.clk.p_state_change_support |= context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching; + context->bw_ctx.bw.dcn.clk.dppclk_khz = 0; context->bw_ctx.bw.dcn.clk.dtbclk_en = is_dtbclk_required(dc, context); context->bw_ctx.bw.dcn.clk.ref_dtbclk_khz = context->bw_ctx.dml.vba.DTBCLKPerState[vlevel] * 1000; -- cgit From 83aeb49c8c467e9fe77c4f01c80472a4329db49c Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Mon, 3 Apr 2023 15:29:36 -0600 Subject: drm/amd/display: Adjust code identation and other minor details This commit replaces spaces with tabs in multiple functions and adjusts the indentation in some other parts of the code to improve readability. Reviewed-by: Aurabindo Pillai Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 44 +++--- .../gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 170 +++++++++++---------- 2 files changed, 109 insertions(+), 105 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index e30d1f60695d..0beb11d95eb7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -324,7 +324,6 @@ static const struct dcn10_link_enc_shift le_shift = { static const struct dcn10_link_enc_mask le_mask = { LINK_ENCODER_MASK_SH_LIST_DCN31(_MASK), \ - //DPCS_DCN31_MASK_SH_LIST(_MASK) }; @@ -2093,27 +2092,28 @@ static bool dcn32_resource_construct( uint32_t pipe_fuses = 0; uint32_t num_pipes = 4; - #undef REG_STRUCT - #define REG_STRUCT bios_regs - bios_regs_init(); - - #undef REG_STRUCT - #define REG_STRUCT clk_src_regs - clk_src_regs_init(0, A), - clk_src_regs_init(1, B), - clk_src_regs_init(2, C), - clk_src_regs_init(3, D), - clk_src_regs_init(4, E); - #undef REG_STRUCT - #define REG_STRUCT abm_regs - abm_regs_init(0), - abm_regs_init(1), - abm_regs_init(2), - abm_regs_init(3); - - #undef REG_STRUCT - #define REG_STRUCT dccg_regs - dccg_regs_init(); +#undef REG_STRUCT +#define REG_STRUCT bios_regs + bios_regs_init(); + +#undef REG_STRUCT +#define REG_STRUCT clk_src_regs + clk_src_regs_init(0, A), + clk_src_regs_init(1, B), + clk_src_regs_init(2, C), + clk_src_regs_init(3, D), + clk_src_regs_init(4, E); + +#undef REG_STRUCT +#define REG_STRUCT abm_regs + abm_regs_init(0), + abm_regs_init(1), + abm_regs_init(2), + abm_regs_init(3); + +#undef REG_STRUCT +#define REG_STRUCT dccg_regs + dccg_regs_init(); DC_FP_START(); 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 38d1f2be8cf3..6e32dc68f7bc 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 @@ -917,19 +917,19 @@ void dcn20_populate_dml_writeback_from_context(struct dc *dc, } void dcn20_fpu_set_wb_arb_params(struct mcif_arb_params *wb_arb_params, - struct dc_state *context, - display_e2e_pipe_params_st *pipes, - int pipe_cnt, int i) + struct dc_state *context, + display_e2e_pipe_params_st *pipes, + int pipe_cnt, int i) { - int k; + int k; - dc_assert_fp_enabled(); + dc_assert_fp_enabled(); - for (k = 0; k < sizeof(wb_arb_params->cli_watermark)/sizeof(wb_arb_params->cli_watermark[0]); k++) { - wb_arb_params->cli_watermark[k] = get_wm_writeback_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - wb_arb_params->pstate_watermark[k] = get_wm_writeback_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - } - wb_arb_params->time_per_pixel = 16.0 * 1000 / (context->res_ctx.pipe_ctx[i].stream->phy_pix_clk / 1000); /* 4 bit fraction, ms */ + for (k = 0; k < sizeof(wb_arb_params->cli_watermark)/sizeof(wb_arb_params->cli_watermark[0]); k++) { + wb_arb_params->cli_watermark[k] = get_wm_writeback_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + wb_arb_params->pstate_watermark[k] = get_wm_writeback_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + } + wb_arb_params->time_per_pixel = 16.0 * 1000 / (context->res_ctx.pipe_ctx[i].stream->phy_pix_clk / 1000); /* 4 bit fraction, ms */ } static bool is_dtbclk_required(struct dc *dc, struct dc_state *context) @@ -1037,11 +1037,11 @@ static void dcn20_adjust_freesync_v_startup( *vstartup_start = ((newVstartup > *vstartup_start) ? newVstartup : *vstartup_start); } -void dcn20_calculate_dlg_params( - struct dc *dc, struct dc_state *context, - display_e2e_pipe_params_st *pipes, - int pipe_cnt, - int vlevel) +void dcn20_calculate_dlg_params(struct dc *dc, + struct dc_state *context, + display_e2e_pipe_params_st *pipes, + int pipe_cnt, + int vlevel) { int i, pipe_idx; @@ -1083,6 +1083,7 @@ void dcn20_calculate_dlg_params( pipes[pipe_idx].pipe.dest.vupdate_offset = get_vupdate_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); pipes[pipe_idx].pipe.dest.vupdate_width = get_vupdate_width(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); pipes[pipe_idx].pipe.dest.vready_offset = get_vready_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); + if (context->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) { // Phantom pipe requires that DET_SIZE = 0 and no unbounded requests context->res_ctx.pipe_ctx[i].det_buffer_size_kb = 0; @@ -1091,6 +1092,7 @@ void dcn20_calculate_dlg_params( context->res_ctx.pipe_ctx[i].det_buffer_size_kb = context->bw_ctx.dml.ip.det_buffer_size_kbytes; context->res_ctx.pipe_ctx[i].unbounded_req = pipes[pipe_idx].pipe.src.unbounded_req_mode; } + if (context->bw_ctx.bw.dcn.clk.dppclk_khz < pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000) context->bw_ctx.bw.dcn.clk.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000; context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz = @@ -1118,6 +1120,7 @@ void dcn20_calculate_dlg_params( if (!context->res_ctx.pipe_ctx[i].stream) continue; + /* cstate disabled on 201 */ if (dc->ctx->dce_version == DCN_VERSION_2_01) cstate_en = false; @@ -1201,11 +1204,10 @@ static void swizzle_to_dml_params( } } -int dcn20_populate_dml_pipes_from_context( - struct dc *dc, - struct dc_state *context, - display_e2e_pipe_params_st *pipes, - bool fast_validate) +int dcn20_populate_dml_pipes_from_context(struct dc *dc, + struct dc_state *context, + display_e2e_pipe_params_st *pipes, + bool fast_validate) { int pipe_cnt, i; bool synchronized_vblank = true; @@ -1507,6 +1509,7 @@ int dcn20_populate_dml_pipes_from_context( default: break; } + pipes[pipe_cnt].pipe.src.viewport_y_y = scl->viewport.y; pipes[pipe_cnt].pipe.src.viewport_y_c = scl->viewport_c.y; pipes[pipe_cnt].pipe.src.viewport_x_y = scl->viewport.x; @@ -1615,13 +1618,12 @@ int dcn20_populate_dml_pipes_from_context( return pipe_cnt; } -void dcn20_calculate_wm( - struct dc *dc, struct dc_state *context, - display_e2e_pipe_params_st *pipes, - int *out_pipe_cnt, - int *pipe_split_from, - int vlevel, - bool fast_validate) +void dcn20_calculate_wm(struct dc *dc, struct dc_state *context, + display_e2e_pipe_params_st *pipes, + int *out_pipe_cnt, + int *pipe_split_from, + int vlevel, + bool fast_validate) { int pipe_cnt, i, pipe_idx; @@ -1733,8 +1735,11 @@ void dcn20_calculate_wm( context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; } -void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb, - struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states) +void dcn20_update_bounding_box(struct dc *dc, + struct _vcs_dpi_soc_bounding_box_st *bb, + struct pp_smu_nv_clock_table *max_clocks, + unsigned int *uclk_states, + unsigned int num_states) { int num_calculated_states = 0; int min_dcfclk = 0; @@ -1796,9 +1801,8 @@ void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s bb->clock_limits[num_calculated_states].state = bb->num_states; } -void dcn20_cap_soc_clocks( - struct _vcs_dpi_soc_bounding_box_st *bb, - struct pp_smu_nv_clock_table max_clocks) +void dcn20_cap_soc_clocks(struct _vcs_dpi_soc_bounding_box_st *bb, + struct pp_smu_nv_clock_table max_clocks) { int i; @@ -1954,80 +1958,80 @@ validate_out: } bool dcn20_validate_bandwidth_fp(struct dc *dc, - struct dc_state *context, - bool fast_validate) + struct dc_state *context, + bool fast_validate) { - bool voltage_supported = false; - bool full_pstate_supported = false; - bool dummy_pstate_supported = false; - double p_state_latency_us; + bool voltage_supported = false; + bool full_pstate_supported = false; + bool dummy_pstate_supported = false; + double p_state_latency_us; - dc_assert_fp_enabled(); + dc_assert_fp_enabled(); - p_state_latency_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us; - context->bw_ctx.dml.soc.disable_dram_clock_change_vactive_support = - dc->debug.disable_dram_clock_change_vactive_support; - context->bw_ctx.dml.soc.allow_dram_clock_one_display_vactive = - dc->debug.enable_dram_clock_change_one_display_vactive; + p_state_latency_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us; + context->bw_ctx.dml.soc.disable_dram_clock_change_vactive_support = + dc->debug.disable_dram_clock_change_vactive_support; + context->bw_ctx.dml.soc.allow_dram_clock_one_display_vactive = + dc->debug.enable_dram_clock_change_one_display_vactive; - /*Unsafe due to current pipe merge and split logic*/ - ASSERT(context != dc->current_state); + /*Unsafe due to current pipe merge and split logic*/ + ASSERT(context != dc->current_state); - if (fast_validate) { - return dcn20_validate_bandwidth_internal(dc, context, true); - } + if (fast_validate) { + return dcn20_validate_bandwidth_internal(dc, context, true); + } - // Best case, we support full UCLK switch latency - voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false); - full_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support; + // Best case, we support full UCLK switch latency + voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false); + full_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support; - if (context->bw_ctx.dml.soc.dummy_pstate_latency_us == 0 || - (voltage_supported && full_pstate_supported)) { - context->bw_ctx.bw.dcn.clk.p_state_change_support = full_pstate_supported; - goto restore_dml_state; - } + if (context->bw_ctx.dml.soc.dummy_pstate_latency_us == 0 || + (voltage_supported && full_pstate_supported)) { + context->bw_ctx.bw.dcn.clk.p_state_change_support = full_pstate_supported; + goto restore_dml_state; + } - // Fallback: Try to only support G6 temperature read latency - context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us; + // Fallback: Try to only support G6 temperature read latency + context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us; - voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false); - dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support; + voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false); + dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support; - if (voltage_supported && (dummy_pstate_supported || !(context->stream_count))) { - context->bw_ctx.bw.dcn.clk.p_state_change_support = false; - goto restore_dml_state; - } + if (voltage_supported && (dummy_pstate_supported || !(context->stream_count))) { + context->bw_ctx.bw.dcn.clk.p_state_change_support = false; + goto restore_dml_state; + } - // ERROR: fallback is supposed to always work. - ASSERT(false); + // ERROR: fallback is supposed to always work. + ASSERT(false); restore_dml_state: - context->bw_ctx.dml.soc.dram_clock_change_latency_us = p_state_latency_us; - return voltage_supported; + context->bw_ctx.dml.soc.dram_clock_change_latency_us = p_state_latency_us; + return voltage_supported; } void dcn20_fpu_set_wm_ranges(int i, - struct pp_smu_wm_range_sets *ranges, - struct _vcs_dpi_soc_bounding_box_st *loaded_bb) + struct pp_smu_wm_range_sets *ranges, + struct _vcs_dpi_soc_bounding_box_st *loaded_bb) { - dc_assert_fp_enabled(); + dc_assert_fp_enabled(); - ranges->reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0; - ranges->reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16; + ranges->reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0; + ranges->reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16; } void dcn20_fpu_adjust_dppclk(struct vba_vars_st *v, - int vlevel, - int max_mpc_comb, - int pipe_idx, - bool is_validating_bw) + int vlevel, + int max_mpc_comb, + int pipe_idx, + bool is_validating_bw) { - dc_assert_fp_enabled(); + dc_assert_fp_enabled(); - if (is_validating_bw) - v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] *= 2; - else - v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] /= 2; + if (is_validating_bw) + v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] *= 2; + else + v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] /= 2; } int dcn21_populate_dml_pipes_from_context(struct dc *dc, -- cgit From 0fdf06e449b6d6d970c0709c71a8738cfe551ecc Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Mon, 3 Apr 2023 15:37:46 -0600 Subject: drm/amd/display: Set maximum VStartup if is DCN201 Reviewed-by: Aurabindo Pillai Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm/amd/display') 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 6e32dc68f7bc..b79014f04cef 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 @@ -1259,6 +1259,8 @@ int dcn20_populate_dml_pipes_from_context(struct dc *dc, pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0; + pipes[pipe_cnt].pipe.dest.use_maximum_vstartup = dc->ctx->dce_version == DCN_VERSION_2_01; + pipes[pipe_cnt].dout.dsc_enable = res_ctx->pipe_ctx[i].stream->timing.flags.DSC; /* todo: rotation?*/ pipes[pipe_cnt].dout.dsc_slices = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.num_slices_h; -- cgit From ac7485cc363f2c603a3e1a7a609ef065ad56b19b Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Mon, 3 Apr 2023 15:38:09 -0600 Subject: drm/amd/display: Set dp_rate to dm_dp_rate_na by default Reviewed-by: Aurabindo Pillai Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 b79014f04cef..9fadac1b4c64 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 @@ -1300,8 +1300,7 @@ int dcn20_populate_dml_pipes_from_context(struct dc *dc, pipes[pipe_cnt].pipe.dest.pixel_rate_mhz *= 2; pipes[pipe_cnt].pipe.dest.otg_inst = res_ctx->pipe_ctx[i].stream_res.tg->inst; pipes[pipe_cnt].dout.dp_lanes = 4; - if (res_ctx->pipe_ctx[i].stream->link) - pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_na; + pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_na; pipes[pipe_cnt].dout.is_virtual = 0; pipes[pipe_cnt].pipe.dest.vtotal_min = res_ctx->pipe_ctx[i].stream->adjust.v_total_min; pipes[pipe_cnt].pipe.dest.vtotal_max = res_ctx->pipe_ctx[i].stream->adjust.v_total_max; -- cgit From b62f91569f9aa54b0a60d46a022482415cb968a9 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Mon, 3 Apr 2023 15:40:21 -0600 Subject: drm/amd/display: Remove wrong assignment of DP link rate Reviewed-by: Aurabindo Pillai Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 9fadac1b4c64..03718cc148e0 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 @@ -1360,7 +1360,6 @@ int dcn20_populate_dml_pipes_from_context(struct dc *dc, pipes[pipe_cnt].dout.is_virtual = 1; pipes[pipe_cnt].dout.output_type = dm_dp; pipes[pipe_cnt].dout.dp_lanes = 4; - pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_hbr2; } switch (res_ctx->pipe_ctx[i].stream->timing.display_color_depth) { -- cgit From 64626c0ee13257e330bc09fa6a169385c0eaf9ca Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Mon, 3 Apr 2023 19:23:29 -0600 Subject: drm/amd/display: Use pointer in the memcpy Reviewed-by: Aurabindo Pillai Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 03718cc148e0..f1c1a4b5fcac 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 @@ -2333,7 +2333,7 @@ void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params k++; } - memcpy(dcn2_1_soc.clock_limits, s, sizeof(dcn2_1_soc.clock_limits)); + memcpy(&dcn2_1_soc.clock_limits, s, sizeof(dcn2_1_soc.clock_limits)); if (clk_table->num_entries) { dcn2_1_soc.num_states = clk_table->num_entries + 1; -- cgit From 0c1f033159712b3d071cfe4a3ec0f36f1914453b Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Sat, 15 Apr 2023 11:17:22 -0400 Subject: drm/amd/display: set variable dccg314_init storage-class-specifier to static smatch reports drivers/gpu/drm/amd/amdgpu/../display/dc/dcn314/dcn314_dccg.c:277:6: warning: symbol 'dccg314_init' was not declared. Should it be static? This variable is only used in one file so should be static. Signed-off-by: Tom Rix Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c index 6f879265ad9c..de7bfba2c179 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c @@ -274,7 +274,7 @@ static void dccg314_set_dpstreamclk( } } -void dccg314_init(struct dccg *dccg) +static void dccg314_init(struct dccg *dccg) { int otg_inst; -- cgit From c8b5a95b570949536a2b75cd8fc4f1de0bc60629 Mon Sep 17 00:00:00 2001 From: Alan Liu Date: Fri, 14 Apr 2023 18:39:52 +0800 Subject: drm/amdgpu: Fix desktop freezed after gpu-reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Why] After gpu-reset, sometimes the driver fails to enable vblank irq, causing flip_done timed out and the desktop freezed. During gpu-reset, we disable and enable vblank irq in dm_suspend() and dm_resume(). Later on in amdgpu_irq_gpu_reset_resume_helper(), we check irqs' refcount and decide to enable or disable the irqs again. However, we have 2 sets of API for controling vblank irq, one is dm_vblank_get/put() and another is amdgpu_irq_get/put(). Each API has its own refcount and flag to store the state of vblank irq, and they are not synchronized. In drm we use the first API to control vblank irq but in amdgpu_irq_gpu_reset_resume_helper() we use the second set of API. The failure happens when vblank irq was enabled by dm_vblank_get() before gpu-reset, we have vblank->enabled true. However, during gpu-reset, in amdgpu_irq_gpu_reset_resume_helper() vblank irq's state checked from amdgpu_irq_update() is DISABLED. So finally it disables vblank irq again. After gpu-reset, if there is a cursor plane commit, the driver will try to enable vblank irq by calling drm_vblank_enable(), but the vblank->enabled is still true, so it fails to turn on vblank irq and causes flip_done can't be completed in vblank irq handler and desktop become freezed. [How] Combining the 2 vblank control APIs by letting drm's API finally calls amdgpu_irq's API, so the irq's refcount and state of both APIs can be synchronized. Also add a check to prevent refcount from being less then 0 in amdgpu_irq_put(). v2: - Add warning in amdgpu_irq_enable() if the irq is already disabled. - Call dc_interrupt_set() in dm_set_vblank() to avoid refcount change if it is in gpu-reset. v3: - Improve commit message and code comments. Signed-off-by: Alan Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index dc4f37240beb..8af70feca720 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -169,10 +169,21 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable) if (rc) return rc; - irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst; + if (amdgpu_in_reset(adev)) { + irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst; + /* During gpu-reset we disable and then enable vblank irq, so + * don't use amdgpu_irq_get/put() to avoid refcount change. + */ + if (!dc_interrupt_set(adev->dm.dc, irq_source, enable)) + rc = -EBUSY; + } else { + rc = (enable) + ? amdgpu_irq_get(adev, &adev->crtc_irq, acrtc->crtc_id) + : amdgpu_irq_put(adev, &adev->crtc_irq, acrtc->crtc_id); + } - if (!dc_interrupt_set(adev->dm.dc, irq_source, enable)) - return -EBUSY; + if (rc) + return rc; skip: if (amdgpu_in_reset(adev)) -- cgit From 6d9240c46f7419aa3210353b5f52cc63da5a6440 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Mon, 3 Apr 2023 10:13:12 -0400 Subject: drm/amd/display: set dcn315 lb bpp to 48 [Why & How] Fix a typo for dcn315 line buffer bpp. Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Dmytro Laktyushkin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c index b37d14369a62..59836570603a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c @@ -222,7 +222,7 @@ struct _vcs_dpi_ip_params_st dcn3_15_ip = { .maximum_dsc_bits_per_component = 10, .dsc422_native_support = false, .is_line_buffer_bpp_fixed = true, - .line_buffer_fixed_bpp = 49, + .line_buffer_fixed_bpp = 48, .line_buffer_size_bits = 789504, .max_line_buffer_lines = 12, .writeback_interface_buffer_size_kbytes = 90, -- cgit From 1e994cc0956b8dabd1b1fef315bbd722733b8aa8 Mon Sep 17 00:00:00 2001 From: Daniel Miess Date: Tue, 4 Apr 2023 14:04:11 -0400 Subject: drm/amd/display: limit timing for single dimm memory [Why] 1. It could hit bandwidth limitdation under single dimm memory when connecting 8K external monitor. 2. IsSupportedVidPn got validation failed with 2K240Hz eDP + 8K24Hz external monitor. 3. It's better to filter out such combination in EnumVidPnCofuncModality 4. For short term, filter out in dc bandwidth validation. [How] Force 2K@240Hz+8K@24Hz timing validation false in dc. Reviewed-by: Nicholas Kazlauskas Acked-by: Qingqing Zhuo Signed-off-by: Daniel Miess Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- .../gpu/drm/amd/display/dc/dcn314/dcn314_resource.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/gpu/drm/amd/display') 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 54ed3de869d3..9ffba4c6fe55 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c @@ -1697,6 +1697,23 @@ static void dcn314_get_panel_config_defaults(struct dc_panel_config *panel_confi *panel_config = panel_config_defaults; } +static bool filter_modes_for_single_channel_workaround(struct dc *dc, + struct dc_state *context) +{ + // Filter 2K@240Hz+8K@24fps above combination timing if memory only has single dimm LPDDR + if (dc->clk_mgr->bw_params->vram_type == 34 && dc->clk_mgr->bw_params->num_channels < 2) { + int total_phy_pix_clk = 0; + + for (int i = 0; i < context->stream_count; i++) + if (context->res_ctx.pipe_ctx[i].stream) + total_phy_pix_clk += context->res_ctx.pipe_ctx[i].stream->phy_pix_clk; + + if (total_phy_pix_clk >= (1148928+826260)) //2K@240Hz+8K@24fps + return true; + } + return false; +} + bool dcn314_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate) @@ -1712,6 +1729,9 @@ bool dcn314_validate_bandwidth(struct dc *dc, BW_VAL_TRACE_COUNT(); + if (filter_modes_for_single_channel_workaround(dc, context)) + goto validate_fail; + DC_FP_START(); // do not support self refresh only out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, false); -- cgit From 0b5dfe12755f87ec014bb4cc1930485026167430 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Mon, 3 Apr 2023 17:45:41 +0800 Subject: drm/amd/display: fix a divided-by-zero error [Why & How] timing.dsc_cfg.num_slices_v can be zero and it is necessary to check before using it. This fixes the error "divide error: 0000 [#1] PREEMPT SMP NOPTI". Reviewed-by: Aurabindo Pillai Acked-by: Qingqing Zhuo Signed-off-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/modules/power/power_helpers.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c index e39b133d05af..b56f07f99d09 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -934,6 +934,10 @@ bool psr_su_set_dsc_slice_height(struct dc *dc, struct dc_link *link, pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom; + + if (stream->timing.dsc_cfg.num_slices_v == 0) + return false; + slice_height = pic_height / stream->timing.dsc_cfg.num_slices_v; config->dsc_slice_height = slice_height; -- cgit From 474f01015ffdb74e01c2eb3584a2822c64e7b2be Mon Sep 17 00:00:00 2001 From: Wesley Chalmers Date: Thu, 3 Nov 2022 22:29:31 -0400 Subject: drm/amd/display: Do not set drr on pipe commit [WHY] Writing to DRR registers such as OTG_V_TOTAL_MIN on the same frame as a pipe commit can cause underflow. [HOW] Move DMUB p-state delegate into optimze_bandwidth; enabling FAMS sets optimized_required. This change expects that Freesync requests are blocked when optimized_required is true. Reviewed-by: Rodrigo Siqueira Signed-off-by: Wesley Chalmers Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 6 ++++++ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 7 +++++++ 2 files changed, 13 insertions(+) (limited to 'drivers/gpu/drm/amd/display') 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 5403e9399a46..6ce10fd4bb1a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -2113,6 +2113,12 @@ void dcn20_optimize_bandwidth( if (hubbub->funcs->program_compbuf_size) hubbub->funcs->program_compbuf_size(hubbub, context->bw_ctx.bw.dcn.compbuf_size_kb, true); + if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) { + dc_dmub_srv_p_state_delegate(dc, + true, context); + context->bw_ctx.bw.dcn.clk.p_state_change_support = true; + } + dc->clk_mgr->funcs->update_clocks( dc->clk_mgr, context, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index 0e071fbc9154..0411867654dd 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -985,11 +985,18 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc, void dcn30_prepare_bandwidth(struct dc *dc, struct dc_state *context) { + if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) { + dc->optimized_required = true; + context->bw_ctx.bw.dcn.clk.p_state_change_support = false; + } + if (dc->clk_mgr->dc_mode_softmax_enabled) if (dc->clk_mgr->clks.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 && context->bw_ctx.bw.dcn.clk.dramclk_khz > dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000) dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz); dcn20_prepare_bandwidth(dc, context); + + dc_dmub_srv_p_state_delegate(dc, false, context); } -- cgit From ce560ac40272a5c8b5b68a9d63a75edd9e66aed2 Mon Sep 17 00:00:00 2001 From: Wesley Chalmers Date: Tue, 28 Feb 2023 13:48:00 -0500 Subject: drm/amd/display: Block optimize on consecutive FAMS enables [WHY] It is possible to commit state multiple times in rapid succession with FAMS enabled; if each of these commits were to set optimized_required, then the user may see latency. [HOW] fw_based_mclk_switching is currently not used in dc->clk_mgr; use it to track whether the current state has FAMS enabled; if it has, then do not disable FAMS in prepare_bandwidth, and do not set optimized_required. Reviewed-by: Rodrigo Siqueira Signed-off-by: Wesley Chalmers Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 3 +++ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 22 +++++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 6ce10fd4bb1a..422fbf79da64 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -2117,6 +2117,9 @@ void dcn20_optimize_bandwidth( dc_dmub_srv_p_state_delegate(dc, true, context); context->bw_ctx.bw.dcn.clk.p_state_change_support = true; + dc->clk_mgr->clks.fw_based_mclk_switching = true; + } else { + dc->clk_mgr->clks.fw_based_mclk_switching = false; } dc->clk_mgr->funcs->update_clocks( diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index 0411867654dd..8263a07f265f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -983,9 +983,13 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc, } void dcn30_prepare_bandwidth(struct dc *dc, - struct dc_state *context) + struct dc_state *context) { - if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) { + bool p_state_change_support = context->bw_ctx.bw.dcn.clk.p_state_change_support; + /* Any transition into an FPO config should disable MCLK switching first to avoid + * driver and FW P-State synchronization issues. + */ + if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) { dc->optimized_required = true; context->bw_ctx.bw.dcn.clk.p_state_change_support = false; } @@ -996,7 +1000,19 @@ void dcn30_prepare_bandwidth(struct dc *dc, dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz); dcn20_prepare_bandwidth(dc, context); + /* + * enabled -> enabled: do not disable + * enabled -> disabled: disable + * disabled -> enabled: don't care + * disabled -> disabled: don't care + */ + if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) + dc_dmub_srv_p_state_delegate(dc, false, context); - dc_dmub_srv_p_state_delegate(dc, false, context); + if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) { + /* After disabling P-State, restore the original value to ensure we get the correct P-State + * on the next optimize. */ + context->bw_ctx.bw.dcn.clk.p_state_change_support = p_state_change_support; + } } -- cgit From 822b84ecfc646da0f87fd947fa00dc3be5e45ecc Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Tue, 4 Apr 2023 14:54:05 -0600 Subject: drm/amd/display: Add missing WA and MCLK validation When the commit fff7eb56b376 ("drm/amd/display: Don't set dram clock change requirement for SubVP") was merged, we missed some parts associated with the MCLK switch. This commit adds all the missing parts. Fixes: fff7eb56b376 ("drm/amd/display: Don't set dram clock change requirement for SubVP") Reviewed-by: Aurabindo Pillai Signed-off-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 1 + drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 2 +- drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c | 18 +++++++++++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index db0974fe58ab..1f5ee5cde6e1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -948,6 +948,7 @@ void dcn32_init_hw(struct dc *dc) if (dc->ctx->dmub_srv) { dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv->dmub); dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr; + dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch; } } diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index 0beb11d95eb7..a876e6eb6cd8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -2023,7 +2023,7 @@ int dcn32_populate_dml_pipes_from_context( // In general cases we want to keep the dram clock change requirement // (prefer configs that support MCLK switch). Only override to false // for SubVP - if (subvp_in_use) + if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || subvp_in_use) context->bw_ctx.dml.soc.dram_clock_change_requirement_final = false; else context->bw_ctx.dml.soc.dram_clock_change_requirement_final = true; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c index 80972ee5e55b..a352c703e258 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c @@ -368,7 +368,9 @@ void dcn30_fpu_update_soc_for_wm_a(struct dc *dc, struct dc_state *context) dc_assert_fp_enabled(); if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].valid) { - context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; + if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || + context->bw_ctx.dml.soc.dram_clock_change_latency_us == 0) + context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us; context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us; } @@ -563,6 +565,20 @@ void dcn30_fpu_calculate_wm_and_dlg( pipe_idx++; } + // WA: restrict FPO to use first non-strobe mode (NV24 BW issue) + if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && + dc->dml.soc.num_chans <= 4 && + context->bw_ctx.dml.vba.DRAMSpeed <= 1700 && + context->bw_ctx.dml.vba.DRAMSpeed >= 1500) { + + for (i = 0; i < dc->dml.soc.num_states; i++) { + if (dc->dml.soc.clock_limits[i].dram_speed_mts > 1700) { + context->bw_ctx.dml.vba.DRAMSpeed = dc->dml.soc.clock_limits[i].dram_speed_mts; + break; + } + } + } + dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); if (!pstate_en) -- cgit From f11aee97b13ea6817287cd8dbed9b09a260ff0e7 Mon Sep 17 00:00:00 2001 From: Josip Pavic Date: Fri, 14 May 2021 14:04:02 -0400 Subject: drm/amd/display: copy dmub caps to dc on dcn31 [Why & How] Add code path to copy dmub caps to dc, which is missing on dcn31 Acked-by: Qingqing Zhuo Signed-off-by: Josip Pavic Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c index 7ac6e69cff37..62ce36c75c4d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c @@ -295,6 +295,10 @@ void dcn31_init_hw(struct dc *dc) if (dc->res_pool->hubbub->funcs->init_crb) dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub); #endif + + // Get DMCUB capabilities + dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv->dmub); + dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr; } void dcn31_dsc_pg_control( -- cgit From 3fb7efd6866e5d43770e999b33d619a3b345dc2f Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Wed, 15 Mar 2023 19:09:15 +0800 Subject: drm/amd/display: allow edp updates for virtual signal [Why] When IGT's kms_hdmi_inject forces EDID for HDMI audio, dc rejects the request because virtual signal is not in dc_is_audio_capable_signal function. [How] Includes SIGNAL_TYPE_VIRTUAL as audio capable. Reviewed-by: Chao-kai Wang Acked-by: Qingqing Zhuo Signed-off-by: Alex Hung Signed-off-by: Wenchieh Chien Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/include/signal_types.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/include/signal_types.h b/drivers/gpu/drm/amd/display/include/signal_types.h index beed70179bb5..23a308c3eccb 100644 --- a/drivers/gpu/drm/amd/display/include/signal_types.h +++ b/drivers/gpu/drm/amd/display/include/signal_types.h @@ -104,6 +104,7 @@ static inline bool dc_is_audio_capable_signal(enum signal_type signal) { return (signal == SIGNAL_TYPE_DISPLAY_PORT || signal == SIGNAL_TYPE_DISPLAY_PORT_MST || + signal == SIGNAL_TYPE_VIRTUAL || dc_is_hdmi_signal(signal)); } -- cgit From da5e14909776edea4462672fb4a3007802d262e7 Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Fri, 24 Mar 2023 10:42:37 -0400 Subject: drm/amd/display: Fix hang when skipping modeset [Why&How] When skipping full modeset since the only state change was a front porch change, the DC commit sequence requires extra checks to handle non existant plane states being asked to be removed from context. Reviewed-by: Alvin Lee Acked-by: Qingqing Zhuo Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ++++- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 6cacb76f389e..c432436cd66d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7972,6 +7972,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, continue; dc_plane = dm_new_plane_state->dc_state; + if (!dc_plane) + continue; bundle->surface_updates[planes_count].surface = dc_plane; if (new_pcrtc_state->color_mgmt_changed) { @@ -9620,8 +9622,9 @@ static int dm_update_plane_state(struct dc *dc, return -EINVAL; } + if (dm_old_plane_state->dc_state) + dc_plane_state_release(dm_old_plane_state->dc_state); - dc_plane_state_release(dm_old_plane_state->dc_state); dm_new_plane_state->dc_state = NULL; *lock_and_validation_needed = true; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 85d54bfb595c..117d80cb36fb 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1707,6 +1707,9 @@ bool dc_remove_plane_from_context( struct dc_stream_status *stream_status = NULL; struct resource_pool *pool = dc->res_pool; + if (!plane_state) + return true; + for (i = 0; i < context->stream_count; i++) if (context->streams[i] == stream) { stream_status = &context->stream_status[i]; -- cgit From 025ce392b5f213696ca0af3e07735d0fae020694 Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Mon, 27 Mar 2023 09:10:48 -0400 Subject: drm/amd/display: fix memleak in aconnector->timing_requested [Why] when amdgpu_dm_update_connector_after_detect is called two times successively with valid sink, memory allocated of aconnector->timing_requested for the first call is not free. this causes memeleak. [How] allocate memory only when aconnector->timing_requested is null. Reviewed-by: Qingqing Zhuo Acked-by: Qingqing Zhuo Signed-off-by: Hersen Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 c432436cd66d..8b03c8d8f0b8 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3128,9 +3128,12 @@ void amdgpu_dm_update_connector_after_detect( 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__); + if (!aconnector->timing_requested) { + aconnector->timing_requested = + kzalloc(sizeof(struct dc_crtc_timing), GFP_KERNEL); + if (!aconnector->timing_requested) + dm_error("failed to create aconnector->requested_timing\n"); + } drm_connector_update_edid_property(connector, aconnector->edid); amdgpu_dm_update_freesync_caps(connector, aconnector->edid); -- cgit From 0c0463ff010b80a0c03937ca8cf85587ded2f20e Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Tue, 28 Mar 2023 09:53:33 -0400 Subject: drm/amd/display: Reduce SubVP + DRR stretch margin [Description] - Having excessively large margin causes failure in the static schedulability check in some cases for SubVP + DRR - 100us of DRR margin is sufficient based on a weeks worth of stress testing on different display configs Reviewed-by: Michael Strauss Acked-by: Qingqing Zhuo Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_stream.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index 181a3408cc61..25284006019c 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -144,7 +144,7 @@ struct test_pattern { unsigned int cust_pattern_size; }; -#define SUBVP_DRR_MARGIN_US 600 // 600us for DRR margin (SubVP + DRR) +#define SUBVP_DRR_MARGIN_US 100 // 100us for DRR margin (SubVP + DRR) enum mall_stream_type { SUBVP_NONE, // subvp not in use -- cgit From 3cf7cd3f770a0b89dc5f06e19edb52e65b93b214 Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Tue, 28 Mar 2023 10:45:24 -0400 Subject: drm/amd/display: fix access hdcp_workqueue assert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Why] hdcp are enabled for asics from raven. for old asics which hdcp are not enabled, hdcp_workqueue are null. some access to hdcp work queue are not guarded with pointer check. [How] add hdcp_workqueue pointer check before access workqueue. Fixes: 82986fd631fa ("drm/amd/display: save restore hdcp state when display is unplugged from mst hub") Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2444 Reported-by: Niklāvs Koļesņikovs <89q1r14hd@relay.firefox.com> Reviewed-by: Bhawanpreet Lakha Acked-by: Qingqing Zhuo Signed-off-by: Hersen Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++++++ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 16 ++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 8b03c8d8f0b8..fc08b4191e24 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8559,6 +8559,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); + if (!adev->dm.hdcp_workqueue) + continue; + pr_debug("[HDCP_DM] -------------- i : %x ----------\n", i); if (!connector) @@ -8607,6 +8610,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); + if (!adev->dm.hdcp_workqueue) + continue; + new_crtc_state = NULL; old_crtc_state = NULL; 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 994ba426ca66..5dc79b753d5f 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 @@ -379,13 +379,17 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) if (aconnector->dc_sink && connector->state) { struct drm_device *dev = connector->dev; struct amdgpu_device *adev = drm_to_adev(dev); - struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue; - struct hdcp_workqueue *hdcp_w = &hdcp_work[aconnector->dc_link->link_index]; - connector->state->hdcp_content_type = - hdcp_w->hdcp_content_type[connector->index]; - connector->state->content_protection = - hdcp_w->content_protection[connector->index]; + if (adev->dm.hdcp_workqueue) { + struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue; + struct hdcp_workqueue *hdcp_w = + &hdcp_work[aconnector->dc_link->link_index]; + + connector->state->hdcp_content_type = + hdcp_w->hdcp_content_type[connector->index]; + connector->state->content_protection = + hdcp_w->content_protection[connector->index]; + } } if (aconnector->dc_sink) { -- cgit From 56d8ce9d8c17bea955b0c2551ee86149486890ae Mon Sep 17 00:00:00 2001 From: Michael Mityushkin Date: Thu, 30 Mar 2023 11:35:08 -0400 Subject: drm/amd/display: Apply correct panel mode when reinitializing hardware [Why] When link training during engine recovery, ASSR might fail causing panel mode to be reset to default. This should not happen for eDP as it will prevent the panel from turning back on. [How] Added dp_panel_mode to struct dc_link to remember previously applied panel mode. Do not reset panel mode to default while performing link training if previously used panel mode = eDP. Reviewed-by: Nicholas Kazlauskas Acked-by: Qingqing Zhuo Signed-off-by: Michael Mityushkin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c | 5 ++++- .../gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 23ee63b98dcd..30f0ba05a6e6 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1454,6 +1454,7 @@ struct dc_link { struct ddc_service *ddc; + enum dp_panel_mode panel_mode; bool aux_mode; /* Private to DC core */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index 170f33835930..579fa222810d 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -1596,7 +1596,10 @@ bool perform_link_training_with_retries( * Report and continue with eDP panel mode to * perform eDP link training with right settings */ - cp_psp->funcs.enable_assr(cp_psp->handle, link); + bool result; + result = cp_psp->funcs.enable_assr(cp_psp->handle, link); + if (!result && link->panel_mode != DP_PANEL_MODE_EDP) + panel_mode = DP_PANEL_MODE_DEFAULT; } } diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index d895046787bc..8d1df863659c 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -83,6 +83,7 @@ void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode) ASSERT(result == DC_OK); } } + link->panel_mode = panel_mode; DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d " "eDP panel mode enabled: %d \n", link->link_index, -- cgit From e0cce122514ff76c3c986103c94de68fbb401949 Mon Sep 17 00:00:00 2001 From: Jingwen Zhu Date: Thu, 30 Mar 2023 16:38:59 +0800 Subject: drm/amd/display: Improvement for handling edp link training fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Why] The eDP retrain will cause the DPCD 300 to be reset to default. And cause the brightness can't be set correctly. [How] delete the call to edp panel power control in both enable_link_output/disable_link_output entirely and only call edp panel control in enable_link_dp and  disable_link_dp once. Reviewed-by: Charlene Liu Acked-by: Qingqing Zhuo Signed-off-by: Jingwen Zhu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 19 +++++++++++-------- drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 5 +++++ 2 files changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 9fe0ce91db00..8d2460d06bce 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -3031,10 +3031,12 @@ void dce110_enable_dp_link_output( const struct link_hwss *link_hwss = get_link_hwss(link, link_res); unsigned int i; - + /* + * Add the logic to extract BOTH power up and power down sequences + * from enable/disable link output and only call edp panel control + * in enable_link_dp and disable_link_dp once. + */ if (link->connector_signal == SIGNAL_TYPE_EDP) { - if (!link->dc->config.edp_no_power_sequencing) - link->dc->hwss.edp_power_control(link, true); link->dc->hwss.edp_wait_for_hpd_ready(link, true); } @@ -3096,11 +3098,12 @@ void dce110_disable_link_output(struct dc_link *link, link_hwss->disable_link_output(link, link_res, signal); link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF; - - if (signal == SIGNAL_TYPE_EDP && - link->dc->hwss.edp_backlight_control) - link->dc->hwss.edp_power_control(link, false); - else if (dmcu != NULL && dmcu->funcs->lock_phy) + /* + * Add the logic to extract BOTH power up and power down sequences + * from enable/disable link output and only call edp panel control + * in enable_link_dp and disable_link_dp once. + */ + if (dmcu != NULL && dmcu->funcs->lock_phy) dmcu->funcs->unlock_phy(dmcu); dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY); } diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index 027ad1f0144d..2267fb097830 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -1927,6 +1927,11 @@ static void disable_link_dp(struct dc_link *link, dp_disable_link_phy(link, link_res, signal); + if (link->connector_signal == SIGNAL_TYPE_EDP) { + if (!link->dc->config.edp_no_power_sequencing) + link->dc->hwss.edp_power_control(link, false); + } + if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST) /* set the sink to SST mode after disabling the link */ enable_mst_on_sink(link, false); -- cgit From dd24662d9dfbad281bbf030f06d68c7938fa0c66 Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Sun, 29 May 2022 10:54:30 -0400 Subject: drm/amd/display: Return error code on DSC atomic check failure [Why&How] We were not returning -EINVAL on DSC atomic check fail. Add it. Fixes: 71be4b16d39a ("drm/amd/display: dsc validate fail not pass to atomic check") Reviewed-by: Aurabindo Pillai Signed-off-by: Hersen Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/gpu/drm/amd/display') 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 fc08b4191e24..b619d7cdb525 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -10170,6 +10170,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, ret = compute_mst_dsc_configs_for_state(state, dm_state->context, vars); if (ret) { DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n"); + ret = -EINVAL; goto fail; } 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 5dc79b753d5f..810ab682f424 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 @@ -1410,6 +1410,7 @@ int pre_validate_dsc(struct drm_atomic_state *state, ret = pre_compute_mst_dsc_configs_for_state(state, local_dc_state, vars); if (ret != 0) { DRM_INFO_ONCE("pre_compute_mst_dsc_configs_for_state() failed\n"); + ret = -EINVAL; goto clean_exit; } -- cgit From fc3888fe2c63b35a22db8234d142823a5ffda9d8 Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Wed, 5 Apr 2023 16:17:42 -0400 Subject: drm/amd/display: remove incorrect early return [Why&How] Remove incorrect early return in a device specific fifo reset workaround Reviewed-by: Leo Li Reviewed-by: Qingqing Zhuo Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 330ab036c830..c6ce2b7123b7 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 @@ -687,7 +687,6 @@ static void apply_synaptics_fifo_reset_wa(struct drm_dp_aux *aux) return; data[0] |= (1 << 1); // set bit 1 to 1 - return; if (!execute_synaptics_rc_command(aux, false, 0x31, 4, 0x221198, data)) return; -- cgit From b1bcdd409d2d158867ce0b71cfa9bcefe83ce07f Mon Sep 17 00:00:00 2001 From: Tianci Yin Date: Mon, 6 Feb 2023 15:58:46 +0800 Subject: drm/amd/display: Disable migration to ensure consistency of per-CPU variable [why] Since the variable fpu_recursion_depth is per-CPU type, it has one copy on each CPU, thread migration causes data consistency issue, then the call trace shows up. And preemption disabling can't prevent migration. [how] Disable migration to ensure consistency of fpu_recursion_depth. Reviewed-by: Aurabindo Pillai Signed-off-by: Tianci Yin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c index 1743ca0a3641..c42aa947c969 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c @@ -89,6 +89,7 @@ void dc_fpu_begin(const char *function_name, const int line) if (*pcpu == 1) { #if defined(CONFIG_X86) + migrate_disable(); kernel_fpu_begin(); #elif defined(CONFIG_PPC64) if (cpu_has_feature(CPU_FTR_VSX_COMP)) { @@ -129,6 +130,7 @@ void dc_fpu_end(const char *function_name, const int line) if (*pcpu <= 0) { #if defined(CONFIG_X86) kernel_fpu_end(); + migrate_enable(); #elif defined(CONFIG_PPC64) if (cpu_has_feature(CPU_FTR_VSX_COMP)) { disable_kernel_vsx(); -- cgit From d1c5c3e252b8a911a524e6ee33b82aca81397745 Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Thu, 6 Apr 2023 12:28:59 -0400 Subject: drm/amd/display: Fixes for dcn32_clk_mgr implementation [Why&How] Fix CLK MGR early initialization and add logging. Fixes: 265280b99822 ("drm/amd/display: add CLKMGR changes for DCN32/321") Reviewed-by: Leo Li Reviewed-by: Qingqing Zhuo Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c index ea753f8fa175..8d9444db092a 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c @@ -878,6 +878,8 @@ void dcn32_clk_mgr_construct( struct pp_smu_funcs *pp_smu, struct dccg *dccg) { + struct clk_log_info log_info = {0}; + clk_mgr->base.ctx = ctx; clk_mgr->base.funcs = &dcn32_funcs; if (ASICREV_IS_GC_11_0_2(clk_mgr->base.ctx->asic_id.hw_internal_rev)) { @@ -911,6 +913,7 @@ void dcn32_clk_mgr_construct( clk_mgr->base.clks.ref_dtbclk_khz = 268750; } + /* integer part is now VCO frequency in kHz */ clk_mgr->base.dentist_vco_freq_khz = dcn32_get_vco_frequency_from_reg(clk_mgr); @@ -918,6 +921,8 @@ void dcn32_clk_mgr_construct( if (clk_mgr->base.dentist_vco_freq_khz == 0) clk_mgr->base.dentist_vco_freq_khz = 4300000; /* Updated as per HW docs */ + dcn32_dump_clk_registers(&clk_mgr->base.boot_snapshot, &clk_mgr->base, &log_info); + if (ctx->dc->debug.disable_dtb_ref_clk_switch && clk_mgr->base.clks.ref_dtbclk_khz != clk_mgr->base.boot_snapshot.dtbclk) { clk_mgr->base.clks.ref_dtbclk_khz = clk_mgr->base.boot_snapshot.dtbclk; -- cgit From 425afa0ac99a05b39e6cd00704fa0e3e925cee2b Mon Sep 17 00:00:00 2001 From: Cruise Hung Date: Fri, 13 May 2022 09:16:42 +0800 Subject: drm/amd/display: Reset OUTBOX0 r/w pointer on DMUB reset [Why & How] We missed resetting OUTBOX0 mailbox r/w pointer on DMUB reset. Fix it. Fixes: 6ecf9773a503 ("drm/amd/display: Fix DMUB outbox trace in S4 (#4465)") Signed-off-by: Cruise Hung Acked-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c index a76da0131add..b0adbf783aae 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c @@ -130,6 +130,8 @@ void dmub_dcn32_reset(struct dmub_srv *dmub) REG_WRITE(DMCUB_INBOX1_WPTR, 0); REG_WRITE(DMCUB_OUTBOX1_RPTR, 0); REG_WRITE(DMCUB_OUTBOX1_WPTR, 0); + REG_WRITE(DMCUB_OUTBOX0_RPTR, 0); + REG_WRITE(DMCUB_OUTBOX0_WPTR, 0); REG_WRITE(DMCUB_SCRATCH0, 0); } -- cgit From 99d92eaca5d915763b240aae24669f5bf3227ecf Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Thu, 6 Apr 2023 15:48:48 -0400 Subject: drm/amd/display: Do not clear GPINT register when releasing DMUB from reset [Why & How] There's no need to clear GPINT register for DMUB when releasing it from reset. Fix that. Fixes: ac2e555e0a7f ("drm/amd/display: Add DMCUB source files and changes for DCN32/321") Reviewed-by: Leo Li Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c index b0adbf783aae..9c20516be066 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c @@ -137,7 +137,6 @@ void dmub_dcn32_reset(struct dmub_srv *dmub) void dmub_dcn32_reset_release(struct dmub_srv *dmub) { - REG_WRITE(DMCUB_GPINT_DATAIN1, 0); REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 0); REG_WRITE(DMCUB_SCRATCH15, dmub->psp_version & 0x001100FF); REG_UPDATE_2(DMCUB_CNTL, DMCUB_ENABLE, 1, DMCUB_TRACEPORT_EN, 1); -- cgit From 989cd3e76a4aab76fe7dd50090ac3fa501c537f6 Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Thu, 6 Apr 2023 15:59:45 -0400 Subject: drm/amd/display: Update bounding box values for DCN321 [Why&how] Update bounding box values as per hardware spec Fixes: 197485c69543 ("drm/amd/display: Create dcn321_fpu file") Acked-by: Leo Li Signed-off-by: Aurabindo Pillai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c index 57b9bd896678..342a1bcb4927 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c @@ -106,16 +106,16 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = { .clock_limits = { { .state = 0, - .dcfclk_mhz = 1564.0, - .fabricclk_mhz = 400.0, - .dispclk_mhz = 2150.0, - .dppclk_mhz = 2150.0, + .dcfclk_mhz = 1434.0, + .fabricclk_mhz = 2250.0, + .dispclk_mhz = 1720.0, + .dppclk_mhz = 1720.0, .phyclk_mhz = 810.0, .phyclk_d18_mhz = 667.0, - .phyclk_d32_mhz = 625.0, + .phyclk_d32_mhz = 313.0, .socclk_mhz = 1200.0, - .dscclk_mhz = 716.667, - .dram_speed_mts = 1600.0, + .dscclk_mhz = 573.333, + .dram_speed_mts = 16000.0, .dtbclk_mhz = 1564.0, }, }, @@ -125,14 +125,14 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = { .sr_exit_z8_time_us = 285.0, .sr_enter_plus_exit_z8_time_us = 320, .writeback_latency_us = 12.0, - .round_trip_ping_latency_dcfclk_cycles = 263, + .round_trip_ping_latency_dcfclk_cycles = 207, .urgent_latency_pixel_data_only_us = 4, .urgent_latency_pixel_mixed_with_vm_data_us = 4, .urgent_latency_vm_data_only_us = 4, - .fclk_change_latency_us = 20, - .usr_retraining_latency_us = 2, - .smn_latency_us = 2, - .mall_allocated_for_dcn_mbytes = 64, + .fclk_change_latency_us = 7, + .usr_retraining_latency_us = 0, + .smn_latency_us = 0, + .mall_allocated_for_dcn_mbytes = 32, .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, -- cgit From 3caab67db1f69e077fb12ac194d3cd2a4de06d8d Mon Sep 17 00:00:00 2001 From: Jasdeep Dhillon Date: Tue, 28 Feb 2023 11:46:31 -0500 Subject: drm/amd/display: Isolate remaining FPU code in DCN32 [Why] DCN32 resource contains code that uses FPU. [How] Moved code into DCN32 FPU Reviewed-by: Rodrigo Siqueira Signed-off-by: Jasdeep Dhillon Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 6 ++++++ drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h | 2 ++ 2 files changed, 8 insertions(+) (limited to 'drivers/gpu/drm/amd/display') 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 23a972f2885f..47beb4ea779d 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 @@ -2876,3 +2876,9 @@ bool dcn32_find_vactive_pipe(struct dc *dc, const struct dc_state *context, uint } return vactive_found; } + +void dcn32_set_clock_limits(const struct _vcs_dpi_soc_bounding_box_st *soc_bb) +{ + dc_assert_fp_enabled(); + dcn3_2_soc.clock_limits[0].dcfclk_mhz = 1200.0; +} diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h index 9a0806a0e2ef..dcf512cd3072 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h @@ -80,4 +80,6 @@ void dcn32_assign_fpo_vactive_candidate(struct dc *dc, const struct dc_state *co bool dcn32_find_vactive_pipe(struct dc *dc, const struct dc_state *context, uint32_t vactive_margin_req); +void dcn32_set_clock_limits(const struct _vcs_dpi_soc_bounding_box_st *soc_bb); + #endif -- cgit From 9675b3ba99ec79273d94afa09e9b69e2b8c0d238 Mon Sep 17 00:00:00 2001 From: Igor Kravchenko Date: Fri, 10 Jul 2020 16:24:30 -0400 Subject: drm/amd/display: Set min_width and min_height capability for DCN30 Add min_width, min_height fields to dc_plane_cap structure. Set values to 16x16 for discrete ASICs, and 64x64 for others. Reviewed-by: Rodrigo Siqueira Signed-off-by: Igor Kravchenko Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index 965f5ceb33f7..67a34cda3774 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -701,7 +701,9 @@ static const struct dc_plane_cap plane_cap = { .argb8888 = 167, .nv12 = 167, .fp16 = 167 - } + }, + 16, + 16 }; static const struct dc_debug_options debug_defaults_drv = { -- cgit From 08da182175db4c7f80850354849d95f2670e8cd9 Mon Sep 17 00:00:00 2001 From: Hamza Mahfooz Date: Fri, 14 Apr 2023 14:26:27 -0400 Subject: drm/amd/display: fix flickering caused by S/G mode Currently, on a handful of ASICs. We allow the framebuffer for a given plane to exist in either VRAM or GTT. However, if the plane's new framebuffer is in a different memory domain than it's previous framebuffer, flipping between them can cause the screen to flicker. So, to fix this, don't perform an immediate flip in the aforementioned case. Cc: stable@vger.kernel.org Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2354 Reviewed-by: Roman Li Fixes: 81d0bcf99009 ("drm/amdgpu: make display pinning more flexible (v2)") Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 b619d7cdb525..8d17fd5a817e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7901,6 +7901,13 @@ static void amdgpu_dm_commit_cursors(struct drm_atomic_state *state) amdgpu_dm_plane_handle_cursor_update(plane, old_plane_state); } +static inline uint32_t get_mem_type(struct drm_framebuffer *fb) +{ + struct amdgpu_bo *abo = gem_to_amdgpu_bo(fb->obj[0]); + + return abo->tbo.resource ? abo->tbo.resource->mem_type : 0; +} + static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, struct dc_state *dc_state, struct drm_device *dev, @@ -8043,11 +8050,13 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, /* * Only allow immediate flips for fast updates that don't - * change FB pitch, DCC state, rotation or mirroing. + * change memory domain, FB pitch, DCC state, rotation or + * mirroring. */ bundle->flip_addrs[planes_count].flip_immediate = crtc->state->async_flip && - acrtc_state->update_type == UPDATE_TYPE_FAST; + acrtc_state->update_type == UPDATE_TYPE_FAST && + get_mem_type(old_plane_state->fb) == get_mem_type(fb); timestamp_ns = ktime_get_ns(); bundle->flip_addrs[planes_count].flip_timestamp_in_us = div_u64(timestamp_ns, 1000); -- cgit From d893f39320e1248d1c97fde0d6e51e5ea008a76b Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Tue, 11 Apr 2023 10:49:38 -0400 Subject: drm/amd/display: Lowering min Z8 residency time [Why & How] Per HW team request, we're lowering the minimum Z8 residency time to 2000us. This enables Z8 support for additional modes we were previously blocking like 2k>60hz Cc: stable@vger.kernel.org Tested-by: Daniel Wheeler Reviewed-by: Nicholas Kazlauskas Acked-by: Rodrigo Siqueira Signed-off-by: Leo Chen Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 50ed7e09d5ba..2f7df8d34a91 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c @@ -885,7 +885,7 @@ static const struct dc_plane_cap plane_cap = { static const struct dc_debug_options debug_defaults_drv = { .disable_z10 = false, .enable_z9_disable_interface = true, - .minimum_z8_residency_time = 3080, + .minimum_z8_residency_time = 2000, .psr_skip_crtc_disable = true, .disable_dmcu = true, .force_abm_enable = false, -- cgit From 8f586cc16c1fc3c2202c9d54563db8c7ed365f82 Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Thu, 13 Apr 2023 17:34:24 -0400 Subject: drm/amd/display: Change default Z8 watermark values [Why & How] Previous Z8 watermark values were causing flickering and OTC underflow. Updating Z8 watermark values based on the measurement. Reviewed-by: Nicholas Kazlauskas Cc: Mario Limonciello Cc: Alex Deucher Cc: stable@vger.kernel.org Acked-by: Alan Liu Signed-off-by: Leo Chen Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c index 44082f65de1f..9e54e3d0eb78 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c @@ -149,8 +149,8 @@ static struct _vcs_dpi_soc_bounding_box_st dcn3_14_soc = { .num_states = 5, .sr_exit_time_us = 16.5, .sr_enter_plus_exit_time_us = 18.5, - .sr_exit_z8_time_us = 210.0, - .sr_enter_plus_exit_z8_time_us = 310.0, + .sr_exit_z8_time_us = 268.0, + .sr_enter_plus_exit_z8_time_us = 393.0, .writeback_latency_us = 12.0, .dram_channel_width_bytes = 4, .round_trip_ping_latency_dcfclk_cycles = 106, -- cgit From 682439fffad9fa9a38d37dd1b1318e9374232213 Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Wed, 19 Apr 2023 18:17:14 -0400 Subject: drm/amd/display: filter out invalid bits in pipe_fuses [Why] Reading pipe_fuses from register may have invalid bits set, which may affect the num_pipes erroneously. [How] Add read_pipes_fuses() call and filter bits based on expected number of pipes. Reviewed-by: Alvin Lee Acked-by: Alan Liu Signed-off-by: Samson Tam Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 6.1.x --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 10 +++++++++- drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index a876e6eb6cd8..22dd1ebea618 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -2079,6 +2079,14 @@ static struct resource_funcs dcn32_res_pool_funcs = { .restore_mall_state = dcn32_restore_mall_state, }; +static uint32_t read_pipe_fuses(struct dc_context *ctx) +{ + uint32_t value = REG_READ(CC_DC_PIPE_DIS); + /* DCN32 support max 4 pipes */ + value = value & 0xf; + return value; +} + static bool dcn32_resource_construct( uint8_t num_virtual_links, @@ -2122,7 +2130,7 @@ static bool dcn32_resource_construct( pool->base.res_cap = &res_cap_dcn32; /* max number of pipes for ASIC before checking for pipe fuses */ num_pipes = pool->base.res_cap->num_timing_generator; - pipe_fuses = REG_READ(CC_DC_PIPE_DIS); + pipe_fuses = read_pipe_fuses(ctx); for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) if (pipe_fuses & 1 << i) 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 e5ab7f3077c4..a60ddb343d13 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c @@ -1632,6 +1632,14 @@ static struct resource_funcs dcn321_res_pool_funcs = { .restore_mall_state = dcn32_restore_mall_state, }; +static uint32_t read_pipe_fuses(struct dc_context *ctx) +{ + uint32_t value = REG_READ(CC_DC_PIPE_DIS); + /* DCN321 support max 4 pipes */ + value = value & 0xf; + return value; +} + static bool dcn321_resource_construct( uint8_t num_virtual_links, @@ -1674,7 +1682,7 @@ static bool dcn321_resource_construct( pool->base.res_cap = &res_cap_dcn321; /* max number of pipes for ASIC before checking for pipe fuses */ num_pipes = pool->base.res_cap->num_timing_generator; - pipe_fuses = REG_READ(CC_DC_PIPE_DIS); + pipe_fuses = read_pipe_fuses(ctx); for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) if (pipe_fuses & 1 << i) -- cgit From f57fa0f23d9707747272b0d09af8b93b19cf8ee4 Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Wed, 26 Apr 2023 16:02:28 -0400 Subject: drm/amd/display: Add symclk workaround during disable link output [Why & How] This is originally a change (9c75891f) in DCN32 because of the lack of interface to set TX while keeping symclk on. Adding this workaround to DCN314 will resolve the current issue. Fixes: 9c75891feef0 ("drm/amd/display: rework recent update PHY state commit") Reviewed-by: Nicholas Kazlauskas Acked-by: Alex Hung Signed-off-by: Leo Chen Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c | 65 ++++++++++++++++++++++ .../gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h | 2 + .../gpu/drm/amd/display/dc/dcn314/dcn314_init.c | 2 +- 3 files changed, 68 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c index 40c488b26901..cc3fe9cac5b5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c @@ -423,3 +423,68 @@ void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool PERF_TRACE(); } +static void apply_symclk_on_tx_off_wa(struct dc_link *link) +{ + /* There are use cases where SYMCLK is referenced by OTG. For instance + * for TMDS signal, OTG relies SYMCLK even if TX video output is off. + * However current link interface will power off PHY when disabling link + * output. This will turn off SYMCLK generated by PHY. The workaround is + * to identify such case where SYMCLK is still in use by OTG when we + * power off PHY. When this is detected, we will temporarily power PHY + * back on and move PHY's SYMCLK state to SYMCLK_ON_TX_OFF by calling + * program_pix_clk interface. When OTG is disabled, we will then power + * off PHY by calling disable link output again. + * + * In future dcn generations, we plan to rework transmitter control + * interface so that we could have an option to set SYMCLK ON TX OFF + * state in one step without this workaround + */ + + struct dc *dc = link->ctx->dc; + struct pipe_ctx *pipe_ctx = NULL; + uint8_t i; + + if (link->phy_state.symclk_ref_cnts.otg > 0) { + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx->stream && pipe_ctx->stream->link == link && pipe_ctx->top_pipe == NULL) { + pipe_ctx->clock_source->funcs->program_pix_clk( + pipe_ctx->clock_source, + &pipe_ctx->stream_res.pix_clk_params, + dc->link_srv->dp_get_encoding_format( + &pipe_ctx->link_config.dp_link_settings), + &pipe_ctx->pll_settings); + link->phy_state.symclk_state = SYMCLK_ON_TX_OFF; + break; + } + } + } +} + +void dcn314_disable_link_output(struct dc_link *link, + const struct link_resource *link_res, + enum signal_type signal) +{ + struct dc *dc = link->ctx->dc; + const struct link_hwss *link_hwss = get_link_hwss(link, link_res); + struct dmcu *dmcu = dc->res_pool->dmcu; + + if (signal == SIGNAL_TYPE_EDP && + link->dc->hwss.edp_backlight_control) + link->dc->hwss.edp_backlight_control(link, false); + else if (dmcu != NULL && dmcu->funcs->lock_phy) + dmcu->funcs->lock_phy(dmcu); + + link_hwss->disable_link_output(link, link_res, signal); + link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF; + /* + * Add the logic to extract BOTH power up and power down sequences + * from enable/disable link output and only call edp panel control + * in enable_link_dp and disable_link_dp once. + */ + if (dmcu != NULL && dmcu->funcs->lock_phy) + dmcu->funcs->unlock_phy(dmcu); + dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY); + + apply_symclk_on_tx_off_wa(link); +} diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h index c786d5e6a428..6d0b62503caa 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h @@ -45,4 +45,6 @@ void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on); +void dcn314_disable_link_output(struct dc_link *link, const struct link_resource *link_res, enum signal_type signal); + #endif /* __DC_HWSS_DCN314_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c index 5267e901a35c..a588f46b166f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c @@ -105,7 +105,7 @@ static const struct hw_sequencer_funcs dcn314_funcs = { .enable_lvds_link_output = dce110_enable_lvds_link_output, .enable_tmds_link_output = dce110_enable_tmds_link_output, .enable_dp_link_output = dce110_enable_dp_link_output, - .disable_link_output = dce110_disable_link_output, + .disable_link_output = dcn314_disable_link_output, .z10_restore = dcn31_z10_restore, .z10_save_init = dcn31_z10_save_init, .set_disp_pattern_generator = dcn30_set_disp_pattern_generator, -- cgit From b504f99ccaa64da364443431e388ecf30b604e38 Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Thu, 27 Apr 2023 15:10:13 -0400 Subject: drm/amd/display: Enforce 60us prefetch for 200Mhz DCFCLK modes [Description] - Due to bandwidth / arbitration issues at 200Mhz DCFCLK, we want to enforce minimum 60us of prefetch to avoid intermittent underflow issues - Since 60us prefetch is already enforced for UCLK DPM0, and many DCFCLK's > 200Mhz are mapped to UCLK DPM1, in theory there should not be any UCLK DPM regressions by enforcing greater prefetch Reviewed-by: Nevenko Stupar Reviewed-by: Jun Lei Cc: Mario Limonciello Cc: Alex Deucher Cc: stable@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c | 5 +++-- drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c index 13c7e7394b1c..d75248b6cae9 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c @@ -810,7 +810,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman v->SwathHeightY[k], v->SwathHeightC[k], TWait, - v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ ? + (v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ || + v->DCFCLKPerState[mode_lib->vba.VoltageLevel] <= MIN_DCFCLK_FREQ_MHZ) ? mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, /* Output */ &v->DSTXAfterScaler[k], @@ -3310,7 +3311,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l v->swath_width_chroma_ub_this_state[k], v->SwathHeightYThisState[k], v->SwathHeightCThisState[k], v->TWait, - v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ ? + (v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKState[i][j] <= MIN_DCFCLK_FREQ_MHZ) ? mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, /* Output */ diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h index 500b3dd6052d..d98e36a9a09c 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h @@ -53,6 +53,7 @@ #define BPP_BLENDED_PIPE 0xffffffff #define MEM_STROBE_FREQ_MHZ 1600 +#define MIN_DCFCLK_FREQ_MHZ 200 #define MEM_STROBE_MAX_DELIVERY_TIME_US 60.0 struct display_mode_lib; -- cgit From 6d600229df1ed06f46ba68ac706d9f44ba8c5fb4 Mon Sep 17 00:00:00 2001 From: Mustapha Ghaddar Date: Fri, 28 Apr 2023 12:13:21 -0400 Subject: drm/amd/display: enable dpia validate Use dpia_validate_usb4_bw() function Fixes: a8b537605e22 ("drm/amd/display: Add function pointer for validate bw usb4") Reviewed-by: Roman Li Reviewed-by: Meenakshikumar Somasundaram Acked-by: Aurabindo Pillai Signed-off-by: Mustapha Ghaddar Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/link_validation.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/link_validation.c b/drivers/gpu/drm/amd/display/dc/link/link_validation.c index d4b7da526f0a..e8b2fc4002a5 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_validation.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_validation.c @@ -359,5 +359,8 @@ bool link_validate_dpia_bandwidth(const struct dc_stream_state *stream, const un link[i] = stream[i].link; bw_needed[i] = dc_bandwidth_in_kbps_from_timing(&stream[i].timing); } + + ret = dpia_validate_usb4_bw(link, bw_needed, num_streams); + return ret; } -- cgit From 137f9cee113df91107cf91c130d5c414c4b191f0 Mon Sep 17 00:00:00 2001 From: Alan Liu Date: Tue, 2 May 2023 17:54:50 +0800 Subject: drm/amd/display: Fix warning in disabling vblank irq [Why] During gpu-reset, we toggle vblank irq by calling dc_interrupt_set() instead of amdgpu_irq_get/put() because we don't want to change the irq source's refcount. However, we see the warning when vblank irq is enabled by dc_interrupt_set() during gpu-reset but disabled by amdgpu_irq_put() after gpu-reset. [How] Only in dm_gpureset_toggle_interrupts() we toggle vblank interrupts by calling dc_interrupt_set(). Apart from this we call dm_set_vblank() which uses amdgpu_irq_get/put() to operate vblank irq. Reviewed-by: Bhawanpreet Lakha Acked-by: Tom Chung Signed-off-by: Alan Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 +++++++++++++-------- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 16 +++------------- 2 files changed, 16 insertions(+), 21 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 8b4b186c57f5..26b5cbc97046 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2479,20 +2479,25 @@ static void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev, if (acrtc && state->stream_status[i].plane_count != 0) { irq_source = IRQ_TYPE_PFLIP + acrtc->otg_inst; rc = dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY; - DRM_DEBUG_VBL("crtc %d - vupdate irq %sabling: r=%d\n", - acrtc->crtc_id, enable ? "en" : "dis", rc); if (rc) DRM_WARN("Failed to %s pflip interrupts\n", enable ? "enable" : "disable"); if (enable) { - rc = amdgpu_dm_crtc_enable_vblank(&acrtc->base); - if (rc) - DRM_WARN("Failed to enable vblank interrupts\n"); - } else { - amdgpu_dm_crtc_disable_vblank(&acrtc->base); - } + if (amdgpu_dm_crtc_vrr_active(to_dm_crtc_state(acrtc->base.state))) + rc = amdgpu_dm_crtc_set_vupdate_irq(&acrtc->base, true); + } else + rc = amdgpu_dm_crtc_set_vupdate_irq(&acrtc->base, false); + if (rc) + DRM_WARN("Failed to %sable vupdate interrupt\n", enable ? "en" : "dis"); + + irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst; + /* During gpu-reset we disable and then enable vblank irq, so + * don't use amdgpu_irq_get/put() to avoid refcount change. + */ + if (!dc_interrupt_set(adev->dm.dc, irq_source, enable)) + DRM_WARN("Failed to %sable vblank interrupt\n", enable ? "en" : "dis"); } } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index e3762e806617..440fc0869a34 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -146,7 +146,6 @@ static void vblank_control_worker(struct work_struct *work) static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable) { - enum dc_irq_source irq_source; struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); struct amdgpu_device *adev = drm_to_adev(crtc->dev); struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state); @@ -169,18 +168,9 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable) if (rc) return rc; - if (amdgpu_in_reset(adev)) { - irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst; - /* During gpu-reset we disable and then enable vblank irq, so - * don't use amdgpu_irq_get/put() to avoid refcount change. - */ - if (!dc_interrupt_set(adev->dm.dc, irq_source, enable)) - rc = -EBUSY; - } else { - rc = (enable) - ? amdgpu_irq_get(adev, &adev->crtc_irq, acrtc->crtc_id) - : amdgpu_irq_put(adev, &adev->crtc_irq, acrtc->crtc_id); - } + rc = (enable) + ? amdgpu_irq_get(adev, &adev->crtc_irq, acrtc->crtc_id) + : amdgpu_irq_put(adev, &adev->crtc_irq, acrtc->crtc_id); if (rc) return rc; -- cgit From 482e6ad9adde69d9da08864b4ccf4dfd53edb2f0 Mon Sep 17 00:00:00 2001 From: Fangzhi Zuo Date: Wed, 10 May 2023 16:43:30 -0400 Subject: drm/amd/display: Have Payload Properly Created After Resume At drm suspend sequence, MST dc_sink is removed. When commit cached MST stream back in drm resume sequence, the MST stream payload is not properly created and added into the payload table. After resume, topology change is reprobed by removing existing streams first. That leads to no payload is found in the existing payload table as below error "[drm] ERROR No payload for [MST PORT:] found in mst state" 1. In encoder .atomic_check routine, remove check existance of dc_sink 2. Bypass MST by checking existence of MST root port. dc_link_type cannot differentiate MST port before topology is rediscovered. Reviewed-by: Wayne Lin Acked-by: Tom Chung Signed-off-by: Fangzhi Zuo Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 26b5cbc97046..d5cec03eaa8d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2857,7 +2857,7 @@ static int dm_resume(void *handle) * this is the case when traversing through already created * MST connectors, should be skipped */ - if (aconnector->dc_link->type == dc_connection_mst_branch) + if (aconnector && aconnector->mst_root) continue; mutex_lock(&aconnector->hpd_lock); @@ -6742,7 +6742,7 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder, int clock, bpp = 0; bool is_y420 = false; - if (!aconnector->mst_output_port || !aconnector->dc_sink) + if (!aconnector->mst_output_port) return 0; mst_port = aconnector->mst_output_port; -- cgit From c14fb01c4629b96b64ab54caea7e543a0239f14e Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Mon, 22 May 2023 15:08:22 +0200 Subject: Revert "drm/amd/display: Block optimize on consecutive FAMS enables" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit ce560ac40272a5c8b5b68a9d63a75edd9e66aed2. It depends on its parent commit, which we want to revert. Acked-by: Alex Deucher Signed-off-by: Michel Dänzer [Hamza: fix a whitespace issue in dcn30_prepare_bandwidth()] Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 3 --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 22 +++------------------- 2 files changed, 3 insertions(+), 22 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 422fbf79da64..6ce10fd4bb1a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -2117,9 +2117,6 @@ void dcn20_optimize_bandwidth( dc_dmub_srv_p_state_delegate(dc, true, context); context->bw_ctx.bw.dcn.clk.p_state_change_support = true; - dc->clk_mgr->clks.fw_based_mclk_switching = true; - } else { - dc->clk_mgr->clks.fw_based_mclk_switching = false; } dc->clk_mgr->funcs->update_clocks( diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index 8263a07f265f..f923224e85fc 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -983,13 +983,9 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc, } void dcn30_prepare_bandwidth(struct dc *dc, - struct dc_state *context) + struct dc_state *context) { - bool p_state_change_support = context->bw_ctx.bw.dcn.clk.p_state_change_support; - /* Any transition into an FPO config should disable MCLK switching first to avoid - * driver and FW P-State synchronization issues. - */ - if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) { + if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) { dc->optimized_required = true; context->bw_ctx.bw.dcn.clk.p_state_change_support = false; } @@ -1000,19 +996,7 @@ void dcn30_prepare_bandwidth(struct dc *dc, dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz); dcn20_prepare_bandwidth(dc, context); - /* - * enabled -> enabled: do not disable - * enabled -> disabled: disable - * disabled -> enabled: don't care - * disabled -> disabled: don't care - */ - if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) - dc_dmub_srv_p_state_delegate(dc, false, context); - if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) { - /* After disabling P-State, restore the original value to ensure we get the correct P-State - * on the next optimize. */ - context->bw_ctx.bw.dcn.clk.p_state_change_support = p_state_change_support; - } + dc_dmub_srv_p_state_delegate(dc, false, context); } -- cgit From 8e1b45c578b799510f9a01a9745a737e74f43cb1 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Mon, 22 May 2023 15:08:23 +0200 Subject: Revert "drm/amd/display: Do not set drr on pipe commit" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 474f01015ffdb74e01c2eb3584a2822c64e7b2be. Caused a regression: Samsung Odyssey Neo G9, running at 5120x1440@240/VRR, connected to Navi 21 via DisplayPort, blanks and the GPU hangs while starting the Steam game Assetto Corsa Competizione (via Proton 7.0). Example dmesg excerpt: amdgpu 0000:0c:00.0: [drm] ERROR [CRTC:82:crtc-0] flip_done timed out NMI watchdog: Watchdog detected hard LOCKUP on cpu 6 [...] RIP: 0010:amdgpu_device_rreg.part.0+0x2f/0xf0 [amdgpu] Code: 41 54 44 8d 24 b5 00 00 00 00 55 89 f5 53 48 89 fb 4c 3b a7 60 0b 00 00 73 6a 83 e2 02 74 29 4c 03 a3 68 0b 00 00 45 8b 24 24 <48> 8b 43 08 0f b7 70 3e 66 90 44 89 e0 5b 5d 41 5c 31 d2 31 c9 31 RSP: 0000:ffffb39a119dfb88 EFLAGS: 00000086 RAX: ffffffffc0eb96a0 RBX: ffff9e7963dc0000 RCX: 0000000000007fff RDX: 0000000000000000 RSI: 0000000000004ff6 RDI: ffff9e7963dc0000 RBP: 0000000000004ff6 R08: ffffb39a119dfc40 R09: 0000000000000010 R10: ffffb39a119dfc40 R11: ffffb39a119dfc44 R12: 00000000000e05ae R13: 0000000000000000 R14: ffff9e7963dc0010 R15: 0000000000000000 FS: 000000001012f6c0(0000) GS:ffff9e805eb80000(0000) knlGS:000000007fd40000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000461ca000 CR3: 00000002a8a20000 CR4: 0000000000350ee0 Call Trace: dm_read_reg_func+0x37/0xc0 [amdgpu] generic_reg_get2+0x22/0x60 [amdgpu] optc1_get_crtc_scanoutpos+0x6a/0xc0 [amdgpu] dc_stream_get_scanoutpos+0x74/0x90 [amdgpu] dm_crtc_get_scanoutpos+0x82/0xf0 [amdgpu] amdgpu_display_get_crtc_scanoutpos+0x91/0x190 [amdgpu] ? dm_read_reg_func+0x37/0xc0 [amdgpu] amdgpu_get_vblank_counter_kms+0xb4/0x1a0 [amdgpu] dm_pflip_high_irq+0x213/0x2f0 [amdgpu] amdgpu_dm_irq_handler+0x8a/0x200 [amdgpu] amdgpu_irq_dispatch+0xd4/0x220 [amdgpu] amdgpu_ih_process+0x7f/0x110 [amdgpu] amdgpu_irq_handler+0x1f/0x70 [amdgpu] __handle_irq_event_percpu+0x46/0x1b0 handle_irq_event+0x34/0x80 handle_edge_irq+0x9f/0x240 __common_interrupt+0x66/0x110 common_interrupt+0x5c/0xd0 asm_common_interrupt+0x22/0x40 Reviewed-by: Aurabindo Pillai Acked-by: Alex Deucher Signed-off-by: Michel Dänzer Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 6 ------ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 7 ------- 2 files changed, 13 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 6ce10fd4bb1a..5403e9399a46 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -2113,12 +2113,6 @@ void dcn20_optimize_bandwidth( if (hubbub->funcs->program_compbuf_size) hubbub->funcs->program_compbuf_size(hubbub, context->bw_ctx.bw.dcn.compbuf_size_kb, true); - if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) { - dc_dmub_srv_p_state_delegate(dc, - true, context); - context->bw_ctx.bw.dcn.clk.p_state_change_support = true; - } - dc->clk_mgr->funcs->update_clocks( dc->clk_mgr, context, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index f923224e85fc..32121db2851e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -985,18 +985,11 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc, void dcn30_prepare_bandwidth(struct dc *dc, struct dc_state *context) { - if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) { - dc->optimized_required = true; - context->bw_ctx.bw.dcn.clk.p_state_change_support = false; - } - if (dc->clk_mgr->dc_mode_softmax_enabled) if (dc->clk_mgr->clks.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 && context->bw_ctx.bw.dcn.clk.dramclk_khz > dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000) dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz); dcn20_prepare_bandwidth(dc, context); - - dc_dmub_srv_p_state_delegate(dc, false, context); } -- cgit From 59de751e3845d699e02dc4da47322b92d83a41e2 Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Tue, 9 May 2023 16:40:19 -0400 Subject: drm/amd/display: add ODM case when looking for first split pipe [Why] When going from ODM 2:1 single display case to max displays, second odm pipe needs to be repurposed for one of the new single displays. However, acquire_first_split_pipe() only handles MPC case and not ODM case [How] Add ODM conditions in acquire_first_split_pipe() Add commit_minimal_transition_state() in commit_streams() to handle odm 2:1 exit first, and then process new streams Handle ODM condition in commit_minimal_transition_state() Cc: Mario Limonciello Cc: Alex Deucher Cc: stable@vger.kernel.org Acked-by: Stylon Wang Signed-off-by: Samson Tam Reviewed-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 36 ++++++++++++++++++++++- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 20 +++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 52564b93f7eb..7cde67b7f0c3 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1981,6 +1981,9 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c return result; } +static bool commit_minimal_transition_state(struct dc *dc, + struct dc_state *transition_base_context); + /** * dc_commit_streams - Commit current stream state * @@ -2002,6 +2005,8 @@ enum dc_status dc_commit_streams(struct dc *dc, struct dc_state *context; enum dc_status res = DC_OK; struct dc_validation_set set[MAX_STREAMS] = {0}; + struct pipe_ctx *pipe; + bool handle_exit_odm2to1 = false; if (dc->ctx->dce_environment == DCE_ENV_VIRTUAL_HW) return res; @@ -2026,6 +2031,22 @@ enum dc_status dc_commit_streams(struct dc *dc, } } + /* Check for case where we are going from odm 2:1 to max + * pipe scenario. For these cases, we will call + * commit_minimal_transition_state() to exit out of odm 2:1 + * first before processing new streams + */ + if (stream_count == dc->res_pool->pipe_count) { + for (i = 0; i < dc->res_pool->pipe_count; i++) { + pipe = &dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe->next_odm_pipe) + handle_exit_odm2to1 = true; + } + } + + if (handle_exit_odm2to1) + res = commit_minimal_transition_state(dc, dc->current_state); + context = dc_create_state(dc); if (!context) goto context_alloc_fail; @@ -3872,6 +3893,7 @@ static bool commit_minimal_transition_state(struct dc *dc, unsigned int i, j; unsigned int pipe_in_use = 0; bool subvp_in_use = false; + bool odm_in_use = false; if (!transition_context) return false; @@ -3900,6 +3922,18 @@ static bool commit_minimal_transition_state(struct dc *dc, } } + /* If ODM is enabled and we are adding or removing planes from any ODM + * pipe, we must use the minimal transition. + */ + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; + + if (pipe->stream && pipe->next_odm_pipe) { + odm_in_use = true; + break; + } + } + /* When the OS add a new surface if we have been used all of pipes with odm combine * and mpc split feature, it need use commit_minimal_transition_state to transition safely. * After OS exit MPO, it will back to use odm and mpc split with all of pipes, we need @@ -3908,7 +3942,7 @@ static bool commit_minimal_transition_state(struct dc *dc, * Reduce the scenarios to use dc_commit_state_no_check in the stage of flip. Especially * enter/exit MPO when DCN still have enough resources. */ - if (pipe_in_use != dc->res_pool->pipe_count && !subvp_in_use) { + if (pipe_in_use != dc->res_pool->pipe_count && !subvp_in_use && !odm_in_use) { dc_release_state(transition_context); return true; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 117d80cb36fb..fe1551393b26 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1444,6 +1444,26 @@ static int acquire_first_split_pipe( split_pipe->plane_res.mpcc_inst = pool->dpps[i]->inst; split_pipe->pipe_idx = i; + split_pipe->stream = stream; + return i; + } else if (split_pipe->prev_odm_pipe && + split_pipe->prev_odm_pipe->plane_state == split_pipe->plane_state) { + split_pipe->prev_odm_pipe->next_odm_pipe = split_pipe->next_odm_pipe; + if (split_pipe->next_odm_pipe) + split_pipe->next_odm_pipe->prev_odm_pipe = split_pipe->prev_odm_pipe; + + if (split_pipe->prev_odm_pipe->plane_state) + resource_build_scaling_params(split_pipe->prev_odm_pipe); + + memset(split_pipe, 0, sizeof(*split_pipe)); + split_pipe->stream_res.tg = pool->timing_generators[i]; + split_pipe->plane_res.hubp = pool->hubps[i]; + split_pipe->plane_res.ipp = pool->ipps[i]; + split_pipe->plane_res.dpp = pool->dpps[i]; + split_pipe->stream_res.opp = pool->opps[i]; + split_pipe->plane_res.mpcc_inst = pool->dpps[i]->inst; + split_pipe->pipe_idx = i; + split_pipe->stream = stream; return i; } -- cgit From e1a600208286c197c2696e51fc313e49889315bd Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Fri, 19 May 2023 11:38:15 -0400 Subject: drm/amd/display: Reduce sdp bw after urgent to 90% [Description] Reduce expected SDP bandwidth due to poor QoS and arbitration issues on high bandwidth configs Cc: Mario Limonciello Cc: Alex Deucher Cc: stable@vger.kernel.org Acked-by: Stylon Wang Signed-off-by: Alvin Lee Reviewed-by: Nevenko Stupar Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 47beb4ea779d..0c4c3208def1 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 @@ -138,7 +138,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = { .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, - .pct_ideal_sdp_bw_after_urgent = 100.0, + .pct_ideal_sdp_bw_after_urgent = 90.0, .pct_ideal_fabric_bw_after_urgent = 67.0, .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 20.0, .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0, // N/A, for now keep as is until DML implemented -- cgit From e749dd10e5f292061ad63d2b030194bf7d7d452c Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Thu, 25 May 2023 08:37:40 -0400 Subject: drm/amd/display: edp do not add non-edid timings [Why] most edp support only timings from edid. applying non-edid timings, especially those timings out of edp bandwidth, may damage edp. [How] do not add non-edid timings for edp. Cc: Mario Limonciello Cc: Alex Deucher Cc: stable@vger.kernel.org Acked-by: Stylon Wang Signed-off-by: Hersen Wu Reviewed-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/display') 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 d5cec03eaa8d..2b8d42de1f73 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7196,7 +7196,13 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) drm_add_modes_noedid(connector, 1920, 1080); } else { amdgpu_dm_connector_ddc_get_modes(connector, edid); - amdgpu_dm_connector_add_common_modes(encoder, connector); + /* most eDP supports only timings from its edid, + * usually only detailed timings are available + * from eDP edid. timings which are not from edid + * may damage eDP + */ + if (connector->connector_type != DRM_MODE_CONNECTOR_eDP) + amdgpu_dm_connector_add_common_modes(encoder, connector); amdgpu_dm_connector_add_freesync_modes(connector, edid); } amdgpu_dm_fbc_init(connector); -- cgit From ea2062dd1f0384ae1b136d333ee4ced15bedae38 Mon Sep 17 00:00:00 2001 From: Tom Chung Date: Mon, 29 May 2023 18:00:09 +0800 Subject: drm/amd/display: fix the system hang while disable PSR [Why] When the PSR enabled. If you try to adjust the timing parameters, it may cause system hang. Because the timing mismatch with the DMCUB settings. [How] Disable the PSR before adjusting timing parameters. Cc: Mario Limonciello Cc: Alex Deucher Cc: stable@vger.kernel.org Acked-by: Stylon Wang Signed-off-by: Tom Chung Reviewed-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/display') 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 2b8d42de1f73..7acd73e5004f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8204,6 +8204,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, if (acrtc_state->abm_level != dm_old_crtc_state->abm_level) bundle->stream_update.abm_level = &acrtc_state->abm_level; + mutex_lock(&dm->dc_lock); + if ((acrtc_state->update_type > UPDATE_TYPE_FAST) && + acrtc_state->stream->link->psr_settings.psr_allow_active) + amdgpu_dm_psr_disable(acrtc_state->stream); + mutex_unlock(&dm->dc_lock); + /* * If FreeSync state on the stream has changed then we need to * re-adjust the min/max bounds now that DC doesn't handle this @@ -8217,10 +8223,6 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags); } mutex_lock(&dm->dc_lock); - if ((acrtc_state->update_type > UPDATE_TYPE_FAST) && - acrtc_state->stream->link->psr_settings.psr_allow_active) - amdgpu_dm_psr_disable(acrtc_state->stream); - update_planes_and_stream_adapter(dm->dc, acrtc_state->update_type, planes_count, -- cgit From 7c5835bcb9176df94683396f1c0e5df6bf5094b3 Mon Sep 17 00:00:00 2001 From: Peichen Huang Date: Wed, 31 May 2023 13:36:14 +0800 Subject: drm/amd/display: limit DPIA link rate to HBR3 [Why] DPIA doesn't support UHBR, driver should not enable UHBR for dp tunneling [How] limit DPIA link rate to HBR3 Cc: Mario Limonciello Cc: Alex Deucher Cc: stable@vger.kernel.org Acked-by: Stylon Wang Signed-off-by: Peichen Huang Reviewed-by: Mustapha Ghaddar Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/link/link_detection.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/amd/display') diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index a131e30fd7d6..d471d58aba92 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -980,6 +980,11 @@ static bool detect_link_and_local_sink(struct dc_link *link, (link->dpcd_caps.dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER)) converter_disable_audio = true; + + /* limited link rate to HBR3 for DPIA until we implement USB4 V2 */ + if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && + link->reported_link_cap.link_rate > LINK_RATE_HIGH3) + link->reported_link_cap.link_rate = LINK_RATE_HIGH3; break; } -- cgit