aboutsummaryrefslogtreecommitdiffstats
path: root/meta-r1000/recipes-kernel/linux/linux-yocto-4.14.71/5248-drm-amd-display-Eliminate-i2c-hw-function-pointers.patch
diff options
context:
space:
mode:
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.patch806
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
-