Commit 9bbdb0f3 authored by David Francis's avatar David Francis Committed by Alex Deucher
Browse files

drm/amd/display: Eliminate i2c hw function pointers



[Why]
The function pointers of the dce_i2c_hw struct were never
accessed from outside dce_i2c_hw.c and had only one version.
As function pointers take up space and make debugging difficult,
and they are not needed in this case, they should be removed.

[How]
Remove the dce_i2c_hw_funcs struct and make static all
functions that were previously a part of it.  Reorder
the functions in dce_i2c_hw.c.

Signed-off-by: default avatarDavid Francis <David.Francis@amd.com>
Reviewed-by: default avatarSun peng Li <Sunpeng.Li@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 284dec43
Loading
Loading
Loading
Loading
+291 −316
Original line number Diff line number Diff line
@@ -36,223 +36,41 @@
#define FN(reg_name, field_name) \
	dce_i2c_hw->shifts->field_name, dce_i2c_hw->masks->field_name


static inline void reset_hw_engine(struct dce_i2c_hw *dce_i2c_hw)
{
	REG_UPDATE_2(DC_I2C_CONTROL,
		     DC_I2C_SW_STATUS_RESET, 1,
		     DC_I2C_SW_STATUS_RESET, 1);
}

static bool is_hw_busy(struct dce_i2c_hw *dce_i2c_hw)
{
	uint32_t i2c_sw_status = 0;

	REG_GET(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, &i2c_sw_status);
	if (i2c_sw_status == DC_I2C_STATUS__DC_I2C_STATUS_IDLE)
		return false;

	reset_hw_engine(dce_i2c_hw);

	REG_GET(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, &i2c_sw_status);
	return i2c_sw_status != DC_I2C_STATUS__DC_I2C_STATUS_IDLE;
}

static void set_speed(
	struct dce_i2c_hw *dce_i2c_hw,
	uint32_t speed)
{

	if (speed) {
		if (dce_i2c_hw->masks->DC_I2C_DDC1_START_STOP_TIMING_CNTL)
			REG_UPDATE_N(SPEED, 3,
				     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,
				     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_START_STOP_TIMING_CNTL), speed > 50 ? 2:1);
		else
			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);
	}
}

bool dce_i2c_hw_engine_acquire_engine(
	struct dce_i2c_hw *dce_i2c_hw,
	struct ddc *ddc)
{

	enum gpio_result result;
	uint32_t current_speed;

	result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE,
		GPIO_DDC_CONFIG_TYPE_MODE_I2C);

	if (result != GPIO_RESULT_OK)
		return false;

	dce_i2c_hw->ddc = ddc;


	current_speed = dce_i2c_hw->funcs->get_speed(dce_i2c_hw);

	if (current_speed)
		dce_i2c_hw->original_speed = current_speed;

	return true;
}
bool dce_i2c_engine_acquire_hw(
	struct dce_i2c_hw *dce_i2c_hw,
	struct ddc *ddc_handle)
{

	uint32_t counter = 0;
	bool result;

	do {
		result = dce_i2c_hw_engine_acquire_engine(
				dce_i2c_hw, ddc_handle);

		if (result)
			break;

		/* i2c_engine is busy by VBios, lets wait and retry */

		udelay(10);

		++counter;
	} while (counter < 2);

	if (result) {
		if (!dce_i2c_hw->funcs->setup_engine(dce_i2c_hw)) {
			dce_i2c_hw->funcs->release_engine(dce_i2c_hw);
			result = false;
		}
	}

	return result;
}
struct dce_i2c_hw *acquire_i2c_hw_engine(
	struct resource_pool *pool,
	struct ddc *ddc)
static void disable_i2c_hw_engine(
	struct dce_i2c_hw *dce_i2c_hw)
{

	struct dce_i2c_hw *engine = NULL;

	if (!ddc)
		return NULL;

	if (ddc->hw_info.hw_supported) {
		enum gpio_ddc_line line = dal_ddc_get_line(ddc);

		if (line < pool->pipe_count)
			engine = pool->hw_i2cs[line];
	}

