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