[PATCH 07/10] drm/amd/display: Combine dce80 and dce100 i2c hw functions

Bhawanpreet Lakha Bhawanpreet.Lakha at amd.com
Tue Aug 14 20:57:28 UTC 2018


From: David Francis <David.Francis at amd.com>

[Why]
There are two versions of the hw function pointers: one for dce80
and one for all other versions.  These paired functions are
nearly identical.  dce80 and dce100 should not require
different i2c access functions.

[How]
Combine each pair of functions into a single function.  Mostly
the new functions are based on the dce100 versions as those
versions are newer, support more features, and
were more maintained.

Change-Id: Ibc747f5d5670a3761988c934e6b24cfe585921d7
Signed-off-by: David Francis <David.Francis at amd.com>
Reviewed-by: Sun peng Li <Sunpeng.Li at amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
---
 drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c | 237 ++++--------------------
 1 file changed, 40 insertions(+), 197 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c
index 6a57c4874e6b..3a63e3cbb91d 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c
@@ -58,18 +58,7 @@ static bool is_hw_busy(struct dce_i2c_hw *dce_i2c_hw)
 	return i2c_sw_status != DC_I2C_STATUS__DC_I2C_STATUS_IDLE;
 }
 
-static void set_speed_hw_dce80(
-	struct dce_i2c_hw *dce_i2c_hw,
-	uint32_t speed)
-{
-
-	if (speed) {
-		REG_UPDATE_N(SPEED, 2,
-			     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), dce_i2c_hw->reference_frequency / speed,
-			     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2);
-	}
-}
-static void set_speed_hw_dce100(
+static void set_speed(
 	struct dce_i2c_hw *dce_i2c_hw,
 	uint32_t speed)
 {
@@ -86,6 +75,7 @@ static void set_speed_hw_dce100(
 				     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2);
 	}
 }
+
 bool dce_i2c_hw_engine_acquire_engine(
 	struct dce_i2c_hw *dce_i2c_hw,
 	struct ddc *ddc)
@@ -172,7 +162,7 @@ struct dce_i2c_hw *acquire_i2c_hw_engine(
 	return NULL;
 }
 