	if (!engine)
		return NULL;


	if (!pool->i2c_hw_buffer_in_use &&
			dce_i2c_engine_acquire_hw(engine, ddc)) {
		pool->i2c_hw_buffer_in_use = true;
		return engine;
	}


	return NULL;
	REG_UPDATE_N(SETUP, 1, FN(SETUP, DC_I2C_DDC1_ENABLE), 0);
}

static bool setup_engine(
static void execute_transaction(
	struct dce_i2c_hw *dce_i2c_hw)
{
	uint32_t i2c_setup_limit = I2C_SETUP_TIME_LIMIT_DCE;
	REG_UPDATE_N(SETUP, 5,
		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_DATA_DRIVE_EN), 0,
		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_CLK_DRIVE_EN), 0,
		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_DATA_DRIVE_SEL), 0,
		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_INTRA_TRANSACTION_DELAY), 0,
		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_INTRA_BYTE_DELAY), 0);

	if (dce_i2c_hw->setup_limit != 0)
		i2c_setup_limit = dce_i2c_hw->setup_limit;
	/* Program pin select */
	REG_UPDATE_6(DC_I2C_CONTROL,
		     DC_I2C_GO, 0,

	REG_UPDATE_5(DC_I2C_CONTROL,
		     DC_I2C_SOFT_RESET, 0,
		     DC_I2C_SW_STATUS_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 */
	if (dce_i2c_hw->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);
	}
	/* 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(
	struct dce_i2c_hw *dce_i2c_hw,
	struct i2c_reply_transaction_data *reply)
{
	uint32_t length = reply->length;
	uint8_t *buffer = reply->data;
		     DC_I2C_GO, 0,
		     DC_I2C_TRANSACTION_COUNT, dce_i2c_hw->transaction_count - 1);

	REG_SET_3(DC_I2C_DATA, 0,
		 DC_I2C_INDEX, dce_i2c_hw->buffer_used_write,
		 DC_I2C_DATA_RW, 1,
		 DC_I2C_INDEX_WRITE, 1);
	/* start I2C transfer */
	REG_UPDATE(DC_I2C_CONTROL, DC_I2C_GO, 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
	/* all transactions were executed and HW buffer became empty
	 * (even though it actually happens when status becomes DONE)
	 */

		uint32_t i2c_data;

		REG_GET(DC_I2C_DATA, DC_I2C_DATA, &i2c_data);
		*buffer++ = i2c_data;

		--length;
	}
	dce_i2c_hw->transaction_count = 0;
	dce_i2c_hw->buffer_used_bytes = 0;
}
enum i2c_channel_operation_result dce_i2c_hw_engine_wait_on_operation_result(
	struct dce_i2c_hw *dce_i2c_hw,
	uint32_t timeout,
	enum i2c_channel_operation_result expected_result)
{
	enum i2c_channel_operation_result result;
	uint32_t i = 0;

	if (!timeout)
		return I2C_CHANNEL_OPERATION_SUCCEEDED;

