DC Patches for Dec 18, 2023
Subsystems (5)
cover DC Patches for Dec 18, 2023
This DC patchset brings improvements in multiple areas. In summary, we highlight:
- change static screen wait frame_count for ips
- Fix hang/underflow when transitioning to ODM4:1
- Only clear symclk otg flag for HDMI
- Fix lightup regression with DP2 single display configs
- Refactor phantom resource allocation
- Refactor dc_state interface
- Wake DMCUB before executing GPINT commands
- Wake DMCUB before sending a command
- Refactor DMCUB enter/exit idle interface
- enable dcn35 idle power optimization
- fix usb-c connector_type
- add debug option for ExtendedVBlank DLG adjust
- Set test_pattern_changed update flag on pipe enable
- dereference variable before checking for zero
- get dprefclk ss info from integration info table
- skip error logging when DMUB is inactive from S3
- make flip_timestamp_in_us a 64-bit variable
- Add case for dcn35 to support usb4 dmub hpd event
- Add function for dumping clk registers
- Unify optimize_required flags and VRR adjustments
- Revert using channel_width as 2 for vram table 3.0
- remove HPO PG in driver side
- do not send commands to DMUB if DMUB is inactive from S3
---
Allen Pan (2):
drm/amd/display: fix usb-c connector_type drm/amd/display: change static screen wait frame_count for ips
Alvin Lee (2):
drm/amd/display: Revert " drm/amd/display: Use channel_width = 2 for
vram table 3.0"
drm/amd/display: Only clear symclk otg flag for HDMI
Anthony Koo (1):
drm/amd/display: [FW Promotion] Release 0.0.197.0
Aric Cyr (2):
drm/amd/display: Unify optimize_required flags and VRR adjustments drm/amd/display: 3.2.265
Charlene Liu (1):
drm/amd/display: get dprefclk ss info from integration info table
Dillon Varone (2):
drm/amd/display: Refactor dc_state interface drm/amd/display: Refactor phantom resource allocation
George Shen (1):
drm/amd/display: Set test_pattern_changed update flag on pipe enable
Ilya Bakoulin (1):
drm/amd/display: Fix hang/underflow when transitioning to ODM4:1
Johnson Chen (1):
drm/amd/display: Add function for dumping clk registers
Josip Pavic (2):
drm/amd/display: make flip_timestamp_in_us a 64-bit variable drm/amd/display: dereference variable before checking for zero
Michael Strauss (1):
drm/amd/display: Fix lightup regression with DP2 single display
configs
Muhammad Ahmed (2):
drm/amd/display: remove HPO PG in driver side drm/amd/display: add debug option for ExtendedVBlank DLG adjust
Nicholas Kazlauskas (3):
drm/amd/display: Refactor DMCUB enter/exit idle interface drm/amd/display: Wake DMCUB before sending a command drm/amd/display: Wake DMCUB before executing GPINT commands
Roman Li (1):
drm/amd/display: enable dcn35 idle power optimization
Samson Tam (2):
drm/amd/display: do not send commands to DMUB if DMUB is inactive from
S3
drm/amd/display: skip error logging when DMUB is inactive from S3
Wayne Lin (1):
drm/amd/display: Add case for dcn35 to support usb4 dmub hpd event
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 59 +- .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 29 +- drivers/gpu/drm/amd/display/dc/Makefile | 2 +- .../drm/amd/display/dc/bios/bios_parser2.c | 27 +- .../drm/amd/display/dc/bios/command_table2.c | 12 +- .../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 3 +- .../display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c | 2 +- .../dc/clk_mgr/dcn314/dcn314_clk_mgr.c | 2 +- .../dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 2 +- .../dc/clk_mgr/dcn316/dcn316_clk_mgr.c | 2 +- .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 9 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 300 ++---- .../drm/amd/display/dc/core/dc_hw_sequencer.c | 19 +- .../gpu/drm/amd/display/dc/core/dc_resource.c | 418 +-------- .../gpu/drm/amd/display/dc/core/dc_state.c | 861 ++++++++++++++++++ .../gpu/drm/amd/display/dc/core/dc_stream.c | 46 +- .../gpu/drm/amd/display/dc/core/dc_surface.c | 6 +- drivers/gpu/drm/amd/display/dc/dc.h | 33 +- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 244 ++++- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 59 +- drivers/gpu/drm/amd/display/dc/dc_helper.c | 6 +- drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 2 +- drivers/gpu/drm/amd/display/dc/dc_plane.h | 38 + .../gpu/drm/amd/display/dc/dc_plane_priv.h | 34 + drivers/gpu/drm/amd/display/dc/dc_state.h | 78 ++ .../gpu/drm/amd/display/dc/dc_state_priv.h | 102 +++ drivers/gpu/drm/amd/display/dc/dc_stream.h | 76 +- .../gpu/drm/amd/display/dc/dc_stream_priv.h | 37 + drivers/gpu/drm/amd/display/dc/dc_types.h | 5 + .../gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c | 14 +- .../drm/amd/display/dc/dce/dmub_hw_lock_mgr.c | 2 +- .../gpu/drm/amd/display/dc/dce/dmub_outbox.c | 2 +- drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 33 +- .../gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c | 2 +- .../display/dc/dcn31/dcn31_dio_link_encoder.c | 4 +- .../amd/display/dc/dcn31/dcn31_panel_cntl.c | 4 +- .../display/dc/dcn32/dcn32_resource_helpers.c | 93 +- .../display/dc/dcn35/dcn35_dio_link_encoder.c | 5 + .../gpu/drm/amd/display/dc/dcn35/dcn35_init.c | 2 +- .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 5 +- .../drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 51 +- .../amd/display/dc/dml2/display_mode_core.c | 2 +- .../drm/amd/display/dc/dml2/dml2_dc_types.h | 1 + .../amd/display/dc/dml2/dml2_mall_phantom.c | 89 +- .../display/dc/dml2/dml2_translation_helper.c | 10 +- .../gpu/drm/amd/display/dc/dml2/dml2_utils.c | 14 +- .../drm/amd/display/dc/dml2/dml2_wrapper.c | 2 +- .../drm/amd/display/dc/dml2/dml2_wrapper.h | 35 +- .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 13 +- .../amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 35 +- .../amd/display/dc/hwss/dcn10/dcn10_hwseq.h | 7 +- .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 79 +- .../amd/display/dc/hwss/dcn20/dcn20_hwseq.h | 2 +- .../amd/display/dc/hwss/dcn201/dcn201_hwseq.c | 8 +- .../amd/display/dc/hwss/dcn201/dcn201_hwseq.h | 2 +- .../amd/display/dc/hwss/dcn21/dcn21_hwseq.c | 4 +- .../amd/display/dc/hwss/dcn30/dcn30_hwseq.c | 12 +- .../amd/display/dc/hwss/dcn31/dcn31_hwseq.c | 7 +- .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 78 +- .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 58 +- .../amd/display/dc/hwss/dcn35/dcn35_hwseq.h | 6 +- .../drm/amd/display/dc/hwss/hw_sequencer.h | 8 +- .../display/dc/hwss/hw_sequencer_private.h | 1 + .../gpu/drm/amd/display/dc/inc/core_types.h | 20 +- .../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h | 19 + .../gpu/drm/amd/display/dc/inc/hw/hw_shared.h | 1 + drivers/gpu/drm/amd/display/dc/inc/resource.h | 1 - .../dc/link/protocols/link_dp_capability.c | 2 +- .../display/dc/link/protocols/link_dp_dpia.c | 3 +- .../amd/display/dc/optc/dcn32/dcn32_optc.c | 7 + .../amd/display/dc/optc/dcn35/dcn35_optc.c | 7 + .../dc/resource/dcn32/dcn32_resource.c | 134 +-- .../dc/resource/dcn32/dcn32_resource.h | 14 - .../dc/resource/dcn321/dcn321_resource.c | 25 +- .../dc/resource/dcn35/dcn35_resource.c | 8 +- drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 22 + .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 2 +- .../gpu/drm/amd/display/dmub/src/dmub_srv.c | 15 + .../display/include/grph_object_ctrl_defs.h | 2 + 79 files changed, 2147 insertions(+), 1338 deletions(-) create mode 100644 drivers/gpu/drm/amd/display/dc/core/dc_state.c create mode 100644 drivers/gpu/drm/amd/display/dc/dc_plane.h create mode 100644 drivers/gpu/drm/amd/display/dc/dc_plane_priv.h create mode 100644 drivers/gpu/drm/amd/display/dc/dc_state.h create mode 100644 drivers/gpu/drm/amd/display/dc/dc_state_priv.h create mode 100644 drivers/gpu/drm/amd/display/dc/dc_stream_priv.h
Signature · 1 line
2.37.3
PATCH 1/25 drm/amd/display: do not send commands to DMUB if DMUB is inactive from S3
From: Samson Tam <[email protected]>
[Why]
On resume from S3, may get apply_idle_optimizations call while DMUB is inactive which will just time out.
[How]
Set and track power state in dmub_srv and check power state before sending commands to DMUB. Add interface in both dmub_srv and dc_dmub_srv
--- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +++ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 14 +++++++++++++ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 2 ++ drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 21 +++++++++++++++++++ .../gpu/drm/amd/display/dmub/src/dmub_srv.c | 15 +++++++++++++ 5 files changed, 55 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +3 -0
@@ -2685,6 +2685,7 @@ static int dm_suspend(void *handle)hpd_rx_irq_work_suspend (dm);dc_set_power_state (dm->dc,DC_ACPI_CM_POWER_STATE_D3 ); +dc_dmub_srv_set_power_state (dm->dc->ctx->dmub_srv,DC_ACPI_CM_POWER_STATE_D3 );return 0 ; }
@@ -2880,6 +2881,7 @@ static int dm_resume(void *handle)if (r)DRM_ERROR ("DMUB interface failed to initialize: status=%d\n" , r); +dc_dmub_srv_set_power_state (dm->dc->ctx->dmub_srv,DC_ACPI_CM_POWER_STATE_D0 );dc_set_power_state (dm->dc,DC_ACPI_CM_POWER_STATE_D0 );dc_resume (dm->dc);
@@ -2930,6 +2932,7 @@ static int dm_resume(void *handle) }/* power on hardware */ +dc_dmub_srv_set_power_state (dm->dc->ctx->dmub_srv,DC_ACPI_CM_POWER_STATE_D0 );dc_set_power_state (dm->dc,DC_ACPI_CM_POWER_STATE_D0 );/* program HPD filter */
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +14 -0
@@ -1268,3 +1268,17 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc)ASSERT (0 ); } +void dc_dmub_srv_set_power_state (struct dc_dmub_srv *dc_dmub_srv,enum dc_acpi_cm_power_state powerState) +{ +struct dmub_srv *dmub; + +if (!dc_dmub_srv) +return ; + + dmub = dc_dmub_srv->dmub; + +if (powerState ==DC_ACPI_CM_POWER_STATE_D0 ) +dmub_srv_set_power_state (dmub,DMUB_POWER_STATE_D0 ); +else +dmub_srv_set_power_state (dmub,DMUB_POWER_STATE_D3 ); +}
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h +2 -0
@@ -102,4 +102,6 @@ void dc_dmub_srv_subvp_save_surf_addr(const struct dc_dmub_srv *dc_dmub_srv, conbool dc_dmub_srv_is_hw_pwr_up (struct dc_dmub_srv *dc_dmub_srv,bool wait);void dc_dmub_srv_notify_idle (const struct dc *dc,bool allow_idle);void dc_dmub_srv_exit_low_power_state (const struct dc *dc); + +void dc_dmub_srv_set_power_state (struct dc_dmub_srv *dc_dmub_srv,enum dc_acpi_cm_power_state powerState);#endif /* _DMUB_DC_SRV_H_ */
drivers/gpu/drm/amd/display/dmub/dmub_srv.h +21 -0
@@ -150,6 +150,13 @@ enum dmub_memory_access_type { DMUB_MEMORY_ACCESS_DMA }; +/* enum dmub_power_state type - to track DC power state in dmub_srv */ +enum dmub_srv_power_state_type { +DMUB_POWER_STATE_UNDEFINED =0 , +DMUB_POWER_STATE_D0 =1 , +DMUB_POWER_STATE_D3 =8 +}; +/** * struct dmub_region - dmub hw memory region * @base: base address for region, must be 256 byte aligned
@@ -485,6 +492,8 @@ struct dmub_srv {/* Feature capabilities reported by fw */ struct dmub_feature_caps feature_caps;struct dmub_visual_confirm_color visual_confirm_color; + +enum dmub_srv_power_state_type power_state; };/**
@@ -889,6 +898,18 @@ enum dmub_status dmub_srv_clear_inbox0_ack(struct dmub_srv *dmub);*/ void dmub_srv_subvp_save_surf_addr (struct dmub_srv *dmub,const struct dc_plane_address *addr,uint8_t subvp_index); +/** +* dmub_srv_set_power_state() - Track DC power state in dmub_srv +* @dmub: The dmub service +* @power_state: DC power state setting +* +* Store DC power state in dmub_srv. If dmub_srv is in D3, then don't send messages to DMUB +* +* Return: +* void +*/ +void dmub_srv_set_power_state (struct dmub_srv *dmub,enum dmub_srv_power_state_type dmub_srv_power_state); +#if defined(__cplusplus) }#endif
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +15 -0
@@ -713,6 +713,7 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, dmub->hw_funcs.reset_release (dmub); dmub->hw_init = true; + dmub->power_state =DMUB_POWER_STATE_D0 ;return DMUB_STATUS_OK ; }
@@ -766,6 +767,9 @@ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub,if (!dmub->hw_init)return DMUB_STATUS_INVALID ; +if (dmub->power_state !=DMUB_POWER_STATE_D0 ) +return DMUB_STATUS_INVALID ; +if (dmub->inbox1_rb.rptr > dmub->inbox1_rb.capacity || dmub->inbox1_rb.wrpt > dmub->inbox1_rb.capacity) {return DMUB_STATUS_HW_FAILURE ;
@@ -784,6 +788,9 @@ enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub)if (!dmub->hw_init)return DMUB_STATUS_INVALID ; +if (dmub->power_state !=DMUB_POWER_STATE_D0 ) +return DMUB_STATUS_INVALID ; +/** * Read back all the queued commands to ensure that they've * been flushed to framebuffer memory. Otherwise DMCUB might
@@ -1100,3 +1107,11 @@ void dmub_srv_subvp_save_surf_addr(struct dmub_srv *dmub, const struct dc_plane_ subvp_index); } } + +void dmub_srv_set_power_state (struct dmub_srv *dmub,enum dmub_srv_power_state_type dmub_srv_power_state) +{ +if (!dmub || !dmub->hw_init) +return ; + + dmub->power_state = dmub_srv_power_state; +}
Signature · 1 line
2.37.3
PATCH 2/25 drm/amd/display: remove HPO PG in driver side
In reply to Wayne LinFrom: Muhammad Ahmed <[email protected]>
[why & how]
Add config to make HPO PG handled in dmubfw ips entry/exit
--- drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +1 -0
@@ -718,6 +718,7 @@ static const struct dc_debug_options debug_defaults_drv = { .disable_dpp_power_gate = true, .disable_hubp_power_gate = true, .disable_optc_power_gate = true, /*should the same as above two*/ + .disable_hpo_power_gate = true, /*dmubfw force domain25 on*/ .disable_clock_gate = false, .disable_dsc_power_gate = true, .vsr_support = true,
Signature · 1 line
2.37.3
PATCH 3/25 drm/amd/display: Revert " drm/amd/display: Use channel_width = 2 for vram table 3.0"
In reply to Wayne LinFrom: Alvin Lee <[email protected]>
[Description]
Revert commit 8c5660987ee1 ("drm/amd/display: Use channel_width = 2 for vram table 3.0") Because the issue is being fixed from VBIOS side.
--- drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +1 -7
@@ -2386,13 +2386,7 @@ static enum bp_result get_vram_info_v30(return BP_RESULT_BADBIOSTABLE ; info->num_chans = info_v30->channel_num; -/* As suggested by VBIOS we should always use -* dram_channel_width_bytes = 2 when using VRAM -* table version 3.0. This is because the channel_width -* param in the VRAM info table is changed in 7000 series and -* no longer represents the memory channel width. -*/ - info->dram_channel_width_bytes =2 ; + info->dram_channel_width_bytes = (1 << info_v30->channel_width) /8 ;return result; }
Signature · 1 line
2.37.3
Re: [PATCH 03/25] drm/amd/display: Revert " drm/amd/display: Use channel_width = 2 for vram table 3.0"
Quoted 10 lines · Wayne Lin
From: Alvin Lee <[email protected]>
[Description]
Revert commit8c5660987ee1("drm/amd/display: Usechannel_width= 2 for vram table 3.0") Because the issue is being fixed from VBIOS side.Reviewed-by Samson Tam <[email protected]>Acked-by Wayne Lin <[email protected]>Signed-off-by Alvin Lee <[email protected]>
Quoted 26 lines
--- drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +1
-8@@ -2386,13 +2386,7 @@ static enum bp_result get_vram_info_v30(return BP_RESULT_BADBIOSTABLE ; info->num_chans = info_v30->channel_num; -/* As suggested by VBIOS we should always use -* dram_channel_width_bytes = 2 when using VRAM -* table version 3.0. This is because the channel_width -* param in the VRAM info table is changed in 7000 series and -* no longer represents the memory channel width. -*/ - info->dram_channel_width_bytes =2 ; + info->dram_channel_width_bytes = (1 << info_v30->channel_width) /8 ;return result; } --2.37.3
PATCH 4/25 drm/amd/display: Unify optimize_required flags and VRR adjustments
In reply to Wayne LinFrom: Aric Cyr <[email protected]>
[why]
There is only a single call to dc_post_update_surfaces_to_stream so there is no need to have two flags to control it. Unifying this to a single flag allows dc_stream_adjust_vmin_vmax to skip actual programming when there is no change required.
[how]
Remove wm_optimze_required flag and set only optimize_required in its place. Then in dc_stream_adjust_vmin_vmax, check that the stream timing range matches the requested one and skip programming if they are equal.
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 14 +++++--------- drivers/gpu/drm/amd/display/dc/dc.h | 1 - drivers/gpu/drm/amd/display/dc/dc_stream.h | 2 -- .../drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 2 +- .../drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 8 ++++---- 5 files changed, 10 insertions(+), 17 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +5 -9
@@ -409,9 +409,12 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,* avoid conflicting with firmware updates. */ if (dc->ctx->dce_version >DCE_VERSION_MAX ) -if (dc->optimized_required || dc->wm_optimized_required) +if (dc->optimized_required)return false; +if (!memcmp (&stream->adjust, adjust,sizeof (*adjust))) +return true; + 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;
@@ -2223,7 +2226,6 @@ void dc_post_update_surfaces_to_stream(struct dc *dc) } dc->optimized_required = false; - dc->wm_optimized_required = false; }static void init_state (struct dc *dc,struct dc_state *context)
@@ -2743,8 +2745,6 @@ enum surface_update_type dc_check_update_surfaces_for_stream( }else if (memcmp (&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks , prev_p_state_change_support)) !=0 ) { dc->optimized_required = true; } - - dc->optimized_required |= dc->wm_optimized_required; }return type;
@@ -2952,9 +2952,6 @@ static void copy_stream_update_to_stream(struct dc *dc,if (update->vrr_active_fixed) stream->vrr_active_fixed = *update->vrr_active_fixed; -if (update->crtc_timing_adjust) - stream->adjust = *update->crtc_timing_adjust; -if (update->dpms_off) stream->dpms_off = *update->dpms_off;
@@ -4401,8 +4398,7 @@ static bool full_update_required(struct dc *dc, stream_update->mst_bw_update || stream_update->func_shaper || stream_update->lut3d_func || - stream_update->pending_test_pattern || - stream_update->crtc_timing_adjust)) + stream_update->pending_test_pattern)) return true;if (stream) {
drivers/gpu/drm/amd/display/dc/dc.h +0 -1
@@ -1026,7 +1026,6 @@ struct dc {/* Require to optimize clocks and bandwidth for added/removed planes */ bool optimized_required; -bool wm_optimized_required;bool idle_optimizations_allowed;bool enable_c20_dtm_b0;
drivers/gpu/drm/amd/display/dc/dc_stream.h +0 -2
@@ -130,7 +130,6 @@ union stream_update_flags { uint32_t wb_update:1; uint32_t dsc_changed : 1; uint32_t mst_bw : 1; - uint32_t crtc_timing_adjust : 1; uint32_t fams_changed : 1; } bits;
@@ -342,7 +341,6 @@ struct dc_stream_update {struct dc_3dlut *lut3d_func;struct test_pattern *pending_test_pattern; -struct dc_crtc_timing_adjust *crtc_timing_adjust; }; bool dc_is_stream_unchanged(
drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c +1 -1
@@ -3068,7 +3068,7 @@ void dcn10_prepare_bandwidth( context, false); - dc->wm_optimized_required = hubbub->funcs->program_watermarks (hubbub, + dc->optimized_required |= hubbub->funcs->program_watermarks (hubbub, &context->bw_ctx.bw.dcn.watermarks, dc->res_pool->ref_clocks.dchub_ref_clock_inKhz /1000 , true);
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +4 -4
@@ -2146,10 +2146,10 @@ void dcn20_prepare_bandwidth( }/* program dchubbub watermarks: -* For assigning wm_optimized_required, use |= operator since we don't want +* For assigning optimized_required, use |= operator since we don't want * to clear the value if the optimize has not happened yet */ - dc->wm_optimized_required |= hubbub->funcs->program_watermarks (hubbub, + dc->optimized_required |= hubbub->funcs->program_watermarks (hubbub, &context->bw_ctx.bw.dcn.watermarks, dc->res_pool->ref_clocks.dchub_ref_clock_inKhz /1000 , false);
@@ -2162,10 +2162,10 @@ void dcn20_prepare_bandwidth(if (hubbub->funcs->program_compbuf_size) {if (context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes) { compbuf_size_kb = context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes; - dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.dml.ip.min_comp_buffer_size_kbytes); + dc->optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.dml.ip.min_comp_buffer_size_kbytes); }else { compbuf_size_kb = context->bw_ctx.bw.dcn.compbuf_size_kb; - dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.bw.dcn.compbuf_size_kb); + dc->optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.bw.dcn.compbuf_size_kb); } hubbub->funcs->program_compbuf_size (hubbub, compbuf_size_kb, false);
Signature · 1 line
2.37.3
PATCH 5/25 drm/amd/display: Add function for dumping clk registers
In reply to Wayne LinFrom: Johnson Chen <[email protected]>
[why]
Allow devs to check raw clk register values by dumping them on the log
[how]
Add clk register dump implementation
--- .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 7 +++---- .../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +3 -4
@@ -50,6 +50,7 @@#include "dc_dmub_srv.h" #include "link.h" #include "logger_types.h" +#undef DC_LOGGER#define DC_LOGGER \ clk_mgr->base.base.ctx->logger
@@ -417,9 +418,8 @@ bool dcn35_are_clock_states_equal(struct dc_clocks *a, }static void dcn35_dump_clk_registers (struct clk_state_registers_and_bypass *regs_and_bypass, -struct clk_mgr *clk_mgr_base,struct clk_log_info *log_info) +struct clk_mgr_dcn35 *clk_mgr) { - }static struct clk_bw_params dcn35_bw_params = {
@@ -986,7 +986,6 @@ void dcn35_clk_mgr_construct( struct dccg *dccg) {struct dcn35_smu_dpm_clks smu_dpm_clks = {0 }; -struct clk_log_info log_info = {0 }; clk_mgr->base.base.ctx = ctx; clk_mgr->base.base.funcs = &dcn35_funcs;
@@ -1039,7 +1038,7 @@ void dcn35_clk_mgr_construct( dcn35_bw_params.wm_table = ddr5_wm_table; }/* Saved clocks configured at boot for debug purposes */ -dcn35_dump_clk_registers (&clk_mgr->base.base.boot_snapshot, &clk_mgr->base.base, &log_info); +dcn35_dump_clk_registers (&clk_mgr->base.base.boot_snapshot, clk_mgr); clk_mgr->base.base.dprefclk_khz =dcn35_smu_get_dprefclk (&clk_mgr->base); clk_mgr->base.base.clks.ref_dtbclk_khz =600000 ;
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +19 -0
@@ -62,6 +62,25 @@ struct dcn3_clk_internal {uint32_t CLK4_CLK0_CURRENT_CNT ;//fclk }; +struct dcn35_clk_internal { +int dummy; +uint32_t CLK1_CLK0_CURRENT_CNT;//dispclk +uint32_t CLK1_CLK1_CURRENT_CNT;//dppclk +uint32_t CLK1_CLK2_CURRENT_CNT;//dprefclk +uint32_t CLK1_CLK3_CURRENT_CNT;//dcfclk +uint32_t CLK1_CLK4_CURRENT_CNT;//dtbclk +//uint32_t CLK1_CLK5_CURRENT_CNT; //dpiaclk +//uint32_t CLK1_CLK6_CURRENT_CNT; //srdbgclk +uint32_t CLK1_CLK3_DS_CNTL;//dcf_deep_sleep_divider +uint32_t CLK1_CLK3_ALLOW_DS;//dcf_deep_sleep_allow + +uint32_t CLK1_CLK0_BYPASS_CNTL;//dispclk bypass +uint32_t CLK1_CLK1_BYPASS_CNTL;//dppclk bypass +uint32_t CLK1_CLK2_BYPASS_CNTL;//dprefclk bypass +uint32_t CLK1_CLK3_BYPASS_CNTL;//dcfclk bypass +uint32_t CLK1_CLK4_BYPASS_CNTL;//dtbclk bypass +}; +struct dcn301_clk_internal {int dummy;uint32_t CLK1_CLK0_CURRENT_CNT;//dispclk
Signature · 1 line
2.37.3
PATCH 6/25 drm/amd/display: Add case for dcn35 to support usb4 dmub hpd event
In reply to Wayne LinFrom: Wayne Lin <[email protected]>
[Why & how]
Refactor dc_is_dmub_outbox_supported() a bit and add case for dcn35 to register dmub outbox notification irq to handle usb4 relevant hpd event.
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 26 ++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +18 -8
@@ -5089,18 +5089,28 @@ void dc_mclk_switch_using_fw_based_vblank_stretch_shut_down(struct dc *dc)*/ bool dc_is_dmub_outbox_supported (struct dc *dc) { -/* DCN31 B0 USB4 DPIA needs dmub notifications for interrupts */ -if (dc->ctx->asic_id.chip_family ==FAMILY_YELLOW_CARP && - dc->ctx->asic_id.hw_internal_rev ==YELLOW_CARP_B0 && - !dc->debug.dpia_debug.bits.disable_dpia) -return true; +switch (dc->ctx->asic_id.chip_family) { -if (dc->ctx->asic_id.chip_family ==AMDGPU_FAMILY_GC_11_0_1 && - !dc->debug.dpia_debug.bits.disable_dpia) -return true; +case FAMILY_YELLOW_CARP : +/* DCN31 B0 USB4 DPIA needs dmub notifications for interrupts */ +if (dc->ctx->asic_id.hw_internal_rev ==YELLOW_CARP_B0 && + !dc->debug.dpia_debug.bits.disable_dpia) +return true; +break ; + +case AMDGPU_FAMILY_GC_11_0_1 : +case AMDGPU_FAMILY_GC_11_5_0 : +if (!dc->debug.dpia_debug.bits.disable_dpia) +return true; +break ; + +default : +break ; + }/* dmub aux needs dmub notifications to be enabled */ return dc->debug.enable_dmub_aux_for_legacy_ddc; + }/**
Signature · 1 line
2.37.3
PATCH 7/25 drm/amd/display: make flip_timestamp_in_us a 64-bit variable
In reply to Wayne LinFrom: Josip Pavic <[email protected]>
[Why]
This variable currently overflows after about 71 minutes. This doesn't cause any known functional issues but it does make debugging more difficult.
[How]
Make it a 64-bit variable.
--- drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dc_hw_types.h +1 -1
@@ -244,7 +244,7 @@ enum pixel_format {#define DC_MAX_DIRTY_RECTS 3struct dc_flip_addrs {struct dc_plane_address address; -unsigned int flip_timestamp_in_us; +unsigned long long flip_timestamp_in_us;bool flip_immediate;/* TODO: add flip duration for FreeSync */ bool triplebuffer_flips;
Signature · 1 line
2.37.3
PATCH 8/25 drm/amd/display: skip error logging when DMUB is inactive from S3
In reply to Wayne LinFrom: Samson Tam <[email protected]>
[Why]
On resume from S3, while DMUB is inactive, DMUB queue and execute calls will not work. Skip reporting errors in these scenarios
[How]
Add new return code during DMUB queue and execute calls when DMUB is in S3 state. Skip logging errors in these scenarios
--- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 34 +++++++++++++------ drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 1 + .../gpu/drm/amd/display/dmub/src/dmub_srv.c | 4 +-- 3 files changed, 27 insertions(+), 12 deletions(-)
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +24 -10
@@ -140,7 +140,10 @@ bool dc_dmub_srv_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_srv,if (status ==DMUB_STATUS_QUEUE_FULL ) {/* Execute and wait for queue to become empty again. */ -dmub_srv_cmd_execute (dmub); + status =dmub_srv_cmd_execute (dmub); +if (status ==DMUB_STATUS_POWER_STATE_D3 ) +return false; +dmub_srv_wait_for_idle (dmub,100000 );/* Requeue the command. */
@@ -148,16 +151,20 @@ bool dc_dmub_srv_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_srv, }if (status !=DMUB_STATUS_OK ) { -DC_ERROR ("Error queueing DMUB command: status=%d\n" , status); -dc_dmub_srv_log_diagnostic_data (dc_dmub_srv); +if (status !=DMUB_STATUS_POWER_STATE_D3 ) { +DC_ERROR ("Error queueing DMUB command: status=%d\n" , status); +dc_dmub_srv_log_diagnostic_data (dc_dmub_srv); + }return false; } } status =dmub_srv_cmd_execute (dmub);if (status !=DMUB_STATUS_OK ) { -DC_ERROR ("Error starting DMUB execution: status=%d\n" , status); -dc_dmub_srv_log_diagnostic_data (dc_dmub_srv); +if (status !=DMUB_STATUS_POWER_STATE_D3 ) { +DC_ERROR ("Error starting DMUB execution: status=%d\n" , status); +dc_dmub_srv_log_diagnostic_data (dc_dmub_srv); + }return false; }
@@ -218,7 +225,10 @@ bool dc_dmub_srv_cmd_run_list(struct dc_dmub_srv *dc_dmub_srv, unsigned int counif (status ==DMUB_STATUS_QUEUE_FULL ) {/* Execute and wait for queue to become empty again. */ -dmub_srv_cmd_execute (dmub); + status =dmub_srv_cmd_execute (dmub); +if (status ==DMUB_STATUS_POWER_STATE_D3 ) +return false; +dmub_srv_wait_for_idle (dmub,100000 );/* Requeue the command. */
@@ -226,16 +236,20 @@ bool dc_dmub_srv_cmd_run_list(struct dc_dmub_srv *dc_dmub_srv, unsigned int coun }if (status !=DMUB_STATUS_OK ) { -DC_ERROR ("Error queueing DMUB command: status=%d\n" , status); -dc_dmub_srv_log_diagnostic_data (dc_dmub_srv); +if (status !=DMUB_STATUS_POWER_STATE_D3 ) { +DC_ERROR ("Error queueing DMUB command: status=%d\n" , status); +dc_dmub_srv_log_diagnostic_data (dc_dmub_srv); + }return false; } } status =dmub_srv_cmd_execute (dmub);if (status !=DMUB_STATUS_OK ) { -DC_ERROR ("Error starting DMUB execution: status=%d\n" , status); -dc_dmub_srv_log_diagnostic_data (dc_dmub_srv); +if (status !=DMUB_STATUS_POWER_STATE_D3 ) { +DC_ERROR ("Error starting DMUB execution: status=%d\n" , status); +dc_dmub_srv_log_diagnostic_data (dc_dmub_srv); + }return false; }
drivers/gpu/drm/amd/display/dmub/dmub_srv.h +1 -0
@@ -86,6 +86,7 @@ enum dmub_status {DMUB_STATUS_TIMEOUT ,DMUB_STATUS_INVALID ,DMUB_STATUS_HW_FAILURE , + DMUB_STATUS_POWER_STATE_D3 };/* enum dmub_asic - dmub asic identifier */
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +2 -2
@@ -768,7 +768,7 @@ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub,return DMUB_STATUS_INVALID ;if (dmub->power_state !=DMUB_POWER_STATE_D0 ) -return DMUB_STATUS_INVALID ; +return DMUB_STATUS_POWER_STATE_D3 ;if (dmub->inbox1_rb.rptr > dmub->inbox1_rb.capacity || dmub->inbox1_rb.wrpt > dmub->inbox1_rb.capacity) {
@@ -789,7 +789,7 @@ enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub)return DMUB_STATUS_INVALID ;if (dmub->power_state !=DMUB_POWER_STATE_D0 ) -return DMUB_STATUS_INVALID ; +return DMUB_STATUS_POWER_STATE_D3 ;/** * Read back all the queued commands to ensure that they've
Signature · 1 line
2.37.3
PATCH 9/25 drm/amd/display: get dprefclk ss info from integration info table
In reply to Wayne LinFrom: Charlene Liu <[email protected]>
[why & how]
we have two SSC_En:
we get ssc_info from dce_info for MPLL_SSC_EN.
we used to call VBIOS cmdtbl's smu_info's SS persentage for DPRECLK SS info, is used for DP AUDIO and VBIOS' smu_info table was from systemIntegrationInfoTable.
since dcn35 VBIOS removed smu_info, driver need to use integrationInfotable directly.
--- .../drm/amd/display/dc/bios/bios_parser2.c | 19 ++++++++++++++----- .../display/include/grph_object_ctrl_defs.h | 2 ++ 2 files changed, 16 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +14 -5
@@ -1014,13 +1014,20 @@ static enum bp_result get_ss_info_v4_5(DC_LOG_BIOS ("AS_SIGNAL_TYPE_HDMI ss_percentage: %d\n" , ss_info->spread_spectrum_percentage);break ;case AS_SIGNAL_TYPE_DISPLAY_PORT : - ss_info->spread_spectrum_percentage = +if (bp->base.integrated_info) { +DC_LOG_BIOS ("gpuclk_ss_percentage (unit of 0.001 percent): %d\n" , bp->base.integrated_info->gpuclk_ss_percentage); + ss_info->spread_spectrum_percentage = + bp->base.integrated_info->gpuclk_ss_percentage; + ss_info->type.CENTER_MODE = + bp->base.integrated_info->gpuclk_ss_type; + }else { + ss_info->spread_spectrum_percentage = disp_cntl_tbl->dp_ss_percentage; - ss_info->spread_spectrum_range = + ss_info->spread_spectrum_range = disp_cntl_tbl->dp_ss_rate_10hz *10 ; -if (disp_cntl_tbl->dp_ss_mode &ATOM_SS_CENTRE_SPREAD_MODE ) - ss_info->type.CENTER_MODE = true; - +if (disp_cntl_tbl->dp_ss_mode &ATOM_SS_CENTRE_SPREAD_MODE ) + ss_info->type.CENTER_MODE = true; + }DC_LOG_BIOS ("AS_SIGNAL_TYPE_DISPLAY_PORT ss_percentage: %d\n" , ss_info->spread_spectrum_percentage);break ;case AS_SIGNAL_TYPE_GPU_PLL :
@@ -2813,6 +2820,8 @@ static enum bp_result get_integrated_info_v2_2( info->ma_channel_number = info_v2_2->umachannelnumber; info->dp_ss_control =le16_to_cpu (info_v2_2->reserved1); + info->gpuclk_ss_percentage = info_v2_2->gpuclk_ss_percentage; + info->gpuclk_ss_type = info_v2_2->gpuclk_ss_type;for (i =0 ; i <NUMBER_OF_UCHAR_FOR_GUID ; ++i) { info->ext_disp_conn_info.gu_id[i] =
drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h +2 -0
@@ -417,6 +417,8 @@ struct integrated_info {/* V2.1 */ struct edp_info edp1_info;struct edp_info edp2_info; +uint32_t gpuclk_ss_percentage; +uint32_t gpuclk_ss_type; };/*
Signature · 1 line
2.37.3
PATCH 10/25 drm/amd/display: dereference variable before checking for zero
In reply to Wayne LinFrom: Josip Pavic <[email protected]>
[Why]
Driver incorrectly checks if pointer variable OutBpp is null instead of if the value being pointed to is zero.
[How]
Dereference OutBpp before checking for a value of zero.
--- drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c +1 -1
@@ -5420,7 +5420,7 @@ static void CalculateOutputLink( *OutBpp =TruncToValidBPP ((1 - Downspreading /100 ) *13500 , OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (dml_uint_t )AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots); -if (OutBpp ==0 && PHYCLKD32PerState <20000 /32 && DSCEnable == dml_dsc_enable_if_necessary && ForcedOutputLinkBPP ==0 ) { +if (*OutBpp ==0 && PHYCLKD32PerState <20000 /32 && DSCEnable == dml_dsc_enable_if_necessary && ForcedOutputLinkBPP ==0 ) { *RequiresDSC = true; LinkDSCEnable = true; *OutBpp = TruncToValidBPP((1 - Downspreading / 100) * 13500, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output,
Signature · 1 line
2.37.3
PATCH 11/25 drm/amd/display: Set test_pattern_changed update flag on pipe enable
In reply to Wayne LinFrom: George Shen <[email protected]>
[Why]
In certain cases, ODM pipe split can occur while stream already has test pattern enabled. The new pipe used in the ODM combine config must be configured to output the test pattern in this case.
[How]
If the stream is configured to output test pattern, then set the test_pattern_changed update flag for the new pipe when it gets enabled.
--- drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +4 -0
@@ -1400,6 +1400,10 @@ static void dcn20_detect_pipe_changes(struct pipe_ctx *old_pipe, struct pipe_ctx new_pipe->update_flags.bits.scaler =1 ; new_pipe->update_flags.bits.viewport =1 ; new_pipe->update_flags.bits.det_size =1 ; +if (new_pipe->stream->test_pattern.type !=DP_TEST_PATTERN_VIDEO_MODE && + new_pipe->stream_res.test_pattern_params.width !=0 && + new_pipe->stream_res.test_pattern_params.height !=0 ) + new_pipe->update_flags.bits.test_pattern_changed =1 ;if (!new_pipe->top_pipe && !new_pipe->prev_odm_pipe) { new_pipe->update_flags.bits.odm =1 ; new_pipe->update_flags.bits.global_sync =1 ;
Signature · 1 line
2.37.3
PATCH 12/25 drm/amd/display: add debug option for ExtendedVBlank DLG adjust
In reply to Wayne LinFrom: Muhammad Ahmed <[email protected]>
[why & how]
Add new option for debug usage
--- drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dc.h +1 -0
@@ -979,6 +979,7 @@ struct dc_debug_options {unsigned int ips2_eval_delay_us;unsigned int ips2_entry_delay_us;bool disable_timeout; +bool disable_extblankadj; };struct gpu_info_soc_bounding_box_v1_0 ;
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +2 -1
@@ -2221,7 +2221,8 @@ void dcn20_optimize_bandwidth( dc->clk_mgr, context, true); -if (context->bw_ctx.bw.dcn.clk.zstate_support ==DCN_ZSTATE_SUPPORT_ALLOW ) { +if (context->bw_ctx.bw.dcn.clk.zstate_support ==DCN_ZSTATE_SUPPORT_ALLOW && + !dc->debug.disable_extblankadj) {for (i =0 ; i < dc->res_pool->pipe_count; ++i) {struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
Signature · 1 line
2.37.3
PATCH 13/25 drm/amd/display: fix usb-c connector_type
In reply to Wayne LinFrom: Allen Pan <[email protected]>
[why]
BIOS switches to use USB-C connector type 0x18, but VBIOS's objectInfo table not supported yet. driver needs to patch it based on enc_cap from system integration info table.
--- .../gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c +5 -0
@@ -256,6 +256,10 @@ void dcn35_link_encoder_construct( enc10->base.features.flags.bits.IS_UHBR10_CAPABLE = bp_cap_info.DP_UHBR10_EN; enc10->base.features.flags.bits.IS_UHBR13_5_CAPABLE = bp_cap_info.DP_UHBR13_5_EN; enc10->base.features.flags.bits.IS_UHBR20_CAPABLE = bp_cap_info.DP_UHBR20_EN; +if (bp_cap_info.DP_IS_USB_C) { +/*BIOS not switch to use CONNECTOR_ID_USBC = 24 yet*/ + enc10->base.features.flags.bits.DP_IS_USB_C =1 ; + } }else { DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
@@ -264,4 +268,5 @@ void dcn35_link_encoder_construct( }if (enc10->base.ctx->dc->debug.hdmi20_disable) enc10->base.features.flags.bits.HDMI_6GB_EN =0 ; + }
Signature · 1 line
2.37.3
PATCH 14/25 drm/amd/display: enable dcn35 idle power optimization
In reply to Wayne LinFrom: Roman Li <[email protected]>
[Why]
Idle power optimization was disabled on dcn35 by default.
[How]
Enable by setting disable_idle_power_optimizations to false.
--- drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +1 -1
@@ -766,7 +766,7 @@ static const struct dc_debug_options debug_defaults_drv = { .enable_hpo_pg_support = false, .enable_legacy_fast_update = true, .enable_single_display_2to1_odm_policy = false, - .disable_idle_power_optimizations = true, + .disable_idle_power_optimizations = false, .dmcub_emulation = false, .disable_boot_optimizations = false, .disable_unbounded_requesting = false,
Signature · 1 line
2.37.3
PATCH 15/25 drm/amd/display: Refactor DMCUB enter/exit idle interface
In reply to Wayne LinFrom: Nicholas Kazlauskas <[email protected]>
[Why]
We can hang in place trying to send commands when the DMCUB isn't powered on.
[How]
We need to exit out of the idle state prior to sending a command, but the process that performs the exit also invokes a command itself.
Fixing this issue involves the following:
1. Using a software state to track whether or not we need to start the process to exit idle or notify idle.
It's possible for the hardware to have exited an idle state without driver knowledge, but entering one is always restricted to a driver allow - which makes the SW state vs HW state mismatch issue purely one of optimization, which should seldomly be hit, if at all.
2. Refactor any instances of exit/notify idle to use a single wrapper that maintains this SW state.
This works simialr to dc_allow_idle_optimizations, but works at the DMCUB level and makes sure the state is marked prior to any notify/exit idle so we don't enter an infinite loop.
3. Make sure we exit out of idle prior to sending any commands or waiting for DMCUB idle.
This patch takes care of 1/2. A future patch will take care of wrapping DMCUB command submission with calls to this new interface.
--- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 37 ++++++++++++++++++- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 6 ++- .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 8 +--- 4 files changed, 43 insertions(+), 12 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +2 -2
@@ -2854,7 +2854,7 @@ static int dm_resume(void *handle)bool need_hotplug = false;if (dm->dc->caps.ips_support) { -dc_dmub_srv_exit_low_power_state (dm->dc); +dc_dmub_srv_apply_idle_power_optimizations (dm->dc, false); }if (amdgpu_in_reset (adev)) {
@@ -8968,7 +8968,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)if (new_con_state->crtc && new_con_state->crtc->state->active &&drm_atomic_crtc_needs_modeset (new_con_state->crtc->state)) { -dc_dmub_srv_exit_low_power_state (dm->dc); +dc_dmub_srv_apply_idle_power_optimizations (dm->dc, false);break ; } }
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +35 -2
@@ -1162,6 +1162,9 @@ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait)struct dc_context *dc_ctx = dc_dmub_srv->ctx;enum dmub_status status; +if (!dc_dmub_srv || !dc_dmub_srv->dmub) +return true; +if (dc_dmub_srv->ctx->dc->debug.dmcub_emulation)return true;
@@ -1183,7 +1186,7 @@ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait)return true; } -void dc_dmub_srv_notify_idle (const struct dc *dc,bool allow_idle) +static void dc_dmub_srv_notify_idle (const struct dc *dc,bool allow_idle) {union dmub_rb_cmd cmd = {0 };
@@ -1207,7 +1210,7 @@ void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle)dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); } -void dc_dmub_srv_exit_low_power_state (const struct dc *dc) +static void dc_dmub_srv_exit_low_power_state (const struct dc *dc) {const uint32_t max_num_polls =10000 ;uint32_t allow_state =0 ;
@@ -1220,6 +1223,9 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc)if (!dc->idle_optimizations_allowed)return ; +if (!dc->ctx->dmub_srv || !dc->ctx->dmub_srv->dmub) +return ; +if (dc->hwss.get_idle_state && dc->hwss.set_idle_state && dc->clk_mgr->funcs->exit_low_power_state) {
@@ -1296,3 +1302,30 @@ void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_celse dmub_srv_set_power_state (dmub,DMUB_POWER_STATE_D3 ); } + +void dc_dmub_srv_apply_idle_power_optimizations (const struct dc *dc,bool allow_idle) +{ +struct dc_dmub_srv *dc_dmub_srv = dc->ctx->dmub_srv; + +if (!dc_dmub_srv || !dc_dmub_srv->dmub) +return ; + +if (dc_dmub_srv->idle_allowed == allow_idle) +return ; + +/* +* Entering a low power state requires a driver notification. +* Powering up the hardware requires notifying PMFW and DMCUB. +* Clearing the driver idle allow requires a DMCUB command. +* DMCUB commands requires the DMCUB to be powered up and restored. +* +* Exit out early to prevent an infinite loop of DMCUB commands +* triggering exit low power - use software state to track this. +*/ + dc_dmub_srv->idle_allowed = allow_idle; + +if (!allow_idle) +dc_dmub_srv_exit_low_power_state (dc); +else +dc_dmub_srv_notify_idle (dc, allow_idle); +}
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h +4 -2
@@ -50,6 +50,8 @@ struct dc_dmub_srv {struct dc_context *ctx;void *dm; + +bool idle_allowed; };void dc_dmub_srv_wait_idle (struct dc_dmub_srv *dc_dmub_srv);
@@ -100,8 +102,8 @@ void dc_dmub_srv_enable_dpia_trace(const struct dc *dc);void dc_dmub_srv_subvp_save_surf_addr (const struct dc_dmub_srv *dc_dmub_srv,const struct dc_plane_address *addr,uint8_t subvp_index);bool dc_dmub_srv_is_hw_pwr_up (struct dc_dmub_srv *dc_dmub_srv,bool wait); -void dc_dmub_srv_notify_idle (const struct dc *dc,bool allow_idle); -void dc_dmub_srv_exit_low_power_state (const struct dc *dc); + +void dc_dmub_srv_apply_idle_power_optimizations (const struct dc *dc,bool allow_idle);void dc_dmub_srv_set_power_state (struct dc_dmub_srv *dc_dmub_srv,enum dc_acpi_cm_power_state powerState);#endif /* _DMUB_DC_SRV_H_ */
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +2 -6
@@ -687,11 +687,7 @@ bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable) }// TODO: review other cases when idle optimization is allowed - -if (!enable) -dc_dmub_srv_exit_low_power_state (dc); -else -dc_dmub_srv_notify_idle (dc, enable); +dc_dmub_srv_apply_idle_power_optimizations (dc, enable);return true; }
@@ -701,7 +697,7 @@ void dcn35_z10_restore(const struct dc *dc)if (dc->debug.disable_z10)return ; -dc_dmub_srv_exit_low_power_state (dc); +dc_dmub_srv_apply_idle_power_optimizations (dc, false);dcn31_z10_restore (dc); }
Signature · 1 line
2.37.3
PATCH 16/25 drm/amd/display: Wake DMCUB before sending a command
In reply to Wayne LinFrom: Nicholas Kazlauskas <[email protected]>
[Why]
We can hang in place trying to send commands when the DMCUB isn't powered on.
[How]
For functions that execute within a DC context or DC lock we can wrap the direct calls to dm_execute_dmub_cmd/list with code that exits idle power optimizations and reallows once we're done with the command submission on success.
For DM direct submissions the DM will need to manage the enter/exit sequencing manually.
We cannot invoke a DMCUB command directly within the DM execution helper or we can deadlock.
--- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- .../drm/amd/display/dc/bios/command_table2.c | 12 ++--- .../display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c | 2 +- .../dc/clk_mgr/dcn314/dcn314_clk_mgr.c | 2 +- .../dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 2 +- .../dc/clk_mgr/dcn316/dcn316_clk_mgr.c | 2 +- .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 2 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 12 ++--- .../drm/amd/display/dc/core/dc_hw_sequencer.c | 2 +- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 53 ++++++++++++++++--- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 40 ++++++++++++++ drivers/gpu/drm/amd/display/dc/dc_helper.c | 6 +-- .../gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c | 14 ++--- .../drm/amd/display/dc/dce/dmub_hw_lock_mgr.c | 2 +- .../gpu/drm/amd/display/dc/dce/dmub_outbox.c | 2 +- drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 14 ++--- .../gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c | 2 +- .../display/dc/dcn31/dcn31_dio_link_encoder.c | 4 +- .../amd/display/dc/dcn31/dcn31_panel_cntl.c | 4 +- .../amd/display/dc/hwss/dcn21/dcn21_hwseq.c | 4 +- .../amd/display/dc/hwss/dcn30/dcn30_hwseq.c | 8 +-- .../amd/display/dc/hwss/dcn31/dcn31_hwseq.c | 4 +- .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 6 +-- .../dc/link/protocols/link_dp_capability.c | 2 +- .../display/dc/link/protocols/link_dp_dpia.c | 3 +- 25 files changed, 143 insertions(+), 63 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +1 -1
@@ -10860,7 +10860,7 @@ static bool dm_edid_parser_send_cea(struct amdgpu_display_manager *dm, input->cea_total_length = total_length;memcpy (input->payload, data, length); - res =dm_execute_dmub_cmd (dm->dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY ); + res =dc_wake_and_execute_dmub_cmd (dm->dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY );if (!res) {DRM_ERROR ("EDID CEA parser failed\n" );return false;
drivers/gpu/drm/amd/display/dc/bios/command_table2.c +6 -6
@@ -123,7 +123,7 @@ static void encoder_control_dmcub(sizeof (cmd.digx_encoder_control.header); cmd.digx_encoder_control.encoder_control.dig.stream_param = *dig; -dm_execute_dmub_cmd (dmcub->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dmcub->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); } static enum bp_result encoder_control_digx_v1_5(
@@ -259,7 +259,7 @@ static void transmitter_control_dmcub(sizeof (cmd.dig1_transmitter_control.header); cmd.dig1_transmitter_control.transmitter_control.dig = *dig; -dm_execute_dmub_cmd (dmcub->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dmcub->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); } static enum bp_result transmitter_control_v1_6(
@@ -321,7 +321,7 @@ static void transmitter_control_dmcub_v1_7(sizeof (cmd.dig1_transmitter_control.header); cmd.dig1_transmitter_control.transmitter_control.dig_v1_7 = *dig; -dm_execute_dmub_cmd (dmcub->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dmcub->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); } static enum bp_result transmitter_control_v1_7(
@@ -429,7 +429,7 @@ static void set_pixel_clock_dmcub(sizeof (cmd.set_pixel_clock.header); cmd.set_pixel_clock.pixel_clock.clk = *clk; -dm_execute_dmub_cmd (dmcub->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dmcub->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); } static enum bp_result set_pixel_clock_v7(
@@ -796,7 +796,7 @@ static void enable_disp_power_gating_dmcub(sizeof (cmd.enable_disp_power_gating.header); cmd.enable_disp_power_gating.power_gating.pwr = *pwr; -dm_execute_dmub_cmd (dmcub->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dmcub->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); } static enum bp_result enable_disp_power_gating_v2_1(
@@ -1006,7 +1006,7 @@ static void enable_lvtma_control_dmcub( pwrseq_instance; cmd.lvtma_control.data.bypass_panel_control_wait = bypass_panel_control_wait; -dm_execute_dmub_cmd (dmcub->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dmcub->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); } static enum bp_result enable_lvtma_control(
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c +1 -1
@@ -253,7 +253,7 @@ void dcn31_update_clocks(struct clk_mgr *clk_mgr_base, cmd.notify_clocks.clocks.dispclk_khz = clk_mgr_base->clks.dispclk_khz; cmd.notify_clocks.clocks.dppclk_khz = clk_mgr_base->clks.dppclk_khz; -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); }static int get_vco_frequency_from_reg (struct clk_mgr_internal *clk_mgr)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c +1 -1
@@ -284,7 +284,7 @@ void dcn314_update_clocks(struct clk_mgr *clk_mgr_base, cmd.notify_clocks.clocks.dispclk_khz = clk_mgr_base->clks.dispclk_khz; cmd.notify_clocks.clocks.dppclk_khz = clk_mgr_base->clks.dppclk_khz; -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); }static int get_vco_frequency_from_reg (struct clk_mgr_internal *clk_mgr)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +1 -1
@@ -232,7 +232,7 @@ static void dcn315_update_clocks(struct clk_mgr *clk_mgr_base, cmd.notify_clocks.clocks.dispclk_khz = clk_mgr_base->clks.dispclk_khz; cmd.notify_clocks.clocks.dppclk_khz = clk_mgr_base->clks.dppclk_khz; -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); } static void dcn315_dump_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass,
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c +1 -1
@@ -239,7 +239,7 @@ static void dcn316_update_clocks(struct clk_mgr *clk_mgr_base, cmd.notify_clocks.clocks.dispclk_khz = clk_mgr_base->clks.dispclk_khz; cmd.notify_clocks.clocks.dppclk_khz = clk_mgr_base->clks.dppclk_khz; -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); } static void dcn316_dump_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass,
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +1 -1
@@ -343,7 +343,7 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base, cmd.notify_clocks.clocks.dispclk_khz = clk_mgr_base->clks.dispclk_khz; cmd.notify_clocks.clocks.dppclk_khz = clk_mgr_base->clks.dppclk_khz; -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); }static int get_vco_frequency_from_reg (struct clk_mgr_internal *clk_mgr)
drivers/gpu/drm/amd/display/dc/core/dc.c +6 -6
@@ -522,7 +522,7 @@ dc_stream_forward_dmub_crc_window(struct dc_dmub_srv *dmub_srv, cmd.secure_display.roi_info.y_end = rect->y + rect->height; } -dm_execute_dmub_cmd (dmub_srv->ctx, &cmd,DM_DMUB_WAIT_TYPE_NO_WAIT ); +dc_wake_and_execute_dmub_cmd (dmub_srv->ctx, &cmd,DM_DMUB_WAIT_TYPE_NO_WAIT ); } static inline void
@@ -3381,7 +3381,7 @@ void dc_dmub_update_dirty_rect(struct dc *dc, update_dirty_rect->panel_inst = panel_inst; update_dirty_rect->pipe_idx = j; -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_NO_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_NO_WAIT ); } } }
@@ -5207,7 +5207,7 @@ bool dc_process_dmub_aux_transfer_async(struct dc *dc, ); } -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT );return true; }
@@ -5261,7 +5261,7 @@ bool dc_process_dmub_set_config_async(struct dc *dc, cmd.set_config_access.set_config_control.cmd_pkt.msg_type = payload->msg_type; cmd.set_config_access.set_config_control.cmd_pkt.msg_data = payload->msg_data; -if (!dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY )) { +if (!dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY )) {/* command is not processed by dmub */ notify->sc_status =SET_CONFIG_UNKNOWN_ERROR ;return is_cmd_complete;
@@ -5304,7 +5304,7 @@ enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc, cmd.set_mst_alloc_slots.mst_slots_control.instance = dc->links[link_index]->ddc_hw_inst; cmd.set_mst_alloc_slots.mst_slots_control.mst_alloc_slots = mst_alloc_slots; -if (!dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY )) +if (!dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY ))/* command is not processed by dmub */ return DC_ERROR_UNEXPECTED ;
@@ -5342,7 +5342,7 @@ void dc_process_dmub_dpia_hpd_int_enable(const struct dc *dc, cmd.dpia_hpd_int_enable.header.type =DMUB_CMD__DPIA_HPD_INT_ENABLE ; cmd.dpia_hpd_int_enable.enable = hpd_int_enable; -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT );DC_LOG_DEBUG ("%s: hpd_int_enable(%d)\n" , __func__, hpd_int_enable); }
drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +1 -1
@@ -724,7 +724,7 @@ void hwss_send_dmcub_cmd(union block_sequence_params *params)union dmub_rb_cmd *cmd = params->send_dmcub_cmd_params.cmd;enum dm_dmub_wait_type wait_type = params->send_dmcub_cmd_params.wait_type; -dm_execute_dmub_cmd (ctx, cmd, wait_type); +dc_wake_and_execute_dmub_cmd (ctx, cmd, wait_type); }void hwss_program_manual_trigger (union block_sequence_params *params)
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +46 -7
104 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h +40 -0
@@ -106,4 +106,44 @@ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait);void dc_dmub_srv_apply_idle_power_optimizations (const struct dc *dc,bool allow_idle);void dc_dmub_srv_set_power_state (struct dc_dmub_srv *dc_dmub_srv,enum dc_acpi_cm_power_state powerState); + +/** +* dc_wake_and_execute_dmub_cmd() - Wrapper for DMUB command execution. +* +* Refer to dc_wake_and_execute_dmub_cmd_list() for usage and limitations, +* This function is a convenience wrapper for a single command execution. +* +* @ctx: DC context +* @cmd: The command to send/receive +* @wait_type: The wait behavior for the execution +* +* Return: true on command submission success, false otherwise +*/ +bool dc_wake_and_execute_dmub_cmd (const struct dc_context *ctx,union dmub_rb_cmd *cmd, +enum dm_dmub_wait_type wait_type); + +/** +* dc_wake_and_execute_dmub_cmd_list() - Wrapper for DMUB command list execution. +* +* If the DMCUB hardware was asleep then it wakes the DMUB before +* executing the command and attempts to re-enter if the command +* submission was successful. +* +* This should be the preferred command submission interface provided +* the DC lock is acquired. +* +* Entry/exit out of idle power optimizations would need to be +* manually performed otherwise through dc_allow_idle_optimizations(). +* +* @ctx: DC context +* @count: Number of commands to send/receive +* @cmd: Array of commands to send +* @wait_type: The wait behavior for the execution +* +* Return: true on command submission success, false otherwise +*/ +bool dc_wake_and_execute_dmub_cmd_list (const struct dc_context *ctx,unsigned int count, +union dmub_rb_cmd *cmd,enum dm_dmub_wait_type wait_type); + +#endif /* _DMUB_DC_SRV_H_ */
drivers/gpu/drm/amd/display/dc/dc_helper.c +3 -3
@@ -50,7 +50,7 @@ static inline void submit_dmub_read_modify_write( cmd_buf->header.payload_bytes =sizeof (struct dmub_cmd_read_modify_write_sequence ) * offload->reg_seq_count; -dm_execute_dmub_cmd (ctx, &offload->cmd_data,DM_DMUB_WAIT_TYPE_NO_WAIT ); +dc_wake_and_execute_dmub_cmd (ctx, &offload->cmd_data,DM_DMUB_WAIT_TYPE_NO_WAIT );memset (cmd_buf,0 ,sizeof (*cmd_buf));
@@ -67,7 +67,7 @@ static inline void submit_dmub_burst_write( cmd_buf->header.payload_bytes =sizeof (uint32_t ) * offload->reg_seq_count; -dm_execute_dmub_cmd (ctx, &offload->cmd_data,DM_DMUB_WAIT_TYPE_NO_WAIT ); +dc_wake_and_execute_dmub_cmd (ctx, &offload->cmd_data,DM_DMUB_WAIT_TYPE_NO_WAIT );memset (cmd_buf,0 ,sizeof (*cmd_buf));
@@ -80,7 +80,7 @@ static inline void submit_dmub_reg_wait( {struct dmub_rb_cmd_reg_wait *cmd_buf = &offload->cmd_data.reg_wait; -dm_execute_dmub_cmd (ctx, &offload->cmd_data,DM_DMUB_WAIT_TYPE_NO_WAIT ); +dc_wake_and_execute_dmub_cmd (ctx, &offload->cmd_data,DM_DMUB_WAIT_TYPE_NO_WAIT );memset (cmd_buf,0 ,sizeof (*cmd_buf)); offload->reg_seq_count =0 ;
drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c +7 -7
@@ -76,7 +76,7 @@ static void dmub_abm_enable_fractional_pwm(struct dc_context *dc) cmd.abm_set_pwm_frac.abm_set_pwm_frac_data.panel_mask = panel_mask; cmd.abm_set_pwm_frac.header.payload_bytes =sizeof (struct dmub_cmd_abm_set_pwm_frac_data ); -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); }void dmub_abm_init (struct abm *abm,uint32_t backlight)
@@ -155,7 +155,7 @@ bool dmub_abm_set_level(struct abm *abm, uint32_t level, uint8_t panel_mask) cmd.abm_set_level.abm_set_level_data.panel_mask = panel_mask; cmd.abm_set_level.header.payload_bytes =sizeof (struct dmub_cmd_abm_set_level_data ); -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT );return true; }
@@ -186,7 +186,7 @@ void dmub_abm_init_config(struct abm *abm, cmd.abm_init_config.header.payload_bytes =sizeof (struct dmub_cmd_abm_init_config_data ); -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); }
@@ -203,7 +203,7 @@ bool dmub_abm_set_pause(struct abm *abm, bool pause, unsigned int panel_inst, un cmd.abm_pause.abm_pause_data.panel_mask = panel_mask; cmd.abm_set_level.header.payload_bytes =sizeof (struct dmub_cmd_abm_pause_data ); -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT );return true; }
@@ -246,7 +246,7 @@ bool dmub_abm_save_restore( cmd.abm_save_restore.header.payload_bytes =sizeof (struct dmub_rb_cmd_abm_save_restore ); -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT );// Copy iramtable data into local structure memcpy ((void *)pData, dc->dmub_srv->dmub->scratch_mem_fb.cpu_addr, bytes);
@@ -274,7 +274,7 @@ bool dmub_abm_set_pipe(struct abm *abm, cmd.abm_set_pipe.abm_set_pipe_data.ramping_boundary = ramping_boundary; cmd.abm_set_pipe.header.payload_bytes =sizeof (struct dmub_cmd_abm_set_pipe_data ); -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT );return true; }
@@ -296,7 +296,7 @@ bool dmub_abm_set_backlight_level(struct abm *abm, cmd.abm_set_backlight.abm_set_backlight_data.panel_mask = (0x01 << panel_inst); cmd.abm_set_backlight.header.payload_bytes =sizeof (struct dmub_cmd_abm_set_backlight_data ); -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT );return true; }
drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c +1 -1
@@ -47,7 +47,7 @@ void dmub_hw_lock_mgr_cmd(struct dc_dmub_srv *dmub_srv,if (!lock) cmd.lock_hw.lock_hw_data.should_release =1 ; -dm_execute_dmub_cmd (dmub_srv->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dmub_srv->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); } void dmub_hw_lock_mgr_inbox0_cmd(struct dc_dmub_srv *dmub_srv,
drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c +1 -1
@@ -48,5 +48,5 @@ void dmub_enable_outbox_notification(struct dc_dmub_srv *dmub_srv)sizeof (cmd.outbox1_enable.header); cmd.outbox1_enable.enable = true; -dm_execute_dmub_cmd (dmub_srv->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dmub_srv->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); }
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +7 -7
@@ -171,7 +171,7 @@ static bool dmub_psr_set_version(struct dmub_psr *dmub, struct dc_stream_state * cmd.psr_set_version.psr_set_version_data.panel_inst = panel_inst; cmd.psr_set_version.header.payload_bytes =sizeof (struct dmub_cmd_psr_set_version_data ); -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT );return true; }
@@ -199,7 +199,7 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait, uint8 cmd.psr_enable.header.payload_bytes =0 ;// Send header only -dm_execute_dmub_cmd (dc->dmub_srv->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->dmub_srv->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT );/* Below loops 1000 x 500us = 500 ms. * Exit PSR may need to wait 1-2 frames to power up. Timeout after at
@@ -248,7 +248,7 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level, uint8_ cmd.psr_set_level.psr_set_level_data.psr_level = psr_level; cmd.psr_set_level.psr_set_level_data.cmd_version =DMUB_CMD_PSR_CONTROL_VERSION_1 ; cmd.psr_set_level.psr_set_level_data.panel_inst = panel_inst; -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); }/*
@@ -267,7 +267,7 @@ static void dmub_psr_set_sink_vtotal_in_psr_active(struct dmub_psr *dmub, cmd.psr_set_vtotal.psr_set_vtotal_data.psr_vtotal_idle = psr_vtotal_idle; cmd.psr_set_vtotal.psr_set_vtotal_data.psr_vtotal_su = psr_vtotal_su; -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); }/*
@@ -286,7 +286,7 @@ static void dmub_psr_set_power_opt(struct dmub_psr *dmub, unsigned int power_opt cmd.psr_set_power_opt.psr_set_power_opt_data.power_opt = power_opt; cmd.psr_set_power_opt.psr_set_power_opt_data.panel_inst = panel_inst; -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); }/*
@@ -423,7 +423,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub, copy_settings_data->relock_delay_frame_cnt =2 ; copy_settings_data->dsc_slice_height = psr_context->dsc_slice_height; -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT );return true; }
@@ -444,7 +444,7 @@ static void dmub_psr_force_static(struct dmub_psr *dmub, uint8_t panel_inst) cmd.psr_force_static.header.sub_type =DMUB_CMD__PSR_FORCE_STATIC ; cmd.psr_enable.header.payload_bytes =0 ; -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); }/*
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c +1 -1
@@ -691,7 +691,7 @@ static void dmcub_PLAT_54186_wa(struct hubp *hubp, cmd.PLAT_54186_wa.flip.flip_params.vmid = flip_regs->vmid;PERF_TRACE ();// TODO: remove after performance is stable. -dm_execute_dmub_cmd (hubp->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (hubp->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT );PERF_TRACE ();// TODO: remove after performance is stable. }
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c +2 -2
@@ -125,7 +125,7 @@ static bool query_dp_alt_from_dmub(struct link_encoder *enc, cmd->query_dp_alt.header.payload_bytes =sizeof (cmd->query_dp_alt.data); cmd->query_dp_alt.data.phy_id =phy_id_from_transmitter (enc10->base.transmitter); -if (!dm_execute_dmub_cmd (enc->ctx, cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY )) +if (!dc_wake_and_execute_dmub_cmd (enc->ctx, cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY ))return false;return true;
@@ -436,7 +436,7 @@ static bool link_dpia_control(struct dc_context *dc_ctx, cmd.dig1_dpia_control.dpia_control = *dpia_control; -dm_execute_dmub_cmd (dc_ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc_ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT );return true; }
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_panel_cntl.c +2 -2
@@ -52,7 +52,7 @@ static bool dcn31_query_backlight_info(struct panel_cntl *panel_cntl, union dmub cmd->panel_cntl.header.payload_bytes =sizeof (cmd->panel_cntl.data); cmd->panel_cntl.data.pwrseq_inst = dcn31_panel_cntl->base.pwrseq_inst; -return dm_execute_dmub_cmd (dc_dmub_srv->ctx, cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY ); +return dc_wake_and_execute_dmub_cmd (dc_dmub_srv->ctx, cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY ); }static uint32_t dcn31_get_16_bit_backlight_from_pwm (struct panel_cntl *panel_cntl)
@@ -85,7 +85,7 @@ static uint32_t dcn31_panel_cntl_hw_init(struct panel_cntl *panel_cntl) panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV; cmd.panel_cntl.data.bl_pwm_ref_div2 = panel_cntl->stored_backlight_registers.PANEL_PWRSEQ_REF_DIV2; -if (!dm_execute_dmub_cmd (dc_dmub_srv->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY )) +if (!dc_wake_and_execute_dmub_cmd (dc_dmub_srv->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY ))return 0 ; panel_cntl->stored_backlight_registers.BL_PWM_CNTL = cmd.panel_cntl.data.bl_pwm_cntl;
drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c +2 -2
@@ -154,7 +154,7 @@ static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, cmd.abm_set_pipe.abm_set_pipe_data.ramping_boundary = ramping_boundary; cmd.abm_set_pipe.header.payload_bytes =sizeof (struct dmub_cmd_abm_set_pipe_data ); -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT );return true; }
@@ -173,7 +173,7 @@ static void dmub_abm_set_backlight(struct dc_context *dc, uint32_t backlight_pwm cmd.abm_set_backlight.abm_set_backlight_data.panel_mask = (0x01 << panel_inst); cmd.abm_set_backlight.header.payload_bytes =sizeof (struct dmub_cmd_abm_set_backlight_data ); -dm_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); }void dcn21_set_abm_immediate_disable (struct pipe_ctx *pipe_ctx)
drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c +4 -4
@@ -754,7 +754,7 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) cmd.mall.header.sub_type =DMUB_CMD__MALL_ACTION_NO_DF_REQ ; cmd.mall.header.payload_bytes =sizeof (cmd.mall) -sizeof (cmd.mall.header); -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_NO_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_NO_WAIT );return true; }
@@ -876,7 +876,7 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) cmd.mall.cursor_height = cursor_attr.height; cmd.mall.cursor_pitch = cursor_attr.pitch; -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT );/* Use copied cursor, and it's okay to not switch back */ cursor_attr.address.quad_part = cmd.mall.cursor_copy_dst.quad_part;
@@ -892,7 +892,7 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) cmd.mall.tmr_scale = tmr_scale; cmd.mall.debug_bits = dc->debug.mall_error_as_fatal; -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_NO_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_NO_WAIT );return true; }
@@ -909,7 +909,7 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) cmd.mall.header.payload_bytes =sizeof (cmd.mall) -sizeof (cmd.mall.header); -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT );return true; }
drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c +2 -2
@@ -416,7 +416,7 @@ void dcn31_z10_save_init(struct dc *dc) cmd.dcn_restore.header.type =DMUB_CMD__IDLE_OPT ; cmd.dcn_restore.header.sub_type =DMUB_CMD__IDLE_OPT_DCN_SAVE_INIT ; -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); }void dcn31_z10_restore (const struct dc *dc)
@@ -434,7 +434,7 @@ void dcn31_z10_restore(const struct dc *dc) cmd.dcn_restore.header.type =DMUB_CMD__IDLE_OPT ; cmd.dcn_restore.header.sub_type =DMUB_CMD__IDLE_OPT_DCN_RESTORE ; -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); }void dcn31_hubp_pg_control (struct dce_hwseq *hws,unsigned int hubp_inst,bool power_on)
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +3 -3
@@ -277,7 +277,7 @@ bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable) cmd.cab.header.sub_type =DMUB_CMD__CAB_NO_DCN_REQ ; cmd.cab.header.payload_bytes =sizeof (cmd.cab) -sizeof (cmd.cab.header); -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_NO_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_NO_WAIT );return true; }
@@ -311,7 +311,7 @@ bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable) cmd.cab.header.payload_bytes =sizeof (cmd.cab) -sizeof (cmd.cab.header); cmd.cab.cab_alloc_ways = (uint8_t )ways; -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_NO_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_NO_WAIT );return true; }
@@ -327,7 +327,7 @@ bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable) cmd.cab.header.payload_bytes =sizeof (cmd.cab) -sizeof (cmd.cab.header); -dm_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT ); +dc_wake_and_execute_dmub_cmd (dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT );return true; }
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +1 -1
@@ -1398,7 +1398,7 @@ static bool get_usbc_cable_id(struct dc_link *link, union dp_cable_id *cable_id) cmd.cable_id.header.payload_bytes =sizeof (cmd.cable_id.data); cmd.cable_id.data.input.phy_inst =resource_transmitter_to_phy_idx ( link->dc, link->link_enc->transmitter); -if (dm_execute_dmub_cmd (link->dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY ) && +if (dc_wake_and_execute_dmub_cmd (link->dc->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY ) && cmd.cable_id.header.ret_status ==1 ) { cable_id->raw = cmd.cable_id.data.output_raw;DC_LOG_DC ("usbc_cable_id = %d.\n" , cable_id->raw);
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c +2 -1
@@ -90,7 +90,8 @@ bool dpia_query_hpd_status(struct dc_link *link) cmd.query_hpd.data.ch_type =AUX_CHANNEL_DPIA ;/* Return HPD status reported by DMUB if query successfully executed. */ -if (dm_execute_dmub_cmd (dmub_srv->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY ) && cmd.query_hpd.data.status ==AUX_RET_SUCCESS ) +if (dc_wake_and_execute_dmub_cmd (dmub_srv->ctx, &cmd,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY ) && + cmd.query_hpd.data.status ==AUX_RET_SUCCESS ) is_hpd_high = cmd.query_hpd.data.result; DC_LOG_DEBUG("%s: link(%d) dpia(%d) cmd_status(%d) result(%d)\n",
Signature · 1 line
2.37.3
PATCH 17/25 drm/amd/display: Wake DMCUB before executing GPINT commands
In reply to Wayne LinFrom: Nicholas Kazlauskas <[email protected]>
[Why]
DMCUB can be in idle when we attempt to interface with the HW through the GPINT mailbox resulting in a system hang.
[How]
Add dc_wake_and_execute_gpint() to wrap the wake, execute, sleep sequence.
If the GPINT executes successfully then DMCUB will be put back into sleep after the optional response is returned.
It functions similar to the inbox command interface.
--- .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 29 ++------ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 72 ++++++++++++++----- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 11 +++ drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 19 ++--- 4 files changed, 77 insertions(+), 54 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +5 -24
@@ -2976,7 +2976,6 @@ static int dmub_trace_mask_set(void *data, u64 val)struct amdgpu_device *adev = data;struct dmub_srv *srv = adev->dm.dc->ctx->dmub_srv->dmub;enum dmub_gpint_command cmd; -enum dmub_status status;u64 mask =0xffff ;u8 shift =0 ;u32 res;
@@ -3003,13 +3002,7 @@ static int dmub_trace_mask_set(void *data, u64 val)break ; } - status =dmub_srv_send_gpint_command (srv, cmd, res,30 ); - -if (status ==DMUB_STATUS_TIMEOUT ) -return -ETIMEDOUT ; -else if (status ==DMUB_STATUS_INVALID ) -return -EINVAL ; -else if (status !=DMUB_STATUS_OK ) +if (!dc_wake_and_execute_gpint (adev->dm.dc->ctx, cmd, res,NULL ,DM_DMUB_WAIT_TYPE_WAIT ))return -EIO ;usleep_range (100 ,1000 );
@@ -3026,7 +3019,6 @@ static int dmub_trace_mask_show(void *data, u64 *val)enum dmub_gpint_command cmd =DMUB_GPINT__GET_TRACE_BUFFER_MASK_WORD0 ;struct amdgpu_device *adev = data;struct dmub_srv *srv = adev->dm.dc->ctx->dmub_srv->dmub; -enum dmub_status status;u8 shift =0 ;u64 raw =0 ;u64 res =0 ;
@@ -3036,23 +3028,12 @@ static int dmub_trace_mask_show(void *data, u64 *val)return -EINVAL ;while (i <4 ) { - status =dmub_srv_send_gpint_command (srv, cmd,0 ,30 ); - -if (status ==DMUB_STATUS_OK ) { - status =dmub_srv_get_gpint_response (srv, (u32 *) &raw); - -if (status ==DMUB_STATUS_INVALID ) -return -EINVAL ; -else if (status !=DMUB_STATUS_OK ) -return -EIO ; - }else if (status ==DMUB_STATUS_TIMEOUT ) { -return -ETIMEDOUT ; - }else if (status ==DMUB_STATUS_INVALID ) { -return -EINVAL ; - }else { +uint32_t response; + +if (!dc_wake_and_execute_gpint (adev->dm.dc->ctx, cmd,0 , &response,DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY ))return -EIO ; - } + raw = response;usleep_range (100 ,1000 ); cmd++;
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +55 -17
100 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h +11 -0
@@ -145,5 +145,16 @@ bool dc_wake_and_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cmbool dc_wake_and_execute_dmub_cmd_list (const struct dc_context *ctx,unsigned int count,union dmub_rb_cmd *cmd,enum dm_dmub_wait_type wait_type); +/** +* dc_wake_and_execute_gpint() +* +* @ctx: DC context +* @command_code: The command ID to send to DMCUB +* @param: The parameter to message DMCUB +* @response: Optional response out value - may be NULL. +* @wait_type: The wait behavior for the execution +*/ +bool dc_wake_and_execute_gpint (const struct dc_context *ctx,enum dmub_gpint_command command_code, +uint16_t param,uint32_t *response,enum dm_dmub_wait_type wait_type);#endif /* _DMUB_DC_SRV_H_ */
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +6 -13
@@ -105,23 +105,18 @@ static enum dc_psr_state convert_psr_state(uint32_t raw_state)*/ static void dmub_psr_get_state (struct dmub_psr *dmub,enum dc_psr_state *state,uint8_t panel_inst) { -struct dmub_srv *srv = dmub->ctx->dmub_srv->dmub;uint32_t raw_state =0 ;uint32_t retry_count =0 ; -enum dmub_status status;do {// Send gpint command and wait for ack - status =dmub_srv_send_gpint_command (srv,DMUB_GPINT__GET_PSR_STATE , panel_inst,30 ); - -if (status ==DMUB_STATUS_OK ) { -// GPINT was executed, get response -dmub_srv_get_gpint_response (srv, &raw_state); +if (dc_wake_and_execute_gpint (dmub->ctx,DMUB_GPINT__GET_PSR_STATE , panel_inst, &raw_state, +DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY )) { *state =convert_psr_state (raw_state); - }else + }else {// Return invalid state when GPINT times out *state =PSR_STATE_INVALID ; - + } }while (++retry_count <=1000 && *state ==PSR_STATE_INVALID );// Assert if max retry hit
@@ -452,13 +447,11 @@ static void dmub_psr_force_static(struct dmub_psr *dmub, uint8_t panel_inst)*/ static void dmub_psr_get_residency (struct dmub_psr *dmub,uint32_t *residency,uint8_t panel_inst) { -struct dmub_srv *srv = dmub->ctx->dmub_srv->dmub;uint16_t param = (uint16_t )(panel_inst <<8 );/* Send gpint command and wait for ack */ -dmub_srv_send_gpint_command (srv,DMUB_GPINT__PSR_RESIDENCY , param,30 ); - -dmub_srv_get_gpint_response (srv, residency); +dc_wake_and_execute_gpint (dmub->ctx,DMUB_GPINT__PSR_RESIDENCY , param, residency, +DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY ); }static const struct dmub_psr_funcs psr_funcs = {
Signature · 1 line
2.37.3
PATCH 18/25 drm/amd/display: Refactor dc_state interface
In reply to Wayne LinFrom: Dillon Varone <[email protected]>
[WHY?]
Part of the dc_state interface that deals with adding streams and planes should remain public, while others that deal with internal status' and subvp should be private to DC.
[HOW?]
Move and rename the public functions to dc_state.h and private functions to dc_state_priv.h. Also add some additional functions for extracting subvp meta data from the state.
--- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 45 +- drivers/gpu/drm/amd/display/dc/Makefile | 2 +- .../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 3 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 171 ++---- .../drm/amd/display/dc/core/dc_hw_sequencer.c | 8 +- .../gpu/drm/amd/display/dc/core/dc_resource.c | 294 +--------- .../gpu/drm/amd/display/dc/core/dc_state.c | 527 ++++++++++++++++++ .../gpu/drm/amd/display/dc/core/dc_stream.c | 33 +- .../gpu/drm/amd/display/dc/core/dc_surface.c | 6 +- drivers/gpu/drm/amd/display/dc/dc.h | 16 +- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 31 +- drivers/gpu/drm/amd/display/dc/dc_plane.h | 38 ++ .../gpu/drm/amd/display/dc/dc_plane_priv.h | 34 ++ drivers/gpu/drm/amd/display/dc/dc_state.h | 74 +++ .../gpu/drm/amd/display/dc/dc_state_priv.h | 97 ++++ drivers/gpu/drm/amd/display/dc/dc_stream.h | 44 -- .../gpu/drm/amd/display/dc/dc_stream_priv.h | 35 ++ drivers/gpu/drm/amd/display/dc/dc_types.h | 5 + .../display/dc/dcn32/dcn32_resource_helpers.c | 28 +- .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 5 +- .../drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 45 +- .../drm/amd/display/dc/dml2/dml2_dc_types.h | 1 + .../amd/display/dc/dml2/dml2_mall_phantom.c | 73 +-- .../display/dc/dml2/dml2_translation_helper.c | 10 +- .../gpu/drm/amd/display/dc/dml2/dml2_utils.c | 6 +- .../drm/amd/display/dc/dml2/dml2_wrapper.c | 2 +- .../drm/amd/display/dc/dml2/dml2_wrapper.h | 32 +- .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 3 +- .../amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 17 +- .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 42 +- .../amd/display/dc/hwss/dcn30/dcn30_hwseq.c | 4 +- .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 36 +- .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 3 +- drivers/gpu/drm/amd/display/dc/inc/resource.h | 1 - .../dc/resource/dcn32/dcn32_resource.c | 83 ++- .../dc/resource/dcn321/dcn321_resource.c | 21 +- .../dc/resource/dcn35/dcn35_resource.c | 2 + 37 files changed, 1171 insertions(+), 706 deletions(-) create mode 100644 drivers/gpu/drm/amd/display/dc/core/dc_state.c create mode 100644 drivers/gpu/drm/amd/display/dc/dc_plane.h create mode 100644 drivers/gpu/drm/amd/display/dc/dc_plane_priv.h create mode 100644 drivers/gpu/drm/amd/display/dc/dc_state.h create mode 100644 drivers/gpu/drm/amd/display/dc/dc_state_priv.h create mode 100644 drivers/gpu/drm/amd/display/dc/dc_stream_priv.h
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +23 -22
@@ -37,6 +37,7 @@#include "dc/dc_dmub_srv.h" #include "dc/dc_edid_parser.h" #include "dc/dc_stat.h" +#include "dc/dc_state.h" #include "amdgpu_dm_trace.h" #include "dpcd_defs.h" #include "link/protocols/link_dpcd.h"
@@ -2605,7 +2606,7 @@ static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc)memset (del_streams,0 ,sizeof (del_streams)); - context =dc_create_state (dc); + context =dc_state_create (dc);if (context ==NULL ) goto context_alloc_fail;
@@ -2620,12 +2621,12 @@ static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc)/* Remove all planes for removed streams and then remove the streams */ for (i =0 ; i < del_streams_count; i++) { -if (!dc_rem_all_planes_for_stream (dc, del_streams[i], context)) { +if (!dc_state_rem_all_planes_for_stream (dc, del_streams[i], context)) { res =DC_FAIL_DETACH_SURFACES ; goto fail; } - res =dc_remove_stream_from_ctx (dc, context, del_streams[i]); + res =dc_state_remove_stream (dc, context, del_streams[i]);if (res !=DC_OK ) goto fail; }
@@ -2633,7 +2634,7 @@ static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc) res =dc_commit_streams (dc, context->streams, context->stream_count); fail: -dc_release_state (context); +dc_state_release (context); context_alloc_fail:return res;
@@ -2660,7 +2661,7 @@ static int dm_suspend(void *handle)dc_allow_idle_optimizations (adev->dm.dc, false); - dm->cached_dc_state =dc_copy_state (dm->dc->current_state); + dm->cached_dc_state =dc_state_create_copy (dm->dc->current_state);dm_gpureset_toggle_interrupts (adev, dm->cached_dc_state, false);
@@ -2907,7 +2908,7 @@ static int dm_resume(void *handle)dm_gpureset_toggle_interrupts (adev, dm->cached_dc_state, true); -dc_release_state (dm->cached_dc_state); +dc_state_release (dm->cached_dc_state); dm->cached_dc_state =NULL ;amdgpu_dm_irq_resume_late (adev);
@@ -2917,8 +2918,8 @@ static int dm_resume(void *handle)return 0 ; }/* Recreate dc_state - DC invalidates it when setting power state to S3. */ -dc_release_state (dm_state->context); - dm_state->context =dc_create_state (dm->dc); +dc_state_release (dm_state->context); + dm_state->context =dc_state_create (dm->dc);/* TODO: Remove dc_state->dccg, use dc->dccg directly. */ dc_resource_state_construct (dm->dc, dm_state->context);
@@ -3996,7 +3997,7 @@ dm_atomic_duplicate_state(struct drm_private_obj *obj) old_state =to_dm_atomic_state (obj->state);if (old_state && old_state->context) - new_state->context =dc_copy_state (old_state->context); + new_state->context =dc_state_create_copy (old_state->context);if (!new_state->context) {kfree (new_state);
@@ -4012,7 +4013,7 @@ static void dm_atomic_destroy_state(struct drm_private_obj *obj,struct dm_atomic_state *dm_state =to_dm_atomic_state (state);if (dm_state && dm_state->context) -dc_release_state (dm_state->context); +dc_state_release (dm_state->context);kfree (dm_state); }
@@ -4048,7 +4049,7 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev)if (!state)return -ENOMEM ; - state->context =dc_create_state (adev->dm.dc); + state->context =dc_state_create (adev->dm.dc);if (!state->context) {kfree (state);return -ENOMEM ;
@@ -4063,7 +4064,7 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) r =amdgpu_display_modeset_create_props (adev);if (r) { -dc_release_state (state->context); +dc_state_release (state->context);kfree (state);return r; }
@@ -4075,7 +4076,7 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) r =amdgpu_dm_audio_init (adev);if (r) { -dc_release_state (state->context); +dc_state_release (state->context);kfree (state);return r; }
@@ -6633,7 +6634,7 @@ static enum dc_status dm_validate_stream_and_context(struct dc *dc,if (!dc_plane_state) goto cleanup; - dc_state =dc_create_state (dc); + dc_state =dc_state_create (dc);if (!dc_state) goto cleanup;
@@ -6660,9 +6661,9 @@ static enum dc_status dm_validate_stream_and_context(struct dc *dc, dc_result =dc_validate_plane (dc, dc_plane_state);if (dc_result ==DC_OK ) - dc_result =dc_add_stream_to_ctx (dc, dc_state, stream); + dc_result =dc_state_add_stream (dc, dc_state, stream); - if (dc_result == DC_OK && !dc_add_plane_to_context( + if (dc_result == DC_OK && !dc_state_add_plane( dc, stream, dc_plane_state,
@@ -6674,7 +6675,7 @@ static enum dc_status dm_validate_stream_and_context(struct dc *dc, cleanup:if (dc_state) -dc_release_state (dc_state); +dc_state_release (dc_state);if (dc_plane_state)dc_plane_state_release (dc_plane_state);
@@ -8825,7 +8826,7 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,dc_stream_get_status (dm_new_crtc_state->stream);if (!status) - status =dc_stream_get_status_from_state (dc_state, + status =dc_state_get_stream_status (dc_state, dm_new_crtc_state->stream);if (!status) drm_err(dev,
@@ -9750,7 +9751,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, crtc->base.id);/* i.e. reset mode */ -if (dc_remove_stream_from_ctx ( +if (dc_state_remove_stream ( dm->dc, dm_state->context, dm_old_crtc_state->stream) !=DC_OK ) {
@@ -9793,7 +9794,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,DRM_DEBUG_ATOMIC ("Enabling DRM crtc: %d\n" , crtc->base.id); -if (dc_add_stream_to_ctx ( +if (dc_state_add_stream ( dm->dc, dm_state->context, dm_new_crtc_state->stream) !=DC_OK ) {
@@ -10098,7 +10099,7 @@ static int dm_update_plane_state(struct dc *dc,if (ret)return ret; - if (!dc_remove_plane_from_context( + if (!dc_state_remove_plane( dc, dm_old_crtc_state->stream, dm_old_plane_state->dc_state,
@@ -10176,7 +10177,7 @@ static int dm_update_plane_state(struct dc *dc,* state. It'll be released when the atomic state is * cleaned. */ - if (!dc_add_plane_to_context( + if (!dc_state_add_plane( dc, dm_new_crtc_state->stream, dc_new_plane_state,
drivers/gpu/drm/amd/display/dc/Makefile +1 -1
@@ -62,7 +62,7 @@ AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/dc/,$(DC_LI include $(AMD_DC) DISPLAY_CORE = dc.o dc_stat.o dc_resource.o dc_hw_sequencer.o dc_sink.o \ -dc_surface.o dc_debug.o dc_stream.o dc_link_enc_cfg.o dc_link_exports.o +dc_surface.o dc_debug.o dc_stream.o dc_link_enc_cfg.o dc_link_exports.o dc_state.o DISPLAY_CORE += dc_vm_helper.o
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +2 -1
@@ -29,6 +29,7 @@#include "dc_types.h" #include "dccg.h" #include "clk_mgr_internal.h" +#include "dc_state_priv.h" #include "link.h" #include "dce100/dce_clk_mgr.h"
@@ -63,7 +64,7 @@ int clk_mgr_helper_get_active_display_cnt(/* Don't count SubVP phantom pipes as part of active * display count */ -if (stream->mall_stream_config.type ==SUBVP_PHANTOM ) +if (dc_state_get_stream_subvp_type (context, stream) ==SUBVP_PHANTOM )continue ;/*
drivers/gpu/drm/amd/display/dc/core/dc.c +39 -132
384 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +4 -4
@@ -31,6 +31,7 @@#include "basics/dc_common.h" #include "resource.h" #include "dc_dmub_srv.h" +#include "dc_state_priv.h" #define NUM_ELEMENTS (a) (sizeof(a) / sizeof((a)[0]))
@@ -440,8 +441,7 @@ void get_subvp_visual_confirm_color(for (i =0 ; i < dc->res_pool->pipe_count; i++) {struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; -if (pipe->stream && pipe->stream->mall_stream_config.paired_stream && - pipe->stream->mall_stream_config.type ==SUBVP_MAIN ) { +if (dc_state_get_pipe_subvp_type (context, pipe) ==SUBVP_MAIN ) {/* SubVP enable - red */ color->color_g_y =0 ; color->color_b_cb =0 ;
@@ -454,7 +454,7 @@ void get_subvp_visual_confirm_color( } } -if (enable_subvp && pipe_ctx->stream->mall_stream_config.type ==SUBVP_NONE ) { +if (enable_subvp &&dc_state_get_pipe_subvp_type (context, pipe_ctx) ==SUBVP_NONE ) { color->color_r_cr =0 ;if (pipe_ctx->stream->allow_freesync ==1 ) {/* SubVP enable and DRR on - green */
@@ -529,7 +529,7 @@ void hwss_build_fast_sequence(struct dc *dc, }if (dc->hwss.update_plane_addr && current_mpc_pipe->plane_state->update_flags.bits.addr_update) {if (resource_is_pipe_type (current_mpc_pipe,OTG_MASTER ) && - current_mpc_pipe->stream->mall_stream_config.type ==SUBVP_MAIN ) { +dc_state_get_pipe_subvp_type (NULL , pipe_ctx) ==SUBVP_MAIN ) { block_sequence[*num_steps].params.subvp_save_surf_addr.dc_dmub_srv = dc->ctx->dmub_srv; block_sequence[*num_steps].params.subvp_save_surf_addr.addr = ¤t_mpc_pipe->plane_state->address; block_sequence[*num_steps].params.subvp_save_surf_addr.subvp_index = current_mpc_pipe->subvp_index;
drivers/gpu/drm/amd/display/dc/core/dc_resource.c +29 -265
334 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/core/dc_state.c new file +527 -0
527 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/core/dc_stream.c +5 -28
@@ -31,6 +31,8 @@#include "ipp.h" #include "timing_generator.h" #include "dc_dmub_srv.h" +#include "dc_state_priv.h" +#include "dc_stream_priv.h" #define DC_LOGGER dc->ctx->logger
@@ -54,7 +56,7 @@ void update_stream_signal(struct dc_stream_state *stream, struct dc_sink *sink) } } -static bool dc_stream_construct (struct dc_stream_state *stream, +bool dc_stream_construct (struct dc_stream_state *stream,struct dc_sink *dc_sink_data) {uint32_t i =0 ;
@@ -127,7 +129,7 @@ static bool dc_stream_construct(struct dc_stream_state *stream,return true; } -static void dc_stream_destruct (struct dc_stream_state *stream) +void dc_stream_destruct (struct dc_stream_state *stream) {dc_sink_release (stream->sink);if (stream->out_transfer_func !=NULL ) {
@@ -208,31 +210,6 @@ struct dc_stream_state *dc_copy_stream(const struct dc_stream_state *stream)return new_stream; } -/** -* dc_stream_get_status_from_state - Get stream status from given dc state -* @state: DC state to find the stream status in -* @stream: The stream to get the stream status for -* -* The given stream is expected to exist in the given dc state. Otherwise, NULL -* will be returned. -*/ -struct dc_stream_status *dc_stream_get_status_from_state ( -struct dc_state *state, -struct dc_stream_state *stream) -{ -uint8_t i; - -if (state ==NULL ) -return NULL ; - -for (i =0 ; i < state->stream_count; i++) { -if (stream == state->streams[i]) -return &state->stream_status[i]; - } - -return NULL ; -} -/** * dc_stream_get_status() - Get current stream status of the given stream state * @stream: The stream to get the stream status for.
@@ -244,7 +221,7 @@ struct dc_stream_status *dc_stream_get_status( struct dc_stream_state *stream) {struct dc *dc = stream->ctx->dc; -return dc_stream_get_status_from_state (dc->current_state, stream); +return dc_state_get_stream_status (dc->current_state, stream); } static void program_cursor_attributes(
drivers/gpu/drm/amd/display/dc/core/dc_surface.c +4 -2
@@ -32,10 +32,12 @@#include "transform.h" #include "dpp.h" +#include "dc_plane_priv.h" +/******************************************************************************* * Private functions ******************************************************************************/ -static void dc_plane_construct (struct dc_context *ctx,struct dc_plane_state *plane_state) +void dc_plane_construct (struct dc_context *ctx,struct dc_plane_state *plane_state) { plane_state->ctx = ctx;
@@ -63,7 +65,7 @@ static void dc_plane_construct(struct dc_context *ctx, struct dc_plane_state *pl } -static void dc_plane_destruct (struct dc_plane_state *plane_state) +void dc_plane_destruct (struct dc_plane_state *plane_state) {if (plane_state->gamma_correction !=NULL ) {dc_gamma_release (&plane_state->gamma_correction);
drivers/gpu/drm/amd/display/dc/dc.h +2 -14
@@ -27,6 +27,8 @@#define DC_INTERFACE_H_ #include "dc_types.h" +#include "dc_state.h" +#include "dc_plane.h" #include "grph_object_defs.h" #include "logger_types.h" #include "hdcp_msg_types.h"
@@ -1386,16 +1388,6 @@ struct dc_surface_update {const struct colorspace_transform *gamut_remap_matrix; }; -/* -* Create a new surface with default parameters; -*/ -struct dc_plane_state *dc_create_plane_state (struct dc *dc); -const struct dc_plane_status *dc_plane_get_status ( -const struct dc_plane_state *plane_state); - -void dc_plane_state_retain (struct dc_plane_state *plane_state); -void dc_plane_state_release (struct dc_plane_state *plane_state); -void dc_gamma_retain (struct dc_gamma *dc_gamma);void dc_gamma_release (struct dc_gamma **dc_gamma);struct dc_gamma *dc_create_gamma (void );
@@ -1486,10 +1478,6 @@ enum dc_status dc_commit_streams(struct dc *dc,struct dc_stream_state *streams[], uint8_t stream_count); -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); -void dc_release_state (struct dc_state *context); struct dc_plane_state *dc_get_surface_for_mpcc(struct dc *dc, struct dc_stream_state *stream,
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +21 -10
@@ -33,6 +33,7 @@#include "cursor_reg_cache.h" #include "resource.h" #include "clk_mgr.h" +#include "dc_state_priv.h" #define CTX dc_dmub_srv->ctx#define DC_LOGGER CTX->logger
@@ -532,12 +533,14 @@ void dc_dmub_srv_get_visual_confirm_color_cmd(struct dc *dc, struct pipe_ctx *pi* 3. Populate the drr_info with the min and max supported vtotal values */ static void populate_subvp_cmd_drr_info (struct dc *dc, +struct dc_state *context,struct pipe_ctx *subvp_pipe,struct pipe_ctx *vblank_pipe,struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2 *pipe_data) { +struct dc_stream_state *phantom_stream =dc_state_get_paired_subvp_stream (context, subvp_pipe->stream);struct dc_crtc_timing *main_timing = &subvp_pipe->stream->timing; -struct dc_crtc_timing *phantom_timing = &subvp_pipe->stream->mall_stream_config.paired_stream->timing; +struct dc_crtc_timing *phantom_timing = &phantom_stream->timing;struct dc_crtc_timing *drr_timing = &vblank_pipe->stream->timing;uint16_t drr_frame_us =0 ;uint16_t min_drr_supported_us =0 ;
@@ -625,7 +628,7 @@ static void populate_subvp_cmd_vblank_pipe_info(struct dc *dc,continue ;// Find the SubVP pipe -if (pipe->stream->mall_stream_config.type ==SUBVP_MAIN ) +if (dc_state_get_pipe_subvp_type (context, pipe) ==SUBVP_MAIN )break ; }
@@ -642,7 +645,7 @@ static void populate_subvp_cmd_vblank_pipe_info(struct dc *dc,if (vblank_pipe->stream->ignore_msa_timing_param && (vblank_pipe->stream->allow_freesync || vblank_pipe->stream->vrr_active_variable || vblank_pipe->stream->vrr_active_fixed)) -populate_subvp_cmd_drr_info (dc, pipe, vblank_pipe, pipe_data); +populate_subvp_cmd_drr_info (dc, context, pipe, vblank_pipe, pipe_data); }/**
@@ -667,10 +670,15 @@ static void update_subvp_prefetch_end_to_mall_start(struct dc *dc,uint32_t subvp0_prefetch_us =0 ;uint32_t subvp1_prefetch_us =0 ;uint32_t prefetch_delta_us =0 ; -struct dc_crtc_timing *phantom_timing0 = &subvp_pipes[0 ]->stream->mall_stream_config.paired_stream->timing; -struct dc_crtc_timing *phantom_timing1 = &subvp_pipes[1 ]->stream->mall_stream_config.paired_stream->timing; +struct dc_stream_state *phantom_stream0 =NULL ; +struct dc_stream_state *phantom_stream1 =NULL ; +struct dc_crtc_timing *phantom_timing0 = &phantom_stream0->timing; +struct dc_crtc_timing *phantom_timing1 = &phantom_stream1->timing;struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2 *pipe_data =NULL ; + phantom_stream0 =dc_state_get_paired_subvp_stream (context, subvp_pipes[0 ]->stream); + phantom_stream1 =dc_state_get_paired_subvp_stream (context, subvp_pipes[1 ]->stream); + subvp0_prefetch_us =div64_u64 (((uint64_t )(phantom_timing0->v_total - phantom_timing0->v_front_porch) * (uint64_t )phantom_timing0->h_total *1000000 ), (((uint64_t )phantom_timing0->pix_clk_100hz *100 ) + dc->caps.subvp_prefetch_end_to_mall_start_us));
@@ -720,8 +728,9 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,uint32_t j;struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2 *pipe_data = &cmd->fw_assisted_mclk_switch_v2.config_data.pipe_data[cmd_pipe_index]; +struct dc_stream_state *phantom_stream =dc_state_get_paired_subvp_stream (context, subvp_pipe->stream);struct dc_crtc_timing *main_timing = &subvp_pipe->stream->timing; -struct dc_crtc_timing *phantom_timing = &subvp_pipe->stream->mall_stream_config.paired_stream->timing; +struct dc_crtc_timing *phantom_timing = &phantom_stream->timing;uint32_t out_num_stream, out_den_stream, out_num_plane, out_den_plane, out_num, out_den; pipe_data->mode =SUBVP ;
@@ -775,7 +784,7 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,for (j =0 ; j < dc->res_pool->pipe_count; j++) {struct pipe_ctx *phantom_pipe = &context->res_ctx.pipe_ctx[j]; -if (phantom_pipe->stream == subvp_pipe->stream->mall_stream_config.paired_stream) { +if (phantom_pipe->stream ==dc_state_get_paired_subvp_stream (context, subvp_pipe->stream)) { 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->plane_res.hubp->inst;
@@ -809,6 +818,7 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,union dmub_rb_cmd cmd;struct pipe_ctx *subvp_pipes[2 ];uint32_t wm_val_refclk =0 ; +enum mall_stream_type pipe_mall_type;memset (&cmd,0 ,sizeof (cmd));// FW command for SUBVP
@@ -824,7 +834,7 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,*/ if (resource_is_pipe_type (pipe,OTG_MASTER ) &&resource_is_pipe_type (pipe,DPP_PIPE ) && - pipe->stream->mall_stream_config.type ==SUBVP_MAIN ) +dc_state_get_pipe_subvp_type (context, pipe) ==SUBVP_MAIN ) subvp_pipes[subvp_count++] = pipe; }
@@ -832,6 +842,7 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,// For each pipe that is a "main" SUBVP pipe, fill in pipe data for DMUB SUBVP cmd for (i =0 , pipe_idx =0 ; i < dc->res_pool->pipe_count; i++) {struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + pipe_mall_type =dc_state_get_pipe_subvp_type (context, pipe);if (!pipe->stream)continue ;
@@ -843,11 +854,11 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,if (resource_is_pipe_type (pipe,OTG_MASTER ) &&resource_is_pipe_type (pipe,DPP_PIPE ) && pipe->stream->mall_stream_config.paired_stream && - pipe->stream->mall_stream_config.type ==SUBVP_MAIN ) { + pipe_mall_type ==SUBVP_MAIN ) {populate_subvp_cmd_pipe_info (dc, context, &cmd, pipe, cmd_pipe_index++); }else if (resource_is_pipe_type (pipe,OTG_MASTER ) &&resource_is_pipe_type (pipe,DPP_PIPE ) && - pipe->stream->mall_stream_config.type ==SUBVP_NONE ) { + pipe_mall_type ==SUBVP_NONE ) {// 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++);
drivers/gpu/drm/amd/display/dc/dc_plane.h new file +38 -0
@@ -0,0 +1,38 @@ +/* +* Copyright 2023 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_PLANE_H_ +#define _DC_PLANE_H_ + +#include "dc.h" +#include "dc_hw_types.h" + +struct dc_plane_state *dc_create_plane_state (struct dc *dc); +const struct dc_plane_status *dc_plane_get_status ( +const struct dc_plane_state *plane_state); +void dc_plane_state_retain (struct dc_plane_state *plane_state); +void dc_plane_state_release (struct dc_plane_state *plane_state); + +#endif /* _DC_PLANE_H_ */
drivers/gpu/drm/amd/display/dc/dc_plane_priv.h new file +34 -0
@@ -0,0 +1,34 @@ +/* +* Copyright 2023 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_PLANE_PRIV_H_ +#define _DC_PLANE_PRIV_H_ + +#include "dc_plane.h" + +void dc_plane_construct (struct dc_context *ctx,struct dc_plane_state *plane_state); +void dc_plane_destruct (struct dc_plane_state *plane_state); + +#endif /* _DC_PLANE_PRIV_H_ */
drivers/gpu/drm/amd/display/dc/dc_state.h new file +74 -0
74 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/dc_state_priv.h new file +97 -0
97 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/dc_stream.h +0 -44
62 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/dc_stream_priv.h new file +35 -0
@@ -0,0 +1,35 @@ +/* +* Copyright 2023 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_STREAM_PRIV_H_ +#define _DC_STREAM_PRIV_H_ + +#include "dc_stream.h" + +bool dc_stream_construct (struct dc_stream_state *stream, +struct dc_sink *dc_sink_data); +void dc_stream_destruct (struct dc_stream_state *stream); + +#endif // _DC_STREAM_PRIV_H_
drivers/gpu/drm/amd/display/dc/dc_types.h +5 -0
@@ -1161,4 +1161,9 @@ enum dc_hpd_enable_select { HPD_EN_FOR_SECONDARY_EDP_ONLY, }; +enum mall_stream_type { +SUBVP_NONE ,// subvp not in use +SUBVP_MAIN ,// subvp in use, this stream is main stream +SUBVP_PHANTOM ,// subvp in use, this stream is a phantom stream +};#endif /* DC_TYPES_H_ */
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c +15 -13
@@ -28,6 +28,7 @@#include "dcn20/dcn20_resource.h" #include "dml/dcn32/display_mode_vba_util_32.h" #include "dml/dcn32/dcn32_fpu.h" +#include "dc_state_priv.h" static bool is_dual_plane (enum surface_pixel_format format) {
@@ -190,7 +191,7 @@ bool dcn32_subvp_in_use(struct dc *dc,for (i =0 ; i < dc->res_pool->pipe_count; i++) {struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; -if (pipe->stream && pipe->stream->mall_stream_config.type !=SUBVP_NONE ) +if (dc_state_get_pipe_subvp_type (context, pipe) !=SUBVP_NONE )return true; }return false;
@@ -264,18 +265,17 @@ static void override_det_for_subvp(struct dc *dc, struct dc_state *context, uint// Do not override if a stream has multiple planes for (i =0 ; i < context->stream_count; i++) { -if (context->stream_status[i].plane_count >1 ) { +if (context->stream_status[i].plane_count >1 )return ; - } -if (context->streams[i]->mall_stream_config.type !=SUBVP_PHANTOM ) { + +if (dc_state_get_stream_subvp_type (context, context->streams[i]) !=SUBVP_PHANTOM ) stream_count++; - } }for (i =0 ; i < dc->res_pool->pipe_count; i++) {struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; -if (pipe_ctx->stream && pipe_ctx->plane_state && pipe_ctx->stream->mall_stream_config.type !=SUBVP_PHANTOM ) { +if (pipe_ctx->stream && pipe_ctx->plane_state &&dc_state_get_pipe_subvp_type (context, pipe_ctx) !=SUBVP_PHANTOM ) {if (dcn32_allow_subvp_high_refresh_rate (dc, context, pipe_ctx)) {if (pipe_ctx->stream->timing.v_addressable ==1080 && pipe_ctx->stream->timing.h_addressable ==1920 ) {
@@ -290,7 +290,7 @@ static void override_det_for_subvp(struct dc *dc, struct dc_state *context, uintfor (i =0 ; i < dc->res_pool->pipe_count; i++) {struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; -if (pipe_ctx->stream && pipe_ctx->plane_state && pipe_ctx->stream->mall_stream_config.type !=SUBVP_PHANTOM ) { +if (pipe_ctx->stream && pipe_ctx->plane_state &&dc_state_get_pipe_subvp_type (context, pipe_ctx)) {if (pipe_ctx->stream->timing.v_addressable ==1080 && pipe_ctx->stream->timing.h_addressable ==1920 ) {if (pipe_segments[i] >4 ) pipe_segments[i] =4 ;
@@ -337,14 +337,14 @@ void dcn32_determine_det_override(struct dc *dc,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 ) +if (dc_state_get_stream_subvp_type (context, context->streams[i]) !=SUBVP_PHANTOM ) stream_count++; }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 ) +if (dc_state_get_stream_subvp_type (context, context->streams[i]) ==SUBVP_PHANTOM )continue ;if (context->stream_status[i].plane_count >0 )
@@ -716,10 +716,11 @@ bool dcn32_subvp_drr_admissable(struct dc *dc, struct dc_state *context)for (i =0 ; i < dc->res_pool->pipe_count; i++) {struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; +enum mall_stream_type pipe_mall_type =dc_state_get_pipe_subvp_type (context, pipe);if (resource_is_pipe_type (pipe,OPP_HEAD ) &&resource_is_pipe_type (pipe,DPP_PIPE )) { -if (pipe->stream->mall_stream_config.type ==SUBVP_MAIN ) { +if (pipe_mall_type ==SUBVP_MAIN ) { subvp_count++; subvp_disallow |=disallow_subvp_in_active_plus_blank (pipe);
@@ -728,7 +729,7 @@ bool dcn32_subvp_drr_admissable(struct dc *dc, struct dc_state *context) refresh_rate =div_u64 (refresh_rate, pipe->stream->timing.v_total); refresh_rate =div_u64 (refresh_rate, pipe->stream->timing.h_total); } -if (pipe->stream->mall_stream_config.type ==SUBVP_NONE ) { +if (pipe_mall_type ==SUBVP_NONE ) { non_subvp_pipes++; drr_psr_capable = (drr_psr_capable ||dcn32_is_psr_capable (pipe)); if (pipe->stream->ignore_msa_timing_param &&
@@ -776,10 +777,11 @@ bool dcn32_subvp_vblank_admissable(struct dc *dc, struct dc_state *context, intfor (i =0 ; i < dc->res_pool->pipe_count; i++) {struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; +enum mall_stream_type pipe_mall_type =dc_state_get_pipe_subvp_type (context, pipe);if (resource_is_pipe_type (pipe,OPP_HEAD ) &&resource_is_pipe_type (pipe,DPP_PIPE )) { -if (pipe->stream->mall_stream_config.type ==SUBVP_MAIN ) { +if (pipe_mall_type ==SUBVP_MAIN ) { subvp_count++; subvp_disallow |=disallow_subvp_in_active_plus_blank (pipe);
@@ -788,7 +790,7 @@ bool dcn32_subvp_vblank_admissable(struct dc *dc, struct dc_state *context, int refresh_rate =div_u64 (refresh_rate, pipe->stream->timing.v_total); refresh_rate =div_u64 (refresh_rate, pipe->stream->timing.h_total); } -if (pipe->stream->mall_stream_config.type ==SUBVP_NONE ) { +if (pipe_mall_type ==SUBVP_NONE ) { non_subvp_pipes++; vblank_psr_capable = (vblank_psr_capable ||dcn32_is_psr_capable (pipe)); if (pipe->stream->ignore_msa_timing_param &&
drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c +3 -2
@@ -33,6 +33,7 @@#include "link.h" #include "dcn20_fpu.h" +#include "dc_state_priv.h" #define DC_LOGGER \ dc->ctx->logger
@@ -1074,7 +1075,7 @@ void dcn20_calculate_dlg_params(struct dc *dc, 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 ) { +if (dc_state_get_pipe_subvp_type (context, &context->res_ctx.pipe_ctx[i]) ==SUBVP_PHANTOM ) {// Phantom pipe requires that DET_SIZE = 0 and no unbounded requests context->res_ctx.pipe_ctx[i].det_buffer_size_kb =0 ; context->res_ctx.pipe_ctx[i].unbounded_req = false;
@@ -1424,7 +1425,7 @@ int dcn20_populate_dml_pipes_from_context(struct dc *dc,*/ if (res_ctx->pipe_ctx[i].plane_state && (res_ctx->pipe_ctx[i].plane_state->address.type ==PLN_ADDR_TYPE_VIDEO_PROGRESSIVE || - res_ctx->pipe_ctx[i].stream->mall_stream_config.type ==SUBVP_PHANTOM )) +dc_state_get_pipe_subvp_type (context, &res_ctx->pipe_ctx[i]) ==SUBVP_PHANTOM )) pipes[pipe_cnt].pipe.src.num_cursors =0 ;else pipes[pipe_cnt].pipe.src.num_cursors = dc->dml.ip.number_of_cursors;
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +26 -19
168 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_types.h +1 -0
@@ -38,5 +38,6 @@#include "core_types.h" #include "dsc.h" #include "clk_mgr.h" +#include "dc_state_priv.h" #endif //__DML2_DC_TYPES_H__
drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c +42 -31
211 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c +6 -4
@@ -1051,6 +1051,7 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_stat {int i =0 , j =0 ;int disp_cfg_stream_location, disp_cfg_plane_location; +enum mall_stream_type stream_mall_type;for (i =0 ; i < __DML2_WRAPPER_MAX_STREAMS_PLANES__; i++) { dml2->v20.scratch.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id_valid[i] = false;
@@ -1071,6 +1072,7 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_statfor (i =0 ; i < context->stream_count; i++) { disp_cfg_stream_location =map_stream_to_dml_display_cfg (dml2, context->streams[i], dml_dispcfg); + stream_mall_type =dc_state_get_stream_subvp_type (context, context->streams[i]);if (disp_cfg_stream_location <0 ) disp_cfg_stream_location = dml_dispcfg->num_timings++;
@@ -1115,10 +1117,10 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_statpopulate_dml_surface_cfg_from_plane_state (dml2->v20.dml_core_ctx.project, &dml_dispcfg->surface, disp_cfg_plane_location, context->stream_status[i].plane_states[j]);populate_dml_plane_cfg_from_plane_state (&dml_dispcfg->plane, disp_cfg_plane_location, context->stream_status[i].plane_states[j], context); -if (context->streams[i]->mall_stream_config.type ==SUBVP_MAIN ) { +if (stream_mall_type ==SUBVP_MAIN ) { dml_dispcfg->plane.UseMALLForPStateChange[disp_cfg_plane_location] = dml_use_mall_pstate_change_sub_viewport; dml_dispcfg->plane.UseMALLForStaticScreen[disp_cfg_plane_location] = dml_use_mall_static_screen_optimize; - }else if (context->streams[i]->mall_stream_config.type ==SUBVP_PHANTOM ) { + }else if (stream_mall_type ==SUBVP_PHANTOM ) { dml_dispcfg->plane.UseMALLForPStateChange[disp_cfg_plane_location] = dml_use_mall_pstate_change_phantom_pipe; dml_dispcfg->plane.UseMALLForStaticScreen[disp_cfg_plane_location] = dml_use_mall_static_screen_disable; dml2->v20.dml_core_ctx.policy.ImmediateFlipRequirement[disp_cfg_plane_location] = dml_immediate_flip_not_required;
@@ -1147,9 +1149,9 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_statbreak ; } -if (context->streams[i]->mall_stream_config.type ==SUBVP_MAIN ) +if (stream_mall_type ==SUBVP_MAIN ) dml_dispcfg->plane.UseMALLForPStateChange[disp_cfg_plane_location] = dml_use_mall_pstate_change_sub_viewport; -else if (context->streams[i]->mall_stream_config.type ==SUBVP_PHANTOM ) +else if (stream_mall_type ==SUBVP_PHANTOM ) dml_dispcfg->plane.UseMALLForPStateChange[disp_cfg_plane_location] = dml_use_mall_pstate_change_phantom_pipe; dml2->v20.scratch.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id[disp_cfg_plane_location] = context->streams[i]->stream_id;
drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c +4 -2
@@ -279,6 +279,7 @@ static void populate_pipe_ctx_dlg_params_from_dml(struct pipe_ctx *pipe_ctx, strvoid dml2_calculate_rq_and_dlg_params (const struct dc *dc,struct dc_state *context,struct resource_context *out_new_hw_state,struct dml2_context *in_ctx,unsigned int pipe_cnt) {unsigned int dc_pipe_ctx_index, dml_pipe_idx, plane_id; +enum mall_stream_type pipe_mall_type;bool unbounded_req_enabled = false;struct dml2_calculate_rq_and_dlg_params_scratch *s = &in_ctx->v20.scratch.calculate_rq_and_dlg_params_scratch;
@@ -326,7 +327,8 @@ void dml2_calculate_rq_and_dlg_params(const struct dc *dc, struct dc_state *cont*/ populate_pipe_ctx_dlg_params_from_dml (&context->res_ctx.pipe_ctx[dc_pipe_ctx_index], &context->bw_ctx.dml2->v20.dml_core_ctx, dml_pipe_idx); -if (context->res_ctx.pipe_ctx[dc_pipe_ctx_index].stream->mall_stream_config.type ==SUBVP_PHANTOM ) { + pipe_mall_type =dc_state_get_pipe_subvp_type (context, &context->res_ctx.pipe_ctx[dc_pipe_ctx_index]); +if (pipe_mall_type ==SUBVP_PHANTOM ) {// Phantom pipe requires that DET_SIZE = 0 and no unbounded requests context->res_ctx.pipe_ctx[dc_pipe_ctx_index].det_buffer_size_kb =0 ; context->res_ctx.pipe_ctx[dc_pipe_ctx_index].unbounded_req = false;
@@ -353,7 +355,7 @@ void dml2_calculate_rq_and_dlg_params(const struct dc *dc, struct dc_state *cont context->res_ctx.pipe_ctx[dc_pipe_ctx_index].plane_state != context->res_ctx.pipe_ctx[dc_pipe_ctx_index].top_pipe->plane_state) && context->res_ctx.pipe_ctx[dc_pipe_ctx_index].prev_odm_pipe == NULL) {/* SS: all active surfaces stored in MALL */ -if (context->res_ctx.pipe_ctx[dc_pipe_ctx_index].stream->mall_stream_config.type !=SUBVP_PHANTOM ) { +if (pipe_mall_type !=SUBVP_PHANTOM ) { context->bw_ctx.bw.dcn.mall_ss_size_bytes += context->res_ctx.pipe_ctx[dc_pipe_ctx_index].surface_size_in_mall_bytes; }else {/* SUBVP: phantom surfaces only stored in MALL */
drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c +1 -1
@@ -418,7 +418,7 @@ static int find_drr_eligible_stream(struct dc_state *display_state)int i;for (i =0 ; i < display_state->stream_count; i++) { -if (display_state->streams[i]->mall_stream_config.type ==SUBVP_NONE +if (dc_state_get_stream_subvp_type (display_state, display_state->streams[i]) ==SUBVP_NONE && display_state->streams[i]->ignore_msa_timing_param) {// Use ignore_msa_timing_param flag to identify as DRR return i;
drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h +24 -8
@@ -93,15 +93,31 @@ struct dml2_dc_callbacks {struct dml2_dc_svp_callbacks {struct dc *dc;bool (*build_scaling_params)(struct pipe_ctx *pipe_ctx); -struct dc_stream_state * (*create_stream_for_sink)(struct dc_sink *dc_sink_data); -struct dc_plane_state * (*create_plane)(struct dc *dc); -enum dc_status (*add_stream_to_ctx)(struct dc *dc,struct dc_state *new_ctx,struct dc_stream_state *dc_stream); -bool (*add_plane_to_context)(const struct dc *dc,struct dc_stream_state *stream,struct dc_plane_state *plane_state,struct dc_state *context); -bool (*remove_plane_from_context)(const struct dc *dc,struct dc_stream_state *stream,struct dc_plane_state *plane_state,struct dc_state *context); -enum dc_status (*remove_stream_from_ctx)(struct dc *dc,struct dc_state *new_ctx,struct dc_stream_state *stream); -void (*plane_state_release)(struct dc_plane_state *plane_state); -void (*stream_release)(struct dc_stream_state *stream); +struct dc_stream_state * (*create_phantom_stream)(const struct dc *dc, +struct dc_state *state, +struct dc_stream_state *main_stream); +struct dc_plane_state * (*create_phantom_plane)(struct dc *dc, +struct dc_state *state, +struct dc_plane_state *main_plane); +enum dc_status (*add_phantom_stream)(struct dc *dc, +struct dc_state *state, +struct dc_stream_state *phantom_stream, +struct dc_stream_state *main_stream); +bool (*add_phantom_plane)(const struct dc *dc,struct dc_stream_state *stream,struct dc_plane_state *plane_state,struct dc_state *context); +bool (*remove_phantom_plane)(const struct dc *dc,struct dc_stream_state *stream,struct dc_plane_state *plane_state,struct dc_state *context); +enum dc_status (*remove_phantom_stream)(struct dc *dc, +struct dc_state *state, +struct dc_stream_state *stream); +void (*release_phantom_plane)(const struct dc *dc, +struct dc_state *state, +struct dc_plane_state *plane); +void (*release_phantom_stream)(const struct dc *dc, +struct dc_state *state, +struct dc_stream_state *stream);void (*release_dsc)(struct resource_context *res_ctx,const struct resource_pool *pool,struct display_stream_compressor **dsc); +enum mall_stream_type (*get_pipe_subvp_type)(const struct dc_state *state,const struct pipe_ctx *pipe_ctx); +enum mall_stream_type (*get_stream_subvp_type)(const struct dc_state *state,const struct dc_stream_state *stream); +struct dc_stream_state *(*get_paired_subvp_stream)(const struct dc_state *state,const struct dc_stream_state *stream); };struct dml2_clks_table_entry {
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +2 -1
@@ -55,6 +55,7 @@#include "audio.h" #include "reg_helper.h" #include "panel_cntl.h" +#include "dc_state_priv.h" #include "dpcd_defs.h" /* include DCE11 register header files */ #include "dce/dce_11_0_d.h"
@@ -1595,7 +1596,7 @@ static enum dc_status apply_single_controller_ctx_to_hw(* is constructed with the same sink). Make sure not to override * and link programming on the main. */ -if (pipe_ctx->stream->mall_stream_config.type !=SUBVP_PHANTOM ) { +if (dc_state_get_pipe_subvp_type (context, pipe_ctx) !=SUBVP_PHANTOM ) { pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false; pipe_ctx->stream->link->replay_settings.replay_feature_enabled = false; }
drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c +9 -8
@@ -56,6 +56,7 @@#include "dc_trace.h" #include "dce/dmub_outbox.h" #include "link.h" +#include "dc_state_priv.h" #define DC_LOGGER \ dc_logger
@@ -115,7 +116,7 @@ void dcn10_lock_all_pipes(struct dc *dc, !pipe_ctx->stream || (!pipe_ctx->plane_state && !old_pipe_ctx->plane_state) || !tg->funcs->is_tg_enabled (tg) || - pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM) + dc_state_get_pipe_subvp_type(context, pipe_ctx) == SUBVP_PHANTOM) continue;if (lock)
@@ -1200,7 +1201,7 @@ void dcn10_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx) mpc->funcs->remove_mpcc (mpc, mpc_tree_params, mpcc_to_remove);// Phantom pipes have OTG disabled by default, so MPCC_STATUS will never assert idle, // so don't wait for MPCC_IDLE in the programming sequence -if (opp !=NULL && !pipe_ctx->plane_state->is_phantom) +if (opp !=NULL &&dc_state_get_pipe_subvp_type (NULL , pipe_ctx) !=SUBVP_PHANTOM ) opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true; dc->optimized_required = true;
@@ -2276,7 +2277,7 @@ void dcn10_enable_timing_synchronization(DC_SYNC_INFO ("Setting up OTG reset trigger\n" );for (i =1 ; i < group_size; i++) { -if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type ==SUBVP_PHANTOM ) +if (grouped_pipes[i]->stream &&dc_state_get_pipe_subvp_type (NULL , grouped_pipes[i]) ==SUBVP_PHANTOM )continue ; opp = grouped_pipes[i]->stream_res.opp;
@@ -2296,14 +2297,14 @@ void dcn10_enable_timing_synchronization(if (grouped_pipes[i]->stream ==NULL )continue ; -if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type ==SUBVP_PHANTOM ) +if (grouped_pipes[i]->stream &&dc_state_get_pipe_subvp_type (NULL , grouped_pipes[i]) ==SUBVP_PHANTOM )continue ; grouped_pipes[i]->stream->vblank_synchronized = false; }for (i =1 ; i < group_size; i++) { -if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type ==SUBVP_PHANTOM ) +if (grouped_pipes[i]->stream &&dc_state_get_pipe_subvp_type (NULL , grouped_pipes[i]) ==SUBVP_PHANTOM )continue ; grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger(
@@ -2317,11 +2318,11 @@ void dcn10_enable_timing_synchronization(* synchronized. Look at last pipe programmed to reset. */ -if (grouped_pipes[1 ]->stream && grouped_pipes[1 ]->stream->mall_stream_config.type !=SUBVP_PHANTOM ) +if (grouped_pipes[1 ]->stream &&dc_state_get_pipe_subvp_type (NULL , grouped_pipes[1 ]) !=SUBVP_PHANTOM )wait_for_reset_trigger_to_occur (dc_ctx, grouped_pipes[1 ]->stream_res.tg);for (i =1 ; i < group_size; i++) { -if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type ==SUBVP_PHANTOM ) +if (grouped_pipes[i]->stream &&dc_state_get_pipe_subvp_type (NULL , grouped_pipes[i]) ==SUBVP_PHANTOM )continue ; grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger(
@@ -2329,7 +2330,7 @@ void dcn10_enable_timing_synchronization( }for (i =1 ; i < group_size; i++) { -if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type ==SUBVP_PHANTOM ) +if (dc_state_get_pipe_subvp_type (state, grouped_pipes[i]) ==SUBVP_PHANTOM )continue ; opp = grouped_pipes[i]->stream_res.opp;
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +24 -18
149 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c +2 -2
@@ -51,7 +51,7 @@#include "dcn20/dcn20_hwseq.h" #include "dcn30/dcn30_resource.h" #include "link.h" - +#include "dc_state_priv.h"
@@ -966,7 +966,7 @@ void dcn30_hardware_release(struct dc *dc)if (!pipe->stream)continue ; -if (pipe->stream->mall_stream_config.type ==SUBVP_MAIN ) { +if (dc_state_get_pipe_subvp_type (dc->current_state, pipe) ==SUBVP_MAIN ) { subvp_in_use = true;break ; }
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +19 -17
@@ -51,6 +51,7 @@#include "dcn32/dcn32_resource.h" #include "link.h" #include "../dcn20/dcn20_hwseq.h" +#include "dc_state_priv.h" #define DC_LOGGER_INIT (logger)
@@ -349,7 +350,7 @@ void dcn32_commit_subvp_config(struct dc *dc, struct dc_state *context)struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];if (pipe_ctx->stream && pipe_ctx->stream->mall_stream_config.paired_stream && - pipe_ctx->stream->mall_stream_config.type ==SUBVP_MAIN ) { +dc_state_get_pipe_subvp_type (context, pipe_ctx) ==SUBVP_MAIN ) {// There is at least 1 SubVP pipe, so enable SubVP enable_subvp = true;break ;
@@ -375,18 +376,20 @@ void dcn32_subvp_pipe_control_lock(struct dc *dc,bool subvp_immediate_flip = false;bool subvp_in_use = false;struct pipe_ctx *pipe; +enum mall_stream_type pipe_mall_type =SUBVP_NONE ;for (i =0 ; i < dc->res_pool->pipe_count; i++) { pipe = &context->res_ctx.pipe_ctx[i]; + pipe_mall_type =dc_state_get_pipe_subvp_type (context, pipe); -if (pipe->stream && pipe->plane_state && pipe->stream->mall_stream_config.type ==SUBVP_MAIN ) { +if (pipe->stream && pipe->plane_state && pipe_mall_type ==SUBVP_MAIN ) { subvp_in_use = true;break ; } }if (top_pipe_to_program && top_pipe_to_program->stream && top_pipe_to_program->plane_state) { -if (top_pipe_to_program->stream->mall_stream_config.type ==SUBVP_MAIN && +if (dc_state_get_pipe_subvp_type (context, top_pipe_to_program) ==SUBVP_MAIN && top_pipe_to_program->plane_state->flip_immediate) subvp_immediate_flip = true; }
@@ -398,7 +401,7 @@ void dcn32_subvp_pipe_control_lock(struct dc *dc,if (!lock) {for (i =0 ; i < dc->res_pool->pipe_count; i++) { pipe = &context->res_ctx.pipe_ctx[i]; -if (pipe->stream && pipe->plane_state && pipe->stream->mall_stream_config.type ==SUBVP_MAIN && +if (pipe->stream && pipe->plane_state && pipe_mall_type ==SUBVP_MAIN && should_lock_all_pipes) pipe->stream_res.tg->funcs->wait_for_state (pipe->stream_res.tg,CRTC_STATE_VBLANK ); }
@@ -420,7 +423,7 @@ void dcn32_subvp_pipe_control_lock_fast(union block_sequence_params *params)bool subvp_immediate_flip = false;if (pipe_ctx && pipe_ctx->stream && pipe_ctx->plane_state) { -if (pipe_ctx->stream->mall_stream_config.type ==SUBVP_MAIN && +if (dc_state_get_pipe_subvp_type (NULL , pipe_ctx) ==SUBVP_MAIN && pipe_ctx->plane_state->flip_immediate) subvp_immediate_flip = true; }
@@ -609,7 +612,7 @@ void dcn32_update_force_pstate(struct dc *dc, struct dc_state *context)struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];struct hubp *hubp = pipe->plane_res.hubp; -if (!pipe->stream || !(pipe->stream->mall_stream_config.type ==SUBVP_MAIN || +if (!pipe->stream || !(dc_state_get_pipe_subvp_type (context, pipe) ==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);
@@ -624,7 +627,7 @@ void dcn32_update_force_pstate(struct dc *dc, struct dc_state *context)struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];struct hubp *hubp = pipe->plane_res.hubp; -if (pipe->stream && (pipe->stream->mall_stream_config.type ==SUBVP_MAIN || +if (pipe->stream && (dc_state_get_pipe_subvp_type (context, pipe) ==SUBVP_MAIN || pipe->stream->fpo_in_use)) {if (hubp && hubp->funcs->hubp_update_force_pstate_disallow) hubp->funcs->hubp_update_force_pstate_disallow (hubp, true);
@@ -671,8 +674,8 @@ void dcn32_update_mall_sel(struct dc *dc, struct dc_state *context)if (cursor_size >16384 ) cache_cursor = true; -if (pipe->stream->mall_stream_config.type ==SUBVP_PHANTOM ) { - hubp->funcs->hubp_update_mall_sel (hubp,1 , false); +if (dc_state_get_pipe_subvp_type (context, pipe) ==SUBVP_PHANTOM ) { + hubp->funcs->hubp_update_mall_sel (hubp,1 , false); }else {// MALL not supported with Stereo3D hubp->funcs->hubp_update_mall_sel(hubp,
@@ -714,9 +717,8 @@ void dcn32_program_mall_pipe_config(struct dc *dc, struct dc_state *context)* see if CURSOR_REQ_MODE will be back to 1 for SubVP * when it should be 0 for MPO */ -if (pipe->stream->mall_stream_config.type ==SUBVP_MAIN ) { +if (dc_state_get_pipe_subvp_type (context, pipe) ==SUBVP_MAIN ) hubp->funcs->hubp_prepare_subvp_buffering (hubp, true); - } } } }
@@ -1222,7 +1224,7 @@ void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_continue ;
Lines of this file are not shown. View the raw message.
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +2 -1
Lines of this file are not shown. View the raw message.
drivers/gpu/drm/amd/display/dc/inc/resource.h +0 -1
Lines of this file are not shown. View the raw message.
drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +36 -47
83 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c +13 -8
Lines of this file are not shown. View the raw message.
drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +2 -0
Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.37.3
Part of the diff is not shown here. View the raw message.
PATCH 19/25 drm/amd/display: Refactor phantom resource allocation
In reply to Wayne LinFrom: Dillon Varone <[email protected]>
[WHY?]
Phantom streams and planes were previously not referenced explcitly on creation.
[HOW?]
To reduce memory management complexity, add an additional phantom streams and planes reference into dc_state, and move mall_stream_config to stream_status inside the state to make it safe to modify in shallow copies. Also consildates any logic that is affected by this change to dc_state.
--- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 91 +--- .../drm/amd/display/dc/core/dc_hw_sequencer.c | 11 +- .../gpu/drm/amd/display/dc/core/dc_resource.c | 128 +----- .../gpu/drm/amd/display/dc/core/dc_state.c | 428 ++++++++++++++++-- .../gpu/drm/amd/display/dc/core/dc_stream.c | 13 +- drivers/gpu/drm/amd/display/dc/dc.h | 18 +- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 7 +- drivers/gpu/drm/amd/display/dc/dc_state.h | 6 +- .../gpu/drm/amd/display/dc/dc_state_priv.h | 15 +- drivers/gpu/drm/amd/display/dc/dc_stream.h | 30 +- .../gpu/drm/amd/display/dc/dc_stream_priv.h | 2 + .../display/dc/dcn32/dcn32_resource_helpers.c | 65 --- .../drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 6 +- .../amd/display/dc/dml2/dml2_mall_phantom.c | 30 +- .../drm/amd/display/dc/dml2/dml2_wrapper.h | 5 +- .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 7 +- .../amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 25 +- .../amd/display/dc/hwss/dcn10/dcn10_hwseq.h | 7 +- .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 27 +- .../amd/display/dc/hwss/dcn20/dcn20_hwseq.h | 2 +- .../amd/display/dc/hwss/dcn201/dcn201_hwseq.c | 8 +- .../amd/display/dc/hwss/dcn201/dcn201_hwseq.h | 2 +- .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 42 +- .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 8 +- .../amd/display/dc/hwss/dcn35/dcn35_hwseq.h | 2 +- .../drm/amd/display/dc/hwss/hw_sequencer.h | 8 +- .../display/dc/hwss/hw_sequencer_private.h | 1 + .../gpu/drm/amd/display/dc/inc/core_types.h | 20 +- .../gpu/drm/amd/display/dc/inc/hw/hw_shared.h | 1 + .../dc/resource/dcn32/dcn32_resource.c | 85 ---- .../dc/resource/dcn32/dcn32_resource.h | 14 - .../dc/resource/dcn321/dcn321_resource.c | 4 - 33 files changed, 578 insertions(+), 549 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +2 -7
@@ -2606,12 +2606,10 @@ static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc)memset (del_streams,0 ,sizeof (del_streams)); - context =dc_state_create (dc); + context =dc_state_create_current_copy (dc);if (context ==NULL ) goto context_alloc_fail; -dc_resource_state_copy_construct_current (dc, context); -/* First remove from context all streams */ for (i =0 ; i < context->stream_count; i++) {struct dc_stream_state *stream = context->streams[i];
@@ -2921,7 +2919,6 @@ static int dm_resume(void *handle)dc_state_release (dm_state->context); dm_state->context =dc_state_create (dm->dc);/* TODO: Remove dc_state->dccg, use dc->dccg directly. */ -dc_resource_state_construct (dm->dc, dm_state->context);/* Before powering on DC we need to re-initialize DMUB. */ dm_dmub_hw_resume (adev);
@@ -4049,14 +4046,12 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev)if (!state)return -ENOMEM ; - state->context =dc_state_create (adev->dm.dc); + state->context =dc_state_create_current_copy (adev->dm.dc);if (!state->context) {kfree (state);return -ENOMEM ; } -dc_resource_state_copy_construct_current (adev->dm.dc, state->context); - drm_atomic_private_obj_init(adev_to_drm(adev), &adev->dm.atomic_obj, &state->base,
drivers/gpu/drm/amd/display/dc/core/dc.c +23 -68
251 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +7 -4
@@ -473,7 +473,8 @@ void hwss_build_fast_sequence(struct dc *dc,unsigned int dmub_cmd_count, struct block_sequence block_sequence[], int *num_steps, - struct pipe_ctx *pipe_ctx) + struct pipe_ctx *pipe_ctx, + struct dc_stream_status *stream_status) { struct dc_plane_state *plane = pipe_ctx->plane_state;struct dc_stream_state *stream = pipe_ctx->stream;
@@ -490,7 +491,8 @@ void hwss_build_fast_sequence(struct dc *dc,if (dc->hwss.subvp_pipe_control_lock_fast) { block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.dc = dc; block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.lock = true; - block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.pipe_ctx = pipe_ctx; + block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.subvp_immediate_flip = + plane->flip_immediate && stream_status->mall_stream_config.type ==SUBVP_MAIN ; block_sequence[*num_steps].func =DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST ; (*num_steps)++; }
@@ -529,7 +531,7 @@ void hwss_build_fast_sequence(struct dc *dc, }if (dc->hwss.update_plane_addr && current_mpc_pipe->plane_state->update_flags.bits.addr_update) {if (resource_is_pipe_type (current_mpc_pipe,OTG_MASTER ) && -dc_state_get_pipe_subvp_type (NULL , pipe_ctx) ==SUBVP_MAIN ) { + stream_status->mall_stream_config.type ==SUBVP_MAIN ) { block_sequence[*num_steps].params.subvp_save_surf_addr.dc_dmub_srv = dc->ctx->dmub_srv; block_sequence[*num_steps].params.subvp_save_surf_addr.addr = ¤t_mpc_pipe->plane_state->address; block_sequence[*num_steps].params.subvp_save_surf_addr.subvp_index = current_mpc_pipe->subvp_index;
@@ -612,7 +614,8 @@ void hwss_build_fast_sequence(struct dc *dc,if (dc->hwss.subvp_pipe_control_lock_fast) { block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.dc = dc; block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.lock = false; - block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.pipe_ctx = pipe_ctx; + block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.subvp_immediate_flip = + plane->flip_immediate && stream_status->mall_stream_config.type ==SUBVP_MAIN ; block_sequence[*num_steps].func =DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST ; (*num_steps)++; }
drivers/gpu/drm/amd/display/dc/core/dc_resource.c +18 -110
160 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/core/dc_state.c +381 -47
563 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/core/dc_stream.c +9 -4
@@ -123,8 +123,7 @@ bool dc_stream_construct(struct dc_stream_state *stream, } stream->out_transfer_func->type =TF_TYPE_BYPASS ; - stream->stream_id = stream->ctx->dc_stream_id_count; - stream->ctx->dc_stream_id_count++; +dc_stream_assign_stream_id (stream);return true; }
@@ -138,6 +137,13 @@ void dc_stream_destruct(struct dc_stream_state *stream) } } +void dc_stream_assign_stream_id (struct dc_stream_state *stream) +{ +/* MSB is reserved to indicate phantoms */ + stream->stream_id = stream->ctx->dc_stream_id_count; + stream->ctx->dc_stream_id_count++; +} +void dc_stream_retain (struct dc_stream_state *stream) {kref_get (&stream->refcount);
@@ -198,8 +204,7 @@ struct dc_stream_state *dc_copy_stream(const struct dc_stream_state *stream)if (new_stream->out_transfer_func)dc_transfer_func_retain (new_stream->out_transfer_func); - new_stream->stream_id = new_stream->ctx->dc_stream_id_count; - new_stream->ctx->dc_stream_id_count++; +dc_stream_assign_stream_id (new_stream);/* If using dynamic encoder assignment, wait till stream committed to assign encoder. */ if (new_stream->ctx->dc->res_pool->funcs->link_encs_assign)
drivers/gpu/drm/amd/display/dc/dc.h +3 -15
@@ -1388,6 +1388,9 @@ struct dc_surface_update {const struct colorspace_transform *gamut_remap_matrix; }; +/* +* Create a new surface with default parameters; +*/ void dc_gamma_retain (struct dc_gamma *dc_gamma);void dc_gamma_release (struct dc_gamma **dc_gamma);struct dc_gamma *dc_create_gamma (void );
@@ -1451,27 +1454,12 @@ enum dc_status dc_validate_global_state(struct dc_state *new_ctx, bool fast_validate); - -void dc_resource_state_construct ( -const struct dc *dc, -struct dc_state *dst_ctx); -bool dc_acquire_release_mpc_3dlut (struct dc *dc,bool acquire,struct dc_stream_state *stream,struct dc_3dlut **lut,struct dc_transfer_func **shaper); -void dc_resource_state_copy_construct ( -const struct dc_state *src_ctx, -struct dc_state *dst_ctx); - -void dc_resource_state_copy_construct_current ( -const struct dc *dc, -struct dc_state *dst_ctx); - -void dc_resource_state_destruct (struct dc_state *context); -bool dc_resource_is_dsc_encoding_supported (const struct dc *dc); enum dc_status dc_commit_streams(struct dc *dc,
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +4 -3
@@ -672,12 +672,14 @@ static void update_subvp_prefetch_end_to_mall_start(struct dc *dc,uint32_t prefetch_delta_us =0 ;struct dc_stream_state *phantom_stream0 =NULL ;struct dc_stream_state *phantom_stream1 =NULL ; -struct dc_crtc_timing *phantom_timing0 = &phantom_stream0->timing; -struct dc_crtc_timing *phantom_timing1 = &phantom_stream1->timing; +struct dc_crtc_timing *phantom_timing0 =NULL ; +struct dc_crtc_timing *phantom_timing1 =NULL ;struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2 *pipe_data =NULL ; phantom_stream0 =dc_state_get_paired_subvp_stream (context, subvp_pipes[0 ]->stream); phantom_stream1 =dc_state_get_paired_subvp_stream (context, subvp_pipes[1 ]->stream); + phantom_timing0 = &phantom_stream0->timing; + phantom_timing1 = &phantom_stream1->timing; subvp0_prefetch_us = div64_u64(((uint64_t)(phantom_timing0->v_total - phantom_timing0->v_front_porch) * (uint64_t)phantom_timing0->h_total * 1000000),
@@ -853,7 +855,6 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,*/ if (resource_is_pipe_type (pipe,OTG_MASTER ) &&resource_is_pipe_type (pipe,DPP_PIPE ) && - pipe->stream->mall_stream_config.paired_stream && pipe_mall_type ==SUBVP_MAIN ) {populate_subvp_cmd_pipe_info (dc, context, &cmd, pipe, cmd_pipe_index++); } else if (resource_is_pipe_type(pipe, OTG_MASTER) &&
drivers/gpu/drm/amd/display/dc/dc_state.h +5 -1
@@ -29,9 +29,13 @@#include "dc.h" #include "inc/core_status.h" -struct dc_state *dc_state_create (struct dc *dc); +void dc_state_copy (struct dc_state *dst_state,struct dc_state *src_state);struct dc_state *dc_state_create_copy (struct dc_state *src_state); +void dc_state_copy_current (struct dc *dc,struct dc_state *dst_state); +struct dc_state *dc_state_create_current_copy (struct dc *dc); +void dc_state_construct (struct dc *dc,struct dc_state *state); +void dc_state_destruct (struct dc_state *state);void dc_state_retain (struct dc_state *state);void dc_state_release (struct dc_state *state);
drivers/gpu/drm/amd/display/dc/dc_state_priv.h +10 -5
@@ -29,10 +29,6 @@#include "dc_state.h" #include "dc_stream.h" -struct dc_stream_status *dc_state_get_stream_status ( -struct dc_state *state, -struct dc_stream_state *stream); -/* Get the type of the provided resource (none, phantom, main) based on the provided * context. If the context is unavailable, determine only if phantom or not. */
@@ -85,7 +81,8 @@ bool dc_state_remove_phantom_plane(bool dc_state_rem_all_phantom_planes_for_stream (const struct dc *dc,struct dc_stream_state *phantom_stream, -struct dc_state *state); +struct dc_state *state, +bool should_release_planes); bool dc_state_add_all_phantom_planes_for_stream( const struct dc *dc,
@@ -94,4 +91,12 @@ bool dc_state_add_all_phantom_planes_for_stream(int plane_count, struct dc_state *state); +bool dc_state_remove_phantom_streams_and_planes ( +struct dc *dc, +struct dc_state *state); + +void dc_state_release_phantom_streams_and_planes ( +struct dc *dc, +struct dc_state *state); +#endif /* _DC_STATE_PRIV_H_ */
drivers/gpu/drm/amd/display/dc/dc_stream.h +10 -20
@@ -38,6 +38,14 @@ struct timing_sync_info {bool master; }; +struct mall_stream_config { +/* MALL stream config to indicate if the stream is phantom or not. +* We will use a phantom stream to indicate that the pipe is phantom. +*/ +enum mall_stream_type type; +struct dc_stream_state *paired_stream;// master / slave stream +}; +struct dc_stream_status {int primary_otg_inst;int stream_enc_inst;
@@ -50,6 +58,7 @@ struct dc_stream_status {struct timing_sync_info timing_sync_info;struct dc_plane_state *plane_states[MAX_SURFACE_NUM ];bool is_abm_supported; +struct mall_stream_config mall_stream_config; };enum hubp_dmdata_mode {
@@ -146,25 +155,6 @@ struct test_pattern {#define SUBVP_DRR_MARGIN_US 100 // 100us for DRR margin (SubVP + DRR) -struct mall_stream_config { -/* MALL stream config to indicate if the stream is phantom or not. -* We will use a phantom stream to indicate that the pipe is phantom. -*/ -enum mall_stream_type type; -struct dc_stream_state *paired_stream;// master / slave stream -}; - -/* Temp struct used to save and restore MALL config -* during validation. -* -* TODO: Move MALL config into dc_state instead of stream struct -* to avoid needing to save/restore. -*/ -struct mall_temp_config { -struct mall_stream_config mall_stream_config[MAX_PIPES ]; -bool is_phantom_plane[MAX_PIPES ]; -}; -struct dc_stream_debug_options {char force_odm_combine_segments; };
@@ -294,7 +284,7 @@ struct dc_stream_state {bool has_non_synchronizable_pclk;bool vblank_synchronized;bool fpo_in_use; -struct mall_stream_config mall_stream_config; +bool is_phantom; };#define ABM_LEVEL_IMMEDIATE_DISABLE 255
drivers/gpu/drm/amd/display/dc/dc_stream_priv.h +2 -0
@@ -32,4 +32,6 @@ bool dc_stream_construct(struct dc_stream_state *stream, struct dc_sink *dc_sink_data);void dc_stream_destruct (struct dc_stream_state *stream); +void dc_stream_assign_stream_id (struct dc_stream_state *stream); +#endif // _DC_STREAM_PRIV_H_
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c +0 -65
71 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +4 -2
@@ -1539,7 +1539,8 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,// If SubVP pipe config is unsupported (or cannot be used for UCLK switching) // remove phantom pipes and repopulate dml pipes if (!found_supported_config) { - dc->res_pool->funcs->remove_phantom_pipes (dc, context, false); +dc_state_remove_phantom_streams_and_planes (dc, context); +dc_state_release_phantom_streams_and_planes (dc, context); vba->DRAMClockChangeSupport[*vlevel][vba->maxMpcComb] = dm_dram_clock_change_unsupported; *pipe_cnt = dc->res_pool->funcs->populate_dml_pipes (dc, context, pipes, false);
@@ -1937,7 +1938,8 @@ bool dcn32_internal_validate_bw(struct dc *dc,return false;// For each full update, remove all existing phantom pipes first - dc->res_pool->funcs->remove_phantom_pipes (dc, context, fast_validate); +dc_state_remove_phantom_streams_and_planes (dc, context); +dc_state_release_phantom_streams_and_planes (dc, context); dc->res_pool->funcs->update_soc_for_wm_a (dc, context);
drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c +7 -23
@@ -807,7 +807,7 @@ static void add_phantom_pipes_for_main_pipe(struct dml2_context *ctx, struct dc_ } } -static bool remove_all_planes_for_stream (struct dml2_context *ctx,struct dc_stream_state *stream,struct dc_state *context) +static bool remove_all_phantom_planes_for_stream (struct dml2_context *ctx,struct dc_stream_state *stream,struct dc_state *context) {int i, old_plane_count;struct dc_stream_status *stream_status =NULL ;
@@ -828,9 +828,11 @@ static bool remove_all_planes_for_stream(struct dml2_context *ctx, struct dc_strfor (i =0 ; i < old_plane_count; i++) del_planes[i] = stream_status->plane_states[i]; -for (i =0 ; i < old_plane_count; i++) +for (i =0 ; i < old_plane_count; i++) {if (!ctx->config.svp_pstate.callbacks.remove_phantom_plane (ctx->config.svp_pstate.callbacks.dc, stream, del_planes[i], context))return false; + ctx->config.svp_pstate.callbacks.release_phantom_plane (ctx->config.svp_pstate.callbacks.dc, context, del_planes[i]); + }return true; }
@@ -839,39 +841,21 @@ bool dml2_svp_remove_all_phantom_pipes(struct dml2_context *ctx, struct dc_state {int i;bool removed_pipe = false; -struct dc_plane_state *phantom_plane =NULL ;struct dc_stream_state *phantom_stream =NULL ;for (i =0 ; i < ctx->config.dcn_pipe_count; i++) {struct pipe_ctx *pipe = &state->res_ctx.pipe_ctx[i];// build scaling params for phantom pipes if (pipe->plane_state && pipe->stream && ctx->config.svp_pstate.callbacks.get_pipe_subvp_type (state, pipe) ==SUBVP_PHANTOM ) { - phantom_plane = pipe->plane_state; phantom_stream = pipe->stream; -remove_all_planes_for_stream (ctx, pipe->stream, state); - ctx->config.svp_pstate.callbacks.remove_phantom_stream (ctx->config.svp_pstate.callbacks.dc, state, pipe->stream); - -/* Ref count is incremented on allocation and also when added to the context. -* Therefore we must call release for the the phantom plane and stream once -* they are removed from the ctx to finally decrement the refcount to 0 to free. -*/ - ctx->config.svp_pstate.callbacks.release_phantom_plane (ctx->config.svp_pstate.callbacks.dc, - state, - phantom_plane); - ctx->config.svp_pstate.callbacks.release_phantom_stream (ctx->config.svp_pstate.callbacks.dc, - state, - phantom_stream); +remove_all_phantom_planes_for_stream (ctx, phantom_stream, state); + ctx->config.svp_pstate.callbacks.remove_phantom_stream (ctx->config.svp_pstate.callbacks.dc, state, phantom_stream); + ctx->config.svp_pstate.callbacks.release_phantom_stream (ctx->config.svp_pstate.callbacks.dc, state, phantom_stream); removed_pipe = true; } -// Clear all phantom stream info -if (pipe->stream) { - pipe->stream->mall_stream_config.type =SUBVP_NONE ; - pipe->stream->mall_stream_config.paired_stream =NULL ; - } -if (pipe->plane_state) { pipe->plane_state->is_phantom = false; }
drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h +4 -1
@@ -104,7 +104,10 @@ struct dml2_dc_svp_callbacks {struct dc_stream_state *phantom_stream, struct dc_stream_state *main_stream);bool (*add_phantom_plane)(const struct dc *dc,struct dc_stream_state *stream,struct dc_plane_state *plane_state,struct dc_state *context); -bool (*remove_phantom_plane)(const struct dc *dc,struct dc_stream_state *stream,struct dc_plane_state *plane_state,struct dc_state *context); +bool (*remove_phantom_plane)(const struct dc *dc, +struct dc_stream_state *stream, +struct dc_plane_state *plane_state, +struct dc_state *context);enum dc_status (*remove_phantom_stream)(struct dc *dc,struct dc_state *state,struct dc_stream_state *stream);
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +4 -3
@@ -1684,7 +1684,7 @@ static void disable_vga_and_power_gate_all_controllers( true); dc->current_state->res_ctx.pipe_ctx[i].pipe_idx = i; - dc->hwss.disable_plane (dc, + dc->hwss.disable_plane (dc, dc->current_state, &dc->current_state->res_ctx.pipe_ctx[i]); } }
@@ -2133,7 +2133,7 @@ static void dce110_reset_hw_ctx_wrap( old_clk)) old_clk->funcs->cs_power_down(old_clk); - dc->hwss.disable_plane (dc, pipe_ctx_old); + dc->hwss.disable_plane (dc, dc->current_state, pipe_ctx_old); pipe_ctx_old->stream =NULL ; }
@@ -2497,6 +2497,7 @@ static bool wait_for_reset_trigger_to_occur(/* Enable timing synchronization for a group of Timing Generators. */ static void dce110_enable_timing_synchronization (struct dc *dc, +struct dc_state *state,int group_index,int group_size,struct pipe_ctx *grouped_pipes[])
@@ -2842,7 +2843,7 @@ static void dce110_post_unlock_program_front_end( { } -static void dce110_power_down_fe (struct dc *dc,struct pipe_ctx *pipe_ctx) +static void dce110_power_down_fe (struct dc *dc,struct dc_state *state,struct pipe_ctx *pipe_ctx) {struct dce_hwseq *hws = dc->hwseq; int fe_idx = pipe_ctx->plane_res.mi ?
drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c +14 -11
@@ -1181,7 +1181,9 @@ void dcn10_verify_allow_pstate_change_high(struct dc *dc) }/* trigger HW to start disconnect plane from stream on the next vsync */ -void dcn10_plane_atomic_disconnect (struct dc *dc,struct pipe_ctx *pipe_ctx) +void dcn10_plane_atomic_disconnect (struct dc *dc, +struct dc_state *state, +struct pipe_ctx *pipe_ctx) {struct dce_hwseq *hws = dc->hwseq;struct hubp *hubp = pipe_ctx->plane_res.hubp;
@@ -1201,7 +1203,7 @@ void dcn10_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx) mpc->funcs->remove_mpcc (mpc, mpc_tree_params, mpcc_to_remove);// Phantom pipes have OTG disabled by default, so MPCC_STATUS will never assert idle, // so don't wait for MPCC_IDLE in the programming sequence -if (opp !=NULL &&dc_state_get_pipe_subvp_type (NULL , pipe_ctx) !=SUBVP_PHANTOM ) +if (opp !=NULL &&dc_state_get_pipe_subvp_type (state, pipe_ctx) !=SUBVP_PHANTOM ) opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true; dc->optimized_required = true;
@@ -1291,7 +1293,7 @@ void dcn10_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx) pipe_ctx->plane_state =NULL ; } -void dcn10_disable_plane (struct dc *dc,struct pipe_ctx *pipe_ctx) +void dcn10_disable_plane (struct dc *dc,struct dc_state *state,struct pipe_ctx *pipe_ctx) {struct dce_hwseq *hws = dc->hwseq;DC_LOGGER_INIT (dc->ctx->logger);
@@ -1417,12 +1419,12 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state *context) dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true; pipe_ctx->stream_res.opp = dc->res_pool->opps[i]; - hws->funcs.plane_atomic_disconnect (dc, pipe_ctx); + hws->funcs.plane_atomic_disconnect (dc, context, pipe_ctx);if (tg->funcs->is_tg_enabled (tg)) tg->funcs->unlock (tg); - dc->hwss.disable_plane (dc, pipe_ctx); + dc->hwss.disable_plane (dc, context, pipe_ctx); pipe_ctx->stream_res.tg =NULL ; pipe_ctx->plane_res.hubp =NULL ;
@@ -2263,6 +2265,7 @@ void dcn10_enable_vblanks_synchronization(void dcn10_enable_timing_synchronization (struct dc *dc, +struct dc_state *state,int group_index,int group_size,struct pipe_ctx *grouped_pipes[])
@@ -2277,7 +2280,7 @@ void dcn10_enable_timing_synchronization(DC_SYNC_INFO ("Setting up OTG reset trigger\n" );for (i =1 ; i < group_size; i++) { -if (grouped_pipes[i]->stream &&dc_state_get_pipe_subvp_type (NULL , grouped_pipes[i]) ==SUBVP_PHANTOM ) +if (grouped_pipes[i]->stream &&dc_state_get_pipe_subvp_type (state, grouped_pipes[i]) ==SUBVP_PHANTOM )continue ; opp = grouped_pipes[i]->stream_res.opp;
@@ -2297,14 +2300,14 @@ void dcn10_enable_timing_synchronization(if (grouped_pipes[i]->stream ==NULL )continue ; -if (grouped_pipes[i]->stream &&dc_state_get_pipe_subvp_type (NULL , grouped_pipes[i]) ==SUBVP_PHANTOM ) +if (grouped_pipes[i]->stream &&dc_state_get_pipe_subvp_type (state, grouped_pipes[i]) ==SUBVP_PHANTOM )continue ; grouped_pipes[i]->stream->vblank_synchronized = false; }for (i =1 ; i < group_size; i++) { -if (grouped_pipes[i]->stream &&dc_state_get_pipe_subvp_type (NULL , grouped_pipes[i]) ==SUBVP_PHANTOM ) +if (grouped_pipes[i]->stream &&dc_state_get_pipe_subvp_type (state, grouped_pipes[i]) ==SUBVP_PHANTOM )continue ; grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger(
@@ -2318,11 +2321,11 @@ void dcn10_enable_timing_synchronization(* synchronized. Look at last pipe programmed to reset. */ -if (grouped_pipes[1 ]->stream &&dc_state_get_pipe_subvp_type (NULL , grouped_pipes[1 ]) !=SUBVP_PHANTOM ) +if (grouped_pipes[1 ]->stream &&dc_state_get_pipe_subvp_type (state, grouped_pipes[1 ]) !=SUBVP_PHANTOM )wait_for_reset_trigger_to_occur (dc_ctx, grouped_pipes[1 ]->stream_res.tg);for (i =1 ; i < group_size; i++) { -if (grouped_pipes[i]->stream &&dc_state_get_pipe_subvp_type (NULL , grouped_pipes[i]) ==SUBVP_PHANTOM ) +if (grouped_pipes[i]->stream &&dc_state_get_pipe_subvp_type (state, grouped_pipes[i]) ==SUBVP_PHANTOM )continue ; grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger(
@@ -3022,7 +3025,7 @@ void dcn10_post_unlock_program_front_end(for (i =0 ; i < dc->res_pool->pipe_count; i++)if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable) - dc->hwss.disable_plane (dc, &dc->current_state->res_ctx.pipe_ctx[i]); + dc->hwss.disable_plane (dc, dc->current_state, &dc->current_state->res_ctx.pipe_ctx[i]);for (i =0 ; i < dc->res_pool->pipe_count; i++)if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable) {
drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h +5 -2
@@ -75,7 +75,7 @@ void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx);void dcn10_reset_hw_ctx_wrap (struct dc *dc,struct dc_state *context); -void dcn10_disable_plane (struct dc *dc,struct pipe_ctx *pipe_ctx); +void dcn10_disable_plane (struct dc *dc,struct dc_state *state,struct pipe_ctx *pipe_ctx); void dcn10_lock_all_pipes( struct dc *dc, struct dc_state *context,
@@ -108,13 +108,16 @@ void dcn10_power_down_on_boot(struct dc *dc);enum dc_status dce110_apply_ctx_to_hw (struct dc *dc,struct dc_state *context); -void dcn10_plane_atomic_disconnect (struct dc *dc,struct pipe_ctx *pipe_ctx); +void dcn10_plane_atomic_disconnect (struct dc *dc, +struct dc_state *state, +struct pipe_ctx *pipe_ctx);void dcn10_update_dchub (struct dce_hwseq *hws,struct dchub_init_data *dh_data);void dcn10_update_pending_status (struct pipe_ctx *pipe_ctx);void dce110_power_down (struct dc *dc);void dce110_enable_accelerated_mode (struct dc *dc,struct dc_state *context);void dcn10_enable_timing_synchronization (struct dc *dc, +struct dc_state *state,int group_index,int group_size,struct pipe_ctx *grouped_pipes[]);
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +15 -12
@@ -624,9 +624,9 @@ void dcn20_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx) } -void dcn20_disable_plane (struct dc *dc,struct pipe_ctx *pipe_ctx) +void dcn20_disable_plane (struct dc *dc,struct dc_state *state,struct pipe_ctx *pipe_ctx) { -bool is_phantom =dc_state_get_pipe_subvp_type (NULL , pipe_ctx) ==SUBVP_PHANTOM ; +bool is_phantom =dc_state_get_pipe_subvp_type (state, pipe_ctx) ==SUBVP_PHANTOM ;struct timing_generator *tg = is_phantom ? pipe_ctx->stream_res.tg :NULL ;DC_LOGGER_INIT (dc->ctx->logger);
@@ -1369,10 +1369,13 @@ void dcn20_pipe_control_lock( } } -static void dcn20_detect_pipe_changes (struct pipe_ctx *old_pipe,struct pipe_ctx *new_pipe) +static void dcn20_detect_pipe_changes (struct dc_state *old_state, +struct dc_state *new_state, +struct pipe_ctx *old_pipe, +struct pipe_ctx *new_pipe) { -bool old_is_phantom =dc_state_get_pipe_subvp_type (NULL , old_pipe) ==SUBVP_PHANTOM ; -bool new_is_phantom =dc_state_get_pipe_subvp_type (NULL , new_pipe) ==SUBVP_PHANTOM ; +bool old_is_phantom =dc_state_get_pipe_subvp_type (old_state, old_pipe) ==SUBVP_PHANTOM ; +bool new_is_phantom =dc_state_get_pipe_subvp_type (new_state, new_pipe) ==SUBVP_PHANTOM ; new_pipe->update_flags.raw =0 ;
@@ -1420,7 +1423,7 @@ static void dcn20_detect_pipe_changes(struct pipe_ctx *old_pipe, struct pipe_ctx* The remove-add sequence of the phantom pipe always results in the pipe * being blanked in enable_stream_timing (DPG). */ -if (new_pipe->stream &&dc_state_get_pipe_subvp_type (NULL , new_pipe) ==SUBVP_PHANTOM ) +if (new_pipe->stream &&dc_state_get_pipe_subvp_type (new_state, new_pipe) ==SUBVP_PHANTOM ) new_pipe->update_flags.bits.enable =1 ;/* Phantom pipes are effectively disabled, if the pipe was previously phantom
@@ -1782,7 +1785,7 @@ 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 ) +if (dc_state_get_pipe_subvp_type (context, pipe_ctx) !=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(
@@ -1921,7 +1924,7 @@ void dcn20_program_front_end_for_ctx(/* Set pipe update flags and lock pipes */ for (i =0 ; i < dc->res_pool->pipe_count; i++) -dcn20_detect_pipe_changes (&dc->current_state->res_ctx.pipe_ctx[i], +dcn20_detect_pipe_changes (dc->current_state, context, &dc->current_state->res_ctx.pipe_ctx[i], &context->res_ctx.pipe_ctx[i]);/* When disabling phantom pipes, turn on phantom OTG first (so we can get double
@@ -1971,7 +1974,7 @@ void dcn20_program_front_end_for_ctx(if (hubbub->funcs->program_det_size && (context->res_ctx.pipe_ctx[i].update_flags.bits.disable || (context->res_ctx.pipe_ctx[i].plane_state &&dc_state_get_pipe_subvp_type (context, &context->res_ctx.pipe_ctx[i]) ==SUBVP_PHANTOM ))) hubbub->funcs->program_det_size (hubbub, dc->current_state->res_ctx.pipe_ctx[i].plane_res.hubp->inst,0 ); - hws->funcs.plane_atomic_disconnect (dc, &dc->current_state->res_ctx.pipe_ctx[i]); + hws->funcs.plane_atomic_disconnect (dc, dc->current_state, &dc->current_state->res_ctx.pipe_ctx[i]);DC_LOG_DC ("Reset mpcc for pipe %d\n" , dc->current_state->res_ctx.pipe_ctx[i].pipe_idx); }
@@ -2044,7 +2047,7 @@ void dcn20_post_unlock_program_front_end(for (i =0 ; i < dc->res_pool->pipe_count; i++)if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable) - dc->hwss.disable_plane (dc, &dc->current_state->res_ctx.pipe_ctx[i]); + dc->hwss.disable_plane (dc, dc->current_state, &dc->current_state->res_ctx.pipe_ctx[i]);/* * If we are enabling a pipe, we need to wait for pending clear as this is a critical
@@ -2954,7 +2957,7 @@ void dcn20_fpga_init_hw(struct dc *dc) dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true; pipe_ctx->stream_res.opp = dc->res_pool->opps[i];/*to do*/ - hws->funcs.plane_atomic_disconnect (dc, pipe_ctx); + hws->funcs.plane_atomic_disconnect (dc, context, pipe_ctx); }/* initialize DWB pointer to MCIF_WB */
@@ -2971,7 +2974,7 @@ void dcn20_fpga_init_hw(struct dc *dc)for (i =0 ; i < dc->res_pool->pipe_count; i++) {struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; - dc->hwss.disable_plane (dc, pipe_ctx); + dc->hwss.disable_plane (dc, context, pipe_ctx); pipe_ctx->stream_res.tg =NULL ; pipe_ctx->plane_res.hubp =NULL ;
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.h +1 -1
@@ -52,7 +52,7 @@ void dcn20_program_output_csc(struct dc *dc,void dcn20_enable_stream (struct pipe_ctx *pipe_ctx);void dcn20_unblank_stream (struct pipe_ctx *pipe_ctx,struct dc_link_settings *link_settings); -void dcn20_disable_plane (struct dc *dc,struct pipe_ctx *pipe_ctx); +void dcn20_disable_plane (struct dc *dc,struct dc_state *state,struct pipe_ctx *pipe_ctx); void dcn20_disable_pixel_data( struct dc *dc, struct pipe_ctx *pipe_ctx,
drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c +5 -3
@@ -320,7 +320,7 @@ void dcn201_init_hw(struct dc *dc) res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true; pipe_ctx->stream_res.opp = res_pool->opps[i];/*To do: number of MPCC != number of opp*/ - hws->funcs.plane_atomic_disconnect (dc, pipe_ctx); + hws->funcs.plane_atomic_disconnect (dc, context, pipe_ctx); }/* initialize DWB pointer to MCIF_WB */
@@ -337,7 +337,7 @@ void dcn201_init_hw(struct dc *dc)for (i =0 ; i < res_pool->pipe_count; i++) {struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; - dc->hwss.disable_plane (dc, pipe_ctx); + dc->hwss.disable_plane (dc, context, pipe_ctx); pipe_ctx->stream_res.tg =NULL ; pipe_ctx->plane_res.hubp =NULL ;
@@ -369,7 +369,9 @@ void dcn201_init_hw(struct dc *dc) }/* trigger HW to start disconnect plane from stream on the next vsync */ -void dcn201_plane_atomic_disconnect (struct dc *dc,struct pipe_ctx *pipe_ctx) +void dcn201_plane_atomic_disconnect (struct dc *dc, +struct dc_state *state, +struct pipe_ctx *pipe_ctx) {struct dce_hwseq *hws = dc->hwseq;struct hubp *hubp = pipe_ctx->plane_res.hubp;
drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.h +1 -1
@@ -33,7 +33,7 @@ void dcn201_init_hw(struct dc *dc);void dcn201_unblank_stream (struct pipe_ctx *pipe_ctx,struct dc_link_settings *link_settings);void dcn201_update_plane_addr (const struct dc *dc,struct pipe_ctx *pipe_ctx); -void dcn201_plane_atomic_disconnect (struct dc *dc,struct pipe_ctx *pipe_ctx); +void dcn201_plane_atomic_disconnect (struct dc *dc,struct dc_state *state,struct pipe_ctx *pipe_ctx);void dcn201_update_mpcc (struct dc *dc,struct pipe_ctx *pipe_ctx);void dcn201_set_cursor_attribute (struct pipe_ctx *pipe_ctx); void dcn201_pipe_control_lock(
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +16 -26
66 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +4 -4
@@ -814,12 +814,12 @@ void dcn35_init_pipes(struct dc *dc, struct dc_state *context) dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true; pipe_ctx->stream_res.opp = dc->res_pool->opps[i]; - hws->funcs.plane_atomic_disconnect (dc, pipe_ctx); + hws->funcs.plane_atomic_disconnect (dc, context, pipe_ctx);if (tg->funcs->is_tg_enabled (tg)) tg->funcs->unlock (tg); - dc->hwss.disable_plane (dc, pipe_ctx); + dc->hwss.disable_plane (dc, context, pipe_ctx); pipe_ctx->stream_res.tg =NULL ; pipe_ctx->plane_res.hubp =NULL ;
@@ -946,10 +946,10 @@ void dcn35_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx) pipe_ctx->plane_state =NULL ; } -void dcn35_disable_plane (struct dc *dc,struct pipe_ctx *pipe_ctx) +void dcn35_disable_plane (struct dc *dc,struct dc_state *state,struct pipe_ctx *pipe_ctx) {struct dce_hwseq *hws = dc->hwseq; -bool is_phantom =dc_state_get_pipe_subvp_type (NULL , pipe_ctx) ==SUBVP_PHANTOM ; +bool is_phantom =dc_state_get_pipe_subvp_type (state, pipe_ctx) ==SUBVP_PHANTOM ;struct timing_generator *tg = is_phantom ? pipe_ctx->stream_res.tg :NULL ;DC_LOGGER_INIT (dc->ctx->logger);
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h +1 -1
@@ -57,7 +57,7 @@ void dcn35_init_pipes(struct dc *dc, struct dc_state *context);void dcn35_plane_atomic_disable (struct dc *dc,struct pipe_ctx *pipe_ctx);void dcn35_enable_plane (struct dc *dc,struct pipe_ctx *pipe_ctx,struct dc_state *context); -void dcn35_disable_plane (struct dc *dc,struct pipe_ctx *pipe_ctx); +void dcn35_disable_plane (struct dc *dc,struct dc_state *state,struct pipe_ctx *pipe_ctx);void dcn35_calc_blocks_to_gate (struct dc *dc,struct dc_state *context,struct pg_block_update *update_state);
drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h +5 -3
@@ -50,7 +50,7 @@ struct pg_block_update;struct subvp_pipe_control_lock_fast_params {struct dc *dc;bool lock; -struct pipe_ctx *pipe_ctx; +bool subvp_immediate_flip; };struct pipe_control_lock_params {
@@ -200,7 +200,7 @@ struct hw_sequencer_funcs { struct dc_state *context);enum dc_status (*apply_ctx_to_hw)(struct dc *dc,struct dc_state *context); -void (*disable_plane)(struct dc *dc,struct pipe_ctx *pipe_ctx); +void (*disable_plane)(struct dc *dc,struct dc_state *state,struct pipe_ctx *pipe_ctx);void (*disable_pixel_data)(struct dc *dc,struct pipe_ctx *pipe_ctx,bool blank); void (*apply_ctx_for_surface)(struct dc *dc, const struct dc_stream_state *stream,
@@ -248,6 +248,7 @@ struct hw_sequencer_funcs {void (*enable_per_frame_crtc_position_reset)(struct dc *dc,int group_size,struct pipe_ctx *grouped_pipes[]);void (*enable_timing_synchronization)(struct dc *dc, +struct dc_state *state,int group_index,int group_size,struct pipe_ctx *grouped_pipes[]); void (*enable_vblanks_synchronization)(struct dc *dc,
@@ -474,7 +475,8 @@ void hwss_build_fast_sequence(struct dc *dc,unsigned int dmub_cmd_count, struct block_sequence block_sequence[], int *num_steps, - struct pipe_ctx *pipe_ctx); + struct pipe_ctx *pipe_ctx, + struct dc_stream_status *stream_status);void hwss_send_dmcub_cmd (union block_sequence_params *params);
drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h +1 -0
@@ -79,6 +79,7 @@ struct hwseq_private_funcs {void (*update_plane_addr)(const struct dc *dc,struct pipe_ctx *pipe_ctx);void (*plane_atomic_disconnect)(struct dc *dc, +struct dc_state *state,struct pipe_ctx *pipe_ctx);void (*update_mpcc)(struct dc *dc,struct pipe_ctx *pipe_ctx); bool (*set_input_transfer_func)(struct dc *dc,
drivers/gpu/drm/amd/display/dc/inc/core_types.h +16 -4
@@ -200,11 +200,7 @@ struct resource_funcs {unsigned int pipe_cnt, unsigned int index); -bool (*remove_phantom_pipes)(struct dc *dc,struct dc_state *context,bool fast_update); -void (*retain_phantom_pipes)(struct dc *dc,struct dc_state *context);void (*get_panel_config_defaults)(struct dc_panel_config *panel_config); -void (*save_mall_state)(struct dc *dc,struct dc_state *context,struct mall_temp_config *temp_config); -void (*restore_mall_state)(struct dc *dc,struct dc_state *context,struct mall_temp_config *temp_config);void (*build_pipe_pix_clk_params)(struct pipe_ctx *pipe_ctx); };
@@ -526,6 +522,14 @@ struct dc_state {* @stream_status: Planes status on a given stream */ struct dc_stream_status stream_status[MAX_PIPES ]; +/** +* @phantom_streams: Stream state properties for phantoms +*/ +struct dc_stream_state *phantom_streams[MAX_PHANTOM_PIPES ]; +/** +* @phantom_planes: Planes state properties for phantoms +*/ +struct dc_plane_state *phantom_planes[MAX_PHANTOM_PIPES ];/** * @stream_count: Total of streams in use
@@ -533,6 +537,14 @@ struct dc_state {uint8_t stream_count;uint8_t stream_mask; +/** +* @stream_count: Total phantom streams in use +*/ +uint8_t phantom_stream_count; +/** +* @stream_count: Total phantom planes in use +*/ +uint8_t phantom_plane_count;/** * @res_ctx: Persistent state of resources */
drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h +1 -0
@@ -43,6 +43,7 @@* to be used inside loops and for determining array sizes. */ #define MAX_PIPES 6 +#define MAX_PHANTOM_PIPES (MAX_PIPES / 2)#define MAX_DIG_LINK_ENCODERS 7#define MAX_DWB_PIPES 1#define MAX_HPO_DP2_ENCODERS 4
drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +0 -85
115 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h +0 -14
@@ -91,12 +91,6 @@ bool dcn32_release_post_bldn_3dlut(struct dc_3dlut **lut, struct dc_transfer_func **shaper); -bool dcn32_remove_phantom_pipes (struct dc *dc, -struct dc_state *context,bool fast_update); - -void dcn32_retain_phantom_pipes (struct dc *dc, -struct dc_state *context); - void dcn32_add_phantom_pipes(struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes,
@@ -169,14 +163,6 @@ void dcn32_determine_det_override(struct dc *dc,void dcn32_set_det_allocations (struct dc *dc,struct dc_state *context,display_e2e_pipe_params_st *pipes); -void dcn32_save_mall_state (struct dc *dc, -struct dc_state *context, -struct mall_temp_config *temp_config); - -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);
drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c +0 -4
@@ -1607,10 +1607,6 @@ static struct resource_funcs dcn321_res_pool_funcs = { .patch_unknown_plane_state = dcn20_patch_unknown_plane_state, .update_soc_for_wm_a = dcn30_update_soc_for_wm_a, .add_phantom_pipes = dcn32_add_phantom_pipes, - .remove_phantom_pipes = dcn32_remove_phantom_pipes, - .retain_phantom_pipes = dcn32_retain_phantom_pipes, - .save_mall_state = dcn32_save_mall_state, - .restore_mall_state = dcn32_restore_mall_state, .build_pipe_pix_clk_params = dcn20_build_pipe_pix_clk_params, };
Signature · 1 line
2.37.3
PATCH 20/25 drm/amd/display: Fix lightup regression with DP2 single display configs
In reply to Wayne LinFrom: Michael Strauss <[email protected]>
[WHY]
Previous fix for multiple displays downstream of DP2 MST hub caused regression
[HOW]
Match sink IDs instead of sink struct addresses
--- drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c +8 -0
@@ -161,6 +161,14 @@ bool is_dp2p0_output_encoder(const struct pipe_ctx *pipe_ctx)if (pipe_ctx->stream ==NULL )return false; +/* Count MST hubs once by treating only 1st remote sink in topology as an encoder */ +if (pipe_ctx->stream->link && pipe_ctx->stream->link->remote_sinks[0 ]) { +return (pipe_ctx->stream_res.hpo_dp_stream_enc && + pipe_ctx->link_res.hpo_dp_link_enc && +dc_is_dp_signal (pipe_ctx->stream->signal) && + (pipe_ctx->stream->link->remote_sinks[0 ]->sink_id == pipe_ctx->stream->sink->sink_id)); + } +return (pipe_ctx->stream_res.hpo_dp_stream_enc && pipe_ctx->link_res.hpo_dp_link_enc &&dc_is_dp_signal (pipe_ctx->stream->signal));
Signature · 1 line
2.37.3
PATCH 21/25 drm/amd/display: Only clear symclk otg flag for HDMI
In reply to Wayne LinFrom: Alvin Lee <[email protected]>
[Description]
There is a corner case where the symclk otg flag is cleared when disabling the phantom pipe for subvp (because the phantom and main pipe share the same link). This is undesired because we need the maintain the correct symclk otg flag state for the main pipe.
For now only clear the flag only for HDMI signal type, since it's only set for HDMI signal type (phantom is virtual). The ideal solution is to not clear it if the stream is phantom but currently there's a bug that doesn't allow us to do this. Once this issue is fixed the proper fix can be implemented.
--- drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 3 ++- drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 3 ++- drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 3 ++- drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +2 -1
@@ -2124,7 +2124,8 @@ static void dce110_reset_hw_ctx_wrap(BREAK_TO_DEBUGGER (); } pipe_ctx_old->stream_res.tg->funcs->disable_crtc (pipe_ctx_old->stream_res.tg); - pipe_ctx_old->stream->link->phy_state.symclk_ref_cnts.otg =0 ; +if (dc_is_hdmi_tmds_signal (pipe_ctx_old->stream->signal)) + pipe_ctx_old->stream->link->phy_state.symclk_ref_cnts.otg =0 ; pipe_ctx_old->plane_res.mi->funcs->free_mem_input ( pipe_ctx_old->plane_res.mi, dc->current_state->stream_count);
drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c +2 -1
@@ -1058,7 +1058,8 @@ static void dcn10_reset_back_end_for_pipe(if (pipe_ctx->stream_res.tg->funcs->set_drr) pipe_ctx->stream_res.tg->funcs->set_drr ( pipe_ctx->stream_res.tg,NULL ); - pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg =0 ; +if (dc_is_hdmi_tmds_signal (pipe_ctx->stream->signal)) + pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg =0 ; }for (i =0 ; i < dc->res_pool->pipe_count; i++)
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +2 -1
@@ -2624,7 +2624,8 @@ static void dcn20_reset_back_end_for_pipe(* the case where the same symclk is shared across multiple otg * instances */ - link->phy_state.symclk_ref_cnts.otg =0 ; +if (dc_is_hdmi_tmds_signal (pipe_ctx->stream->signal)) + link->phy_state.symclk_ref_cnts.otg =0 ;if (link->phy_state.symclk_state ==SYMCLK_ON_TX_OFF ) { link_hwss->disable_link_output (link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c +2 -1
@@ -524,7 +524,8 @@ static void dcn31_reset_back_end_for_pipe(if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass) pipe_ctx->stream_res.tg->funcs->set_odm_bypass ( pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); - pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg =0 ; +if (dc_is_hdmi_tmds_signal (pipe_ctx->stream->signal)) + pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg =0 ;if (pipe_ctx->stream_res.tg->funcs->set_drr) pipe_ctx->stream_res.tg->funcs->set_drr(
Signature · 1 line
2.37.3
PATCH 22/25 drm/amd/display: Fix hang/underflow when transitioning to ODM4:1
In reply to Wayne LinFrom: Ilya Bakoulin <[email protected]>
[Why]
Under some circumstances, disabling an OPTC and attempting to reclaim its OPP(s) for a different OPTC could cause a hang/underflow due to OPPs not being properly disconnected from the disabled OPTC.
[How]
Ensure that all OPPs are unassigned from an OPTC when it gets disabled.
--- drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c | 7 +++++++ drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c | 7 +++++++ 2 files changed, 14 insertions(+)
drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c +7 -0
@@ -172,6 +172,13 @@ static bool optc32_disable_crtc(struct timing_generator *optc)REG_UPDATE (OTG_CONTROL ,OTG_MASTER_EN ,0 ); +REG_UPDATE_5 (OPTC_DATA_SOURCE_SELECT , +OPTC_SEG0_SRC_SEL ,0xf , +OPTC_SEG1_SRC_SEL ,0xf , +OPTC_SEG2_SRC_SEL ,0xf , +OPTC_SEG3_SRC_SEL ,0xf , +OPTC_NUM_OF_INPUT_SEGMENT ,0 ); +REG_UPDATE (CONTROL ,VTG0_ENABLE ,0 );
drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c +7 -0
@@ -144,6 +144,13 @@ static bool optc35_disable_crtc(struct timing_generator *optc)REG_UPDATE (OTG_CONTROL ,OTG_MASTER_EN ,0 ); +REG_UPDATE_5 (OPTC_DATA_SOURCE_SELECT , +OPTC_SEG0_SRC_SEL ,0xf , +OPTC_SEG1_SRC_SEL ,0xf , +OPTC_SEG2_SRC_SEL ,0xf , +OPTC_SEG3_SRC_SEL ,0xf , +OPTC_NUM_OF_INPUT_SEGMENT ,0 ); +REG_UPDATE (CONTROL ,VTG0_ENABLE ,0 );
Signature · 1 line
2.37.3
PATCH 23/25 drm/amd/display: change static screen wait frame_count for ips
In reply to Wayne LinFrom: Allen Pan <[email protected]>
[Why]
the original wait for 2 static frames before enter static screen was not good enough for IPS-enabled case since enter/exit takes more time.
[How]
Changed logic for hardcoded wait frame values.
--- drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../gpu/drm/amd/display/dc/dcn35/dcn35_init.c | 2 +- .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 41 +++++++++++++++++++ .../amd/display/dc/hwss/dcn35/dcn35_hwseq.h | 4 ++ .../dc/resource/dcn35/dcn35_resource.c | 3 +- 5 files changed, 49 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/dc.h +1 -0
@@ -982,6 +982,7 @@ struct dc_debug_options {unsigned int ips2_entry_delay_us;bool disable_timeout;bool disable_extblankadj; +unsigned int static_screen_wait_frames; };struct gpu_info_soc_bounding_box_v1_0 ;
drivers/gpu/drm/amd/display/dc/dcn35/dcn35_init.c +1 -1
@@ -68,7 +68,7 @@ static const struct hw_sequencer_funcs dcn35_funcs = { .prepare_bandwidth = dcn35_prepare_bandwidth, .optimize_bandwidth = dcn35_optimize_bandwidth, .update_bandwidth = dcn20_update_bandwidth, - .set_drr = dcn10_set_drr, + .set_drr = dcn35_set_drr, .get_position = dcn10_get_position, .set_static_screen_control = dcn30_set_static_screen_control, .setup_stereo = dcn10_setup_stereo,
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +41 -0
44 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h +4 -0
@@ -86,4 +86,8 @@ void dcn35_dsc_pg_control(void dcn35_set_idle_state (const struct dc *dc,bool allow_idle);uint32_t dcn35_get_idle_state (const struct dc *dc); + +void dcn35_set_drr (struct pipe_ctx **pipe_ctx, +int num_pipes,struct dc_crtc_timing_adjust adjust); +#endif /* __DC_HWSS_DCN35_H__ */
drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +2 -1
@@ -780,7 +780,8 @@ static const struct dc_debug_options debug_defaults_drv = { .ignore_pg = true, .psp_disabled_wa = true, .ips2_eval_delay_us = 200, - .ips2_entry_delay_us = 400 + .ips2_entry_delay_us = 400, + .static_screen_wait_frames = 2, };static const struct dc_panel_config panel_config_defaults = {
Signature · 1 line
2.37.3
PATCH 24/25 drm/amd/display: [FW Promotion] Release 0.0.197.0
In reply to Wayne LinFrom: Anthony Koo <[email protected]>
- Remove unused dmub_fw_boot_options flag
--- drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +1 -1
@@ -653,7 +653,7 @@ union dmub_fw_boot_options { uint32_t gpint_scratch8: 1; /* 1 if GPINT is in scratch8*/ 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 reserved0: 1; uint32_t disable_clk_ds: 1; /* 1 if disallow dispclk_ds and dppclk_ds*/ uint32_t disable_timeout_recovery : 1; /* 1 if timeout recovery should be disabled */ uint32_t ips_pg_disable: 1; /* 1 to disable ONO domains power gating*/
Signature · 1 line
2.37.3
PATCH 25/25 drm/amd/display: 3.2.265
In reply to Wayne LinFrom: Aric Cyr <[email protected]>
This DC patchset brings improvements in multiple areas. In summary, we highlight:
- change static screen wait frame_count for ips
- Fix hang/underflow when transitioning to ODM4:1
- Only clear symclk otg flag for HDMI
- Fix lightup regression with DP2 single display configs
- Refactor phantom resource allocation
- Refactor dc_state interface
- Wake DMCUB before executing GPINT commands
- Wake DMCUB before sending a command
- Refactor DMCUB enter/exit idle interface
- enable dcn35 idle power optimization
- fix usb-c connector_type
- add debug option for ExtendedVBlank DLG adjust
- Set test_pattern_changed update flag on pipe enable
- dereference variable before checking for zero
- get dprefclk ss info from integration info table
- skip error logging when DMUB is inactive from S3
- make flip_timestamp_in_us a 64-bit variable
- Add case for dcn35 to support usb4 dmub hpd event
- Add function for dumping clk registers
- Unify optimize_required flags and VRR adjustments
- Revert using channel_width as 2 for vram table 3.0
- remove HPO PG in driver side
- do not send commands to DMUB if DMUB is inactive from S3
--- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dc.h +1 -1
@@ -51,7 +51,7 @@ struct aux_payload;struct set_config_cmd_payload ;struct dmub_notification ; -#define DC_VER "3.2.264" +#define DC_VER "3.2.265"#define MAX_SURFACES 3#define MAX_PLANES 6
Signature · 1 line
2.37.3
[Public]
Hi all,
This week this patchset was tested on the following systems:
* Lenovo ThinkBook T13s Gen4 with AMD Ryzen 5 6600U
* MSI Gaming X Trio RX 6800
* Gigabyte Gaming OC RX 7900 XTX
These systems were tested on the following display/connection types:
* eDP, (1080p 60hz [5650U]) (1920x1200 60hz [6600U]) (2560x1600 120hz[6600U])
* VGA and DVI (1680x1050 60hz [DP to VGA/DVI, USB-C to VGA/DVI])
* DP/HDMI/USB-C (1440p 170hz, 4k 60hz, 4k 144hz, 4k 240hz [Includes USB-C to DP/HDMI adapters])
* Thunderbolt (LG Ultrafine 5k)
* MST (Startech MST14DP123DP [DP to 3x DP] and 2x 4k 60Hz displays)
* DSC (with Cable Matters 101075 [DP to 3x DP] with 3x 4k60 displays, and HP Hook G2 with 1 4k60 display)
* USB 4 (Kensington SD5700T and 1x 4k 60Hz display)
* PCON (Club3D CAC-1085 and 1x 4k 144Hz display [at 4k 120HZ, as that is the max the adapter supports])
The testing is a mix of automated and manual tests. Manual testing includes (but is not limited to):
* Changing display configurations and settings
* Benchmark testing
* Feature testing (Freesync, etc.)
Automated testing includes (but is not limited to):
* Script testing (scripts to automate some of the manual checks)
* IGT testing
The patchset consists of the amd-staging-drm-next branch (Head commit - cf25f7abf109 drm/amdgpu: xgmi_fill_topology_info) with new patches added on top of it.
Tested on Ubuntu 22.04.3, on Wayland and X11, using KDE Plasma and Gnome.
Thank you,
Dan Wheeler
Sr. Technologist | AMD
SW Display
------------------------------------------------------------------------------------------------------------------
1 Commerce Valley Dr E, Thornhill, ON L3T 7X6
amd.com
-----Original Message-----
From: Wayne Lin <[email protected]>
Sent: Wednesday, December 13, 2023 1:12 AM
To: [email protected]
Cc: Wentland, Harry <[email protected]>; Li, Sun peng (Leo) <[email protected]>; Siqueira, Rodrigo <[email protected]>; Pillai, Aurabindo <[email protected]>; Li, Roman <[email protected]>; Lin, Wayne <[email protected]>; Wang, Chao-kai (Stylon) <[email protected]>; Gutierrez, Agustin <[email protected]>; Chung, ChiaHsuan (Tom) <[email protected]>; Wu, Hersen <[email protected]>; Zuo, Jerry <[email protected]>; Lin, Wayne <[email protected]>; Wheeler, Daniel <[email protected]>
Subject: [PATCH 00/25] DC Patches for Dec 18, 2023
This DC patchset brings improvements in multiple areas. In summary, we highlight:
- change static screen wait frame_count for ips
- Fix hang/underflow when transitioning to ODM4:1
- Only clear symclk otg flag for HDMI
- Fix lightup regression with DP2 single display configs
- Refactor phantom resource allocation
- Refactor dc_state interface
- Wake DMCUB before executing GPINT commands
- Wake DMCUB before sending a command
- Refactor DMCUB enter/exit idle interface
- enable dcn35 idle power optimization
- fix usb-c connector_type
- add debug option for ExtendedVBlank DLG adjust
- Set test_pattern_changed update flag on pipe enable
- dereference variable before checking for zero
- get dprefclk ss info from integration info table
- skip error logging when DMUB is inactive from S3
- make flip_timestamp_in_us a 64-bit variable
- Add case for dcn35 to support usb4 dmub hpd event
- Add function for dumping clk registers
- Unify optimize_required flags and VRR adjustments
- Revert using channel_width as 2 for vram table 3.0
- remove HPO PG in driver side
- do not send commands to DMUB if DMUB is inactive from S3
---
Allen Pan (2):
drm/amd/display: fix usb-c connector_type drm/amd/display: change static screen wait frame_count for ips
Alvin Lee (2):
drm/amd/display: Revert " drm/amd/display: Use channel_width = 2 for
vram table 3.0"
drm/amd/display: Only clear symclk otg flag for HDMI
Anthony Koo (1):
drm/amd/display: [FW Promotion] Release 0.0.197.0
Aric Cyr (2):
drm/amd/display: Unify optimize_required flags and VRR adjustments drm/amd/display: 3.2.265
Charlene Liu (1):
drm/amd/display: get dprefclk ss info from integration info table
Dillon Varone (2):
drm/amd/display: Refactor dc_state interface drm/amd/display: Refactor phantom resource allocation
George Shen (1):
drm/amd/display: Set test_pattern_changed update flag on pipe enable
Ilya Bakoulin (1):
drm/amd/display: Fix hang/underflow when transitioning to ODM4:1
Johnson Chen (1):
drm/amd/display: Add function for dumping clk registers
Josip Pavic (2):
drm/amd/display: make flip_timestamp_in_us a 64-bit variable drm/amd/display: dereference variable before checking for zero
Michael Strauss (1):
drm/amd/display: Fix lightup regression with DP2 single display
configs
Muhammad Ahmed (2):
drm/amd/display: remove HPO PG in driver side drm/amd/display: add debug option for ExtendedVBlank DLG adjust
Nicholas Kazlauskas (3):
drm/amd/display: Refactor DMCUB enter/exit idle interface drm/amd/display: Wake DMCUB before sending a command drm/amd/display: Wake DMCUB before executing GPINT commands
Roman Li (1):
drm/amd/display: enable dcn35 idle power optimization
Samson Tam (2):
drm/amd/display: do not send commands to DMUB if DMUB is inactive from
S3
drm/amd/display: skip error logging when DMUB is inactive from S3
Wayne Lin (1):
drm/amd/display: Add case for dcn35 to support usb4 dmub hpd event
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 59 +- .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 29 +- drivers/gpu/drm/amd/display/dc/Makefile | 2 +- .../drm/amd/display/dc/bios/bios_parser2.c | 27 +- .../drm/amd/display/dc/bios/command_table2.c | 12 +- .../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 3 +- .../display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c | 2 +- .../dc/clk_mgr/dcn314/dcn314_clk_mgr.c | 2 +- .../dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 2 +- .../dc/clk_mgr/dcn316/dcn316_clk_mgr.c | 2 +- .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 9 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 300 ++---- .../drm/amd/display/dc/core/dc_hw_sequencer.c | 19 +- .../gpu/drm/amd/display/dc/core/dc_resource.c | 418 +-------- .../gpu/drm/amd/display/dc/core/dc_state.c | 861 ++++++++++++++++++ .../gpu/drm/amd/display/dc/core/dc_stream.c | 46 +- .../gpu/drm/amd/display/dc/core/dc_surface.c | 6 +- drivers/gpu/drm/amd/display/dc/dc.h | 33 +- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 244 ++++- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 59 +- drivers/gpu/drm/amd/display/dc/dc_helper.c | 6 +- drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 2 +- drivers/gpu/drm/amd/display/dc/dc_plane.h | 38 + .../gpu/drm/amd/display/dc/dc_plane_priv.h | 34 + drivers/gpu/drm/amd/display/dc/dc_state.h | 78 ++ .../gpu/drm/amd/display/dc/dc_state_priv.h | 102 +++ drivers/gpu/drm/amd/display/dc/dc_stream.h | 76 +- .../gpu/drm/amd/display/dc/dc_stream_priv.h | 37 + drivers/gpu/drm/amd/display/dc/dc_types.h | 5 + .../gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c | 14 +- .../drm/amd/display/dc/dce/dmub_hw_lock_mgr.c | 2 +- .../gpu/drm/amd/display/dc/dce/dmub_outbox.c | 2 +- drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 33 +- .../gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c | 2 +- .../display/dc/dcn31/dcn31_dio_link_encoder.c | 4 +- .../amd/display/dc/dcn31/dcn31_panel_cntl.c | 4 +- .../display/dc/dcn32/dcn32_resource_helpers.c | 93 +- .../display/dc/dcn35/dcn35_dio_link_encoder.c | 5 + .../gpu/drm/amd/display/dc/dcn35/dcn35_init.c | 2 +- .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 5 +- .../drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 51 +- .../amd/display/dc/dml2/display_mode_core.c | 2 +- .../drm/amd/display/dc/dml2/dml2_dc_types.h | 1 + .../amd/display/dc/dml2/dml2_mall_phantom.c | 89 +- .../display/dc/dml2/dml2_translation_helper.c | 10 +- .../gpu/drm/amd/display/dc/dml2/dml2_utils.c | 14 +- .../drm/amd/display/dc/dml2/dml2_wrapper.c | 2 +- .../drm/amd/display/dc/dml2/dml2_wrapper.h | 35 +- .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 13 +- .../amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 35 +- .../amd/display/dc/hwss/dcn10/dcn10_hwseq.h | 7 +- .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 79 +- .../amd/display/dc/hwss/dcn20/dcn20_hwseq.h | 2 +- .../amd/display/dc/hwss/dcn201/dcn201_hwseq.c | 8 +- .../amd/display/dc/hwss/dcn201/dcn201_hwseq.h | 2 +- .../amd/display/dc/hwss/dcn21/dcn21_hwseq.c | 4 +- .../amd/display/dc/hwss/dcn30/dcn30_hwseq.c | 12 +- .../amd/display/dc/hwss/dcn31/dcn31_hwseq.c | 7 +- .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 78 +- .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 58 +- .../amd/display/dc/hwss/dcn35/dcn35_hwseq.h | 6 +- .../drm/amd/display/dc/hwss/hw_sequencer.h | 8 +- .../display/dc/hwss/hw_sequencer_private.h | 1 + .../gpu/drm/amd/display/dc/inc/core_types.h | 20 +- .../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h | 19 + .../gpu/drm/amd/display/dc/inc/hw/hw_shared.h | 1 + drivers/gpu/drm/amd/display/dc/inc/resource.h | 1 - .../dc/link/protocols/link_dp_capability.c | 2 +- .../display/dc/link/protocols/link_dp_dpia.c | 3 +- .../amd/display/dc/optc/dcn32/dcn32_optc.c | 7 + .../amd/display/dc/optc/dcn35/dcn35_optc.c | 7 + .../dc/resource/dcn32/dcn32_resource.c | 134 +-- .../dc/resource/dcn32/dcn32_resource.h | 14 - .../dc/resource/dcn321/dcn321_resource.c | 25 +- .../dc/resource/dcn35/dcn35_resource.c | 8 +- drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 22 + .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 2 +- .../gpu/drm/amd/display/dmub/src/dmub_srv.c | 15 + .../display/include/grph_object_ctrl_defs.h | 2 + 79 files changed, 2147 insertions(+), 1338 deletions(-) create mode 100644 drivers/gpu/drm/amd/display/dc/core/dc_state.c create mode 100644 drivers/gpu/drm/amd/display/dc/dc_plane.h create mode 100644 drivers/gpu/drm/amd/display/dc/dc_plane_priv.h create mode 100644 drivers/gpu/drm/amd/display/dc/dc_state.h create mode 100644 drivers/gpu/drm/amd/display/dc/dc_state_priv.h create mode 100644 drivers/gpu/drm/amd/display/dc/dc_stream_priv.h
--
2.37.3