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