	do {

		result = dce_i2c_hw->funcs->get_channel_status(
				dce_i2c_hw, NULL);

		if (result != expected_result)
			break;

		udelay(1);

		++i;
	} while (i < timeout);
	return result;
}
static enum i2c_channel_operation_result get_channel_status_hw(
static enum i2c_channel_operation_result get_channel_status(
	struct dce_i2c_hw *dce_i2c_hw,
	uint8_t *returned_bytes)
{
@@ -277,24 +95,13 @@ static enum i2c_channel_operation_result get_channel_status_hw(
	return I2C_CHANNEL_OPERATION_SUCCEEDED;
}

static void submit_channel_request_hw(
	struct dce_i2c_hw *dce_i2c_hw,
	struct i2c_request_transaction_data *request)
static uint32_t get_hw_buffer_available_size(
	const struct dce_i2c_hw *dce_i2c_hw)
{
	request->status = I2C_CHANNEL_OPERATION_SUCCEEDED;

	if (!dce_i2c_hw->funcs->process_transaction(dce_i2c_hw, request))
		return;

	if (dce_i2c_hw->funcs->is_hw_busy(dce_i2c_hw)) {
		request->status = I2C_CHANNEL_OPERATION_ENGINE_BUSY;
		return;
	return dce_i2c_hw->buffer_size -
			dce_i2c_hw->buffer_used_bytes;
}

	dce_i2c_hw->funcs->execute_transaction(dce_i2c_hw);


}
uint32_t get_reference_clock(
		struct dc_bios *bios)
{
@@ -306,33 +113,48 @@ uint32_t get_reference_clock(
	return info.pll_info.crystal_frequency;
}

static void execute_transaction_hw(
	struct dce_i2c_hw *dce_i2c_hw)
static uint32_t get_speed(
	const struct dce_i2c_hw *dce_i2c_hw)
{
	REG_UPDATE_N(SETUP, 5,
		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_DATA_DRIVE_EN), 0,
		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_CLK_DRIVE_EN), 0,
		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_DATA_DRIVE_SEL), 0,
		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_INTRA_TRANSACTION_DELAY), 0,
		     FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_INTRA_BYTE_DELAY), 0);
	uint32_t pre_scale = 0;

	REG_GET(SPEED, DC_I2C_DDC1_PRESCALE, &pre_scale);

	REG_UPDATE_5(DC_I2C_CONTROL,
		     DC_I2C_SOFT_RESET, 0,
		     DC_I2C_SW_STATUS_RESET, 0,
		     DC_I2C_SEND_RESET, 0,
		     DC_I2C_GO, 0,
		     DC_I2C_TRANSACTION_COUNT, dce_i2c_hw->transaction_count - 1);
	/* [anaumov] it seems following is unnecessary */
	/*ASSERT(value.bits.DC_I2C_DDC1_PRESCALE);*/
	return pre_scale ?
		dce_i2c_hw->reference_frequency / pre_scale :
		dce_i2c_hw->default_speed;
}

	/* start I2C transfer */
	REG_UPDATE(DC_I2C_CONTROL, DC_I2C_GO, 1);
static void process_channel_reply(
	struct dce_i2c_hw *dce_i2c_hw,
	struct i2c_reply_transaction_data *reply)
{
	uint32_t length = reply->length;
	uint8_t *buffer = reply->data;

	/* all transactions were executed and HW buffer became empty
	 * (even though it actually happens when status becomes DONE)
	REG_SET_3(DC_I2C_DATA, 0,
		 DC_I2C_INDEX, dce_i2c_hw->buffer_used_write,
		 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
		 */
	dce_i2c_hw->transaction_count = 0;
	dce_i2c_hw->buffer_used_bytes = 0;

		uint32_t i2c_data;

		REG_GET(DC_I2C_DATA, DC_I2C_DATA, &i2c_data);
		*buffer++ = i2c_data;

		--length;
	}
}

static bool process_transaction(
	struct dce_i2c_hw *dce_i2c_hw,
	struct i2c_request_transaction_data *request)
@@ -422,51 +244,89 @@ static bool process_transaction(

	return last_transaction;
}
static uint32_t get_transaction_timeout_hw(
	const struct dce_i2c_hw *dce_i2c_hw,
	uint32_t length)
{

	uint32_t speed = dce_i2c_hw->funcs->get_speed(dce_i2c_hw);

static inline void reset_hw_engine(struct dce_i2c_hw *dce_i2c_hw)
{
	REG_UPDATE_2(DC_I2C_CONTROL,
		     DC_I2C_SW_STATUS_RESET, 1,
		     DC_I2C_SW_STATUS_RESET, 1);
}

static void set_speed(
	struct dce_i2c_hw *dce_i2c_hw,
	uint32_t speed)
{

	uint32_t period_timeout;
	uint32_t num_of_clock_stretches;
	if (speed) {
		if (dce_i2c_hw->masks->DC_I2C_DDC1_START_STOP_TIMING_CNTL)
			REG_UPDATE_N(SPEED, 3,
				     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,
				     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_START_STOP_TIMING_CNTL), speed > 50 ? 2:1);
		else
			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);
	}
}

	if (!speed)
		return 0;
