root/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. execute_transaction
  2. get_channel_status
  3. get_hw_buffer_available_size
  4. get_speed
  5. process_channel_reply
  6. is_engine_available
  7. is_hw_busy
  8. process_transaction
  9. reset_hw_engine
  10. set_speed
  11. setup_engine
  12. release_engine
  13. acquire_i2c_hw_engine
  14. dce_i2c_hw_engine_wait_on_operation_result
  15. submit_channel_request_hw
  16. get_transaction_timeout_hw
  17. dce_i2c_hw_engine_submit_payload
  18. dce_i2c_submit_command_hw
  19. dce_i2c_hw_construct
  20. dce100_i2c_hw_construct
  21. dce112_i2c_hw_construct
  22. dcn1_i2c_hw_construct
  23. dcn2_i2c_hw_construct

   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 
  43 static 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 
  71 static 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 
  96 static 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 
 103 static 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 
 117 static 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 
 145 static 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 
 161 static 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 
 175 static 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 
 270 static 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 
 277 static 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 
 295 static 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 
 345 static 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 
 379 struct 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 
 437 enum 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 
 463 static 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 
 483 static 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 
 508 bool 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 
 576 bool 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 
 615 void 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 
 639 void 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 
 674 void 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 
 691 void 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)
 709 void 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

/* [<][>][^][v][top][bottom][index][help] */