drm/amd/display: add explicit handshake between x86 and DMCU
authorJun Lei <Jun.Lei@amd.com>
Mon, 8 Apr 2019 19:27:53 +0000 (15:27 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 23 Apr 2019 22:28:19 +0000 (17:28 -0500)
[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 <Jun.Lei@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h

index f7f7515..b0dea75 100644 (file)
@@ -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));
index 9ad7c54..818536e 100644 (file)
@@ -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,
index cbaa438..c68f0ce 100644 (file)
@@ -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