-static bool setup_engine_hw_dce100(
+static bool setup_engine(
 	struct dce_i2c_hw *dce_i2c_hw)
 {
 	uint32_t i2c_setup_limit = I2C_SETUP_TIME_LIMIT_DCE;
@@ -206,72 +196,11 @@ static bool setup_engine_hw_dce100(
 
 	return true;
 }
-static bool setup_engine_hw_dce80(
-	struct dce_i2c_hw *dce_i2c_hw)
-{
-
-	/* Program pin select */
-	{
-		REG_UPDATE_6(DC_I2C_CONTROL,
-			     DC_I2C_GO, 0,
-			     DC_I2C_SOFT_RESET, 0,
-			     DC_I2C_SEND_RESET, 0,
-			     DC_I2C_SW_STATUS_RESET, 1,
-			     DC_I2C_TRANSACTION_COUNT, 0,
-			     DC_I2C_DDC_SELECT, dce_i2c_hw->engine_id);
-	}
-
-	/* Program time limit */
-	{
-		REG_UPDATE_2(SETUP,
-			     DC_I2C_DDC1_TIME_LIMIT, I2C_SETUP_TIME_LIMIT_DCE,
-			     DC_I2C_DDC1_ENABLE, 1);
-	}
-
-	/* Program HW priority
-	 * set to High - interrupt software I2C at any time
-	 * Enable restart of SW I2C that was interrupted by HW
-	 * disable queuing of software while I2C is in use by HW
-	 */
-	{
-		REG_UPDATE_2(DC_I2C_ARBITRATION,
-			     DC_I2C_NO_QUEUED_SW_GO, 0,
-			     DC_I2C_SW_PRIORITY, DC_I2C_ARBITRATION__DC_I2C_SW_PRIORITY_NORMAL);
-	}
 
-	return true;
-}
 
 
 
-static void process_channel_reply_hw_dce80(
-	struct dce_i2c_hw *dce_i2c_hw,
-	struct i2c_reply_transaction_data *reply)
-{
-	uint32_t length = reply->length;
-	uint8_t *buffer = reply->data;
-
-	REG_SET_3(DC_I2C_DATA, 0,
-		 DC_I2C_INDEX, length - 1,
-		 DC_I2C_DATA_RW, 1,
-		 DC_I2C_INDEX_WRITE, 1);
-
-	while (length) {
-		/* after reading the status,
-		 * if the I2C operation executed successfully
-		 * (i.e. DC_I2C_STATUS_DONE = 1) then the I2C controller
-		 * should read data bytes from I2C circular data buffer
-		 */
-
-		uint32_t i2c_data;
-
-		REG_GET(DC_I2C_DATA, DC_I2C_DATA, &i2c_data);
-		*buffer++ = i2c_data;
-
-		--length;
-	}
-}
-static void process_channel_reply_hw_dce100(
+static void process_channel_reply(
 	struct dce_i2c_hw *dce_i2c_hw,
 	struct i2c_reply_transaction_data *reply)
 {
@@ -404,7 +333,7 @@ static void execute_transaction_hw(
 	dce_i2c_hw->transaction_count = 0;
 	dce_i2c_hw->buffer_used_bytes = 0;
 }
-static bool process_transaction_hw_dce80(
+static bool process_transaction(
 	struct dce_i2c_hw *dce_i2c_hw,
 	struct i2c_request_transaction_data *request)
 {
@@ -414,135 +343,49 @@ static bool process_transaction_hw_dce80(
 	bool last_transaction = false;
 	uint32_t value = 0;
 
-	{
-
-		last_transaction = ((dce_i2c_hw->transaction_count == 3) ||
-				(request->action == DCE_I2C_TRANSACTION_ACTION_I2C_WRITE) ||
-				(request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ));
+	last_transaction = ((dce_i2c_hw->transaction_count == 3) ||
+			(request->action == DCE_I2C_TRANSACTION_ACTION_I2C_WRITE) ||
+			(request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ));
 
 
-		switch (dce_i2c_hw->transaction_count) {
-		case 0:
-			REG_UPDATE_5(DC_I2C_TRANSACTION0,
-				     DC_I2C_STOP_ON_NACK0, 1,
-				     DC_I2C_START0, 1,
-				     DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
-				     DC_I2C_COUNT0, length,
-				     DC_I2C_STOP0, last_transaction ? 1 : 0);
-			break;
-		case 1:
-			REG_UPDATE_5(DC_I2C_TRANSACTION1,
-				     DC_I2C_STOP_ON_NACK0, 1,
-				     DC_I2C_START0, 1,
-				     DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
-				     DC_I2C_COUNT0, length,
-				     DC_I2C_STOP0, last_transaction ? 1 : 0);
-			break;
-		case 2:
-			REG_UPDATE_5(DC_I2C_TRANSACTION2,
-				     DC_I2C_STOP_ON_NACK0, 1,
-				     DC_I2C_START0, 1,
-				     DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
-				     DC_I2C_COUNT0, length,
-				     DC_I2C_STOP0, last_transaction ? 1 : 0);
-			break;
-		case 3:
-			REG_UPDATE_5(DC_I2C_TRANSACTION3,
-				     DC_I2C_STOP_ON_NACK0, 1,
-				     DC_I2C_START0, 1,
-				     DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
-				     DC_I2C_COUNT0, length,
-				     DC_I2C_STOP0, last_transaction ? 1 : 0);
-			break;
-		default:
-			/* TODO Warning ? */
-			break;
-		}
-	}
-
-	/* Write the I2C address and I2C data
-	 * into the hardware circular buffer, one byte per entry.
-	 * As an example, the 7-bit I2C slave address for CRT monitor
-	 * for reading DDC/EDID information is 0b1010001.
-	 * For an I2C send operation, the LSB must be programmed to 0;
-	 * for I2C receive operation, the LSB must be programmed to 1.
-	 */
-
-	{
-		if (dce_i2c_hw->transaction_count == 0) {
-			value = REG_SET_4(DC_I2C_DATA, 0,
-					 DC_I2C_DATA_RW, false,
-					 DC_I2C_DATA, request->address,
-					 DC_I2C_INDEX, 0,
-					 DC_I2C_INDEX_WRITE, 1);
-		} else
-			value = REG_SET_2(DC_I2C_DATA, 0,
-					 DC_I2C_DATA_RW, false,
-					 DC_I2C_DATA, request->address);
-
-		if (!(request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ)) {
-
-			while (length) {
-				REG_SET_2(DC_I2C_DATA, value,
-					 DC_I2C_INDEX_WRITE, 0,
-					 DC_I2C_DATA, *buffer++);
-				--length;
-			}
-		}
-	}
-
-	++dce_i2c_hw->transaction_count;
-	dce_i2c_hw->buffer_used_bytes += length + 1;
-
-	return last_transaction;
-}
-
-#define STOP_TRANS_PREDICAT \
-		((dce_i2c_hw->transaction_count == 3) ||	\
-				(request->action == DCE_I2C_TRANSACTION_ACTION_I2C_WRITE) ||	\
-				(request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ))
-
-#define SET_I2C_TRANSACTION(id)	\
-		do {	\
-			REG_UPDATE_N(DC_I2C_TRANSACTION##id, 5,	\
-				FN(DC_I2C_TRANSACTION0, DC_I2C_STOP_ON_NACK0), 1,	\
-				FN(DC_I2C_TRANSACTION0, DC_I2C_START0), 1,	\
-				FN(DC_I2C_TRANSACTION0, DC_I2C_STOP0), STOP_TRANS_PREDICAT ? 1:0,	\
-				FN(DC_I2C_TRANSACTION0, DC_I2C_RW0), (0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ)),	\
-				FN(DC_I2C_TRANSACTION0, DC_I2C_COUNT0), length);	\
-				if (STOP_TRANS_PREDICAT)	\
-					last_transaction = true;	\
-		} while (false)
-
-static bool process_transaction_hw_dce100(
-	struct dce_i2c_hw *dce_i2c_hw,
-	struct i2c_request_transaction_data *request)
-{
-	uint32_t length = request->length;
-	uint8_t *buffer = request->data;
-	uint32_t value = 0;
-
-	bool last_transaction = false;
-
 	switch (dce_i2c_hw->transaction_count) {
 	case 0:
-		SET_I2C_TRANSACTION(0);
+		REG_UPDATE_5(DC_I2C_TRANSACTION0,
+				 DC_I2C_STOP_ON_NACK0, 1,
+				 DC_I2C_START0, 1,
+				 DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
+				 DC_I2C_COUNT0, length,
+				 DC_I2C_STOP0, last_transaction ? 1 : 0);
 		break;
 	case 1:
-		SET_I2C_TRANSACTION(1);
+		REG_UPDATE_5(DC_I2C_TRANSACTION1,
+				 DC_I2C_STOP_ON_NACK0, 1,
+				 DC_I2C_START0, 1,
+				 DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
+				 DC_I2C_COUNT0, length,
+				 DC_I2C_STOP0, last_transaction ? 1 : 0);
 		break;
 	case 2:
-		SET_I2C_TRANSACTION(2);
+		REG_UPDATE_5(DC_I2C_TRANSACTION2,
+				 DC_I2C_STOP_ON_NACK0, 1,
+				 DC_I2C_START0, 1,
+				 DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
+				 DC_I2C_COUNT0, length,
+				 DC_I2C_STOP0, last_transaction ? 1 : 0);
 		break;
 	case 3:
-		SET_I2C_TRANSACTION(3);
+		REG_UPDATE_5(DC_I2C_TRANSACTION3,
+				 DC_I2C_STOP_ON_NACK0, 1,
+				 DC_I2C_START0, 1,
+				 DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
+				 DC_I2C_COUNT0, length,
+				 DC_I2C_STOP0, last_transaction ? 1 : 0);
 		break;
 	default:
 		/* TODO Warning ? */
 		break;
 	}
 
-
 	/* Write the I2C address and I2C data
 	 * into the hardware circular buffer, one byte per entry.
 	 * As an example, the 7-bit I2C slave address for CRT monitor
@@ -828,24 +671,24 @@ bool dce_i2c_submit_command_hw(
 	return result;
 }
 static const struct dce_i2c_hw_funcs dce100_i2c_hw_funcs = {
-		.setup_engine = setup_engine_hw_dce100,
-		.set_speed = set_speed_hw_dce100,
+		.setup_engine = setup_engine,
+		.set_speed = set_speed,
 		.get_speed = get_speed_hw,
 		.release_engine = release_engine_hw,
-		.process_transaction = process_transaction_hw_dce100,
-		.process_channel_reply = process_channel_reply_hw_dce100,
+		.process_transaction = process_transaction,
+		.process_channel_reply = process_channel_reply,
 		.is_hw_busy = is_hw_busy,
 		.get_channel_status = get_channel_status_hw,
 		.execute_transaction = execute_transaction_hw,
 		.disable_i2c_hw_engine = disable_i2c_hw_engine
 };
 static const struct dce_i2c_hw_funcs dce80_i2c_hw_funcs = {
-		.setup_engine = setup_engine_hw_dce80,
-		.set_speed = set_speed_hw_dce80,
+		.setup_engine = setup_engine,
+		.set_speed = set_speed,
 		.get_speed = get_speed_hw,
 		.release_engine = release_engine_hw,
-		.process_transaction = process_transaction_hw_dce80,
-		.process_channel_reply = process_channel_reply_hw_dce80,
+		.process_transaction = process_transaction,
+		.process_channel_reply = process_channel_reply,
 		.is_hw_busy = is_hw_busy,
 		.get_channel_status = get_channel_status_hw,
 		.execute_transaction = execute_transaction_hw,
-- 
2.14.1



More information about the amd-gfx mailing list