drm/amd/display: Support for SET_CONFIG processing with DMUB
authorJude Shih <shenshih@amd.com>
Wed, 11 Aug 2021 06:41:34 +0000 (14:41 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 6 Oct 2021 19:52:30 +0000 (15:52 -0400)
[Why]
To process SET_CONFIG transactions with DMUB using inbox1 and
outbox1 mail boxes.

[How]
1) DMUB posts SET_CONFIG reply as an Outbox1 message of type
   DMUB_OUT_CMD__SET_CONFIG_REPLY.
2) The dmub async to sync mechanism for AUX is modified to accommodate
   SET_CONFIG commands for both command issue and reply code paths.

Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Jude Shih <shenshih@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c

index 49be531..f59fdb7 100644 (file)
@@ -11345,29 +11345,74 @@ uint32_t dm_read_reg_func(const struct dc_context *ctx, uint32_t address,
        return value;
 }
 
-int amdgpu_dm_process_dmub_aux_transfer_sync(struct dc_context *ctx, unsigned int linkIndex,
-                               struct aux_payload *payload, enum aux_return_code_type *operation_result)
+int amdgpu_dm_set_dmub_async_sync_status(bool is_cmd_aux, struct dc_context *ctx,
+       uint8_t status_type, uint32_t *operation_result)
+{
+       struct amdgpu_device *adev = ctx->driver_context;
+       int return_status = -1;
+       struct dmub_notification *p_notify = adev->dm.dmub_notify;
+
+       if (is_cmd_aux) {
+               if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS) {
+                       return_status = p_notify->aux_reply.length;
+                       *operation_result = p_notify->result;
+               } else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT) {
+                       *operation_result = AUX_RET_ERROR_TIMEOUT;
+               } else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_FAIL) {
+                       *operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE;
+               } else {
+                       *operation_result = AUX_RET_ERROR_UNKNOWN;
+               }
+       } else {
+               if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS) {
+                       return_status = 0;
+                       *operation_result = p_notify->sc_status;
+               } else {
+                       *operation_result = SET_CONFIG_UNKNOWN_ERROR;
+               }
+       }
+
+       return return_status;
+}
+
+int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux, struct dc_context *ctx,
+       unsigned int link_index, void *cmd_payload, void *operation_result)
 {
        struct amdgpu_device *adev = ctx->driver_context;
        int ret = 0;
 
-       dc_process_dmub_aux_transfer_async(ctx->dc, linkIndex, payload);
+       if (is_cmd_aux) {
+               dc_process_dmub_aux_transfer_async(ctx->dc,
+                       link_index, (struct aux_payload *)cmd_payload);
+       } else if (dc_process_dmub_set_config_async(ctx->dc, link_index,
+                                       (struct set_config_cmd_payload *)cmd_payload,
+                                       adev->dm.dmub_notify)) {
+               return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux,
+                                       ctx, DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS,
+                                       (uint32_t *)operation_result);
+       }
+
        ret = wait_for_completion_interruptible_timeout(&adev->dm.dmub_aux_transfer_done, 10*HZ);
        if (ret == 0) {
-               *operation_result = AUX_RET_ERROR_TIMEOUT;
-               return -1;
+               return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux,
+                               ctx, DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT,
+                               (uint32_t *)operation_result);
        }
-       *operation_result = (enum aux_return_code_type)adev->dm.dmub_notify->result;
 
-       if (adev->dm.dmub_notify->result == AUX_RET_SUCCESS) {
-               (*payload->reply) = adev->dm.dmub_notify->aux_reply.command;
+       if (is_cmd_aux) {
+               if (adev->dm.dmub_notify->result == AUX_RET_SUCCESS) {
+                       struct aux_payload *payload = (struct aux_payload *)cmd_payload;
 
-               // For read case, Copy data to payload
-               if (!payload->write && adev->dm.dmub_notify->aux_reply.length &&
-               (*payload->reply == AUX_TRANSACTION_REPLY_AUX_ACK))
-                       memcpy(payload->data, adev->dm.dmub_notify->aux_reply.data,
-                       adev->dm.dmub_notify->aux_reply.length);
+                       payload->reply[0] = adev->dm.dmub_notify->aux_reply.command;
+                       if (!payload->write && adev->dm.dmub_notify->aux_reply.length &&
+                           payload->reply[0] == AUX_TRANSACTION_REPLY_AUX_ACK) {
+                               memcpy(payload->data, adev->dm.dmub_notify->aux_reply.data,
+                                      adev->dm.dmub_notify->aux_reply.length);
+                       }
+               }
        }
 
-       return adev->dm.dmub_notify->aux_reply.length;
+       return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux,
+                       ctx, DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS,
+                       (uint32_t *)operation_result);
 }
