diff options
Diffstat (limited to 'meta-r1000/recipes-kernel/linux/linux-yocto-4.14.71/5248-drm-amd-display-Eliminate-i2c-hw-function-pointers.patch')
-rw-r--r-- | meta-r1000/recipes-kernel/linux/linux-yocto-4.14.71/5248-drm-amd-display-Eliminate-i2c-hw-function-pointers.patch | 806 |
1 files changed, 0 insertions, 806 deletions
diff --git a/meta-r1000/recipes-kernel/linux/linux-yocto-4.14.71/5248-drm-amd-display-Eliminate-i2c-hw-function-pointers.patch b/meta-r1000/recipes-kernel/linux/linux-yocto-4.14.71/5248-drm-amd-display-Eliminate-i2c-hw-function-pointers.patch deleted file mode 100644 index ff8fda80..00000000 --- a/meta-r1000/recipes-kernel/linux/linux-yocto-4.14.71/5248-drm-amd-display-Eliminate-i2c-hw-function-pointers.patch +++ /dev/null @@ -1,806 +0,0 @@ -From 00b3bee54353b4bf547e46a7b527046cfdf4fa07 Mon Sep 17 00:00:00 2001 -From: David Francis <David.Francis@amd.com> -Date: Thu, 9 Aug 2018 13:20:04 -0400 -Subject: [PATCH 5248/5725] 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: David Francis <David.Francis@amd.com> -Reviewed-by: Sun peng Li <Sunpeng.Li@amd.com> -Acked-by: Leo Li <sunpeng.li@amd.com> -Signed-off-by: Alex Deucher <alexander.deucher@amd.com> ---- - drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c | 607 ++++++++++++------------ - drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h | 29 -- - 2 files changed, 291 insertions(+), 345 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 3a63e3c..cd7da59 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 -@@ -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; -- -- 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 -- */ -- -- uint32_t i2c_data; -+ DC_I2C_GO, 0, -+ DC_I2C_TRANSACTION_COUNT, dce_i2c_hw->transaction_count - 1); - -- REG_GET(DC_I2C_DATA, DC_I2C_DATA, &i2c_data); -- *buffer++ = i2c_data; -+ /* start I2C transfer */ -+ REG_UPDATE(DC_I2C_CONTROL, DC_I2C_GO, 1); - -- --length; -- } -+ /* all transactions were executed and HW buffer became empty -+ * (even though it actually happens when status becomes DONE) -+ */ -+ 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; -- } -- -- dce_i2c_hw->funcs->execute_transaction(dce_i2c_hw); -- -- -+ return dce_i2c_hw->buffer_size - -+ dce_i2c_hw->buffer_used_bytes; - } -+ - 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) -- */ -- dce_i2c_hw->transaction_count = 0; -- dce_i2c_hw->buffer_used_bytes = 0; -+ 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 -+ */ -+ -+ 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); -diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h -index 8baef39..742c1da 100644 ---- a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h -+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h -@@ -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, --- -2.7.4 - |