dce_i2c_sw.c (10600B)
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}