From ceda4e980058316531a1a6b72797d9068ddacd02 Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Thu, 24 Aug 2017 17:12:48 -0400 Subject: [PATCH] drm/amd/display: add aux arbitration logic Signed-off-by: Charlene Liu Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/i2caux/aux_engine.c | 6 ++++ .../drm/amd/display/dc/i2caux/aux_engine.h | 2 ++ .../dc/i2caux/dce110/aux_engine_dce110.c | 30 +++++++++++++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c index 667660f3fa26..3c9608ce94b8 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c @@ -69,6 +69,12 @@ bool dal_aux_engine_acquire( struct aux_engine *aux_engine = FROM_ENGINE(engine); enum gpio_result result; + if (aux_engine->funcs->is_engine_available) { + /*check whether SW could use the engine*/ + if (!aux_engine->funcs->is_engine_available(aux_engine)) { + return false; + } + } result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE, GPIO_DDC_CONFIG_TYPE_MODE_AUX); diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h index b5d6c79eb029..40b202893772 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h +++ b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h @@ -86,6 +86,8 @@ struct aux_engine_funcs { enum aux_channel_operation_result (*get_channel_status)( struct aux_engine *engine, uint8_t *returned_bytes); + bool (*is_engine_available) ( + struct aux_engine *engine); }; struct aux_engine { diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c index f49fd1ad3807..98ce0fe5ac37 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c @@ -93,15 +93,36 @@ static void destroy( } #define SW_CAN_ACCESS_AUX 1 +#define DMCU_CAN_ACCESS_AUX 2 +static bool is_engine_available( + struct aux_engine *engine) +{ + struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); + + uint32_t value = REG_READ(AUX_ARB_CONTROL); + uint32_t field = get_reg_field_value( + value, + AUX_ARB_CONTROL, + AUX_REG_RW_CNTL_STATUS); + + return (field != DMCU_CAN_ACCESS_AUX); +} static bool acquire_engine( struct aux_engine *engine) { struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); + uint32_t value = REG_READ(AUX_ARB_CONTROL); + uint32_t field = get_reg_field_value( + value, + AUX_ARB_CONTROL, + AUX_REG_RW_CNTL_STATUS); + if (field == DMCU_CAN_ACCESS_AUX) + return false; /* enable AUX before request SW to access AUX */ - uint32_t value = REG_READ(AUX_CONTROL); - uint32_t field = get_reg_field_value(value, + value = REG_READ(AUX_CONTROL); + field = get_reg_field_value(value, AUX_CONTROL, AUX_EN); @@ -395,6 +416,7 @@ static const struct aux_engine_funcs aux_engine_funcs = { .submit_channel_request = submit_channel_request, .process_channel_reply = process_channel_reply, .get_channel_status = get_channel_status, + .is_engine_available = is_engine_available, }; static const struct engine_funcs engine_funcs = { @@ -425,6 +447,10 @@ static bool construct( static void destruct( struct aux_engine_dce110 *engine) { + struct aux_engine_dce110 *aux110 = engine; +/*temp w/a, to do*/ + REG_UPDATE(AUX_ARB_CONTROL, AUX_DMCU_DONE_USING_AUX_REG, 1); + REG_UPDATE(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, 1); dal_aux_engine_destruct(&engine->base); }