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