From e0d85b20c74fc078862262da64b36e8e7b6663e7 Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Mon, 25 Jun 2018 19:28:54 -0400 Subject: [PATCH] drm/amd/display: introduce concept of send_reset_length for i2c engines Signed-off-by: Charlene Liu Reviewed-by: Dmytro Laktyushkin Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../dc/i2caux/dce110/i2c_hw_engine_dce110.c | 26 +++++++++++-------- .../dc/i2caux/dce110/i2c_hw_engine_dce110.h | 8 ++++++ .../display/dc/i2caux/dce110/i2caux_dce110.c | 18 ++++++++++++- .../drm/amd/display/dc/i2caux/i2c_engine.h | 2 ++ 5 files changed, 43 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 6074680ecee1..ede3489b4f37 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -250,6 +250,7 @@ struct dc_debug { bool p010_mpo_support; bool recovery_enabled; bool avoid_vbios_exec_table; + bool scl_reset_length10; }; struct dc_state; diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c index b7256f595052..9cbe1a7a6bcb 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c @@ -62,12 +62,7 @@ enum dc_i2c_arbitration { DC_I2C_ARBITRATION__DC_I2C_SW_PRIORITY_HIGH }; -enum { - /* No timeout in HW - * (timeout implemented in SW by querying status) */ - I2C_SETUP_TIME_LIMIT = 255, - I2C_HW_BUFFER_SIZE = 538 -}; + /* * @brief @@ -152,6 +147,11 @@ static bool setup_engine( struct i2c_engine *i2c_engine) { struct i2c_hw_engine_dce110 *hw_engine = FROM_I2C_ENGINE(i2c_engine); + uint32_t i2c_setup_limit = I2C_SETUP_TIME_LIMIT_DCE; + uint32_t reset_length = 0; + + if (hw_engine->base.base.setup_limit != 0) + i2c_setup_limit = hw_engine->base.base.setup_limit; /* Program pin select */ REG_UPDATE_6( @@ -164,11 +164,15 @@ static bool setup_engine( DC_I2C_DDC_SELECT, hw_engine->engine_id); /* Program time limit */ - REG_UPDATE_N( - SETUP, 2, - FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_TIME_LIMIT), I2C_SETUP_TIME_LIMIT, - FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE), 1); - + if (hw_engine->base.base.send_reset_length == 0) { + /*pre-dcn*/ + REG_UPDATE_N( + SETUP, 2, + FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_TIME_LIMIT), i2c_setup_limit, + FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE), 1); + } else { + reset_length = hw_engine->base.base.send_reset_length; + } /* Program HW priority * set to High - interrupt software I2C at any time * Enable restart of SW I2C that was interrupted by HW diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.h b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.h index 5bb04085f670..fea2946906ed 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.h +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.h @@ -192,6 +192,7 @@ struct i2c_hw_engine_dce110 { /* number of pending transactions (before GO) */ uint32_t transaction_count; uint32_t engine_keep_power_up_count; + uint32_t i2_setup_time_limit; }; struct i2c_hw_engine_dce110_create_arg { @@ -207,4 +208,11 @@ struct i2c_hw_engine_dce110_create_arg { struct i2c_engine *dal_i2c_hw_engine_dce110_create( const struct i2c_hw_engine_dce110_create_arg *arg); +enum { + I2C_SETUP_TIME_LIMIT_DCE = 255, + I2C_SETUP_TIME_LIMIT_DCN = 3, + I2C_HW_BUFFER_SIZE = 538, + I2C_SEND_RESET_LENGTH_9 = 9, + I2C_SEND_RESET_LENGTH_10 = 10, +}; #endif diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.c index e0557d353818..1d748ac1d6d6 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.c @@ -43,6 +43,9 @@ #include "i2c_sw_engine_dce110.h" #include "i2c_hw_engine_dce110.h" #include "aux_engine_dce110.h" +#include "../../dc.h" +#include "dc_types.h" + /* * Post-requisites: headers required by this unit @@ -250,7 +253,20 @@ void dal_i2caux_dce110_construct( base->i2c_hw_engines[line_id] = dal_i2c_hw_engine_dce110_create(&hw_arg_dce110); - + if (base->i2c_hw_engines[line_id] != NULL) { + switch (ctx->dce_version) { + case DCN_VERSION_1_0: + base->i2c_hw_engines[line_id]->setup_limit = + I2C_SETUP_TIME_LIMIT_DCN; + base->i2c_hw_engines[line_id]->send_reset_length = 0; + break; + default: + base->i2c_hw_engines[line_id]->setup_limit = + I2C_SETUP_TIME_LIMIT_DCE; + base->i2c_hw_engines[line_id]->send_reset_length = 0; + break; + } + } ++i; } while (i < num_i2caux_inst); diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/i2c_engine.h b/drivers/gpu/drm/amd/display/dc/i2caux/i2c_engine.h index 58fc0f25eceb..ded6ea34b714 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/i2c_engine.h +++ b/drivers/gpu/drm/amd/display/dc/i2caux/i2c_engine.h @@ -86,6 +86,8 @@ struct i2c_engine { struct engine base; const struct i2c_engine_funcs *funcs; uint32_t timeout_delay; + uint32_t setup_limit; + uint32_t send_reset_length; }; void dal_i2c_engine_construct( -- 2.30.2