static bool setup_engine(
	struct dce_i2c_hw *dce_i2c_hw)
{
	uint32_t i2c_setup_limit = I2C_SETUP_TIME_LIMIT_DCE;

	period_timeout = (1000 * TRANSACTION_TIMEOUT_IN_I2C_CLOCKS) / speed;
	if (dce_i2c_hw->setup_limit != 0)
		i2c_setup_limit = dce_i2c_hw->setup_limit;
	/* 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);

	num_of_clock_stretches = 1 + (length << 3) + 1;
	num_of_clock_stretches +=
		(dce_i2c_hw->buffer_used_bytes << 3) +
		(dce_i2c_hw->transaction_count << 1);
	/* Program time limit */
	if (dce_i2c_hw->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);
	}
	/* 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 period_timeout * num_of_clock_stretches;
	return true;
}

static void release_engine_dce_hw(
	struct resource_pool *pool,
	struct dce_i2c_hw *dce_i2c_hw)
static bool is_hw_busy(struct dce_i2c_hw *dce_i2c_hw)
{
	pool->i2c_hw_buffer_in_use = false;
	uint32_t i2c_sw_status = 0;

	dce_i2c_hw->funcs->release_engine(dce_i2c_hw);
	dal_ddc_close(dce_i2c_hw->ddc);
	REG_GET(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, &i2c_sw_status);
	if (i2c_sw_status == DC_I2C_STATUS__DC_I2C_STATUS_IDLE)
		return false;

	dce_i2c_hw->ddc = NULL;
	reset_hw_engine(dce_i2c_hw);

	REG_GET(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, &i2c_sw_status);
	return i2c_sw_status != DC_I2C_STATUS__DC_I2C_STATUS_IDLE;
}

static void release_engine_hw(
static void release_engine(
	struct dce_i2c_hw *dce_i2c_hw)
{
	bool safe_to_reset;

	/* Restore original HW engine speed */

	dce_i2c_hw->funcs->set_speed(dce_i2c_hw, dce_i2c_hw->original_speed);
	set_speed(dce_i2c_hw, dce_i2c_hw->original_speed);

	/* Release I2C */
	REG_UPDATE(DC_I2C_ARBITRATION, DC_I2C_SW_DONE_USING_I2C_REG, 1);
@@ -488,35 +348,180 @@ static void release_engine_hw(
		REG_UPDATE(DC_I2C_CONTROL, DC_I2C_SW_STATUS_RESET, 1);
	/* HW I2c engine - clock gating feature */
	if (!dce_i2c_hw->engine_keep_power_up_count)
		dce_i2c_hw->funcs->disable_i2c_hw_engine(dce_i2c_hw);
		disable_i2c_hw_engine(dce_i2c_hw);

}


static void disable_i2c_hw_engine(
static void release_engine_dce_hw(
	struct resource_pool *pool,
	struct dce_i2c_hw *dce_i2c_hw)
{
	REG_UPDATE_N(SETUP, 1, FN(SETUP, DC_I2C_DDC1_ENABLE), 0);
	pool->i2c_hw_buffer_in_use = false;

	release_engine(dce_i2c_hw);
	dal_ddc_close(dce_i2c_hw->ddc);

	dce_i2c_hw->ddc = NULL;
}
static uint32_t get_speed_hw(
	const struct dce_i2c_hw *dce_i2c_hw)

bool dce_i2c_hw_engine_acquire_engine(
	struct dce_i2c_hw *dce_i2c_hw,
	struct ddc *ddc)
{
	uint32_t pre_scale = 0;

	REG_GET(SPEED, DC_I2C_DDC1_PRESCALE, &pre_scale);
	enum gpio_result result;
	uint32_t current_speed;

	/* [anaumov] it seems following is unnecessary */
	/*ASSERT(value.bits.DC_I2C_DDC1_PRESCALE);*/
	return pre_scale ?
		dce_i2c_hw->reference_frequency / pre_scale :
		dce_i2c_hw->default_speed;
	result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE,
		GPIO_DDC_CONFIG_TYPE_MODE_I2C);

	if (result != GPIO_RESULT_OK)
		return false;

	dce_i2c_hw->ddc = ddc;


	current_speed = get_speed(dce_i2c_hw);

	if (current_speed)
		dce_i2c_hw->original_speed = current_speed;

	return true;
}
static uint32_t get_hw_buffer_available_size(
	const struct dce_i2c_hw *dce_i2c_hw)

