Blob Blame History Raw
From: Charlene Liu <charlene.liu@amd.com>
Date: Mon, 25 Jun 2018 19:28:54 -0400
Subject: drm/amd/display: introduce concept of send_reset_length for i2c
 engines
Git-commit: e0d85b20c74fc078862262da64b36e8e7b6663e7
Patch-mainline: v4.19-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

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>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/amd/display/dc/dc.h                                 |    1 
 drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c |   26 +++++-----
 drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.h |    8 +++
 drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.c        |   18 ++++++
 drivers/gpu/drm/amd/display/dc/i2caux/i2c_engine.h                  |    2 
 5 files changed, 43 insertions(+), 12 deletions(-)

--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -251,6 +251,7 @@ struct dc_debug {
 	bool p010_mpo_support;
 	bool recovery_enabled;
 	bool avoid_vbios_exec_table;
+	bool scl_reset_length10;
 
 };
 struct dc_state;
--- 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
--- 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
--- 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);
 
--- 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(