Commit 88f52b1f authored by Jude Shih's avatar Jude Shih Committed by Alex Deucher

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: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: default avatarWayne Lin <Wayne.Lin@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarJude Shih <shenshih@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b0ce6272
......@@ -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);
}
......@@ -49,6 +49,13 @@
#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__ */
......@@ -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
......@@ -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
......
......@@ -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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment