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

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

DEFINITIONS

This source file includes following definitions.
  1. dce_i2c_sw_construct
  2. read_bit_from_ddc
  3. write_bit_to_ddc
  4. release_engine_dce_sw
  5. get_hw_supported_ddc_line
  6. wait_for_scl_high_sw
  7. write_byte_sw
  8. read_byte_sw
  9. stop_sync_sw
  10. i2c_write_sw
  11. i2c_read_sw
  12. start_sync_sw
  13. dce_i2c_sw_engine_set_speed
  14. dce_i2c_sw_engine_acquire_engine
  15. dce_i2c_engine_acquire_sw
  16. dce_i2c_sw_engine_submit_channel_request
  17. dce_i2c_sw_engine_submit_payload
  18. dce_i2c_submit_command_sw
  19. dce_i2c_acquire_i2c_sw_engine

   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 "dce_i2c.h"
  29 #include "dce_i2c_sw.h"
  30 #include "include/gpio_service_interface.h"
  31 #define SCL false
  32 #define SDA true
  33 
  34 void dce_i2c_sw_construct(
  35         struct dce_i2c_sw *dce_i2c_sw,
  36         struct dc_context *ctx)
  37 {
  38         dce_i2c_sw->ctx = ctx;
  39 }
  40 
  41 static inline bool read_bit_from_ddc(
  42         struct ddc *ddc,
  43         bool data_nor_clock)
  44 {
  45         uint32_t value = 0;
  46 
  47         if (data_nor_clock)
  48                 dal_gpio_get_value(ddc->pin_data, &value);
  49         else
  50                 dal_gpio_get_value(ddc->pin_clock, &value);
  51 
  52         return (value != 0);
  53 }
  54 
  55 static inline void write_bit_to_ddc(
  56         struct ddc *ddc,
  57         bool data_nor_clock,
  58         bool bit)
  59 {
  60         uint32_t value = bit ? 1 : 0;
  61 
  62         if (data_nor_clock)
  63                 dal_gpio_set_value(ddc->pin_data, value);
  64         else
  65                 dal_gpio_set_value(ddc->pin_clock, value);
  66 }
  67 
  68 static void release_engine_dce_sw(
  69         struct resource_pool *pool,
  70         struct dce_i2c_sw *dce_i2c_sw)
  71 {
  72         dal_ddc_close(dce_i2c_sw->ddc);
  73         dce_i2c_sw->ddc = NULL;
  74 }
  75 
  76 static bool get_hw_supported_ddc_line(
  77         struct ddc *ddc,
  78         enum gpio_ddc_line *line)
  79 {
  80         enum gpio_ddc_line line_found;
  81 
  82         *line = GPIO_DDC_LINE_UNKNOWN;
  83 
  84         if (!ddc) {
  85                 BREAK_TO_DEBUGGER();
  86                 return false;
  87         }
  88 
  89         if (!ddc->hw_info.hw_supported)
  90                 return false;
  91 
  92         line_found = dal_ddc_get_line(ddc);
  93 
  94         if (line_found >= GPIO_DDC_LINE_COUNT)
  95                 return false;
  96 
  97         *line = line_found;
  98 
  99         return true;
 100 }
 101 static bool wait_for_scl_high_sw(
 102         struct dc_context *ctx,
 103         struct ddc *ddc,
 104         uint16_t clock_delay_div_4)
 105 {
 106         uint32_t scl_retry = 0;
 107         uint32_t scl_retry_max = I2C_SW_TIMEOUT_DELAY / clock_delay_div_4;
 108 
 109         udelay(clock_delay_div_4);
 110 
 111         do {
 112                 if (read_bit_from_ddc(ddc, SCL))
 113                         return true;
 114 
 115                 udelay(clock_delay_div_4);
 116 
 117                 ++scl_retry;
 118         } while (scl_retry <= scl_retry_max);
 119 
 120         return false;
 121 }
 122 static bool write_byte_sw(
 123         struct dc_context *ctx,
 124         struct ddc *ddc_handle,
 125         uint16_t clock_delay_div_4,
 126         uint8_t byte)
 127 {
 128         int32_t shift = 7;
 129         bool ack;
 130 
 131         /* bits are transmitted serially, starting from MSB */
 132 
 133         do {
 134                 udelay(clock_delay_div_4);
 135 
 136                 write_bit_to_ddc(ddc_handle, SDA, (byte >> shift) & 1);
 137 
 138                 udelay(clock_delay_div_4);
 139 
 140                 write_bit_to_ddc(ddc_handle, SCL, true);
 141 
 142                 if (!wait_for_scl_high_sw(ctx, ddc_handle, clock_delay_div_4))
 143                         return false;
 144 
 145                 write_bit_to_ddc(ddc_handle, SCL, false);
 146 
 147                 --shift;
 148         } while (shift >= 0);
 149 
 150         /* The display sends ACK by preventing the SDA from going high
 151          * after the SCL pulse we use to send our last data bit.
 152          * If the SDA goes high after that bit, it's a NACK
 153          */
 154 
 155         udelay(clock_delay_div_4);
 156 
 157         write_bit_to_ddc(ddc_handle, SDA, true);
 158 
 159         udelay(clock_delay_div_4);
 160 
 161         write_bit_to_ddc(ddc_handle, SCL, true);
 162 
 163         if (!wait_for_scl_high_sw(ctx, ddc_handle, clock_delay_div_4))
 164                 return false;
 165 
 166         /* read ACK bit */
 167 
 168         ack = !read_bit_from_ddc(ddc_handle, SDA);
 169 
 170         udelay(clock_delay_div_4 << 1);
 171 
 172         write_bit_to_ddc(ddc_handle, SCL, false);
 173 
 174         udelay(clock_delay_div_4 << 1);
 175 
 176         return ack;
 177 }
 178 
 179 static bool read_byte_sw(
 180         struct dc_context *ctx,
 181         struct ddc *ddc_handle,
 182         uint16_t clock_delay_div_4,
 183         uint8_t *byte,
 184         bool more)
 185 {
 186         int32_t shift = 7;
 187 
 188         uint8_t data = 0;
 189 
 190         /* The data bits are read from MSB to LSB;
 191          * bit is read while SCL is high
 192          */
 193 
 194         do {
 195                 write_bit_to_ddc(ddc_handle, SCL, true);
 196 
 197                 if (!wait_for_scl_high_sw(ctx, ddc_handle, clock_delay_div_4))
 198                         return false;
 199 
 200                 if (read_bit_from_ddc(ddc_handle, SDA))
 201                         data |= (1 << shift);
 202 
 203                 write_bit_to_ddc(ddc_handle, SCL, false);
 204 
 205                 udelay(clock_delay_div_4 << 1);
 206 
 207                 --shift;
 208         } while (shift >= 0);
 209 
 210         /* read only whole byte */
 211 
 212         *byte = data;
 213 
 214         udelay(clock_delay_div_4);
 215 
 216         /* send the acknowledge bit:
 217          * SDA low means ACK, SDA high means NACK
 218          */
 219 
 220         write_bit_to_ddc(ddc_handle, SDA, !more);
 221 
 222         udelay(clock_delay_div_4);
 223 
 224         write_bit_to_ddc(ddc_handle, SCL, true);
 225 
 226         if (!wait_for_scl_high_sw(ctx, ddc_handle, clock_delay_div_4))
 227                 return false;
 228 
 229         write_bit_to_ddc(ddc_handle, SCL, false);
 230 
 231         udelay(clock_delay_div_4);
 232 
 233         write_bit_to_ddc(ddc_handle, SDA, true);
 234 
 235         udelay(clock_delay_div_4);
 236 
 237         return true;
 238 }
 239 static bool stop_sync_sw(
 240         struct dc_context *ctx,
 241         struct ddc *ddc_handle,
 242         uint16_t clock_delay_div_4)
 243 {
 244         uint32_t retry = 0;
 245 
 246         /* The I2C communications stop signal is:
 247          * the SDA going high from low, while the SCL is high.
 248          */
 249 
 250         write_bit_to_ddc(ddc_handle, SCL, false);
 251 
 252         udelay(clock_delay_div_4);
 253 
 254         write_bit_to_ddc(ddc_handle, SDA, false);
 255 
 256         udelay(clock_delay_div_4);
 257 
 258         write_bit_to_ddc(ddc_handle, SCL, true);
 259 
 260         if (!wait_for_scl_high_sw(ctx, ddc_handle, clock_delay_div_4))
 261                 return false;
 262 
 263         write_bit_to_ddc(ddc_handle, SDA, true);
 264 
 265         do {
 266                 udelay(clock_delay_div_4);
 267 
 268                 if (read_bit_from_ddc(ddc_handle, SDA))
 269                         return true;
 270 
 271                 ++retry;
 272         } while (retry <= 2);
 273 
 274         return false;
 275 }
 276 static bool i2c_write_sw(
 277         struct dc_context *ctx,
 278         struct ddc *ddc_handle,
 279         uint16_t clock_delay_div_4,
 280         uint8_t address,
 281         uint32_t length,
 282         const uint8_t *data)
 283 {
 284         uint32_t i = 0;
 285 
 286         if (!write_byte_sw(ctx, ddc_handle, clock_delay_div_4, address))
 287                 return false;
 288 
 289         while (i < length) {
 290                 if (!write_byte_sw(ctx, ddc_handle, clock_delay_div_4, data[i]))
 291                         return false;
 292                 ++i;
 293         }
 294 
 295         return true;
 296 }
 297 
 298 static bool i2c_read_sw(
 299         struct dc_context *ctx,
 300         struct ddc *ddc_handle,
 301         uint16_t clock_delay_div_4,
 302         uint8_t address,
 303         uint32_t length,
 304         uint8_t *data)
 305 {
 306         uint32_t i = 0;
 307 
 308         if (!write_byte_sw(ctx, ddc_handle, clock_delay_div_4, address))
 309                 return false;
 310 
 311         while (i < length) {
 312                 if (!read_byte_sw(ctx, ddc_handle, clock_delay_div_4, data + i,
 313                         i < length - 1))
 314                         return false;
 315                 ++i;
 316         }
 317 
 318         return true;
 319 }
 320 
 321 
 322 
 323 static bool start_sync_sw(
 324         struct dc_context *ctx,
 325         struct ddc *ddc_handle,
 326         uint16_t clock_delay_div_4)
 327 {
 328         uint32_t retry = 0;
 329 
 330         /* The I2C communications start signal is:
 331          * the SDA going low from high, while the SCL is high.
 332          */
 333 
 334         write_bit_to_ddc(ddc_handle, SCL, true);
 335 
 336         udelay(clock_delay_div_4);
 337 
 338         do {
 339                 write_bit_to_ddc(ddc_handle, SDA, true);
 340 
 341                 if (!read_bit_from_ddc(ddc_handle, SDA)) {
 342                         ++retry;
 343                         continue;
 344                 }
 345 
 346                 udelay(clock_delay_div_4);
 347 
 348                 write_bit_to_ddc(ddc_handle, SCL, true);
 349 
 350                 if (!wait_for_scl_high_sw(ctx, ddc_handle, clock_delay_div_4))
 351                         break;
 352 
 353                 write_bit_to_ddc(ddc_handle, SDA, false);
 354 
 355                 udelay(clock_delay_div_4);
 356 
 357                 write_bit_to_ddc(ddc_handle, SCL, false);
 358 
 359                 udelay(clock_delay_div_4);
 360 
 361                 return true;
 362         } while (retry <= I2C_SW_RETRIES);
 363 
 364         return false;
 365 }
 366 
 367 void dce_i2c_sw_engine_set_speed(
 368         struct dce_i2c_sw *engine,
 369         uint32_t speed)
 370 {
 371         ASSERT(speed);
 372 
 373         engine->speed = speed ? speed : DCE_I2C_DEFAULT_I2C_SW_SPEED;
 374 
 375         engine->clock_delay = 1000 / engine->speed;
 376 
 377         if (engine->clock_delay < 12)
 378                 engine->clock_delay = 12;
 379 }
 380 
 381 bool dce_i2c_sw_engine_acquire_engine(
 382         struct dce_i2c_sw *engine,
 383         struct ddc *ddc)
 384 {
 385         enum gpio_result result;
 386 
 387         result = dal_ddc_open(ddc, GPIO_MODE_FAST_OUTPUT,
 388                 GPIO_DDC_CONFIG_TYPE_MODE_I2C);
 389 
 390         if (result != GPIO_RESULT_OK)
 391                 return false;
 392 
 393         engine->ddc = ddc;
 394 
 395         return true;
 396 }
 397 bool dce_i2c_engine_acquire_sw(
 398         struct dce_i2c_sw *dce_i2c_sw,
 399         struct ddc *ddc_handle)
 400 {
 401         uint32_t counter = 0;
 402         bool result;
 403 
 404         do {
 405 
 406                 result = dce_i2c_sw_engine_acquire_engine(
 407                                 dce_i2c_sw, ddc_handle);
 408 
 409                 if (result)
 410                         break;
 411 
 412                 /* i2c_engine is busy by VBios, lets wait and retry */
 413 
 414                 udelay(10);
 415 
 416                 ++counter;
 417         } while (counter < 2);
 418 
 419         return result;
 420 }
 421 
 422 
 423 
 424 
 425 void dce_i2c_sw_engine_submit_channel_request(
 426         struct dce_i2c_sw *engine,
 427         struct i2c_request_transaction_data *req)
 428 {
 429         struct ddc *ddc = engine->ddc;
 430         uint16_t clock_delay_div_4 = engine->clock_delay >> 2;
 431 
 432         /* send sync (start / repeated start) */
 433 
 434         bool result = start_sync_sw(engine->ctx, ddc, clock_delay_div_4);
 435 
 436         /* process payload */
 437 
 438         if (result) {
 439                 switch (req->action) {
 440                 case DCE_I2C_TRANSACTION_ACTION_I2C_WRITE:
 441                 case DCE_I2C_TRANSACTION_ACTION_I2C_WRITE_MOT:
 442                         result = i2c_write_sw(engine->ctx, ddc, clock_delay_div_4,
 443                                 req->address, req->length, req->data);
 444                 break;
 445                 case DCE_I2C_TRANSACTION_ACTION_I2C_READ:
 446                 case DCE_I2C_TRANSACTION_ACTION_I2C_READ_MOT:
 447                         result = i2c_read_sw(engine->ctx, ddc, clock_delay_div_4,
 448                                 req->address, req->length, req->data);
 449                 break;
 450                 default:
 451                         result = false;
 452                 break;
 453                 }
 454         }
 455 
 456         /* send stop if not 'mot' or operation failed */
 457 
 458         if (!result ||
 459                 (req->action == DCE_I2C_TRANSACTION_ACTION_I2C_WRITE) ||
 460                 (req->action == DCE_I2C_TRANSACTION_ACTION_I2C_READ))
 461                 if (!stop_sync_sw(engine->ctx, ddc, clock_delay_div_4))
 462                         result = false;
 463 
 464         req->status = result ?
 465                 I2C_CHANNEL_OPERATION_SUCCEEDED :
 466                 I2C_CHANNEL_OPERATION_FAILED;
 467 }
 468 bool dce_i2c_sw_engine_submit_payload(
 469         struct dce_i2c_sw *engine,
 470         struct i2c_payload *payload,
 471         bool middle_of_transaction)
 472 {
 473         struct i2c_request_transaction_data request;
 474 
 475         if (!payload->write)
 476                 request.action = middle_of_transaction ?
 477                         DCE_I2C_TRANSACTION_ACTION_I2C_READ_MOT :
 478                         DCE_I2C_TRANSACTION_ACTION_I2C_READ;
 479         else
 480                 request.action = middle_of_transaction ?
 481                         DCE_I2C_TRANSACTION_ACTION_I2C_WRITE_MOT :
 482                         DCE_I2C_TRANSACTION_ACTION_I2C_WRITE;
 483 
 484         request.address = (uint8_t) ((payload->address << 1) | !payload->write);
 485         request.length = payload->length;
 486         request.data = payload->data;
 487 
 488         dce_i2c_sw_engine_submit_channel_request(engine, &request);
 489 
 490         if ((request.status == I2C_CHANNEL_OPERATION_ENGINE_BUSY) ||
 491                 (request.status == I2C_CHANNEL_OPERATION_FAILED))
 492                 return false;
 493 
 494         return true;
 495 }
 496 bool dce_i2c_submit_command_sw(
 497         struct resource_pool *pool,
 498         struct ddc *ddc,
 499         struct i2c_command *cmd,
 500         struct dce_i2c_sw *dce_i2c_sw)
 501 {
 502         uint8_t index_of_payload = 0;
 503         bool result;
 504 
 505         dce_i2c_sw_engine_set_speed(dce_i2c_sw, cmd->speed);
 506 
 507         result = true;
 508 
 509         while (index_of_payload < cmd->number_of_payloads) {
 510                 bool mot = (index_of_payload != cmd->number_of_payloads - 1);
 511 
 512                 struct i2c_payload *payload = cmd->payloads + index_of_payload;
 513 
 514                 if (!dce_i2c_sw_engine_submit_payload(
 515                         dce_i2c_sw, payload, mot)) {
 516                         result = false;
 517                         break;
 518                 }
 519 
 520                 ++index_of_payload;
 521         }
 522 
 523         release_engine_dce_sw(pool, dce_i2c_sw);
 524 
 525         return result;
 526 }
 527 struct dce_i2c_sw *dce_i2c_acquire_i2c_sw_engine(
 528         struct resource_pool *pool,
 529         struct ddc *ddc)
 530 {
 531         enum gpio_ddc_line line;
 532         struct dce_i2c_sw *engine = NULL;
 533 
 534         if (get_hw_supported_ddc_line(ddc, &line))
 535                 engine = pool->sw_i2cs[line];
 536 
 537         if (!engine)
 538                 return NULL;
 539 
 540         if (!dce_i2c_engine_acquire_sw(engine, ddc))
 541                 return NULL;
 542 
 543         return engine;
 544 }

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