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 
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 
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 
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 
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 
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 }
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 
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 }
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 }
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 
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 
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 
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 
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 }
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 
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 
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 }
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