drm/amd/display: Support for SET_CONFIG processing with DMUB

[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>
This commit is contained in:
Jude Shih
2021-08-11 14:41:34 +08:00
committed by Alex Deucher
parent b0ce627218
commit 88f52b1fff
5 changed files with 97 additions and 23 deletions

View 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;
}
*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;
// 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);
return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux,
ctx, DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT,
(uint32_t *)operation_result);
}
return adev->dm.dmub_notify->aux_reply.length;
if (is_cmd_aux) {
if (adev->dm.dmub_notify->result == AUX_RET_SUCCESS) {
struct aux_payload *payload = (struct aux_payload *)cmd_payload;
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 amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux,
ctx, DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS,
(uint32_t *)operation_result);
}