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        /* we have checked I2c not used by DMCU, set SW use I2C REQ to 1 to indicate SW using it*/
 297        REG_UPDATE(DC_I2C_ARBITRATION, DC_I2C_SW_USE_I2C_REG_REQ, 1);
 298
 299        /* we have checked I2c not used by DMCU, set SW use I2C REQ to 1 to indicate SW using it*/
 300        REG_UPDATE(DC_I2C_ARBITRATION, DC_I2C_SW_USE_I2C_REG_REQ, 1);
 301
 302        if (dce_i2c_hw->setup_limit != 0)
 303                i2c_setup_limit = dce_i2c_hw->setup_limit;
 304        /* Program pin select */
 305        REG_UPDATE_6(DC_I2C_CONTROL,
 306                     DC_I2C_GO, 0,
 307                     DC_I2C_SOFT_RESET, 0,
 308                     DC_I2C_SEND_RESET, 0,
 309                     DC_I2C_SW_STATUS_RESET, 1,
 310                     DC_I2C_TRANSACTION_COUNT, 0,
 311                     DC_I2C_DDC_SELECT, dce_i2c_hw->engine_id);
 312
 313        /* Program time limit */
 314        if (dce_i2c_hw->send_reset_length == 0) {
 315                /*pre-dcn*/
 316                REG_UPDATE_N(SETUP, 2,
 317                             FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_TIME_LIMIT), i2c_setup_limit,
 318                             FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE), 1);
 319        } else {
 320                reset_length = dce_i2c_hw->send_reset_length;
 321                REG_UPDATE_N(SETUP, 3,
 322                             FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_TIME_LIMIT), i2c_setup_limit,
 323                             FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_SEND_RESET_LENGTH), reset_length,
 324                             FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE), 1);
 325        }
 326        /* Program HW priority
 327         * set to High - interrupt software I2C at any time
 328         * Enable restart of SW I2C that was interrupted by HW
 329         * disable queuing of software while I2C is in use by HW
 330         */
 331        REG_UPDATE(DC_I2C_ARBITRATION,
 332                        DC_I2C_NO_QUEUED_SW_GO, 0);
 333
 334        return true;
 335}
 336
 337static void release_engine(
 338        struct dce_i2c_hw *dce_i2c_hw)
 339{
 340        bool safe_to_reset;
 341
 342        /* Restore original HW engine speed */
 343        set_speed(dce_i2c_hw, dce_i2c_hw->default_speed);
 344
 345        /* Reset HW engine */
 346        {
 347                uint32_t i2c_sw_status = 0;
 348
 349                REG_GET(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, &i2c_sw_status);
 350                /* if used by SW, safe to reset */
 351                safe_to_reset = (i2c_sw_status == 1);
 352        }
 353
 354        if (safe_to_reset)
 355                REG_UPDATE_2(DC_I2C_CONTROL,
 356                             DC_I2C_SOFT_RESET, 1,
 357                             DC_I2C_SW_STATUS_RESET, 1);
 358        else
 359                REG_UPDATE(DC_I2C_CONTROL, DC_I2C_SW_STATUS_RESET, 1);
 360        /* HW I2c engine - clock gating feature */
 361        if (!dce_i2c_hw->engine_keep_power_up_count)
 362                REG_UPDATE_N(SETUP, 1, FN(SETUP, DC_I2C_DDC1_ENABLE), 0);
 363        /* Release I2C after reset, so HW or DMCU could use it */
 364        REG_UPDATE_2(DC_I2C_ARBITRATION, DC_I2C_SW_DONE_USING_I2C_REG, 1,
 365                DC_I2C_SW_USE_I2C_REG_REQ, 0);
 366
 367}
 368
 369struct dce_i2c_hw *acquire_i2c_hw_engine(
 370        struct resource_pool *pool,
 371        struct ddc *ddc)
 372{
 373        uint32_t counter = 0;
 374        enum gpio_result result;
 375        struct dce_i2c_hw *dce_i2c_hw = NULL;
 376
 377        if (!ddc)
 378                return NULL;
 379
 380        if (ddc->hw_info.hw_supported) {
 381                enum gpio_ddc_line line = dal_ddc_get_line(ddc);
 382
 383                if (line < pool->res_cap->num_ddc)
 384                        dce_i2c_hw = pool->hw_i2cs[line];
 385        }
 386
 387        if (!dce_i2c_hw)
 388                return NULL;
 389
 390        if (pool->i2c_hw_buffer_in_use || !is_engine_available(dce_i2c_hw))
 391                return NULL;
 392
 393        do {
 394                result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE,
 395                        GPIO_DDC_CONFIG_TYPE_MODE_I2C);
 396
 397                if (result == GPIO_RESULT_OK)
 398                        break;
 399
 400                /* i2c_engine is busy by VBios, lets wait and retry */
 401
 402                udelay(10);
 403
 404                ++counter;
 405        } while (counter < 2);
 406
 407        if (result != GPIO_RESULT_OK)
 408                return NULL;
 409
 410        dce_i2c_hw->ddc = ddc;
 411
 412        if (!setup_engine(dce_i2c_hw)) {
 413                release_engine(dce_i2c_hw);
 414                return NULL;
 415        }
 416
 417        pool->i2c_hw_buffer_in_use = true;
 418        return dce_i2c_hw;
 419}
 420
 421enum i2c_channel_operation_result dce_i2c_hw_engine_wait_on_operation_result(
 422        struct dce_i2c_hw *dce_i2c_hw,
 423        uint32_t timeout,
 424        enum i2c_channel_operation_result expected_result)
 425{
 426        enum i2c_channel_operation_result result;
 427        uint32_t i = 0;
 428
 429        if (!timeout)
 430                return I2C_CHANNEL_OPERATION_SUCCEEDED;
 431
 432        do {
 433
 434                result = get_channel_status(
 435                                dce_i2c_hw, NULL);
 436
 437                if (result != expected_result)
 438                        break;
 439
 440                udelay(1);
 441
 442                ++i;
 443        } while (i < timeout);
 444        return result;
 445}
 446
 447static void submit_channel_request_hw(
 448        struct dce_i2c_hw *dce_i2c_hw,
 449        struct i2c_request_transaction_data *request)
 450{
 451        request->status = I2C_CHANNEL_OPERATION_SUCCEEDED;
 452
 453        if (!process_transaction(dce_i2c_hw, request))
 454                return;
 455
 456        if (is_hw_busy(dce_i2c_hw)) {
 457                request->status = I2C_CHANNEL_OPERATION_ENGINE_BUSY;
 458                return;
 459        }
 460        reset_hw_engine(dce_i2c_hw);
 461
 462        execute_transaction(dce_i2c_hw);
 463
 464
 465}
 466
 467static uint32_t get_transaction_timeout_hw(
 468        const struct dce_i2c_hw *dce_i2c_hw,
 469        uint32_t length,
 470        uint32_t speed)
 471{
 472        uint32_t period_timeout;
 473        uint32_t num_of_clock_stretches;
 474
 475        if (!speed)
 476                return 0;
 477
 478        period_timeout = (1000 * TRANSACTION_TIMEOUT_IN_I2C_CLOCKS) / speed;
 479
 480        num_of_clock_stretches = 1 + (length << 3) + 1;
 481        num_of_clock_stretches +=
 482                (dce_i2c_hw->buffer_used_bytes << 3) +
 483                (dce_i2c_hw->transaction_count << 1);
 484
 485        return period_timeout * num_of_clock_stretches;
 486}
 487
 488bool dce_i2c_hw_engine_submit_payload(
 489        struct dce_i2c_hw *dce_i2c_hw,
 490        struct i2c_payload *payload,
 491        bool middle_of_transaction,
 492        uint32_t speed)
 493{
 494
 495        struct i2c_request_transaction_data request;
 496
 497        uint32_t transaction_timeout;
 498
 499        enum i2c_channel_operation_result operation_result;
 500
 501        bool result = false;
 502
 503        /* We need following:
 504         * transaction length will not exceed
 505         * the number of free bytes in HW buffer (minus one for address)
 506         */
 507
 508        if (payload->length >=
 509                        get_hw_buffer_available_size(dce_i2c_hw)) {
 510                return false;
 511        }
 512
 513        if (!payload->write)
 514                request.action = middle_of_transaction ?
 515                        DCE_I2C_TRANSACTION_ACTION_I2C_READ_MOT :
 516                        DCE_I2C_TRANSACTION_ACTION_I2C_READ;
 517        else
 518                request.action = middle_of_transaction ?
 519                        DCE_I2C_TRANSACTION_ACTION_I2C_WRITE_MOT :
 520                        DCE_I2C_TRANSACTION_ACTION_I2C_WRITE;
 521
 522
 523        request.address = (uint8_t) ((payload->address << 1) | !payload->write);
 524        request.length = payload->length;
 525        request.data = payload->data;
 526
 527        /* obtain timeout value before submitting request */
 528
 529        transaction_timeout = get_transaction_timeout_hw(
 530                dce_i2c_hw, payload->length + 1, speed);
 531
 532        submit_channel_request_hw(
 533                dce_i2c_hw, &request);
 534
 535        if ((request.status == I2C_CHANNEL_OPERATION_FAILED) ||
 536                (request.status == I2C_CHANNEL_OPERATION_ENGINE_BUSY))
 537                return false;
 538
 539        /* wait until transaction proceed */
 540
 541        operation_result = dce_i2c_hw_engine_wait_on_operation_result(
 542                dce_i2c_hw,
 543                transaction_timeout,
 544                I2C_CHANNEL_OPERATION_ENGINE_BUSY);
 545
 546        /* update transaction status */
 547
 548        if (operation_result == I2C_CHANNEL_OPERATION_SUCCEEDED)
 549                result = true;
 550
 551        if (result && (!payload->write))
 552                process_channel_reply(dce_i2c_hw, payload);
 553
 554        return result;
 555}
 556
 557bool dce_i2c_submit_command_hw(
 558        struct resource_pool *pool,
 559        struct ddc *ddc,
 560        struct i2c_command *cmd,
 561        struct dce_i2c_hw *dce_i2c_hw)
 562{
 563        uint8_t index_of_payload = 0;
 564        bool result;
 565
 566        set_speed(dce_i2c_hw, cmd->speed);
 567
 568        result = true;
 569
 570        while (index_of_payload < cmd->number_of_payloads) {
 571                bool mot = (index_of_payload != cmd->number_of_payloads - 1);
 572
 573                struct i2c_payload *payload = cmd->payloads + index_of_payload;
 574
 575                if (!dce_i2c_hw_engine_submit_payload(
 576                                dce_i2c_hw, payload, mot, cmd->speed)) {
 577                        result = false;
 578                        break;
 579                }
 580
 581                ++index_of_payload;
 582        }
 583
 584        pool->i2c_hw_buffer_in_use = false;
 585
 586        release_engine(dce_i2c_hw);
 587        dal_ddc_close(dce_i2c_hw->ddc);
 588
 589        dce_i2c_hw->ddc = NULL;
 590
 591        return result;
 592}
 593
 594void dce_i2c_hw_construct(
 595        struct dce_i2c_hw *dce_i2c_hw,
 596        struct dc_context *ctx,
 597        uint32_t engine_id,
 598        const struct dce_i2c_registers *regs,
 599        const struct dce_i2c_shift *shifts,
 600        const struct dce_i2c_mask *masks)
 601{
 602        dce_i2c_hw->ctx = ctx;
 603        dce_i2c_hw->engine_id = engine_id;
 604        dce_i2c_hw->reference_frequency = (ctx->dc_bios->fw_info.pll_info.crystal_frequency) >> 1;
 605        dce_i2c_hw->regs = regs;
 606        dce_i2c_hw->shifts = shifts;
 607        dce_i2c_hw->masks = masks;
 608        dce_i2c_hw->buffer_used_bytes = 0;
 609        dce_i2c_hw->transaction_count = 0;
 610        dce_i2c_hw->engine_keep_power_up_count = 1;
 611        dce_i2c_hw->default_speed = DEFAULT_I2C_HW_SPEED;
 612        dce_i2c_hw->send_reset_length = 0;
 613        dce_i2c_hw->setup_limit = I2C_SETUP_TIME_LIMIT_DCE;
 614        dce_i2c_hw->buffer_size = I2C_HW_BUFFER_SIZE_DCE;
 615}
 616
 617void dce100_i2c_hw_construct(
 618        struct dce_i2c_hw *dce_i2c_hw,
 619        struct dc_context *ctx,
 620        uint32_t engine_id,
 621        const struct dce_i2c_registers *regs,
 622        const struct dce_i2c_shift *shifts,
 623        const struct dce_i2c_mask *masks)
 624{
 625        dce_i2c_hw_construct(dce_i2c_hw,
 626                        ctx,
 627                        engine_id,
 628                        regs,
 629                        shifts,
 630                        masks);
 631        dce_i2c_hw->buffer_size = I2C_HW_BUFFER_SIZE_DCE100;
 632}
 633
 634void dce112_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        dce100_i2c_hw_construct(dce_i2c_hw,
 643                        ctx,
 644                        engine_id,
 645                        regs,
 646                        shifts,
 647                        masks);
 648        dce_i2c_hw->default_speed = DEFAULT_I2C_HW_SPEED_100KHZ;
 649}
 650
 651void dcn1_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        dce112_i2c_hw_construct(dce_i2c_hw,
 660                        ctx,
 661                        engine_id,
 662                        regs,
 663                        shifts,
 664                        masks);
 665        dce_i2c_hw->setup_limit = I2C_SETUP_TIME_LIMIT_DCN;
 666}
 667
 668void dcn2_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        dcn1_i2c_hw_construct(dce_i2c_hw,
 677                        ctx,
 678                        engine_id,
 679                        regs,
 680                        shifts,
 681                        masks);
 682        dce_i2c_hw->send_reset_length = I2C_SEND_RESET_LENGTH_9;
 683        if (ctx->dc->debug.scl_reset_length10)
 684                dce_i2c_hw->send_reset_length = I2C_SEND_RESET_LENGTH_10;
 685}
 686