Home | History | Annotate | Line # | Download | only in dce
      1 /*	$NetBSD: amdgpu_dce_i2c_hw.c,v 1.2 2021/12/18 23:45:02 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2018 Advanced Micro Devices, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors: AMD
     25  *
     26  */
     27 
     28 #include <sys/cdefs.h>
     29 __KERNEL_RCSID(0, "$NetBSD: amdgpu_dce_i2c_hw.c,v 1.2 2021/12/18 23:45:02 riastradh Exp $");
     30 
     31 #include <linux/delay.h>
     32 
     33 #include "resource.h"
     34 #include "dce_i2c.h"
     35 #include "dce_i2c_hw.h"
     36 #include "reg_helper.h"
     37 #include "include/gpio_service_interface.h"
     38 
     39 #define CTX \
     40 	dce_i2c_hw->ctx
     41 #define REG(reg)\
     42 	dce_i2c_hw->regs->reg
     43 
     44 #undef FN
     45 #define FN(reg_name, field_name) \
     46 	dce_i2c_hw->shifts->field_name, dce_i2c_hw->masks->field_name
     47 
     48 static void execute_transaction(
     49 	struct dce_i2c_hw *dce_i2c_hw)
     50 {
     51 	REG_UPDATE_N(SETUP, 5,
     52 		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_DATA_DRIVE_EN), 0,
     53 		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_CLK_DRIVE_EN), 0,
     54 		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_DATA_DRIVE_SEL), 0,
     55 		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_INTRA_TRANSACTION_DELAY), 0,
     56 		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_INTRA_BYTE_DELAY), 0);
     57 
     58 
     59 	REG_UPDATE_5(DC_I2C_CONTROL,
     60 		     DC_I2C_SOFT_RESET, 0,
     61 		     DC_I2C_SW_STATUS_RESET, 0,
     62 		     DC_I2C_SEND_RESET, 0,
     63 		     DC_I2C_GO, 0,
     64 		     DC_I2C_TRANSACTION_COUNT, dce_i2c_hw->transaction_count - 1);
     65 
     66 	/* start I2C transfer */
     67 	REG_UPDATE(DC_I2C_CONTROL, DC_I2C_GO, 1);
     68 
     69 	/* all transactions were executed and HW buffer became empty
     70 	 * (even though it actually happens when status becomes DONE)
     71 	 */
     72 	dce_i2c_hw->transaction_count = 0;
     73 	dce_i2c_hw->buffer_used_bytes = 0;
     74 }
     75 
     76 static enum i2c_channel_operation_result get_channel_status(
     77 	struct dce_i2c_hw *dce_i2c_hw,
     78 	uint8_t *returned_bytes)
     79 {
     80 	uint32_t i2c_sw_status = 0;
     81 	uint32_t value =
     82 		REG_GET(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, &i2c_sw_status);
     83 	if (i2c_sw_status == DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_SW)
     84 		return I2C_CHANNEL_OPERATION_ENGINE_BUSY;
     85 	else if (value & dce_i2c_hw->masks->DC_I2C_SW_STOPPED_ON_NACK)
     86 		return I2C_CHANNEL_OPERATION_NO_RESPONSE;
     87 	else if (value & dce_i2c_hw->masks->DC_I2C_SW_TIMEOUT)
     88 		return I2C_CHANNEL_OPERATION_TIMEOUT;
     89 	else if (value & dce_i2c_hw->masks->DC_I2C_SW_ABORTED)
     90 		return I2C_CHANNEL_OPERATION_FAILED;
     91 	else if (value & dce_i2c_hw->masks->DC_I2C_SW_DONE)
     92 		return I2C_CHANNEL_OPERATION_SUCCEEDED;
     93 
     94 	/*
     95 	 * this is the case when HW used for communication, I2C_SW_STATUS
     96 	 * could be zero
     97 	 */
     98 	return I2C_CHANNEL_OPERATION_SUCCEEDED;
     99 }
    100 
    101 static uint32_t get_hw_buffer_available_size(
    102 	const struct dce_i2c_hw *dce_i2c_hw)
    103 {
    104 	return dce_i2c_hw->buffer_size -
    105 			dce_i2c_hw->buffer_used_bytes;
    106 }
    107 
    108 static void process_channel_reply(
    109 	struct dce_i2c_hw *dce_i2c_hw,
    110 	struct i2c_payload *reply)
    111 {
    112 	uint32_t length = reply->length;
    113 	uint8_t *buffer = reply->data;
    114 
    115 	REG_SET_3(DC_I2C_DATA, 0,
    116 		 DC_I2C_INDEX, dce_i2c_hw->buffer_used_write,
    117 		 DC_I2C_DATA_RW, 1,
    118 		 DC_I2C_INDEX_WRITE, 1);
    119 
    120 	while (length) {
    121 		/* after reading the status,
    122 		 * if the I2C operation executed successfully
    123 		 * (i.e. DC_I2C_STATUS_DONE = 1) then the I2C controller
    124 		 * should read data bytes from I2C circular data buffer
    125 		 */
    126 
    127 		uint32_t i2c_data;
    128 
    129 		REG_GET(DC_I2C_DATA, DC_I2C_DATA, &i2c_data);
    130 		*buffer++ = i2c_data;
    131 
    132 		--length;
    133 	}
    134 }
    135 
    136 static bool is_engine_available(struct dce_i2c_hw *dce_i2c_hw)
    137 {
    138 	unsigned int arbitrate;
    139 	unsigned int i2c_hw_status;
    140 
    141 	REG_GET(HW_STATUS, DC_I2C_DDC1_HW_STATUS, &i2c_hw_status);
    142 	if (i2c_hw_status == DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_HW)
    143 		return false;
    144 
    145 	REG_GET(DC_I2C_ARBITRATION, DC_I2C_REG_RW_CNTL_STATUS, &arbitrate);
    146 	if (arbitrate == DC_I2C_REG_RW_CNTL_STATUS_DMCU_ONLY)
    147 		return false;
    148 
    149 	return true;
    150 }
    151 
    152 static bool is_hw_busy(struct dce_i2c_hw *dce_i2c_hw)
    153 {
    154 	uint32_t i2c_sw_status = 0;
    155 
    156 	REG_GET(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, &i2c_sw_status);
    157 	if (i2c_sw_status == DC_I2C_STATUS__DC_I2C_STATUS_IDLE)
    158 		return false;
    159 
    160 	if (is_engine_available(dce_i2c_hw))
    161 		return false;
    162 
    163 	return true;
    164 }
    165 
    166 static bool process_transaction(
    167 	struct dce_i2c_hw *dce_i2c_hw,
    168 	struct i2c_request_transaction_data *request)
    169 {
    170 	uint32_t length = request->length;
    171 	uint8_t *buffer = request->data;
    172 
    173 	bool last_transaction = false;
    174 	uint32_t value = 0;
    175 
    176 	if (is_hw_busy(dce_i2c_hw)) {
    177 		request->status = I2C_CHANNEL_OPERATION_ENGINE_BUSY;
    178 		return false;
    179 	}
    180 
    181 	last_transaction = ((dce_i2c_hw->transaction_count == 3) ||
    182 			(request->action == DCE_I2C_TRANSACTION_ACTION_I2C_WRITE) ||
    183 			(request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ));
    184 
    185 
    186 	switch (dce_i2c_hw->transaction_count) {
    187 	case 0:
    188 		REG_UPDATE_5(DC_I2C_TRANSACTION0,
    189 				 DC_I2C_STOP_ON_NACK0, 1,
    190 				 DC_I2C_START0, 1,
    191 				 DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
    192 				 DC_I2C_COUNT0, length,
    193 				 DC_I2C_STOP0, last_transaction ? 1 : 0);
    194 		break;
    195 	case 1:
    196 		REG_UPDATE_5(DC_I2C_TRANSACTION1,
    197 				 DC_I2C_STOP_ON_NACK0, 1,
    198 				 DC_I2C_START0, 1,
    199 				 DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
    200 				 DC_I2C_COUNT0, length,
    201 				 DC_I2C_STOP0, last_transaction ? 1 : 0);
    202 		break;
    203 	case 2:
    204 		REG_UPDATE_5(DC_I2C_TRANSACTION2,
    205 				 DC_I2C_STOP_ON_NACK0, 1,
    206 				 DC_I2C_START0, 1,
    207 				 DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
    208 				 DC_I2C_COUNT0, length,
    209 				 DC_I2C_STOP0, last_transaction ? 1 : 0);
    210 		break;
    211 	case 3:
    212 		REG_UPDATE_5(DC_I2C_TRANSACTION3,
    213 				 DC_I2C_STOP_ON_NACK0, 1,
    214 				 DC_I2C_START0, 1,
    215 				 DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
    216 				 DC_I2C_COUNT0, length,
    217 				 DC_I2C_STOP0, last_transaction ? 1 : 0);
    218 		break;
    219 	default:
    220 		/* TODO Warning ? */
    221 		break;
    222 	}
    223 
    224 	/* Write the I2C address and I2C data
    225 	 * into the hardware circular buffer, one byte per entry.
    226 	 * As an example, the 7-bit I2C slave address for CRT monitor
    227 	 * for reading DDC/EDID information is 0b1010001.
    228 	 * For an I2C send operation, the LSB must be programmed to 0;
    229 	 * for I2C receive operation, the LSB must be programmed to 1.
    230 	 */
    231 	if (dce_i2c_hw->transaction_count == 0) {
    232 		value = REG_SET_4(DC_I2C_DATA, 0,
    233 				  DC_I2C_DATA_RW, false,
    234 				  DC_I2C_DATA, request->address,
    235 				  DC_I2C_INDEX, 0,
    236 				  DC_I2C_INDEX_WRITE, 1);
    237 		dce_i2c_hw->buffer_used_write = 0;
    238 	} else
    239 		value = REG_SET_2(DC_I2C_DATA, 0,
    240 			  DC_I2C_DATA_RW, false,
    241 			  DC_I2C_DATA, request->address);
    242 
    243 	dce_i2c_hw->buffer_used_write++;
    244 
    245 	if (!(request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ)) {
    246 		while (length) {
    247 			REG_SET_2(DC_I2C_DATA, value,
    248 				  DC_I2C_INDEX_WRITE, 0,
    249 				  DC_I2C_DATA, *buffer++);
    250 			dce_i2c_hw->buffer_used_write++;
    251 			--length;
    252 		}
    253 	}
    254 
    255 	++dce_i2c_hw->transaction_count;
    256 	dce_i2c_hw->buffer_used_bytes += length + 1;
    257 
    258 	return last_transaction;
    259 }
    260 
    261 static inline void reset_hw_engine(struct dce_i2c_hw *dce_i2c_hw)
    262 {
    263 	REG_UPDATE_2(DC_I2C_CONTROL,
    264 		     DC_I2C_SW_STATUS_RESET, 1,
    265 		     DC_I2C_SW_STATUS_RESET, 1);
    266 }
    267 
    268 static void set_speed(
    269 	struct dce_i2c_hw *dce_i2c_hw,
    270 	uint32_t speed)
    271 {
    272 	uint32_t xtal_ref_div = 0;
    273 	uint32_t prescale = 0;
    274 
    275 	REG_GET(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, &xtal_ref_div);
    276 
    277 	if (xtal_ref_div == 0)
    278 		xtal_ref_div = 2;
    279 
    280 	prescale = ((dce_i2c_hw->reference_frequency * 2) / xtal_ref_div) / speed;
    281 
    282 	if (speed) {
    283 		if (dce_i2c_hw->masks->DC_I2C_DDC1_START_STOP_TIMING_CNTL)
    284 			REG_UPDATE_N(SPEED, 3,
    285 				     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), prescale,
    286 				     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2,
    287 				     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_START_STOP_TIMING_CNTL), speed > 50 ? 2:1);
    288 		else
    289 			REG_UPDATE_N(SPEED, 2,
    290 				     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), prescale,
    291 				     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2);
    292 	}
    293 }
    294 
    295 static bool setup_engine(
    296 	struct dce_i2c_hw *dce_i2c_hw)
    297 {
    298 	uint32_t i2c_setup_limit = I2C_SETUP_TIME_LIMIT_DCE;
    299 	uint32_t  reset_length = 0;
    300 	/* we have checked I2c not used by DMCU, set SW use I2C REQ to 1 to indicate SW using it*/
    301 	REG_UPDATE(DC_I2C_ARBITRATION, DC_I2C_SW_USE_I2C_REG_REQ, 1);
    302 
    303 	/* we have checked I2c not used by DMCU, set SW use I2C REQ to 1 to indicate SW using it*/
    304 	REG_UPDATE(DC_I2C_ARBITRATION, DC_I2C_SW_USE_I2C_REG_REQ, 1);
    305 
    306 	if (dce_i2c_hw->setup_limit != 0)
    307 		i2c_setup_limit = dce_i2c_hw->setup_limit;
    308 	/* Program pin select */
    309 	REG_UPDATE_6(DC_I2C_CONTROL,
    310 		     DC_I2C_GO, 0,
    311 		     DC_I2C_SOFT_RESET, 0,
    312 		     DC_I2C_SEND_RESET, 0,
    313 		     DC_I2C_SW_STATUS_RESET, 1,
    314 		     DC_I2C_TRANSACTION_COUNT, 0,
    315 		     DC_I2C_DDC_SELECT, dce_i2c_hw->engine_id);
    316 
    317 	/* Program time limit */
    318 	if (dce_i2c_hw->send_reset_length == 0) {
    319 		/*pre-dcn*/
    320 		REG_UPDATE_N(SETUP, 2,
    321 			     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_TIME_LIMIT), i2c_setup_limit,
    322 			     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE), 1);
    323 	} else {
    324 		reset_length = dce_i2c_hw->send_reset_length;
    325 		REG_UPDATE_N(SETUP, 3,
    326 			     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_TIME_LIMIT), i2c_setup_limit,
    327 			     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_SEND_RESET_LENGTH), reset_length,
    328 			     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE), 1);
    329 	}
    330 	/* Program HW priority
    331 	 * set to High - interrupt software I2C at any time
    332 	 * Enable restart of SW I2C that was interrupted by HW
    333 	 * disable queuing of software while I2C is in use by HW
    334 	 */
    335 	REG_UPDATE(DC_I2C_ARBITRATION,
    336 			DC_I2C_NO_QUEUED_SW_GO, 0);
    337 
    338 	return true;
    339 }
    340 
    341 static void release_engine(
    342 	struct dce_i2c_hw *dce_i2c_hw)
    343 {
    344 	bool safe_to_reset;
    345 
    346 	/* Restore original HW engine speed */
    347 	set_speed(dce_i2c_hw, dce_i2c_hw->default_speed);
    348 
    349 	/* Reset HW engine */
    350 	{
    351 		uint32_t i2c_sw_status = 0;
    352 
    353 		REG_GET(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, &i2c_sw_status);
    354 		/* if used by SW, safe to reset */
    355 		safe_to_reset = (i2c_sw_status == 1);
    356 	}
    357 
    358 	if (safe_to_reset)
    359 		REG_UPDATE_2(DC_I2C_CONTROL,
    360 			     DC_I2C_SOFT_RESET, 1,
    361 			     DC_I2C_SW_STATUS_RESET, 1);
    362 	else
    363 		REG_UPDATE(DC_I2C_CONTROL, DC_I2C_SW_STATUS_RESET, 1);
    364 	/* HW I2c engine - clock gating feature */
    365 	if (!dce_i2c_hw->engine_keep_power_up_count)
    366 		REG_UPDATE_N(SETUP, 1, FN(SETUP, DC_I2C_DDC1_ENABLE), 0);
    367 	/* Release I2C after reset, so HW or DMCU could use it */
    368 	REG_UPDATE_2(DC_I2C_ARBITRATION, DC_I2C_SW_DONE_USING_I2C_REG, 1,
    369 		DC_I2C_SW_USE_I2C_REG_REQ, 0);
    370 
    371 }
    372 
    373 struct dce_i2c_hw *acquire_i2c_hw_engine(
    374 	struct resource_pool *pool,
    375 	struct ddc *ddc)
    376 {
    377 	uint32_t counter = 0;
    378 	enum gpio_result result;
    379 	struct dce_i2c_hw *dce_i2c_hw = NULL;
    380 
    381 	if (!ddc)
    382 		return NULL;
    383 
    384 	if (ddc->hw_info.hw_supported) {
    385 		enum gpio_ddc_line line = dal_ddc_get_line(ddc);
    386 
    387 		if (line < pool->res_cap->num_ddc)
    388 			dce_i2c_hw = pool->hw_i2cs[line];
    389 	}
    390 
    391 	if (!dce_i2c_hw)
    392 		return NULL;
    393 
    394 	if (pool->i2c_hw_buffer_in_use || !is_engine_available(dce_i2c_hw))
    395 		return NULL;
    396 
    397 	do {
    398 		result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE,
    399 			GPIO_DDC_CONFIG_TYPE_MODE_I2C);
    400 
    401 		if (result == GPIO_RESULT_OK)
    402 			break;
    403 
    404 		/* i2c_engine is busy by VBios, lets wait and retry */
    405 
    406 		udelay(10);
    407 
    408 		++counter;
    409 	} while (counter < 2);
    410 
    411 	if (result != GPIO_RESULT_OK)
    412 		return NULL;
    413 
    414 	dce_i2c_hw->ddc = ddc;
    415 
    416 	if (!setup_engine(dce_i2c_hw)) {
    417 		release_engine(dce_i2c_hw);
    418 		return NULL;
    419 	}
    420 
    421 	pool->i2c_hw_buffer_in_use = true;
    422 	return dce_i2c_hw;
    423 }
    424 
    425 enum i2c_channel_operation_result dce_i2c_hw_engine_wait_on_operation_result(
    426 	struct dce_i2c_hw *dce_i2c_hw,
    427 	uint32_t timeout,
    428 	enum i2c_channel_operation_result expected_result)
    429 {
    430 	enum i2c_channel_operation_result result;
    431 	uint32_t i = 0;
    432 
    433 	if (!timeout)
    434 		return I2C_CHANNEL_OPERATION_SUCCEEDED;
    435 
    436 	do {
    437 
    438 		result = get_channel_status(
    439 				dce_i2c_hw, NULL);
    440 
    441 		if (result != expected_result)
    442 			break;
    443 
    444 		udelay(1);
    445 
    446 		++i;
    447 	} while (i < timeout);
    448 	return result;
    449 }
    450 
    451 static void submit_channel_request_hw(
    452 	struct dce_i2c_hw *dce_i2c_hw,
    453 	struct i2c_request_transaction_data *request)
    454 {
    455 	request->status = I2C_CHANNEL_OPERATION_SUCCEEDED;
    456 
    457 	if (!process_transaction(dce_i2c_hw, request))
    458 		return;
    459 
    460 	if (is_hw_busy(dce_i2c_hw)) {
    461 		request->status = I2C_CHANNEL_OPERATION_ENGINE_BUSY;
    462 		return;
    463 	}
    464 	reset_hw_engine(dce_i2c_hw);
    465 
    466 	execute_transaction(dce_i2c_hw);
    467 
    468 
    469 }
    470 
    471 static uint32_t get_transaction_timeout_hw(
    472 	const struct dce_i2c_hw *dce_i2c_hw,
    473 	uint32_t length,
    474 	uint32_t speed)
    475 {
    476 	uint32_t period_timeout;
    477 	uint32_t num_of_clock_stretches;
    478 
    479 	if (!speed)
    480 		return 0;
    481 
    482 	period_timeout = (1000 * TRANSACTION_TIMEOUT_IN_I2C_CLOCKS) / speed;
    483 
    484 	num_of_clock_stretches = 1 + (length << 3) + 1;
    485 	num_of_clock_stretches +=
    486 		(dce_i2c_hw->buffer_used_bytes << 3) +
    487 		(dce_i2c_hw->transaction_count << 1);
    488 
    489 	return period_timeout * num_of_clock_stretches;
    490 }
    491 
    492 bool dce_i2c_hw_engine_submit_payload(
    493 	struct dce_i2c_hw *dce_i2c_hw,
    494 	struct i2c_payload *payload,
    495 	bool middle_of_transaction,
    496 	uint32_t speed)
    497 {
    498 
    499 	struct i2c_request_transaction_data request;
    500 
    501 	uint32_t transaction_timeout;
    502 
    503 	enum i2c_channel_operation_result operation_result;
    504 
    505 	bool result = false;
    506 
    507 	/* We need following:
    508 	 * transaction length will not exceed
    509 	 * the number of free bytes in HW buffer (minus one for address)
    510 	 */
    511 
    512 	if (payload->length >=
    513 			get_hw_buffer_available_size(dce_i2c_hw)) {
    514 		return false;
    515 	}
    516 
    517 	if (!payload->write)
    518 		request.action = middle_of_transaction ?
    519 			DCE_I2C_TRANSACTION_ACTION_I2C_READ_MOT :
    520 			DCE_I2C_TRANSACTION_ACTION_I2C_READ;
    521 	else
    522 		request.action = middle_of_transaction ?
    523 			DCE_I2C_TRANSACTION_ACTION_I2C_WRITE_MOT :
    524 			DCE_I2C_TRANSACTION_ACTION_I2C_WRITE;
    525 
    526 
    527 	request.address = (uint8_t) ((payload->address << 1) | !payload->write);
    528 	request.length = payload->length;
    529 	request.data = payload->data;
    530 
    531 	/* obtain timeout value before submitting request */
    532 
    533 	transaction_timeout = get_transaction_timeout_hw(
    534 		dce_i2c_hw, payload->length + 1, speed);
    535 
    536 	submit_channel_request_hw(
    537 		dce_i2c_hw, &request);
    538 
    539 	if ((request.status == I2C_CHANNEL_OPERATION_FAILED) ||
    540 		(request.status == I2C_CHANNEL_OPERATION_ENGINE_BUSY))
    541 		return false;
    542 
    543 	/* wait until transaction proceed */
    544 
    545 	operation_result = dce_i2c_hw_engine_wait_on_operation_result(
    546 		dce_i2c_hw,
    547 		transaction_timeout,
    548 		I2C_CHANNEL_OPERATION_ENGINE_BUSY);
    549 
    550 	/* update transaction status */
    551 
    552 	if (operation_result == I2C_CHANNEL_OPERATION_SUCCEEDED)
    553 		result = true;
    554 
    555 	if (result && (!payload->write))
    556 		process_channel_reply(dce_i2c_hw, payload);
    557 
    558 	return result;
    559 }
    560 
    561 bool dce_i2c_submit_command_hw(
    562 	struct resource_pool *pool,
    563 	struct ddc *ddc,
    564 	struct i2c_command *cmd,
    565 	struct dce_i2c_hw *dce_i2c_hw)
    566 {
    567 	uint8_t index_of_payload = 0;
    568 	bool result;
    569 
    570 	set_speed(dce_i2c_hw, cmd->speed);
    571 
    572 	result = true;
    573 
    574 	while (index_of_payload < cmd->number_of_payloads) {
    575 		bool mot = (index_of_payload != cmd->number_of_payloads - 1);
    576 
    577 		struct i2c_payload *payload = cmd->payloads + index_of_payload;
    578 
    579 		if (!dce_i2c_hw_engine_submit_payload(
    580 				dce_i2c_hw, payload, mot, cmd->speed)) {
    581 			result = false;
    582 			break;
    583 		}
    584 
    585 		++index_of_payload;
    586 	}
    587 
    588 	pool->i2c_hw_buffer_in_use = false;
    589 
    590 	release_engine(dce_i2c_hw);
    591 	dal_ddc_close(dce_i2c_hw->ddc);
    592 
    593 	dce_i2c_hw->ddc = NULL;
    594 
    595 	return result;
    596 }
    597 
    598 void dce_i2c_hw_construct(
    599 	struct dce_i2c_hw *dce_i2c_hw,
    600 	struct dc_context *ctx,
    601 	uint32_t engine_id,
    602 	const struct dce_i2c_registers *regs,
    603 	const struct dce_i2c_shift *shifts,
    604 	const struct dce_i2c_mask *masks)
    605 {
    606 	dce_i2c_hw->ctx = ctx;
    607 	dce_i2c_hw->engine_id = engine_id;
    608 	dce_i2c_hw->reference_frequency = (ctx->dc_bios->fw_info.pll_info.crystal_frequency) >> 1;
    609 	dce_i2c_hw->regs = regs;
    610 	dce_i2c_hw->shifts = shifts;
    611 	dce_i2c_hw->masks = masks;
    612 	dce_i2c_hw->buffer_used_bytes = 0;
    613 	dce_i2c_hw->transaction_count = 0;
    614 	dce_i2c_hw->engine_keep_power_up_count = 1;
    615 	dce_i2c_hw->default_speed = DEFAULT_I2C_HW_SPEED;
    616 	dce_i2c_hw->send_reset_length = 0;
    617 	dce_i2c_hw->setup_limit = I2C_SETUP_TIME_LIMIT_DCE;
    618 	dce_i2c_hw->buffer_size = I2C_HW_BUFFER_SIZE_DCE;
    619 }
    620 
    621 void dce100_i2c_hw_construct(
    622 	struct dce_i2c_hw *dce_i2c_hw,
    623 	struct dc_context *ctx,
    624 	uint32_t engine_id,
    625 	const struct dce_i2c_registers *regs,
    626 	const struct dce_i2c_shift *shifts,
    627 	const struct dce_i2c_mask *masks)
    628 {
    629 	dce_i2c_hw_construct(dce_i2c_hw,
    630 			ctx,
    631 			engine_id,
    632 			regs,
    633 			shifts,
    634 			masks);
    635 	dce_i2c_hw->buffer_size = I2C_HW_BUFFER_SIZE_DCE100;
    636 }
    637 
    638 void dce112_i2c_hw_construct(
    639 	struct dce_i2c_hw *dce_i2c_hw,
    640 	struct dc_context *ctx,
    641 	uint32_t engine_id,
    642 	const struct dce_i2c_registers *regs,
    643 	const struct dce_i2c_shift *shifts,
    644 	const struct dce_i2c_mask *masks)
    645 {
    646 	dce100_i2c_hw_construct(dce_i2c_hw,
    647 			ctx,
    648 			engine_id,
    649 			regs,
    650 			shifts,
    651 			masks);
    652 	dce_i2c_hw->default_speed = DEFAULT_I2C_HW_SPEED_100KHZ;
    653 }
    654 
    655 void dcn1_i2c_hw_construct(
    656 	struct dce_i2c_hw *dce_i2c_hw,
    657 	struct dc_context *ctx,
    658 	uint32_t engine_id,
    659 	const struct dce_i2c_registers *regs,
    660 	const struct dce_i2c_shift *shifts,
    661 	const struct dce_i2c_mask *masks)
    662 {
    663 	dce112_i2c_hw_construct(dce_i2c_hw,
    664 			ctx,
    665 			engine_id,
    666 			regs,
    667 			shifts,
    668 			masks);
    669 	dce_i2c_hw->setup_limit = I2C_SETUP_TIME_LIMIT_DCN;
    670 }
    671 
    672 void dcn2_i2c_hw_construct(
    673 	struct dce_i2c_hw *dce_i2c_hw,
    674 	struct dc_context *ctx,
    675 	uint32_t engine_id,
    676 	const struct dce_i2c_registers *regs,
    677 	const struct dce_i2c_shift *shifts,
    678 	const struct dce_i2c_mask *masks)
    679 {
    680 	dcn1_i2c_hw_construct(dce_i2c_hw,
    681 			ctx,
    682 			engine_id,
    683 			regs,
    684 			shifts,
    685 			masks);
    686 	dce_i2c_hw->send_reset_length = I2C_SEND_RESET_LENGTH_9;
    687 	if (ctx->dc->debug.scl_reset_length10)
    688 		dce_i2c_hw->send_reset_length = I2C_SEND_RESET_LENGTH_10;
    689 }
    690