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