index a85b099..37e61a8 100644 (file)
 #define AMDGPU_DM_MAX_NUM_EDP 2
 
 #define AMDGPU_DMUB_NOTIFICATION_MAX 5
+
+/**
+ * DMUB Async to Sync Mechanism Status
+ **/
+#define DMUB_ASYNC_TO_SYNC_ACCESS_FAIL 1
+#define DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT 2
+#define DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS 3
 /*
 #include "include/amdgpu_dal_power_if.h"
 #include "amdgpu_dm_irq.h"
@@ -721,6 +728,7 @@ void amdgpu_dm_update_connector_after_detect(
 
 extern const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs;
 
-int amdgpu_dm_process_dmub_aux_transfer_sync(struct dc_context *ctx, unsigned int linkIndex,
-                                       struct aux_payload *payload, enum aux_return_code_type *operation_result);
+int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux,
+                                       struct dc_context *ctx, unsigned int link_index,
+                                       void *payload, void *operation_result);
 #endif /* __AMDGPU_DM_H__ */
index 1aa69dd..ff0f91c 100644 (file)
@@ -683,8 +683,21 @@ int dm_helper_dmub_aux_transfer_sync(
                struct aux_payload *payload,
                enum aux_return_code_type *operation_result)
 {
-       return amdgpu_dm_process_dmub_aux_transfer_sync(ctx, link->link_index, payload, operation_result);
+       return amdgpu_dm_process_dmub_aux_transfer_sync(true, ctx,
+                       link->link_index, (void *)payload,
+                       (void *)operation_result);
 }
+
+int dm_helpers_dmub_set_config_sync(struct dc_context *ctx,
+               const struct dc_link *link,
+               struct set_config_cmd_payload *payload,
+               enum set_config_status *operation_result)
+{
+       return amdgpu_dm_process_dmub_aux_transfer_sync(false, ctx,
+                       link->link_index, (void *)payload,
+                       (void *)operation_result);
+}
+
 void dm_set_dcn_clocks(struct dc_context *ctx, struct dc_clocks *clks)
 {
        /* TODO: something */
@@ -799,4 +812,4 @@ void dm_helpers_enable_periodic_detection(struct dc_context *ctx, bool enable)
 {
        /* TODO: add peridic detection implementation */
 }
-#endif
\ No newline at end of file
+#endif
index dd6c473..b0f1cd7 100644 (file)
@@ -659,10 +659,12 @@ int dc_link_aux_transfer_raw(struct ddc_service *ddc,
                struct aux_payload *payload,
                enum aux_return_code_type *operation_result)
 {
-       if (dc_enable_dmub_notifications(ddc->ctx->dc))
+       if (ddc->ctx->dc->debug.enable_dmub_aux_for_legacy_ddc ||
+           !ddc->ddc_pin) {
                return dce_aux_transfer_dmub_raw(ddc, payload, operation_result);
-       else
+       } else {
                return dce_aux_transfer_raw(ddc, payload, operation_result);
+       }
 }
 
 /* dc_link_aux_transfer_with_retries() - Attempt to submit an
index c95ee46..bb2efce 100644 (file)
@@ -130,6 +130,12 @@ static enum dc_status core_link_send_set_config(struct dc_link *link,
        payload.msg_type = msg_type;
        payload.msg_data = msg_data;
 
+       if (!link->ddc->ddc_pin && !link->aux_access_disabled &&
+           (dm_helpers_dmub_set_config_sync(link->ctx, link,
+                                            &payload, &set_config_result) == -1)) {
+               return DC_ERROR_UNEXPECTED;
+       }
+
        /* set_config should return ACK if successful */
        return (set_config_result == SET_CONFIG_ACK_RECEIVED) ? DC_OK : DC_ERROR_UNEXPECTED;
 }