From: Webb Chen <[email protected]>

[Why & How]
It is a SW lock mechanism to prevent racing with driver/FW.

Reviewed-by: Nicholas Kazlauskas <[email protected]>
Signed-off-by: Webb Chen <[email protected]>
Signed-off-by: Ray Wu <[email protected]>
---
 .../drm/amd/display/dc/dce/dmub_hw_lock_mgr.c |  5 +++
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c   | 45 +++++++++++++++++++
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.h   |  4 ++
 .../amd/display/dc/hwss/dcn35/dcn35_init.c    |  2 +
 .../amd/display/dc/hwss/dcn351/dcn351_init.c  |  2 +
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   |  3 +-
 6 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c 
b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c
index 7116fdd4c7ec..f68cb10ab38b 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c
@@ -105,5 +105,10 @@ bool should_use_dmub_inbox1_lock(const struct dc *dc, 
const struct dc_link *link
        if (dc->ctx->dce_version >= DCN_VERSION_4_01)
                return false;
 
+       if ((dc->hwss.dmub_hw_control_lock) &&
+               (dc->hwss.dmub_hw_control_lock_fast) &&
+               
(dc->ctx->dmub_srv->dmub->meta_info.feature_bits.bits.inbox0_lock_support))
+               return false;
+
        return dmub_hw_lock_mgr_does_link_require_lock(dc, link);
 }
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
index 0cbd75ab61a1..d757a0fdc62c 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
@@ -48,6 +48,7 @@
 #include "dpcd_defs.h"
 #include "dce/dmub_outbox.h"
 #include "link_service.h"
+#include "dce/dmub_hw_lock_mgr.h"
 #include "dcn10/dcn10_hwseq.h"
 #include "inc/link_enc_cfg.h"
 #include "dcn30/dcn30_vpg.h"
@@ -1778,3 +1779,47 @@ void dcn35_disable_link_output(struct dc_link *link,
 
        dc->link_srv->dp_trace_source_sequence(link, 
DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
 }
+
+void dcn35_dmub_hw_control_lock(struct dc *dc, struct dc_state *context, bool 
lock)
+{
+       /* use always for now */
+       union dmub_inbox0_cmd_lock_hw hw_lock_cmd = { 0 };
+
+       if (!dc->ctx || !dc->ctx->dmub_srv)
+               return;
+
+       /* if not support inbox0 lock, would not use inbox0 lock mechanism  */
+       if 
(!dc->ctx->dmub_srv->dmub->meta_info.feature_bits.bits.inbox0_lock_support)
+               return;
+
+       if (!dc_dmub_srv_is_cursor_offload_enabled(dc) &&
+               !dmub_hw_lock_mgr_does_context_require_lock(dc, context))
+               return;
+
+       hw_lock_cmd.bits.command_code = DMUB_INBOX0_CMD__HW_LOCK;
+       hw_lock_cmd.bits.hw_lock_client = HW_LOCK_CLIENT_DRIVER;
+       hw_lock_cmd.bits.lock = lock;
+       hw_lock_cmd.bits.should_release = !lock;
+       dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd);
+}
+
+void dcn35_dmub_hw_control_lock_fast(union block_sequence_params *params)
+{
+       struct dc *dc = params->dmub_hw_control_lock_fast_params.dc;
+       bool lock = params->dmub_hw_control_lock_fast_params.lock;
+
+       /* if not support inbox0 lock, would not use inbox0 lock mechanism  */
+       if 
(!dc->ctx->dmub_srv->dmub->meta_info.feature_bits.bits.inbox0_lock_support)
+               return;
+
+       if (params->dmub_hw_control_lock_fast_params.is_required) {
+               union dmub_inbox0_cmd_lock_hw hw_lock_cmd = { 0 };
+
+               hw_lock_cmd.bits.command_code = DMUB_INBOX0_CMD__HW_LOCK;
+               hw_lock_cmd.bits.hw_lock_client = HW_LOCK_CLIENT_DRIVER;
+               hw_lock_cmd.bits.lock = lock;
+               hw_lock_cmd.bits.should_release = !lock;
+               dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd);
+       }
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h
index e3459546a908..f84409f678ba 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h
@@ -27,6 +27,8 @@
 #ifndef __DC_HWSS_DCN35_H__
 #define __DC_HWSS_DCN35_H__
 
+#include "inc/core_types.h"
+#include "dc.h"
 #include "hw_sequencer_private.h"
 
 struct dc;
@@ -111,5 +113,7 @@ void dcn35_program_cursor_offload_now(struct dc *dc, const 
struct pipe_ctx *pipe
 void dcn35_disable_link_output(struct dc_link *link,
                const struct link_resource *link_res,
                enum signal_type signal);
+void dcn35_dmub_hw_control_lock(struct dc *dc, struct dc_state *context, bool 
lock);
+void dcn35_dmub_hw_control_lock_fast(union block_sequence_params *params);
 
 #endif /* __DC_HWSS_DCN35_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
index 6ac8ad97cf13..b3b4b8cae138 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
@@ -134,6 +134,8 @@ static const struct hw_sequencer_funcs dcn35_funcs = {
        .update_dchubp_dpp = dcn20_update_dchubp_dpp,
        .post_unlock_reset_opp = dcn20_post_unlock_reset_opp,
        .get_underflow_debug_data = dcn30_get_underflow_debug_data,
+       .dmub_hw_control_lock = dcn35_dmub_hw_control_lock,
+       .dmub_hw_control_lock_fast = dcn35_dmub_hw_control_lock_fast,
 };
 
 static const struct hwseq_private_funcs dcn35_private_funcs = {
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c
index 04c260015eec..a7006322cde4 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c
@@ -123,6 +123,8 @@ static const struct hw_sequencer_funcs dcn351_funcs = {
        .calculate_pix_rate_divider = dcn32_calculate_pix_rate_divider,
        .setup_hpo_hw_control = dcn35_setup_hpo_hw_control,
        .get_underflow_debug_data = dcn30_get_underflow_debug_data,
+       .dmub_hw_control_lock = dcn35_dmub_hw_control_lock,
+       .dmub_hw_control_lock_fast = dcn35_dmub_hw_control_lock_fast,
 };
 
 static const struct hwseq_private_funcs dcn351_private_funcs = {
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h 
b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index 6f388c910e18..555e35e55b03 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -909,7 +909,8 @@ union dmub_fw_meta_feature_bits {
        struct {
                uint32_t shared_state_link_detection : 1; /**< 1 supports link 
detection via shared state */
                uint32_t cursor_offload_v1_support: 1; /**< 1 supports cursor 
offload */
-               uint32_t reserved : 30;
+               uint32_t inbox0_lock_support: 1; /**< 1 supports inbox0 lock 
mechanism */
+               uint32_t reserved : 29;
        } bits; /**< status bits */
        uint32_t all; /**< 32-bit access to status bits */
 };
-- 
2.43.0

Reply via email to