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
32void 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
39static 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
53static 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
66static 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
74static 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}
95static 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
152static 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}
212static 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}
249static 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
271static 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
296static 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
340static 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
354static 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
371bool dce_i2c_engine_acquire_sw(
372	struct dce_i2c_sw *dce_i2c_sw,
373	struct ddc *ddc_handle)
374{
375	uint32_t counter = 0;
376	bool result;
377
378	do {
379
380		result = dce_i2c_sw_engine_acquire_engine(
381				dce_i2c_sw, ddc_handle);
382
383		if (result)
384			break;
385
386		/* i2c_engine is busy by VBios, lets wait and retry */
387
388		udelay(10);
389
390		++counter;
391	} while (counter < 2);
392
393	return result;
394}
395
396static void dce_i2c_sw_engine_submit_channel_request(struct dce_i2c_sw *engine,
397						     struct i2c_request_transaction_data *req)
398{
399	struct ddc *ddc = engine->ddc;
400	uint16_t clock_delay_div_4 = engine->clock_delay >> 2;
401
402	/* send sync (start / repeated start) */
403
404	bool result = start_sync_sw(engine->ctx, ddc, clock_delay_div_4);
405
406	/* process payload */
407
408	if (result) {
409		switch (req->action) {
410		case DCE_I2C_TRANSACTION_ACTION_I2C_WRITE:
411		case DCE_I2C_TRANSACTION_ACTION_I2C_WRITE_MOT:
412			result = i2c_write_sw(engine->ctx, ddc, clock_delay_div_4,
413				req->address, req->length, req->data);
414		break;
415		case DCE_I2C_TRANSACTION_ACTION_I2C_READ:
416		case DCE_I2C_TRANSACTION_ACTION_I2C_READ_MOT:
417			result = i2c_read_sw(engine->ctx, ddc, clock_delay_div_4,
418				req->address, req->length, req->data);
419		break;
420		default:
421			result = false;
422		break;
423		}
424	}
425
426	/* send stop if not 'mot' or operation failed */
427
428	if (!result ||
429		(req->action == DCE_I2C_TRANSACTION_ACTION_I2C_WRITE) ||
430		(req->action == DCE_I2C_TRANSACTION_ACTION_I2C_READ))
431		if (!stop_sync_sw(engine->ctx, ddc, clock_delay_div_4))
432			result = false;
433
434	req->status = result ?
435		I2C_CHANNEL_OPERATION_SUCCEEDED :
436		I2C_CHANNEL_OPERATION_FAILED;
437}
438
439static bool dce_i2c_sw_engine_submit_payload(struct dce_i2c_sw *engine,
440					     struct i2c_payload *payload,
441					     bool middle_of_transaction)
442{
443	struct i2c_request_transaction_data request;
444
445	if (!payload->write)
446		request.action = middle_of_transaction ?
447			DCE_I2C_TRANSACTION_ACTION_I2C_READ_MOT :
448			DCE_I2C_TRANSACTION_ACTION_I2C_READ;
449	else
450		request.action = middle_of_transaction ?
451			DCE_I2C_TRANSACTION_ACTION_I2C_WRITE_MOT :
452			DCE_I2C_TRANSACTION_ACTION_I2C_WRITE;
453
454	request.address = (uint8_t) ((payload->address << 1) | !payload->write);
455	request.length = payload->length;
456	request.data = payload->data;
457
458	dce_i2c_sw_engine_submit_channel_request(engine, &request);
459
460	if ((request.status == I2C_CHANNEL_OPERATION_ENGINE_BUSY) ||
461		(request.status == I2C_CHANNEL_OPERATION_FAILED))
462		return false;
463
464	return true;
465}
466bool dce_i2c_submit_command_sw(
467	struct resource_pool *pool,
468	struct ddc *ddc,
469	struct i2c_command *cmd,
470	struct dce_i2c_sw *dce_i2c_sw)
471{
472	uint8_t index_of_payload = 0;
473	bool result;
474
475	dce_i2c_sw_engine_set_speed(dce_i2c_sw, cmd->speed);
476
477	result = true;
478
479	while (index_of_payload < cmd->number_of_payloads) {
480		bool mot = (index_of_payload != cmd->number_of_payloads - 1);
481
482		struct i2c_payload *payload = cmd->payloads + index_of_payload;
483
484		if (!dce_i2c_sw_engine_submit_payload(
485			dce_i2c_sw, payload, mot)) {
486			result = false;
487			break;
488		}
489
490		++index_of_payload;
491	}
492
493	release_engine_dce_sw(pool, dce_i2c_sw);
494
495	return result;
496}
497