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 uint32_t get_speed(
 104        const struct dce_i2c_hw *dce_i2c_hw)
 105{
 106        uint32_t pre_scale = 0;
 107
 108        REG_GET(SPEED, DC_I2C_DDC1_PRESCALE, &pre_scale);
 109
 110        /* [anaumov] it seems following is unnecessary */
 111        /*ASSERT(value.bits.DC_I2C_DDC1_PRESCALE);*/
 112        return pre_scale ?
 113                dce_i2c_hw->reference_frequency / pre_scale :
 114                dce_i2c_hw->default_speed;
 115}
 116
 117static void process_channel_reply(
 118        struct dce_i2c_hw *dce_i2c_hw,
 119        struct i2c_payload *reply)
 120{
 121        uint32_t length = reply->length;
 122        uint8_t *buffer = reply->data;
 123
 124        REG_SET_3(DC_I2C_DATA, 0,
 125                 DC_I2C_INDEX, dce_i2c_hw->buffer_used_write,
 126                 DC_I2C_DATA_RW, 1,
 127                 DC_I2C_INDEX_WRITE, 1);
 128
 129        while (length) {
 130                /* after reading the status,
 131                 * if the I2C operation executed successfully
 132                 * (i.e. DC_I2C_STATUS_DONE = 1) then the I2C controller
 133                 * should read data bytes from I2C circular data buffer
 134                 */
 135
 136                uint32_t i2c_data;
 137
 138                REG_GET(DC_I2C_DATA, DC_I2C_DATA, &i2c_data);
 139                *buffer++ = i2c_data;
 140
 141                --length;
 142        }
 143}
 144
 145static bool is_engine_available(struct dce_i2c_hw *dce_i2c_hw)
 146{
 147        unsigned int arbitrate;
 148        unsigned int i2c_hw_status;
 149
 150        REG_GET(HW_STATUS, DC_I2C_DDC1_HW_STATUS, &i2c_hw_status);
 151        if (i2c_hw_status == DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_HW)
 152                return false;
 153
 154        REG_GET(DC_I2C_ARBITRATION, DC_I2C_REG_RW_CNTL_STATUS, &arbitrate);
 155        if (arbitrate == DC_I2C_REG_RW_CNTL_STATUS_DMCU_ONLY)
 156                return false;
 157
 158        return true;
 159}
 160
 161static bool is_hw_busy(struct dce_i2c_hw *dce_i2c_hw)
 162{
 163        uint32_t i2c_sw_status = 0;
 164
 165        REG_GET(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, &i2c_sw_status);
 166        if (i2c_sw_status == DC_I2C_STATUS__DC_I2C_STATUS_IDLE)
 167                return false;
 168
 169        if (is_engine_available(dce_i2c_hw))
 170                return false;
 171
 172        return true;
 173}
 174
 175static bool process_transaction(
 176        struct dce_i2c_hw *dce_i2c_hw,
 177        struct i2c_request_transaction_data *request)
 178{
 179        uint32_t length = request->length;
 180        uint8_t *buffer = request->data;
 181
 182        bool last_transaction = false;
 183        uint32_t value = 0;
 184
 185        if (is_hw_busy(dce_i2c_hw)) {
 186                request->status = I2C_CHANNEL_OPERATION_ENGINE_BUSY;
 187                return false;
 188        }
 189
 190        last_transaction = ((dce_i2c_hw->transaction_count == 3) ||
 191                        (request->action == DCE_I2C_TRANSACTION_ACTION_I2C_WRITE) ||
 192                        (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ));
 193
 194
 195        switch (dce_i2c_hw->transaction_count) {
 196        case 0:
 197                REG_UPDATE_5(DC_I2C_TRANSACTION0,
 198                                 DC_I2C_STOP_ON_NACK0, 1,
 199                                 DC_I2C_START0, 1,
 200                                 DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
 201                                 DC_I2C_COUNT0, length,
 202                                 DC_I2C_STOP0, last_transaction ? 1 : 0);
 203                break;
 204        case 1:
 205                REG_UPDATE_5(DC_I2C_TRANSACTION1,
 206                                 DC_I2C_STOP_ON_NACK0, 1,
 207                                 DC_I2C_START0, 1,
 208                                 DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
 209                                 DC_I2C_COUNT0, length,
 210                                 DC_I2C_STOP0, last_transaction ? 1 : 0);
 211                break;
 212        case 2:
 213                REG_UPDATE_5(DC_I2C_TRANSACTION2,
 214                                 DC_I2C_STOP_ON_NACK0, 1,
 215                                 DC_I2C_START0, 1,
 216                                 DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
 217                                 DC_I2C_COUNT0, length,
 218                                 DC_I2C_STOP0, last_transaction ? 1 : 0);
 219                break;
 220        case 3:
 221                REG_UPDATE_5(DC_I2C_TRANSACTION3,
 222                                 DC_I2C_STOP_ON_NACK0, 1,
 223                                 DC_I2C_START0, 1,
 224                                 DC_I2C_RW0, 0 != (request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ),
 225                                 DC_I2C_COUNT0, length,
 226                                 DC_I2C_STOP0, last_transaction ? 1 : 0);
 227                break;
 228        default:
 229                /* TODO Warning ? */
 230                break;
 231        }
 232
 233        /* Write the I2C address and I2C data
 234         * into the hardware circular buffer, one byte per entry.
 235         * As an example, the 7-bit I2C slave address for CRT monitor
 236         * for reading DDC/EDID information is 0b1010001.
 237         * For an I2C send operation, the LSB must be programmed to 0;
 238         * for I2C receive operation, the LSB must be programmed to 1.
 239         */
 240        if (dce_i2c_hw->transaction_count == 0) {
 241                value = REG_SET_4(DC_I2C_DATA, 0,
 242                                  DC_I2C_DATA_RW, false,
 243                                  DC_I2C_DATA, request->address,
 244                                  DC_I2C_INDEX, 0,
 245                                  DC_I2C_INDEX_WRITE, 1);
 246                dce_i2c_hw->buffer_used_write = 0;
 247        } else
 248                value = REG_SET_2(DC_I2C_DATA, 0,
 249                          DC_I2C_DATA_RW, false,
 250                          DC_I2C_DATA, request->address);
 251
 252        dce_i2c_hw->buffer_used_write++;
 253
 254        if (!(request->action & DCE_I2C_TRANSACTION_ACTION_I2C_READ)) {
 255                while (length) {
 256                        REG_SET_2(DC_I2C_DATA, value,
 257                                  DC_I2C_INDEX_WRITE, 0,
 258                                  DC_I2C_DATA, *buffer++);
 259                        dce_i2c_hw->buffer_used_write++;
 260                        --length;
 261                }
 262        }
 263
 264        ++dce_i2c_hw->transaction_count;
 265        dce_i2c_hw->buffer_used_bytes += length + 1;
 266
 267        return last_transaction;
 268}
 269
 270static inline void reset_hw_engine(struct dce_i2c_hw *dce_i2c_hw)
 271{
 272        REG_UPDATE_2(DC_I2C_CONTROL,
 273                     DC_I2C_SW_STATUS_RESET, 1,
 274                     DC_I2C_SW_STATUS_RESET, 1);
 275}
 276
 277static void set_speed(
 278        struct dce_i2c_hw *dce_i2c_hw,
 279        uint32_t speed)
 280{
 281
 282        if (speed) {
 283                if (dce_i2c_hw->masks->DC_I2C_DDC1_START_STOP_TIMING_CNTL)
 284                        REG_UPDATE_N(SPEED, 3,
 285                                     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), dce_i2c_hw->reference_frequency / speed,
 286                                     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2,
 287                                     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_START_STOP_TIMING_CNTL), speed > 50 ? 2:1);
 288                else
 289                        REG_UPDATE_N(SPEED, 2,
 290                                     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), dce_i2c_hw->reference_frequency / speed,
 291                                     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2);
 292        }
 293}
 294
 295static bool setup_engine(
 296        struct dce_i2c_hw *dce_i2c_hw)
 297{
 298        uint32_t i2c_setup_limit = I2C_SETUP_TIME_LIMIT_DCE;
 299#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 300        uint32_t  reset_length = 0;
 301#endif
 302        /* we have checked I2c not used by DMCU, set SW use I2C REQ to 1 to indicate SW using it*/
 303        REG_UPDATE(DC_I2C_ARBITRATION, DC_I2C_SW_USE_I2C_REG_REQ, 1);
 304
 305        /* we have checked I2c not used by DMCU, set SW use I2C REQ to 1 to indicate SW using it*/
 306        REG_UPDATE(DC_I2C_ARBITRATION, DC_I2C_SW_USE_I2C_REG_REQ, 1);
 307
 308        if (dce_i2c_hw->setup_limit != 0)
 309                i2c_setup_limit = dce_i2c_hw->setup_limit;
 310        /* Program pin select */
 311        REG_UPDATE_6(DC_I2C_CONTROL,
 312                     DC_I2C_GO, 0,
 313                     DC_I2C_SOFT_RESET, 0,
 314                     DC_I2C_SEND_RESET, 0,
 315                     DC_I2C_SW_STATUS_RESET, 1,
 316                     DC_I2C_TRANSACTION_COUNT, 0,
 317                     DC_I2C_DDC_SELECT, dce_i2c_hw->engine_id);
 318
 319        /* Program time limit */
 320        if (dce_i2c_hw->send_reset_length == 0) {
 321                /*pre-dcn*/
 322                REG_UPDATE_N(SETUP, 2,
 323                             FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_TIME_LIMIT), i2c_setup_limit,
 324                             FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE), 1);
 325#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 326        } else {
 327                reset_length = dce_i2c_hw->send_reset_length;
 328                REG_UPDATE_N(SETUP, 3,
 329                             FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_TIME_LIMIT), i2c_setup_limit,
 330                             FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_SEND_RESET_LENGTH), reset_length,
 331                             FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE), 1);
 332#endif
 333        }
 334        /* Program HW priority
 335         * set to High - interrupt software I2C at any time
 336         * Enable restart of SW I2C that was interrupted by HW
 337         * disable queuing of software while I2C is in use by HW
 338         */
 339        REG_UPDATE(DC_I2C_ARBITRATION,
 340                        DC_I2C_NO_QUEUED_SW_GO, 0);
 341
 342        return true;
 343}
 344
 345static void release_engine(
 346        struct dce_i2c_hw *dce_i2c_hw)
 347{
 348        bool safe_to_reset;
 349
 350        /* Restore original HW engine speed */
 351
 352        set_speed(dce_i2c_hw, dce_i2c_hw->original_speed);
 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        /* Release I2C after reset, so HW or DMCU could use it */
 374        REG_UPDATE_2(DC_I2C_ARBITRATION, DC_I2C_SW_DONE_USING_I2C_REG, 1,
 375                DC_I2C_SW_USE_I2C_REG_REQ, 0);
 376
 377}
 378
 379struct dce_i2c_hw *acquire_i2c_hw_engine(
 380        struct resource_pool *pool,
 381        struct ddc *ddc)
 382{
 383        uint32_t counter = 0;
 384        enum gpio_result result;
 385        uint32_t current_speed;
 386        struct dce_i2c_hw *dce_i2c_hw = NULL;
 387
 388        if (!ddc)
 389                return NULL;
 390
 391        if (ddc->hw_info.hw_supported) {
 392                enum gpio_ddc_line line = dal_ddc_get_line(ddc);
 393
 394                if (line < pool->res_cap->num_ddc)
 395                        dce_i2c_hw = pool->hw_i2cs[line];
 396        }
 397
 398        if (!dce_i2c_hw)
 399                return NULL;
 400
 401        if (pool->i2c_hw_buffer_in_use || !is_engine_available(dce_i2c_hw))
 402                return NULL;
 403
 404        do {
 405                result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE,
 406                        GPIO_DDC_CONFIG_TYPE_MODE_I2C);
 407
 408                if (result == GPIO_RESULT_OK)
 409                        break;
 410
 411                /* i2c_engine is busy by VBios, lets wait and retry */
 412
 413                udelay(10);
 414
 415                ++counter;
 416        } while (counter < 2);
 417
 418        if (result != GPIO_RESULT_OK)
 419                return NULL;
 420
 421        dce_i2c_hw->ddc = ddc;
 422
 423        current_speed = get_speed(dce_i2c_hw);
 424
 425        if (current_speed)
 426                dce_i2c_hw->original_speed = current_speed;
 427
 428        if (!setup_engine(dce_i2c_hw)) {
 429                release_engine(dce_i2c_hw);
 430                return NULL;
 431        }
 432
 433        pool->i2c_hw_buffer_in_use = true;
 434        return dce_i2c_hw;
 435}
 436
 437enum i2c_channel_operation_result dce_i2c_hw_engine_wait_on_operation_result(
 438        struct dce_i2c_hw *dce_i2c_hw,
 439        uint32_t timeout,
 440        enum i2c_channel_operation_result expected_result)
 441{
 442        enum i2c_channel_operation_result result;
 443        uint32_t i = 0;
 444
 445        if (!timeout)
 446                return I2C_CHANNEL_OPERATION_SUCCEEDED;
 447
 448        do {
 449
 450                result = get_channel_status(
 451                                dce_i2c_hw, NULL);
 452
 453                if (result != expected_result)
 454                        break;
 455
 456                udelay(1);
 457
 458                ++i;
 459        } while (i < timeout);
 460        return result;
 461}
 462
 463static void submit_channel_request_hw(
 464        struct dce_i2c_hw *dce_i2c_hw,
 465        struct i2c_request_transaction_data *request)
 466{
 467        request->status = I2C_CHANNEL_OPERATION_SUCCEEDED;
 468
 469        if (!process_transaction(dce_i2c_hw, request))
 470                return;
 471
 472        if (is_hw_busy(dce_i2c_hw)) {
 473                request->status = I2C_CHANNEL_OPERATION_ENGINE_BUSY;
 474                return;
 475        }
 476        reset_hw_engine(dce_i2c_hw);
 477
 478        execute_transaction(dce_i2c_hw);
 479
 480
 481}
 482
 483static uint32_t get_transaction_timeout_hw(
 484        const struct dce_i2c_hw *dce_i2c_hw,
 485        uint32_t length)
 486{
 487
 488        uint32_t speed = get_speed(dce_i2c_hw);
 489
 490
 491
 492        uint32_t period_timeout;
 493        uint32_t num_of_clock_stretches;
 494
 495        if (!speed)
 496                return 0;
 497
 498        period_timeout = (1000 * TRANSACTION_TIMEOUT_IN_I2C_CLOCKS) / speed;
 499
 500        num_of_clock_stretches = 1 + (length << 3) + 1;
 501        num_of_clock_stretches +=
 502                (dce_i2c_hw->buffer_used_bytes << 3) +
 503                (dce_i2c_hw->transaction_count << 1);
 504
 505        return period_timeout * num_of_clock_stretches;
 506}
 507
 508bool dce_i2c_hw_engine_submit_payload(
 509        struct dce_i2c_hw *dce_i2c_hw,
 510        struct i2c_payload *payload,
 511        bool middle_of_transaction)
 512{
 513
 514        struct i2c_request_transaction_data request;
 515
 516        uint32_t transaction_timeout;
 517
 518        enum i2c_channel_operation_result operation_result;
 519
 520        bool result = false;
 521
 522        /* We need following:
 523         * transaction length will not exceed
 524         * the number of free bytes in HW buffer (minus one for address)
 525         */
 526
 527        if (payload->length >=
 528                        get_hw_buffer_available_size(dce_i2c_hw)) {
 529                return false;
 530        }
 531
 532        if (!payload->write)
 533                request.action = middle_of_transaction ?
 534                        DCE_I2C_TRANSACTION_ACTION_I2C_READ_MOT :
 535                        DCE_I2C_TRANSACTION_ACTION_I2C_READ;
 536        else
 537                request.action = middle_of_transaction ?
 538                        DCE_I2C_TRANSACTION_ACTION_I2C_WRITE_MOT :
 539                        DCE_I2C_TRANSACTION_ACTION_I2C_WRITE;
 540
 541
 542        request.address = (uint8_t) ((payload->address << 1) | !payload->write);
 543        request.length = payload->length;
 544        request.data = payload->data;
 545
 546        /* obtain timeout value before submitting request */
 547
 548        transaction_timeout = get_transaction_timeout_hw(
 549                dce_i2c_hw, payload->length + 1);
 550
 551        submit_channel_request_hw(
 552                dce_i2c_hw, &request);
 553
 554        if ((request.status == I2C_CHANNEL_OPERATION_FAILED) ||
 555                (request.status == I2C_CHANNEL_OPERATION_ENGINE_BUSY))
 556                return false;
 557
 558        /* wait until transaction proceed */
 559
 560        operation_result = dce_i2c_hw_engine_wait_on_operation_result(
 561                dce_i2c_hw,
 562                transaction_timeout,
 563                I2C_CHANNEL_OPERATION_ENGINE_BUSY);
 564
 565        /* update transaction status */
 566
 567        if (operation_result == I2C_CHANNEL_OPERATION_SUCCEEDED)
 568                result = true;
 569
 570        if (result && (!payload->write))
 571                process_channel_reply(dce_i2c_hw, payload);
 572
 573        return result;
 574}
 575
 576bool dce_i2c_submit_command_hw(
 577        struct resource_pool *pool,
 578        struct ddc *ddc,
 579        struct i2c_command *cmd,
 580        struct dce_i2c_hw *dce_i2c_hw)
 581{
 582        uint8_t index_of_payload = 0;
 583        bool result;
 584
 585        set_speed(dce_i2c_hw, cmd->speed);
 586
 587        result = true;
 588
 589        while (index_of_payload < cmd->number_of_payloads) {
 590                bool mot = (index_of_payload != cmd->number_of_payloads - 1);
 591
 592                struct i2c_payload *payload = cmd->payloads + index_of_payload;
 593
 594                if (!dce_i2c_hw_engine_submit_payload(
 595                                dce_i2c_hw, payload, mot)) {
 596                        result = false;
 597                        break;
 598                }
 599
 600
 601
 602                ++index_of_payload;
 603        }
 604
 605        pool->i2c_hw_buffer_in_use = false;
 606
 607        release_engine(dce_i2c_hw);
 608        dal_ddc_close(dce_i2c_hw->ddc);
 609
 610        dce_i2c_hw->ddc = NULL;
 611
 612        return result;
 613}
 614
 615void dce_i2c_hw_construct(
 616        struct dce_i2c_hw *dce_i2c_hw,
 617        struct dc_context *ctx,
 618        uint32_t engine_id,
 619        const struct dce_i2c_registers *regs,
 620        const struct dce_i2c_shift *shifts,
 621        const struct dce_i2c_mask *masks)
 622{
 623        dce_i2c_hw->ctx = ctx;
 624        dce_i2c_hw->engine_id = engine_id;
 625        dce_i2c_hw->reference_frequency = (ctx->dc_bios->fw_info.pll_info.crystal_frequency) >> 1;
 626        dce_i2c_hw->regs = regs;
 627        dce_i2c_hw->shifts = shifts;
 628        dce_i2c_hw->masks = masks;
 629        dce_i2c_hw->buffer_used_bytes = 0;
 630        dce_i2c_hw->transaction_count = 0;
 631        dce_i2c_hw->engine_keep_power_up_count = 1;
 632        dce_i2c_hw->original_speed = DEFAULT_I2C_HW_SPEED;
 633        dce_i2c_hw->default_speed = DEFAULT_I2C_HW_SPEED;
 634        dce_i2c_hw->send_reset_length = 0;
 635        dce_i2c_hw->setup_limit = I2C_SETUP_TIME_LIMIT_DCE;
 636        dce_i2c_hw->buffer_size = I2C_HW_BUFFER_SIZE_DCE;
 637}
 638
 639void dce100_i2c_hw_construct(
 640        struct dce_i2c_hw *dce_i2c_hw,
 641        struct dc_context *ctx,
 642        uint32_t engine_id,
 643        const struct dce_i2c_registers *regs,
 644        const struct dce_i2c_shift *shifts,
 645        const struct dce_i2c_mask *masks)
 646{
 647
 648        uint32_t xtal_ref_div = 0;
 649
 650        dce_i2c_hw_construct(dce_i2c_hw,
 651                        ctx,
 652                        engine_id,
 653                        regs,
 654                        shifts,
 655                        masks);
 656        dce_i2c_hw->buffer_size = I2C_HW_BUFFER_SIZE_DCE100;
 657
 658        REG_GET(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, &xtal_ref_div);
 659
 660        if (xtal_ref_div == 0)
 661                xtal_ref_div = 2;
 662
 663        /*Calculating Reference Clock by divding original frequency by
 664         * XTAL_REF_DIV.
 665         * At upper level, uint32_t reference_frequency =
 666         *  dal_dce_i2c_get_reference_clock(as) >> 1
 667         *  which already divided by 2. So we need x2 to get original
 668         *  reference clock from ppll_info
 669         */
 670        dce_i2c_hw->reference_frequency =
 671                (dce_i2c_hw->reference_frequency * 2) / xtal_ref_div;
 672}
 673
 674void dce112_i2c_hw_construct(
 675        struct dce_i2c_hw *dce_i2c_hw,
 676        struct dc_context *ctx,
 677        uint32_t engine_id,
 678        const struct dce_i2c_registers *regs,
 679        const struct dce_i2c_shift *shifts,
 680        const struct dce_i2c_mask *masks)
 681{
 682        dce100_i2c_hw_construct(dce_i2c_hw,
 683                        ctx,
 684                        engine_id,
 685                        regs,
 686                        shifts,
 687                        masks);
 688        dce_i2c_hw->default_speed = DEFAULT_I2C_HW_SPEED_100KHZ;
 689}
 690
 691void dcn1_i2c_hw_construct(
 692        struct dce_i2c_hw *dce_i2c_hw,
 693        struct dc_context *ctx,
 694        uint32_t engine_id,
 695        const struct dce_i2c_registers *regs,
 696        const struct dce_i2c_shift *shifts,
 697        const struct dce_i2c_mask *masks)
 698{
 699        dce112_i2c_hw_construct(dce_i2c_hw,
 700                        ctx,
 701                        engine_id,
 702                        regs,
 703                        shifts,
 704                        masks);
 705        dce_i2c_hw->setup_limit = I2C_SETUP_TIME_LIMIT_DCN;
 706}
 707
 708#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 709void dcn2_i2c_hw_construct(
 710        struct dce_i2c_hw *dce_i2c_hw,
 711        struct dc_context *ctx,
 712        uint32_t engine_id,
 713        const struct dce_i2c_registers *regs,
 714        const struct dce_i2c_shift *shifts,
 715        const struct dce_i2c_mask *masks)
 716{
 717        dcn1_i2c_hw_construct(dce_i2c_hw,
 718                        ctx,
 719                        engine_id,
 720                        regs,
 721                        shifts,
 722                        masks);
 723        dce_i2c_hw->send_reset_length = I2C_SEND_RESET_LENGTH_9;
 724        if (ctx->dc->debug.scl_reset_length10)
 725                dce_i2c_hw->send_reset_length = I2C_SEND_RESET_LENGTH_10;
 726}
 727#endif
 728