2 * Copyright 2018 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
26 #include <linux/delay.h>
30 #include "dce_i2c_hw.h"
31 #include "reg_helper.h"
32 #include "include/gpio_service_interface.h"
40 #define FN(reg_name, field_name) \
41 dce_i2c_hw->shifts->field_name, dce_i2c_hw->masks->field_name
43 static void execute_transaction(
44 struct dce_i2c_hw
*dce_i2c_hw
)
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);
54 REG_UPDATE_5(DC_I2C_CONTROL
,
56 DC_I2C_SW_STATUS_RESET
, 0,
59 DC_I2C_TRANSACTION_COUNT
, dce_i2c_hw
->transaction_count
- 1);
61 /* start I2C transfer */
62 REG_UPDATE(DC_I2C_CONTROL
, DC_I2C_GO
, 1);
64 /* all transactions were executed and HW buffer became empty
65 * (even though it actually happens when status becomes DONE)
67 dce_i2c_hw
->transaction_count
= 0;
68 dce_i2c_hw
->buffer_used_bytes
= 0;
71 static enum i2c_channel_operation_result
get_channel_status(
72 struct dce_i2c_hw
*dce_i2c_hw
,
73 uint8_t *returned_bytes
)
75 uint32_t i2c_sw_status
= 0;
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
;
90 * this is the case when HW used for communication, I2C_SW_STATUS
93 return I2C_CHANNEL_OPERATION_SUCCEEDED
;
96 static uint32_t get_hw_buffer_available_size(
97 const struct dce_i2c_hw
*dce_i2c_hw
)
99 return dce_i2c_hw
->buffer_size
-
100 dce_i2c_hw
->buffer_used_bytes
;
103 static uint32_t get_speed(
104 const struct dce_i2c_hw
*dce_i2c_hw
)
106 uint32_t pre_scale
= 0;
108 REG_GET(SPEED
, DC_I2C_DDC1_PRESCALE
, &pre_scale
);
110 /* [anaumov] it seems following is unnecessary */
111 /*ASSERT(value.bits.DC_I2C_DDC1_PRESCALE);*/
113 dce_i2c_hw
->reference_frequency
/ pre_scale
:
114 dce_i2c_hw
->default_speed
;
117 static void process_channel_reply(
118 struct dce_i2c_hw
*dce_i2c_hw
,
119 struct i2c_payload
*reply
)
121 uint32_t length
= reply
->length
;
122 uint8_t *buffer
= reply
->data
;
124 REG_SET_3(DC_I2C_DATA
, 0,
125 DC_I2C_INDEX
, dce_i2c_hw
->buffer_used_write
,
127 DC_I2C_INDEX_WRITE
, 1);
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
138 REG_GET(DC_I2C_DATA
, DC_I2C_DATA
, &i2c_data
);
139 *buffer
++ = i2c_data
;
145 static bool is_engine_available(struct dce_i2c_hw
*dce_i2c_hw
)
147 unsigned int arbitrate
;
148 unsigned int i2c_hw_status
;
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
)
154 REG_GET(DC_I2C_ARBITRATION
, DC_I2C_REG_RW_CNTL_STATUS
, &arbitrate
);
155 if (arbitrate
== DC_I2C_REG_RW_CNTL_STATUS_DMCU_ONLY
)
161 static bool is_hw_busy(struct dce_i2c_hw
*dce_i2c_hw
)
163 uint32_t i2c_sw_status
= 0;
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
)
169 if (is_engine_available(dce_i2c_hw
))
175 static bool process_transaction(
176 struct dce_i2c_hw
*dce_i2c_hw
,
177 struct i2c_request_transaction_data
*request
)
179 uint32_t length
= request
->length
;
180 uint8_t *buffer
= request
->data
;
182 bool last_transaction
= false;
185 if (is_hw_busy(dce_i2c_hw
)) {
186 request
->status
= I2C_CHANNEL_OPERATION_ENGINE_BUSY
;
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
));
195 switch (dce_i2c_hw
->transaction_count
) {
197 REG_UPDATE_5(DC_I2C_TRANSACTION0
,
198 DC_I2C_STOP_ON_NACK0
, 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);
205 REG_UPDATE_5(DC_I2C_TRANSACTION1
,
206 DC_I2C_STOP_ON_NACK0
, 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);
213 REG_UPDATE_5(DC_I2C_TRANSACTION2
,
214 DC_I2C_STOP_ON_NACK0
, 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);
221 REG_UPDATE_5(DC_I2C_TRANSACTION3
,
222 DC_I2C_STOP_ON_NACK0
, 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);
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.
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
,
245 DC_I2C_INDEX_WRITE
, 1);
246 dce_i2c_hw
->buffer_used_write
= 0;
248 value
= REG_SET_2(DC_I2C_DATA
, 0,
249 DC_I2C_DATA_RW
, false,
250 DC_I2C_DATA
, request
->address
);
252 dce_i2c_hw
->buffer_used_write
++;
254 if (!(request
->action
& DCE_I2C_TRANSACTION_ACTION_I2C_READ
)) {
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
++;
264 ++dce_i2c_hw
->transaction_count
;
265 dce_i2c_hw
->buffer_used_bytes
+= length
+ 1;
267 return last_transaction
;
270 static inline void reset_hw_engine(struct dce_i2c_hw
*dce_i2c_hw
)
272 REG_UPDATE_2(DC_I2C_CONTROL
,
273 DC_I2C_SW_STATUS_RESET
, 1,
274 DC_I2C_SW_STATUS_RESET
, 1);
277 static void set_speed(
278 struct dce_i2c_hw
*dce_i2c_hw
,
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);
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);
295 static bool setup_engine(
296 struct dce_i2c_hw
*dce_i2c_hw
)
298 uint32_t i2c_setup_limit
= I2C_SETUP_TIME_LIMIT_DCE
;
299 uint32_t reset_length
= 0;
300 /* we have checked I2c not used by DMCU, set SW use I2C REQ to 1 to indicate SW using it*/
301 REG_UPDATE(DC_I2C_ARBITRATION
, DC_I2C_SW_USE_I2C_REG_REQ
, 1);
303 /* we have checked I2c not used by DMCU, set SW use I2C REQ to 1 to indicate SW using it*/
304 REG_UPDATE(DC_I2C_ARBITRATION
, DC_I2C_SW_USE_I2C_REG_REQ
, 1);
306 if (dce_i2c_hw
->setup_limit
!= 0)
307 i2c_setup_limit
= dce_i2c_hw
->setup_limit
;
308 /* Program pin select */
309 REG_UPDATE_6(DC_I2C_CONTROL
,
311 DC_I2C_SOFT_RESET
, 0,
312 DC_I2C_SEND_RESET
, 0,
313 DC_I2C_SW_STATUS_RESET
, 1,
314 DC_I2C_TRANSACTION_COUNT
, 0,
315 DC_I2C_DDC_SELECT
, dce_i2c_hw
->engine_id
);
317 /* Program time limit */
318 if (dce_i2c_hw
->send_reset_length
== 0) {
320 REG_UPDATE_N(SETUP
, 2,
321 FN(DC_I2C_DDC1_SETUP
, DC_I2C_DDC1_TIME_LIMIT
), i2c_setup_limit
,
322 FN(DC_I2C_DDC1_SETUP
, DC_I2C_DDC1_ENABLE
), 1);
324 reset_length
= dce_i2c_hw
->send_reset_length
;
325 REG_UPDATE_N(SETUP
, 3,
326 FN(DC_I2C_DDC1_SETUP
, DC_I2C_DDC1_TIME_LIMIT
), i2c_setup_limit
,
327 FN(DC_I2C_DDC1_SETUP
, DC_I2C_DDC1_SEND_RESET_LENGTH
), reset_length
,
328 FN(DC_I2C_DDC1_SETUP
, DC_I2C_DDC1_ENABLE
), 1);
330 /* Program HW priority
331 * set to High - interrupt software I2C at any time
332 * Enable restart of SW I2C that was interrupted by HW
333 * disable queuing of software while I2C is in use by HW
335 REG_UPDATE(DC_I2C_ARBITRATION
,
336 DC_I2C_NO_QUEUED_SW_GO
, 0);
341 static void release_engine(
342 struct dce_i2c_hw
*dce_i2c_hw
)
346 /* Restore original HW engine speed */
348 set_speed(dce_i2c_hw
, dce_i2c_hw
->original_speed
);
351 /* Reset HW engine */
353 uint32_t i2c_sw_status
= 0;
355 REG_GET(DC_I2C_SW_STATUS
, DC_I2C_SW_STATUS
, &i2c_sw_status
);
356 /* if used by SW, safe to reset */
357 safe_to_reset
= (i2c_sw_status
== 1);
361 REG_UPDATE_2(DC_I2C_CONTROL
,
362 DC_I2C_SOFT_RESET
, 1,
363 DC_I2C_SW_STATUS_RESET
, 1);
365 REG_UPDATE(DC_I2C_CONTROL
, DC_I2C_SW_STATUS_RESET
, 1);
366 /* HW I2c engine - clock gating feature */
367 if (!dce_i2c_hw
->engine_keep_power_up_count
)
368 REG_UPDATE_N(SETUP
, 1, FN(SETUP
, DC_I2C_DDC1_ENABLE
), 0);
369 /* Release I2C after reset, so HW or DMCU could use it */
370 REG_UPDATE_2(DC_I2C_ARBITRATION
, DC_I2C_SW_DONE_USING_I2C_REG
, 1,
371 DC_I2C_SW_USE_I2C_REG_REQ
, 0);
375 struct dce_i2c_hw
*acquire_i2c_hw_engine(
376 struct resource_pool
*pool
,
379 uint32_t counter
= 0;
380 enum gpio_result result
;
381 uint32_t current_speed
;
382 struct dce_i2c_hw
*dce_i2c_hw
= NULL
;
387 if (ddc
->hw_info
.hw_supported
) {
388 enum gpio_ddc_line line
= dal_ddc_get_line(ddc
);
390 if (line
< pool
->res_cap
->num_ddc
)
391 dce_i2c_hw
= pool
->hw_i2cs
[line
];
397 if (pool
->i2c_hw_buffer_in_use
|| !is_engine_available(dce_i2c_hw
))
401 result
= dal_ddc_open(ddc
, GPIO_MODE_HARDWARE
,
402 GPIO_DDC_CONFIG_TYPE_MODE_I2C
);
404 if (result
== GPIO_RESULT_OK
)
407 /* i2c_engine is busy by VBios, lets wait and retry */
412 } while (counter
< 2);
414 if (result
!= GPIO_RESULT_OK
)
417 dce_i2c_hw
->ddc
= ddc
;
419 current_speed
= get_speed(dce_i2c_hw
);
422 dce_i2c_hw
->original_speed
= current_speed
;
424 if (!setup_engine(dce_i2c_hw
)) {
425 release_engine(dce_i2c_hw
);
429 pool
->i2c_hw_buffer_in_use
= true;
433 enum i2c_channel_operation_result
dce_i2c_hw_engine_wait_on_operation_result(
434 struct dce_i2c_hw
*dce_i2c_hw
,
436 enum i2c_channel_operation_result expected_result
)
438 enum i2c_channel_operation_result result
;
442 return I2C_CHANNEL_OPERATION_SUCCEEDED
;
446 result
= get_channel_status(
449 if (result
!= expected_result
)
455 } while (i
< timeout
);
459 static void submit_channel_request_hw(
460 struct dce_i2c_hw
*dce_i2c_hw
,
461 struct i2c_request_transaction_data
*request
)
463 request
->status
= I2C_CHANNEL_OPERATION_SUCCEEDED
;
465 if (!process_transaction(dce_i2c_hw
, request
))
468 if (is_hw_busy(dce_i2c_hw
)) {
469 request
->status
= I2C_CHANNEL_OPERATION_ENGINE_BUSY
;
472 reset_hw_engine(dce_i2c_hw
);
474 execute_transaction(dce_i2c_hw
);
479 static uint32_t get_transaction_timeout_hw(
480 const struct dce_i2c_hw
*dce_i2c_hw
,
484 uint32_t speed
= get_speed(dce_i2c_hw
);
488 uint32_t period_timeout
;
489 uint32_t num_of_clock_stretches
;
494 period_timeout
= (1000 * TRANSACTION_TIMEOUT_IN_I2C_CLOCKS
) / speed
;
496 num_of_clock_stretches
= 1 + (length
<< 3) + 1;
497 num_of_clock_stretches
+=
498 (dce_i2c_hw
->buffer_used_bytes
<< 3) +
499 (dce_i2c_hw
->transaction_count
<< 1);
501 return period_timeout
* num_of_clock_stretches
;
504 bool dce_i2c_hw_engine_submit_payload(
505 struct dce_i2c_hw
*dce_i2c_hw
,
506 struct i2c_payload
*payload
,
507 bool middle_of_transaction
)
510 struct i2c_request_transaction_data request
;
512 uint32_t transaction_timeout
;
514 enum i2c_channel_operation_result operation_result
;
518 /* We need following:
519 * transaction length will not exceed
520 * the number of free bytes in HW buffer (minus one for address)
523 if (payload
->length
>=
524 get_hw_buffer_available_size(dce_i2c_hw
)) {
529 request
.action
= middle_of_transaction
?
530 DCE_I2C_TRANSACTION_ACTION_I2C_READ_MOT
:
531 DCE_I2C_TRANSACTION_ACTION_I2C_READ
;
533 request
.action
= middle_of_transaction
?
534 DCE_I2C_TRANSACTION_ACTION_I2C_WRITE_MOT
:
535 DCE_I2C_TRANSACTION_ACTION_I2C_WRITE
;
538 request
.address
= (uint8_t) ((payload
->address
<< 1) | !payload
->write
);
539 request
.length
= payload
->length
;
540 request
.data
= payload
->data
;
542 /* obtain timeout value before submitting request */
544 transaction_timeout
= get_transaction_timeout_hw(
545 dce_i2c_hw
, payload
->length
+ 1);
547 submit_channel_request_hw(
548 dce_i2c_hw
, &request
);
550 if ((request
.status
== I2C_CHANNEL_OPERATION_FAILED
) ||
551 (request
.status
== I2C_CHANNEL_OPERATION_ENGINE_BUSY
))
554 /* wait until transaction proceed */
556 operation_result
= dce_i2c_hw_engine_wait_on_operation_result(
559 I2C_CHANNEL_OPERATION_ENGINE_BUSY
);
561 /* update transaction status */
563 if (operation_result
== I2C_CHANNEL_OPERATION_SUCCEEDED
)
566 if (result
&& (!payload
->write
))
567 process_channel_reply(dce_i2c_hw
, payload
);
572 bool dce_i2c_submit_command_hw(
573 struct resource_pool
*pool
,
575 struct i2c_command
*cmd
,
576 struct dce_i2c_hw
*dce_i2c_hw
)
578 uint8_t index_of_payload
= 0;
581 set_speed(dce_i2c_hw
, cmd
->speed
);
585 while (index_of_payload
< cmd
->number_of_payloads
) {
586 bool mot
= (index_of_payload
!= cmd
->number_of_payloads
- 1);
588 struct i2c_payload
*payload
= cmd
->payloads
+ index_of_payload
;
590 if (!dce_i2c_hw_engine_submit_payload(
591 dce_i2c_hw
, payload
, mot
)) {
601 pool
->i2c_hw_buffer_in_use
= false;
603 release_engine(dce_i2c_hw
);
604 dal_ddc_close(dce_i2c_hw
->ddc
);
606 dce_i2c_hw
->ddc
= NULL
;
611 void dce_i2c_hw_construct(
612 struct dce_i2c_hw
*dce_i2c_hw
,
613 struct dc_context
*ctx
,
615 const struct dce_i2c_registers
*regs
,
616 const struct dce_i2c_shift
*shifts
,
617 const struct dce_i2c_mask
*masks
)
619 dce_i2c_hw
->ctx
= ctx
;
620 dce_i2c_hw
->engine_id
= engine_id
;
621 dce_i2c_hw
->reference_frequency
= (ctx
->dc_bios
->fw_info
.pll_info
.crystal_frequency
) >> 1;
622 dce_i2c_hw
->regs
= regs
;
623 dce_i2c_hw
->shifts
= shifts
;
624 dce_i2c_hw
->masks
= masks
;
625 dce_i2c_hw
->buffer_used_bytes
= 0;
626 dce_i2c_hw
->transaction_count
= 0;
627 dce_i2c_hw
->engine_keep_power_up_count
= 1;
628 dce_i2c_hw
->original_speed
= DEFAULT_I2C_HW_SPEED
;
629 dce_i2c_hw
->default_speed
= DEFAULT_I2C_HW_SPEED
;
630 dce_i2c_hw
->send_reset_length
= 0;
631 dce_i2c_hw
->setup_limit
= I2C_SETUP_TIME_LIMIT_DCE
;
632 dce_i2c_hw
->buffer_size
= I2C_HW_BUFFER_SIZE_DCE
;
635 void dce100_i2c_hw_construct(
636 struct dce_i2c_hw
*dce_i2c_hw
,
637 struct dc_context
*ctx
,
639 const struct dce_i2c_registers
*regs
,
640 const struct dce_i2c_shift
*shifts
,
641 const struct dce_i2c_mask
*masks
)
644 uint32_t xtal_ref_div
= 0;
646 dce_i2c_hw_construct(dce_i2c_hw
,
652 dce_i2c_hw
->buffer_size
= I2C_HW_BUFFER_SIZE_DCE100
;
654 REG_GET(MICROSECOND_TIME_BASE_DIV
, XTAL_REF_DIV
, &xtal_ref_div
);
656 if (xtal_ref_div
== 0)
659 /*Calculating Reference Clock by divding original frequency by
661 * At upper level, uint32_t reference_frequency =
662 * dal_dce_i2c_get_reference_clock(as) >> 1
663 * which already divided by 2. So we need x2 to get original
664 * reference clock from ppll_info
666 dce_i2c_hw
->reference_frequency
=
667 (dce_i2c_hw
->reference_frequency
* 2) / xtal_ref_div
;
670 void dce112_i2c_hw_construct(
671 struct dce_i2c_hw
*dce_i2c_hw
,
672 struct dc_context
*ctx
,
674 const struct dce_i2c_registers
*regs
,
675 const struct dce_i2c_shift
*shifts
,
676 const struct dce_i2c_mask
*masks
)
678 dce100_i2c_hw_construct(dce_i2c_hw
,
684 dce_i2c_hw
->default_speed
= DEFAULT_I2C_HW_SPEED_100KHZ
;
687 void dcn1_i2c_hw_construct(
688 struct dce_i2c_hw
*dce_i2c_hw
,
689 struct dc_context
*ctx
,
691 const struct dce_i2c_registers
*regs
,
692 const struct dce_i2c_shift
*shifts
,
693 const struct dce_i2c_mask
*masks
)
695 dce112_i2c_hw_construct(dce_i2c_hw
,
701 dce_i2c_hw
->setup_limit
= I2C_SETUP_TIME_LIMIT_DCN
;
704 void dcn2_i2c_hw_construct(
705 struct dce_i2c_hw
*dce_i2c_hw
,
706 struct dc_context
*ctx
,
708 const struct dce_i2c_registers
*regs
,
709 const struct dce_i2c_shift
*shifts
,
710 const struct dce_i2c_mask
*masks
)
712 dcn1_i2c_hw_construct(dce_i2c_hw
,
718 dce_i2c_hw
->send_reset_length
= I2C_SEND_RESET_LENGTH_9
;
719 if (ctx
->dc
->debug
.scl_reset_length10
)
720 dce_i2c_hw
->send_reset_length
= I2C_SEND_RESET_LENGTH_10
;