drm/amd/display: Eliminate i2c hw function pointers
authorDavid Francis <David.Francis@amd.com>
Thu, 9 Aug 2018 17:20:04 +0000 (13:20 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 27 Aug 2018 20:19:56 +0000 (15:19 -0500)
[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
drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h

index 3a63e3cbb91d2c52763206ad2d3e29388b8b222c..cd7da59794d000faec19485ffa899f79ba636173 100644 (file)
 #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);
index 8baef3916246ddea5a61078a653d063debd28faa..742c1da84d456560a882da469fdad7fba7f0c3dd 100644 (file)
@@ -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,