1 /* 2 * Copyright 2012-15 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 "dm_services.h" 27 28 /* 29 * Pre-requisites: headers required by header of this unit 30 */ 31 #include "include/i2caux_interface.h" 32 #include "../engine.h" 33 #include "../i2c_engine.h" 34 #include "../i2c_hw_engine.h" 35 #include "../i2c_generic_hw_engine.h" 36 /* 37 * Header of this unit 38 */ 39 40 #include "i2c_hw_engine_dce80.h" 41 42 /* 43 * Post-requisites: headers required by this unit 44 */ 45 46 #include "dce/dce_8_0_d.h" 47 #include "dce/dce_8_0_sh_mask.h" 48 /* 49 * This unit 50 */ 51 52 enum dc_i2c_status { 53 DC_I2C_STATUS__DC_I2C_STATUS_IDLE, 54 DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_SW, 55 DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_HW 56 }; 57 58 enum dc_i2c_arbitration { 59 DC_I2C_ARBITRATION__DC_I2C_SW_PRIORITY_NORMAL, 60 DC_I2C_ARBITRATION__DC_I2C_SW_PRIORITY_HIGH 61 }; 62 63 enum { 64 /* No timeout in HW 65 * (timeout implemented in SW by querying status) */ 66 I2C_SETUP_TIME_LIMIT = 255, 67 I2C_HW_BUFFER_SIZE = 144 68 }; 69 70 /* 71 * @brief 72 * Cast 'struct i2c_hw_engine *' 73 * to 'struct i2c_hw_engine_dce80 *' 74 */ 75 #define FROM_I2C_HW_ENGINE(ptr) \ 76 container_of((ptr), struct i2c_hw_engine_dce80, base) 77 78 /* 79 * @brief 80 * Cast pointer to 'struct i2c_engine *' 81 * to pointer to 'struct i2c_hw_engine_dce80 *' 82 */ 83 #define FROM_I2C_ENGINE(ptr) \ 84 FROM_I2C_HW_ENGINE(container_of((ptr), struct i2c_hw_engine, base)) 85 86 /* 87 * @brief 88 * Cast pointer to 'struct engine *' 89 * to 'pointer to struct i2c_hw_engine_dce80 *' 90 */ 91 #define FROM_ENGINE(ptr) \ 92 FROM_I2C_ENGINE(container_of((ptr), struct i2c_engine, base)) 93 94 static void disable_i2c_hw_engine( 95 struct i2c_hw_engine_dce80 *engine) 96 { 97 const uint32_t addr = engine->addr.DC_I2C_DDCX_SETUP; 98 uint32_t value = 0; 99 100 struct dc_context *ctx = NULL; 101 102 ctx = engine->base.base.base.ctx; 103 104 value = dm_read_reg(ctx, addr); 105 106 set_reg_field_value( 107 value, 108 0, 109 DC_I2C_DDC1_SETUP, 110 DC_I2C_DDC1_ENABLE); 111 112 dm_write_reg(ctx, addr, value); 113 } 114 115 static void release_engine( 116 struct engine *engine) 117 { 118 struct i2c_hw_engine_dce80 *hw_engine = FROM_ENGINE(engine); 119 120 struct i2c_engine *base = NULL; 121 bool safe_to_reset; 122 uint32_t value = 0; 123 124 base = &hw_engine->base.base; 125 126 /* Restore original HW engine speed */ 127 128 base->funcs->set_speed(base, hw_engine->base.original_speed); 129 130 /* Release I2C */ 131 { 132 value = dm_read_reg(engine->ctx, mmDC_I2C_ARBITRATION); 133 134 set_reg_field_value( 135 value, 136 1, 137 DC_I2C_ARBITRATION, 138 DC_I2C_SW_DONE_USING_I2C_REG); 139 140 dm_write_reg(engine->ctx, mmDC_I2C_ARBITRATION, value); 141 } 142 143 /* Reset HW engine */ 144 { 145 uint32_t i2c_sw_status = 0; 146 147 value = dm_read_reg(engine->ctx, mmDC_I2C_SW_STATUS); 148 149 i2c_sw_status = get_reg_field_value( 150 value, 151 DC_I2C_SW_STATUS, 152 DC_I2C_SW_STATUS); 153 /* if used by SW, safe to reset */ 154 safe_to_reset = (i2c_sw_status == 1); 155 } 156 { 157 value = dm_read_reg(engine->ctx, mmDC_I2C_CONTROL); 158 159 if (safe_to_reset) 160 set_reg_field_value( 161 value, 162 1, 163 DC_I2C_CONTROL, 164 DC_I2C_SOFT_RESET); 165 166 set_reg_field_value( 167 value, 168 1, 169 DC_I2C_CONTROL, 170 DC_I2C_SW_STATUS_RESET); 171 172 dm_write_reg(engine->ctx, mmDC_I2C_CONTROL, value); 173 } 174 175 /* HW I2c engine - clock gating feature */ 176 if (!hw_engine->engine_keep_power_up_count) 177 disable_i2c_hw_engine(hw_engine); 178 } 179 180 static void destruct( 181 struct i2c_hw_engine_dce80 *engine) 182 { 183 dal_i2c_hw_engine_destruct(&engine->base); 184 } 185 186 static void destroy( 187 struct i2c_engine **i2c_engine) 188 { 189 struct i2c_hw_engine_dce80 *engine = FROM_I2C_ENGINE(*i2c_engine); 190 191 destruct(engine); 192 193 kfree(engine); 194 195 *i2c_engine = NULL; 196 } 197 198 static bool setup_engine( 199 struct i2c_engine *i2c_engine) 200 { 201 uint32_t value = 0; 202 struct i2c_hw_engine_dce80 *engine = FROM_I2C_ENGINE(i2c_engine); 203 204 /* Program pin select */ 205 { 206 const uint32_t addr = mmDC_I2C_CONTROL; 207 208 value = dm_read_reg(i2c_engine->base.ctx, addr); 209 210 set_reg_field_value( 211 value, 212 0, 213 DC_I2C_CONTROL, 214 DC_I2C_GO); 215 216 set_reg_field_value( 217 value, 218 0, 219 DC_I2C_CONTROL, 220 DC_I2C_SOFT_RESET); 221 222 set_reg_field_value( 223 value, 224 0, 225 DC_I2C_CONTROL, 226 DC_I2C_SEND_RESET); 227 228 set_reg_field_value( 229 value, 230 0, 231 DC_I2C_CONTROL, 232 DC_I2C_SW_STATUS_RESET); 233 234 set_reg_field_value( 235 value, 236 0, 237 DC_I2C_CONTROL, 238 DC_I2C_TRANSACTION_COUNT); 239 240 set_reg_field_value( 241 value, 242 engine->engine_id, 243 DC_I2C_CONTROL, 244 DC_I2C_DDC_SELECT); 245 246 dm_write_reg(i2c_engine->base.ctx, addr, value); 247 } 248 249 /* Program time limit */ 250 { 251 const uint32_t addr = engine->addr.DC_I2C_DDCX_SETUP; 252 253 value = dm_read_reg(i2c_engine->base.ctx, addr); 254 255 set_reg_field_value( 256 value, 257 I2C_SETUP_TIME_LIMIT, 258 DC_I2C_DDC1_SETUP, 259 DC_I2C_DDC1_TIME_LIMIT); 260 261 set_reg_field_value( 262 value, 263 1, 264 DC_I2C_DDC1_SETUP, 265 DC_I2C_DDC1_ENABLE); 266 267 dm_write_reg(i2c_engine->base.ctx, addr, value); 268 } 269 270 /* Program HW priority 271 * set to High - interrupt software I2C at any time 272 * Enable restart of SW I2C that was interrupted by HW 273 * disable queuing of software while I2C is in use by HW */ 274 { 275 value = dm_read_reg(i2c_engine->base.ctx, 276 mmDC_I2C_ARBITRATION); 277 278 set_reg_field_value( 279 value, 280 0, 281 DC_I2C_ARBITRATION, 282 DC_I2C_NO_QUEUED_SW_GO); 283 284 set_reg_field_value( 285 value, 286 DC_I2C_ARBITRATION__DC_I2C_SW_PRIORITY_NORMAL, 287 DC_I2C_ARBITRATION, 288 DC_I2C_SW_PRIORITY); 289 290 dm_write_reg(i2c_engine->base.ctx, 291 mmDC_I2C_ARBITRATION, value); 292 } 293 294 return true; 295 } 296 297 static uint32_t get_speed( 298 const struct i2c_engine *i2c_engine) 299 { 300 const struct i2c_hw_engine_dce80 *engine = FROM_I2C_ENGINE(i2c_engine); 301 302 const uint32_t addr = engine->addr.DC_I2C_DDCX_SPEED; 303 304 uint32_t pre_scale = 0; 305 306 uint32_t value = dm_read_reg(i2c_engine->base.ctx, addr); 307 308 pre_scale = get_reg_field_value( 309 value, 310 DC_I2C_DDC1_SPEED, 311 DC_I2C_DDC1_PRESCALE); 312 313 /* [anaumov] it seems following is unnecessary */ 314 /*ASSERT(value.bits.DC_I2C_DDC1_PRESCALE);*/ 315 316 return pre_scale ? 317 engine->reference_frequency / pre_scale : 318 engine->base.default_speed; 319 } 320 321 static void set_speed( 322 struct i2c_engine *i2c_engine, 323 uint32_t speed) 324 { 325 struct i2c_hw_engine_dce80 *engine = FROM_I2C_ENGINE(i2c_engine); 326 327 if (speed) { 328 const uint32_t addr = engine->addr.DC_I2C_DDCX_SPEED; 329 330 uint32_t value = dm_read_reg(i2c_engine->base.ctx, addr); 331 332 set_reg_field_value( 333 value, 334 engine->reference_frequency / speed, 335 DC_I2C_DDC1_SPEED, 336 DC_I2C_DDC1_PRESCALE); 337 338 set_reg_field_value( 339 value, 340 2, 341 DC_I2C_DDC1_SPEED, 342 DC_I2C_DDC1_THRESHOLD); 343 344 dm_write_reg(i2c_engine->base.ctx, addr, value); 345 } 346 } 347 348 static inline void reset_hw_engine(struct engine *engine) 349 { 350 uint32_t value = dm_read_reg(engine->ctx, mmDC_I2C_CONTROL); 351 352 set_reg_field_value( 353 value, 354 1, 355 DC_I2C_CONTROL, 356 DC_I2C_SOFT_RESET); 357 358 set_reg_field_value( 359 value, 360 1, 361 DC_I2C_CONTROL, 362 DC_I2C_SW_STATUS_RESET); 363 364 dm_write_reg(engine->ctx, mmDC_I2C_CONTROL, value); 365 } 366 367 static bool is_hw_busy(struct engine *engine) 368 { 369 uint32_t i2c_sw_status = 0; 370 371 uint32_t value = dm_read_reg(engine->ctx, mmDC_I2C_SW_STATUS); 372 373 i2c_sw_status = get_reg_field_value( 374 value, 375 DC_I2C_SW_STATUS, 376 DC_I2C_SW_STATUS); 377 378 if (i2c_sw_status == DC_I2C_STATUS__DC_I2C_STATUS_IDLE) 379 return false; 380 381 reset_hw_engine(engine); 382 383 value = dm_read_reg(engine->ctx, mmDC_I2C_SW_STATUS); 384 385 i2c_sw_status = get_reg_field_value( 386 value, 387 DC_I2C_SW_STATUS, 388 DC_I2C_SW_STATUS); 389 390 return i2c_sw_status != DC_I2C_STATUS__DC_I2C_STATUS_IDLE; 391 } 392 393 /* 394 * @brief 395 * DC_GPIO_DDC MM register offsets 396 */ 397 static const uint32_t transaction_addr[] = { 398 mmDC_I2C_TRANSACTION0, 399 mmDC_I2C_TRANSACTION1, 400 mmDC_I2C_TRANSACTION2, 401 mmDC_I2C_TRANSACTION3 402 }; 403 404 static bool process_transaction( 405 struct i2c_hw_engine_dce80 *engine, 406 struct i2c_request_transaction_data *request) 407 { 408 uint32_t length = request->length; 409 uint8_t *buffer = request->data; 410 411 bool last_transaction = false; 412 uint32_t value = 0; 413 414 struct dc_context *ctx = NULL; 415 416 ctx = engine->base.base.base.ctx; 417 418 { 419 const uint32_t addr = 420 transaction_addr[engine->transaction_count]; 421 422 value = dm_read_reg(ctx, addr); 423 424 set_reg_field_value( 425 value, 426 1, 427 DC_I2C_TRANSACTION0, 428 DC_I2C_STOP_ON_NACK0); 429 430 set_reg_field_value( 431 value, 432 1, 433 DC_I2C_TRANSACTION0, 434 DC_I2C_START0); 435 436 if ((engine->transaction_count == 3) || 437 (request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE) || 438 (request->action & I2CAUX_TRANSACTION_ACTION_I2C_READ)) { 439 440 set_reg_field_value( 441 value, 442 1, 443 DC_I2C_TRANSACTION0, 444 DC_I2C_STOP0); 445 446 last_transaction = true; 447 } else 448 set_reg_field_value( 449 value, 450 0, 451 DC_I2C_TRANSACTION0, 452 DC_I2C_STOP0); 453 454 set_reg_field_value( 455 value, 456 (0 != (request->action & 457 I2CAUX_TRANSACTION_ACTION_I2C_READ)), 458 DC_I2C_TRANSACTION0, 459 DC_I2C_RW0); 460 461 set_reg_field_value( 462 value, 463 length, 464 DC_I2C_TRANSACTION0, 465 DC_I2C_COUNT0); 466 467 dm_write_reg(ctx, addr, value); 468 } 469 470 /* Write the I2C address and I2C data 471 * into the hardware circular buffer, one byte per entry. 472 * As an example, the 7-bit I2C slave address for CRT monitor 473 * for reading DDC/EDID information is 0b1010001. 474 * For an I2C send operation, the LSB must be programmed to 0; 475 * for I2C receive operation, the LSB must be programmed to 1. */ 476 477 { 478 value = 0; 479 480 set_reg_field_value( 481 value, 482 false, 483 DC_I2C_DATA, 484 DC_I2C_DATA_RW); 485 486 set_reg_field_value( 487 value, 488 request->address, 489 DC_I2C_DATA, 490 DC_I2C_DATA); 491 492 if (engine->transaction_count == 0) { 493 set_reg_field_value( 494 value, 495 0, 496 DC_I2C_DATA, 497 DC_I2C_INDEX); 498 499 /*enable index write*/ 500 set_reg_field_value( 501 value, 502 1, 503 DC_I2C_DATA, 504 DC_I2C_INDEX_WRITE); 505 } 506 507 dm_write_reg(ctx, mmDC_I2C_DATA, value); 508 509 if (!(request->action & I2CAUX_TRANSACTION_ACTION_I2C_READ)) { 510 511 set_reg_field_value( 512 value, 513 0, 514 DC_I2C_DATA, 515 DC_I2C_INDEX_WRITE); 516 517 while (length) { 518 519 set_reg_field_value( 520 value, 521 *buffer++, 522 DC_I2C_DATA, 523 DC_I2C_DATA); 524 525 dm_write_reg(ctx, mmDC_I2C_DATA, value); 526 --length; 527 } 528 } 529 } 530 531 ++engine->transaction_count; 532 engine->buffer_used_bytes += length + 1; 533 534 return last_transaction; 535 } 536 537 static void execute_transaction( 538 struct i2c_hw_engine_dce80 *engine) 539 { 540 uint32_t value = 0; 541 struct dc_context *ctx = NULL; 542 543 ctx = engine->base.base.base.ctx; 544 545 { 546 const uint32_t addr = engine->addr.DC_I2C_DDCX_SETUP; 547 548 value = dm_read_reg(ctx, addr); 549 550 set_reg_field_value( 551 value, 552 0, 553 DC_I2C_DDC1_SETUP, 554 DC_I2C_DDC1_DATA_DRIVE_EN); 555 556 set_reg_field_value( 557 value, 558 0, 559 DC_I2C_DDC1_SETUP, 560 DC_I2C_DDC1_CLK_DRIVE_EN); 561 562 set_reg_field_value( 563 value, 564 0, 565 DC_I2C_DDC1_SETUP, 566 DC_I2C_DDC1_DATA_DRIVE_SEL); 567 568 set_reg_field_value( 569 value, 570 0, 571 DC_I2C_DDC1_SETUP, 572 DC_I2C_DDC1_INTRA_TRANSACTION_DELAY); 573 574 set_reg_field_value( 575 value, 576 0, 577 DC_I2C_DDC1_SETUP, 578 DC_I2C_DDC1_INTRA_BYTE_DELAY); 579 580 dm_write_reg(ctx, addr, value); 581 } 582 583 { 584 const uint32_t addr = mmDC_I2C_CONTROL; 585 586 value = dm_read_reg(ctx, addr); 587 588 set_reg_field_value( 589 value, 590 0, 591 DC_I2C_CONTROL, 592 DC_I2C_SOFT_RESET); 593 594 set_reg_field_value( 595 value, 596 0, 597 DC_I2C_CONTROL, 598 DC_I2C_SW_STATUS_RESET); 599 600 set_reg_field_value( 601 value, 602 0, 603 DC_I2C_CONTROL, 604 DC_I2C_SEND_RESET); 605 606 set_reg_field_value( 607 value, 608 0, 609 DC_I2C_CONTROL, 610 DC_I2C_GO); 611 612 set_reg_field_value( 613 value, 614 engine->transaction_count - 1, 615 DC_I2C_CONTROL, 616 DC_I2C_TRANSACTION_COUNT); 617 618 dm_write_reg(ctx, addr, value); 619 } 620 621 /* start I2C transfer */ 622 { 623 const uint32_t addr = mmDC_I2C_CONTROL; 624 625 value = dm_read_reg(ctx, addr); 626 627 set_reg_field_value( 628 value, 629 1, 630 DC_I2C_CONTROL, 631 DC_I2C_GO); 632 633 dm_write_reg(ctx, addr, value); 634 } 635 636 /* all transactions were executed and HW buffer became empty 637 * (even though it actually happens when status becomes DONE) */ 638 engine->transaction_count = 0; 639 engine->buffer_used_bytes = 0; 640 } 641 642 static void submit_channel_request( 643 struct i2c_engine *engine, 644 struct i2c_request_transaction_data *request) 645 { 646 request->status = I2C_CHANNEL_OPERATION_SUCCEEDED; 647 648 if (!process_transaction(FROM_I2C_ENGINE(engine), request)) 649 return; 650 651 if (is_hw_busy(&engine->base)) { 652 request->status = I2C_CHANNEL_OPERATION_ENGINE_BUSY; 653 return; 654 } 655 656 execute_transaction(FROM_I2C_ENGINE(engine)); 657 } 658 659 static void process_channel_reply( 660 struct i2c_engine *engine, 661 struct i2c_reply_transaction_data *reply) 662 { 663 uint32_t length = reply->length; 664 uint8_t *buffer = reply->data; 665 666 uint32_t value = 0; 667 668 /*set index*/ 669 set_reg_field_value( 670 value, 671 length - 1, 672 DC_I2C_DATA, 673 DC_I2C_INDEX); 674 675 set_reg_field_value( 676 value, 677 1, 678 DC_I2C_DATA, 679 DC_I2C_DATA_RW); 680 681 set_reg_field_value( 682 value, 683 1, 684 DC_I2C_DATA, 685 DC_I2C_INDEX_WRITE); 686 687 dm_write_reg(engine->base.ctx, mmDC_I2C_DATA, value); 688 689 while (length) { 690 /* after reading the status, 691 * if the I2C operation executed successfully 692 * (i.e. DC_I2C_STATUS_DONE = 1) then the I2C controller 693 * should read data bytes from I2C circular data buffer */ 694 695 value = dm_read_reg(engine->base.ctx, mmDC_I2C_DATA); 696 697 *buffer++ = get_reg_field_value( 698 value, 699 DC_I2C_DATA, 700 DC_I2C_DATA); 701 702 --length; 703 } 704 } 705 706 static enum i2c_channel_operation_result get_channel_status( 707 struct i2c_engine *engine, 708 uint8_t *returned_bytes) 709 { 710 uint32_t i2c_sw_status = 0; 711 uint32_t value = dm_read_reg(engine->base.ctx, mmDC_I2C_SW_STATUS); 712 713 i2c_sw_status = get_reg_field_value( 714 value, 715 DC_I2C_SW_STATUS, 716 DC_I2C_SW_STATUS); 717 718 if (i2c_sw_status == DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_SW) 719 return I2C_CHANNEL_OPERATION_ENGINE_BUSY; 720 else if (value & DC_I2C_SW_STATUS__DC_I2C_SW_STOPPED_ON_NACK_MASK) 721 return I2C_CHANNEL_OPERATION_NO_RESPONSE; 722 else if (value & DC_I2C_SW_STATUS__DC_I2C_SW_TIMEOUT_MASK) 723 return I2C_CHANNEL_OPERATION_TIMEOUT; 724 else if (value & DC_I2C_SW_STATUS__DC_I2C_SW_ABORTED_MASK) 725 return I2C_CHANNEL_OPERATION_FAILED; 726 else if (value & DC_I2C_SW_STATUS__DC_I2C_SW_DONE_MASK) 727 return I2C_CHANNEL_OPERATION_SUCCEEDED; 728 729 /* 730 * this is the case when HW used for communication, I2C_SW_STATUS 731 * could be zero 732 */ 733 return I2C_CHANNEL_OPERATION_SUCCEEDED; 734 } 735 736 static uint32_t get_hw_buffer_available_size( 737 const struct i2c_hw_engine *engine) 738 { 739 return I2C_HW_BUFFER_SIZE - 740 FROM_I2C_HW_ENGINE(engine)->buffer_used_bytes; 741 } 742 743 static uint32_t get_transaction_timeout( 744 const struct i2c_hw_engine *engine, 745 uint32_t length) 746 { 747 uint32_t speed = engine->base.funcs->get_speed(&engine->base); 748 749 uint32_t period_timeout; 750 uint32_t num_of_clock_stretches; 751 752 if (!speed) 753 return 0; 754 755 period_timeout = (1000 * TRANSACTION_TIMEOUT_IN_I2C_CLOCKS) / speed; 756 757 num_of_clock_stretches = 1 + (length << 3) + 1; 758 num_of_clock_stretches += 759 (FROM_I2C_HW_ENGINE(engine)->buffer_used_bytes << 3) + 760 (FROM_I2C_HW_ENGINE(engine)->transaction_count << 1); 761 762 return period_timeout * num_of_clock_stretches; 763 } 764 765 /* 766 * @brief 767 * DC_I2C_DDC1_SETUP MM register offsets 768 * 769 * @note 770 * The indices of this offset array are DDC engine IDs 771 */ 772 static const int32_t ddc_setup_offset[] = { 773 774 mmDC_I2C_DDC1_SETUP - mmDC_I2C_DDC1_SETUP, /* DDC Engine 1 */ 775 mmDC_I2C_DDC2_SETUP - mmDC_I2C_DDC1_SETUP, /* DDC Engine 2 */ 776 mmDC_I2C_DDC3_SETUP - mmDC_I2C_DDC1_SETUP, /* DDC Engine 3 */ 777 mmDC_I2C_DDC4_SETUP - mmDC_I2C_DDC1_SETUP, /* DDC Engine 4 */ 778 mmDC_I2C_DDC5_SETUP - mmDC_I2C_DDC1_SETUP, /* DDC Engine 5 */ 779 mmDC_I2C_DDC6_SETUP - mmDC_I2C_DDC1_SETUP, /* DDC Engine 6 */ 780 mmDC_I2C_DDCVGA_SETUP - mmDC_I2C_DDC1_SETUP /* DDC Engine 7 */ 781 }; 782 783 /* 784 * @brief 785 * DC_I2C_DDC1_SPEED MM register offsets 786 * 787 * @note 788 * The indices of this offset array are DDC engine IDs 789 */ 790 static const int32_t ddc_speed_offset[] = { 791 mmDC_I2C_DDC1_SPEED - mmDC_I2C_DDC1_SPEED, /* DDC Engine 1 */ 792 mmDC_I2C_DDC2_SPEED - mmDC_I2C_DDC1_SPEED, /* DDC Engine 2 */ 793 mmDC_I2C_DDC3_SPEED - mmDC_I2C_DDC1_SPEED, /* DDC Engine 3 */ 794 mmDC_I2C_DDC4_SPEED - mmDC_I2C_DDC1_SPEED, /* DDC Engine 4 */ 795 mmDC_I2C_DDC5_SPEED - mmDC_I2C_DDC1_SPEED, /* DDC Engine 5 */ 796 mmDC_I2C_DDC6_SPEED - mmDC_I2C_DDC1_SPEED, /* DDC Engine 6 */ 797 mmDC_I2C_DDCVGA_SPEED - mmDC_I2C_DDC1_SPEED /* DDC Engine 7 */ 798 }; 799 800 static const struct i2c_engine_funcs i2c_engine_funcs = { 801 .destroy = destroy, 802 .get_speed = get_speed, 803 .set_speed = set_speed, 804 .setup_engine = setup_engine, 805 .submit_channel_request = submit_channel_request, 806 .process_channel_reply = process_channel_reply, 807 .get_channel_status = get_channel_status, 808 .acquire_engine = dal_i2c_hw_engine_acquire_engine, 809 }; 810 811 static const struct engine_funcs engine_funcs = { 812 .release_engine = release_engine, 813 .get_engine_type = dal_i2c_hw_engine_get_engine_type, 814 .acquire = dal_i2c_engine_acquire, 815 .submit_request = dal_i2c_hw_engine_submit_request, 816 }; 817 818 static const struct i2c_hw_engine_funcs i2c_hw_engine_funcs = { 819 .get_hw_buffer_available_size = 820 get_hw_buffer_available_size, 821 .get_transaction_timeout = 822 get_transaction_timeout, 823 .wait_on_operation_result = 824 dal_i2c_hw_engine_wait_on_operation_result, 825 }; 826 827 static void construct( 828 struct i2c_hw_engine_dce80 *engine, 829 const struct i2c_hw_engine_dce80_create_arg *arg) 830 { 831 dal_i2c_hw_engine_construct(&engine->base, arg->ctx); 832 833 engine->base.base.base.funcs = &engine_funcs; 834 engine->base.base.funcs = &i2c_engine_funcs; 835 engine->base.funcs = &i2c_hw_engine_funcs; 836 engine->base.default_speed = arg->default_speed; 837 engine->addr.DC_I2C_DDCX_SETUP = 838 mmDC_I2C_DDC1_SETUP + ddc_setup_offset[arg->engine_id]; 839 engine->addr.DC_I2C_DDCX_SPEED = 840 mmDC_I2C_DDC1_SPEED + ddc_speed_offset[arg->engine_id]; 841 842 engine->engine_id = arg->engine_id; 843 engine->reference_frequency = arg->reference_frequency; 844 engine->buffer_used_bytes = 0; 845 engine->transaction_count = 0; 846 engine->engine_keep_power_up_count = 1; 847 } 848 849 struct i2c_engine *dal_i2c_hw_engine_dce80_create( 850 const struct i2c_hw_engine_dce80_create_arg *arg) 851 { 852 struct i2c_hw_engine_dce80 *engine; 853 854 if (!arg) { 855 BREAK_TO_DEBUGGER(); 856 return NULL; 857 } 858 859 if ((arg->engine_id >= sizeof(ddc_setup_offset) / sizeof(int32_t)) || 860 (arg->engine_id >= sizeof(ddc_speed_offset) / sizeof(int32_t)) || 861 !arg->reference_frequency) { 862 BREAK_TO_DEBUGGER(); 863 return NULL; 864 } 865 866 engine = kzalloc(sizeof(struct i2c_hw_engine_dce80), GFP_KERNEL); 867 868 if (!engine) { 869 BREAK_TO_DEBUGGER(); 870 return NULL; 871 } 872 873 construct(engine, arg); 874 return &engine->base.base; 875 } 876