• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }
370 
dce_i2c_engine_acquire_sw(struct dce_i2c_sw * dce_i2c_sw,struct ddc * ddc_handle)371 bool 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 
dce_i2c_sw_engine_submit_channel_request(struct dce_i2c_sw * engine,struct i2c_request_transaction_data * req)396 static 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 
dce_i2c_sw_engine_submit_payload(struct dce_i2c_sw * engine,struct i2c_payload * payload,bool middle_of_transaction)439 static 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 }
dce_i2c_submit_command_sw(struct resource_pool * pool,struct ddc * ddc,struct i2c_command * cmd,struct dce_i2c_sw * dce_i2c_sw)466 bool 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