]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/display/dc/dce/dce_i2c_sw.c
Merge remote-tracking branch 'spi/for-5.14' into spi-linus
[linux.git] / drivers / gpu / drm / amd / display / dc / dce / dce_i2c_sw.c
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
34 void 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
41 static 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
55 static 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
68 static 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
76 static 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 }
97 static 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
154 static 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 }
214 static 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 }
251 static 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
273 static 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
298 static 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
342 static 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
356 static 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 }
372 bool 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
400 static 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
444 static 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 }
472 bool 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 }
This page took 0.066101 seconds and 4 git commands to generate.