drm/amd/display: introduce concept of send_reset_length for i2c engines
authorCharlene Liu <charlene.liu@amd.com>
Mon, 25 Jun 2018 23:28:54 +0000 (19:28 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 13 Jul 2018 19:51:04 +0000 (14:51 -0500)
Signed-off-by: Charlene Liu <charlene.liu@amd.com>
Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c
drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.h
drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.c
drivers/gpu/drm/amd/display/dc/i2caux/i2c_engine.h

index 6074680ecee1a7232579f67e474409bae6cad2bc..ede3489b4f37df3390265b3019dd9a5d3c4a099e 100644 (file)
@@ -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;
index b7256f595052b88a617a68213bd0eee8e4eb26b0..9cbe1a7a6bcb2c994b327c41bd68e151e10a14e6 100644 (file)
@@ -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
index 5bb04085f670657b5c2d50aa3c6debc46ea059a8..fea2946906ed67682b1adde2194ff15c7051748e 100644 (file)
@@ -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
index e0557d3538188b7bcca12309d79d4e1f7de23cae..1d748ac1d6d655e3cc8d36af03b96127f27115fb 100644 (file)
@@ -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);
 
index 58fc0f25ecebb68d1d7900cf58c620d5109aa9b1..ded6ea34b714cc81d9dd51aec780dd39f6a64c9d 100644 (file)
@@ -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(