bool dce_i2c_engine_acquire_hw(
	struct dce_i2c_hw *dce_i2c_hw,
	struct ddc *ddc_handle)
{
	return dce_i2c_hw->buffer_size -
			dce_i2c_hw->buffer_used_bytes;

	uint32_t counter = 0;
	bool result;

	do {
		result = dce_i2c_hw_engine_acquire_engine(
				dce_i2c_hw, ddc_handle);

		if (result)
			break;

		/* i2c_engine is busy by VBios, lets wait and retry */

		udelay(10);

		++counter;
	} while (counter < 2);

	if (result) {
		if (!setup_engine(dce_i2c_hw)) {
			release_engine(dce_i2c_hw);
			result = false;
		}
	}

	return result;
}

struct dce_i2c_hw *acquire_i2c_hw_engine(
	struct resource_pool *pool,
	struct ddc *ddc)
{

	struct dce_i2c_hw *engine = NULL;

	if (!ddc)
		return NULL;

	if (ddc->hw_info.hw_supported) {
		enum gpio_ddc_line line = dal_ddc_get_line(ddc);

		if (line < pool->pipe_count)
			engine = pool->hw_i2cs[line];
	}

	if (!engine)
		return NULL;


	if (!pool->i2c_hw_buffer_in_use &&
			dce_i2c_engine_acquire_hw(engine, ddc)) {
		pool->i2c_hw_buffer_in_use = true;
		return engine;
	}


	return NULL;
}

enum i2c_channel_operation_result dce_i2c_hw_engine_wait_on_operation_result(
	struct dce_i2c_hw *dce_i2c_hw,
	uint32_t timeout,
	enum i2c_channel_operation_result expected_result)
{
	enum i2c_channel_operation_result result;
	uint32_t i = 0;

	if (!timeout)
		return I2C_CHANNEL_OPERATION_SUCCEEDED;

	do {

		result = get_channel_status(
				dce_i2c_hw, NULL);

		if (result != expected_result)
			break;

		udelay(1);

		++i;
	} while (i < timeout);
	return result;
}

static void submit_channel_request_hw(
	struct dce_i2c_hw *dce_i2c_hw,
	struct i2c_request_transaction_data *request)
{
	request->status = I2C_CHANNEL_OPERATION_SUCCEEDED;

	if (!process_transaction(dce_i2c_hw, request))
		return;

	if (is_hw_busy(dce_i2c_hw)) {
		request->status = I2C_CHANNEL_OPERATION_ENGINE_BUSY;
		return;
	}

	execute_transaction(dce_i2c_hw);


}

static uint32_t get_transaction_timeout_hw(
	const struct dce_i2c_hw *dce_i2c_hw,
	uint32_t length)
{

	uint32_t speed = get_speed(dce_i2c_hw);



	uint32_t period_timeout;
	uint32_t num_of_clock_stretches;

	if (!speed)
		return 0;

	period_timeout = (1000 * TRANSACTION_TIMEOUT_IN_I2C_CLOCKS) / speed;

	num_of_clock_stretches = 1 + (length << 3) + 1;
	num_of_clock_stretches +=
		(dce_i2c_hw->buffer_used_bytes << 3) +
		(dce_i2c_hw->transaction_count << 1);

	return period_timeout * num_of_clock_stretches;
}

