From a9a3c0da1427153e74a4ad97b1a897384a6b0404 Mon Sep 17 00:00:00 2001 From: Jun Lei Date: Mon, 8 Apr 2019 15:27:53 -0400 Subject: [PATCH] drm/amd/display: add explicit handshake between x86 and DMCU [why] When DMCU interrupts x86, it leads to undefined phy programming [how] expand dmcu interface to support new PHY lock and unlock commands if DMCU FW doesn't support these commands, they fail silently so its okay Signed-off-by: Jun Lei Reviewed-by: Anthony Koo Acked-by: Leo Li Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/core/dc_link_hwss.c | 21 ++++++++++++++++++- drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 4 +++- drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h | 2 ++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c index f7f7515f65f4..b0dea759cd86 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c @@ -58,6 +58,8 @@ void dp_enable_link_phy( const struct dc_link_settings *link_settings) { struct link_encoder *link_enc = link->link_enc; + struct dc *core_dc = link->ctx->dc; + struct dmcu *dmcu = core_dc->res_pool->dmcu; struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx; @@ -84,6 +86,9 @@ void dp_enable_link_phy( } } + if (dmcu != NULL && dmcu->funcs->lock_phy) + dmcu->funcs->lock_phy(dmcu); + if (dc_is_dp_sst_signal(signal)) { link_enc->funcs->enable_dp_output( link_enc, @@ -95,6 +100,10 @@ void dp_enable_link_phy( link_settings, clock_source); } + + if (dmcu != NULL && dmcu->funcs->unlock_phy) + dmcu->funcs->unlock_phy(dmcu); + link->cur_link_settings = *link_settings; dp_receiver_power_ctrl(link, true); @@ -150,15 +159,25 @@ bool edp_receiver_ready_T7(struct dc_link *link) void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) { + struct dc *core_dc = link->ctx->dc; + struct dmcu *dmcu = core_dc->res_pool->dmcu; + if (!link->wa_flags.dp_keep_receiver_powered) dp_receiver_power_ctrl(link, false); if (signal == SIGNAL_TYPE_EDP) { link->link_enc->funcs->disable_output(link->link_enc, signal); link->dc->hwss.edp_power_control(link, false); - } else + } else { + if (dmcu != NULL && dmcu->funcs->lock_phy) + dmcu->funcs->lock_phy(dmcu); + link->link_enc->funcs->disable_output(link->link_enc, signal); + if (dmcu != NULL && dmcu->funcs->unlock_phy) + dmcu->funcs->unlock_phy(dmcu); + } + /* Clear current link setting.*/ memset(&link->cur_link_settings, 0, sizeof(link->cur_link_settings)); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index 9ad7c543cc4c..818536eea00a 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -51,6 +51,8 @@ #define PSR_SET_WAITLOOP 0x31 #define MCP_INIT_DMCU 0x88 #define MCP_INIT_IRAM 0x89 +#define MCP_SYNC_PHY_LOCK 0x90 +#define MCP_SYNC_PHY_UNLOCK 0x91 #define MCP_BL_SET_PWM_FRAC 0x6A /* Enable or disable Fractional PWM */ #define MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK 0x00000001L @@ -719,7 +721,7 @@ static bool dcn10_is_dmcu_initialized(struct dmcu *dmcu) return true; } -#endif +#endif //(CONFIG_DRM_AMD_DC_DCN1_0) static const struct dmcu_funcs dce_funcs = { .dmcu_init = dce_dmcu_init, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h index cbaa43853611..c68f0ce346c7 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h @@ -70,6 +70,8 @@ struct dmcu_funcs { void (*get_psr_wait_loop)(struct dmcu *dmcu, unsigned int *psr_wait_loop_number); bool (*is_dmcu_initialized)(struct dmcu *dmcu); + bool (*lock_phy)(struct dmcu *dmcu); + bool (*unlock_phy)(struct dmcu *dmcu); }; #endif -- 2.30.2