bool dce_i2c_hw_engine_submit_request(
	struct dce_i2c_hw *dce_i2c_hw,
	struct dce_i2c_transaction_request *dce_i2c_request,
@@ -615,9 +620,7 @@ bool dce_i2c_hw_engine_submit_request(
		reply.data = dce_i2c_request->payload.data;
		reply.length = dce_i2c_request->payload.length;

		dce_i2c_hw->funcs->process_channel_reply(dce_i2c_hw, &reply);


		process_channel_reply(dce_i2c_hw, &reply);
	}

	return result;
@@ -632,7 +635,7 @@ bool dce_i2c_submit_command_hw(
	uint8_t index_of_payload = 0;
	bool result;

	dce_i2c_hw->funcs->set_speed(dce_i2c_hw, cmd->speed);
	set_speed(dce_i2c_hw, cmd->speed);

	result = true;

@@ -670,32 +673,6 @@ bool dce_i2c_submit_command_hw(

	return result;
}
static const struct dce_i2c_hw_funcs dce100_i2c_hw_funcs = {
		.setup_engine = setup_engine,
		.set_speed = set_speed,
		.get_speed = get_speed_hw,
		.release_engine = release_engine_hw,
		.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,
		.set_speed = set_speed,
		.get_speed = get_speed_hw,
		.release_engine = release_engine_hw,
		.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
};



void dce_i2c_hw_construct(
	struct dce_i2c_hw *dce_i2c_hw,
@@ -718,7 +695,6 @@ void dce_i2c_hw_construct(
	dce_i2c_hw->default_speed = DEFAULT_I2C_HW_SPEED;
	dce_i2c_hw->send_reset_length = 0;
	dce_i2c_hw->setup_limit = I2C_SETUP_TIME_LIMIT_DCE;
	dce_i2c_hw->funcs = &dce80_i2c_hw_funcs;
	dce_i2c_hw->buffer_size = I2C_HW_BUFFER_SIZE_DCE;
}

@@ -739,7 +715,6 @@ void dce100_i2c_hw_construct(
			regs,
			shifts,
			masks);
	dce_i2c_hw->funcs = &dce100_i2c_hw_funcs;
	dce_i2c_hw->buffer_size = I2C_HW_BUFFER_SIZE_DCE100;

	REG_GET(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, &xtal_ref_div);
+0 −29
Original line number Diff line number Diff line
@@ -256,40 +256,11 @@ struct dce_i2c_hw {
	uint32_t buffer_size;
	struct dc_context *ctx;

	const struct dce_i2c_hw_funcs *funcs;
	const struct dce_i2c_registers *regs;
	const struct dce_i2c_shift *shifts;
	const struct dce_i2c_mask *masks;
};


struct dce_i2c_hw_funcs {
	bool (*setup_engine)(
		struct dce_i2c_hw *dce_i2c_hw);
	void (*set_speed)(
		struct dce_i2c_hw *dce_i2c_hw,
		uint32_t speed);
	uint32_t (*get_speed)(
		const struct dce_i2c_hw *dce_i2c_hw);
	void (*release_engine)(
		struct dce_i2c_hw *dce_i2c_hw);
	bool (*process_transaction)(
		struct dce_i2c_hw *dce_i2c_hw,
		struct i2c_request_transaction_data *request);
	void (*process_channel_reply)(
		struct dce_i2c_hw *dce_i2c_hw,
		struct i2c_reply_transaction_data *reply);
	bool (*is_hw_busy)(
		struct dce_i2c_hw *dce_i2c_hw);
	enum i2c_channel_operation_result (*get_channel_status)(
		struct dce_i2c_hw *dce_i2c_hw,
		uint8_t *returned_bytes);
	void (*execute_transaction)(
		struct dce_i2c_hw *dce_i2c_hw);
	void (*disable_i2c_hw_engine)(
		struct dce_i2c_hw *dce_i2c_hw);
};

void dce_i2c_hw_construct(
	struct dce_i2c_hw *dce_i2c_hw,
	struct dc_context *ctx,