xref: /linux/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c (revision b7019ac550eb3916f34d79db583e9b7ea2524afa)
1 /*
2  * Copyright 2012-15 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 #include <linux/slab.h>
28 
29 #include "dm_services.h"
30 #include "core_types.h"
31 #include "dce_aux.h"
32 #include "dce/dce_11_0_sh_mask.h"
33 
34 #define CTX \
35 	aux110->base.ctx
36 #define REG(reg_name)\
37 	(aux110->regs->reg_name)
38 
39 #define DC_LOGGER \
40 	engine->ctx->logger
41 
42 #include "reg_helper.h"
43 
44 #define FROM_AUX_ENGINE(ptr) \
45 	container_of((ptr), struct aux_engine_dce110, base)
46 
47 #define FROM_ENGINE(ptr) \
48 	FROM_AUX_ENGINE(container_of((ptr), struct dce_aux, base))
49 
50 #define FROM_AUX_ENGINE_ENGINE(ptr) \
51 	container_of((ptr), struct dce_aux, base)
52 enum {
53 	AUX_INVALID_REPLY_RETRY_COUNTER = 1,
54 	AUX_TIMED_OUT_RETRY_COUNTER = 2,
55 	AUX_DEFER_RETRY_COUNTER = 6
56 };
57 static void release_engine(
58 	struct dce_aux *engine)
59 {
60 	struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
61 
62 	dal_ddc_close(engine->ddc);
63 
64 	engine->ddc = NULL;
65 
66 	REG_UPDATE(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, 1);
67 }
68 
69 #define SW_CAN_ACCESS_AUX 1
70 #define DMCU_CAN_ACCESS_AUX 2
71 
72 static bool is_engine_available(
73 	struct dce_aux *engine)
74 {
75 	struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
76 
77 	uint32_t value = REG_READ(AUX_ARB_CONTROL);
78 	uint32_t field = get_reg_field_value(
79 			value,
80 			AUX_ARB_CONTROL,
81 			AUX_REG_RW_CNTL_STATUS);
82 
83 	return (field != DMCU_CAN_ACCESS_AUX);
84 }
85 static bool acquire_engine(
86 	struct dce_aux *engine)
87 {
88 	struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
89 
90 	uint32_t value = REG_READ(AUX_ARB_CONTROL);
91 	uint32_t field = get_reg_field_value(
92 			value,
93 			AUX_ARB_CONTROL,
94 			AUX_REG_RW_CNTL_STATUS);
95 	if (field == DMCU_CAN_ACCESS_AUX)
96 		return false;
97 	/* enable AUX before request SW to access AUX */
98 	value = REG_READ(AUX_CONTROL);
99 	field = get_reg_field_value(value,
100 				AUX_CONTROL,
101 				AUX_EN);
102 
103 	if (field == 0) {
104 		set_reg_field_value(
105 				value,
106 				1,
107 				AUX_CONTROL,
108 				AUX_EN);
109 
110 		if (REG(AUX_RESET_MASK)) {
111 			/*DP_AUX block as part of the enable sequence*/
112 			set_reg_field_value(
113 				value,
114 				1,
115 				AUX_CONTROL,
116 				AUX_RESET);
117 		}
118 
119 		REG_WRITE(AUX_CONTROL, value);
120 
121 		if (REG(AUX_RESET_MASK)) {
122 			/*poll HW to make sure reset it done*/
123 
124 			REG_WAIT(AUX_CONTROL, AUX_RESET_DONE, 1,
125 					1, 11);
126 
127 			set_reg_field_value(
128 				value,
129 				0,
130 				AUX_CONTROL,
131 				AUX_RESET);
132 
133 			REG_WRITE(AUX_CONTROL, value);
134 
135 			REG_WAIT(AUX_CONTROL, AUX_RESET_DONE, 0,
136 					1, 11);
137 		}
138 	} /*if (field)*/
139 
140 	/* request SW to access AUX */
141 	REG_UPDATE(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, 1);
142 
143 	value = REG_READ(AUX_ARB_CONTROL);
144 	field = get_reg_field_value(
145 			value,
146 			AUX_ARB_CONTROL,
147 			AUX_REG_RW_CNTL_STATUS);
148 
149 	return (field == SW_CAN_ACCESS_AUX);
150 }
151 
152 #define COMPOSE_AUX_SW_DATA_16_20(command, address) \
153 	((command) | ((0xF0000 & (address)) >> 16))
154 
155 #define COMPOSE_AUX_SW_DATA_8_15(address) \
156 	((0xFF00 & (address)) >> 8)
157 
158 #define COMPOSE_AUX_SW_DATA_0_7(address) \
159 	(0xFF & (address))
160 
161 static void submit_channel_request(
162 	struct dce_aux *engine,
163 	struct aux_request_transaction_data *request)
164 {
165 	struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
166 	uint32_t value;
167 	uint32_t length;
168 
169 	bool is_write =
170 		((request->type == AUX_TRANSACTION_TYPE_DP) &&
171 		 (request->action == I2CAUX_TRANSACTION_ACTION_DP_WRITE)) ||
172 		((request->type == AUX_TRANSACTION_TYPE_I2C) &&
173 		((request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE) ||
174 		 (request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT)));
175 	if (REG(AUXN_IMPCAL)) {
176 		/* clear_aux_error */
177 		REG_UPDATE_SEQ_2(AUXN_IMPCAL,
178 				AUXN_CALOUT_ERROR_AK, 1,
179 				AUXN_CALOUT_ERROR_AK, 0);
180 
181 		REG_UPDATE_SEQ_2(AUXP_IMPCAL,
182 				AUXP_CALOUT_ERROR_AK, 1,
183 				AUXP_CALOUT_ERROR_AK, 0);
184 
185 		/* force_default_calibrate */
186 		REG_UPDATE_SEQ_2(AUXN_IMPCAL,
187 				AUXN_IMPCAL_ENABLE, 1,
188 				AUXN_IMPCAL_OVERRIDE_ENABLE, 0);
189 
190 		/* bug? why AUXN update EN and OVERRIDE_EN 1 by 1 while AUX P toggles OVERRIDE? */
191 
192 		REG_UPDATE_SEQ_2(AUXP_IMPCAL,
193 				AUXP_IMPCAL_OVERRIDE_ENABLE, 1,
194 				AUXP_IMPCAL_OVERRIDE_ENABLE, 0);
195 	}
196 
197 	REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1);
198 
199 	REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 0,
200 				10, aux110->timeout_period/10);
201 
202 	/* set the delay and the number of bytes to write */
203 
204 	/* The length include
205 	 * the 4 bit header and the 20 bit address
206 	 * (that is 3 byte).
207 	 * If the requested length is non zero this means
208 	 * an addition byte specifying the length is required.
209 	 */
210 
211 	length = request->length ? 4 : 3;
212 	if (is_write)
213 		length += request->length;
214 
215 	REG_UPDATE_2(AUX_SW_CONTROL,
216 			AUX_SW_START_DELAY, request->delay,
217 			AUX_SW_WR_BYTES, length);
218 
219 	/* program action and address and payload data (if 'is_write') */
220 	value = REG_UPDATE_4(AUX_SW_DATA,
221 			AUX_SW_INDEX, 0,
222 			AUX_SW_DATA_RW, 0,
223 			AUX_SW_AUTOINCREMENT_DISABLE, 1,
224 			AUX_SW_DATA, COMPOSE_AUX_SW_DATA_16_20(request->action, request->address));
225 
226 	value = REG_SET_2(AUX_SW_DATA, value,
227 			AUX_SW_AUTOINCREMENT_DISABLE, 0,
228 			AUX_SW_DATA, COMPOSE_AUX_SW_DATA_8_15(request->address));
229 
230 	value = REG_SET(AUX_SW_DATA, value,
231 			AUX_SW_DATA, COMPOSE_AUX_SW_DATA_0_7(request->address));
232 
233 	if (request->length) {
234 		value = REG_SET(AUX_SW_DATA, value,
235 				AUX_SW_DATA, request->length - 1);
236 	}
237 
238 	if (is_write) {
239 		/* Load the HW buffer with the Data to be sent.
240 		 * This is relevant for write operation.
241 		 * For read, the data recived data will be
242 		 * processed in process_channel_reply().
243 		 */
244 		uint32_t i = 0;
245 
246 		while (i < request->length) {
247 			value = REG_SET(AUX_SW_DATA, value,
248 					AUX_SW_DATA, request->data[i]);
249 
250 			++i;
251 		}
252 	}
253 
254 	REG_UPDATE(AUX_SW_CONTROL, AUX_SW_GO, 1);
255 }
256 
257 static int read_channel_reply(struct dce_aux *engine, uint32_t size,
258 			      uint8_t *buffer, uint8_t *reply_result,
259 			      uint32_t *sw_status)
260 {
261 	struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
262 	uint32_t bytes_replied;
263 	uint32_t reply_result_32;
264 
265 	*sw_status = REG_GET(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT,
266 			     &bytes_replied);
267 
268 	/* In case HPD is LOW, exit AUX transaction */
269 	if ((*sw_status & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK))
270 		return -1;
271 
272 	/* Need at least the status byte */
273 	if (!bytes_replied)
274 		return -1;
275 
276 	REG_UPDATE_SEQ_3(AUX_SW_DATA,
277 			  AUX_SW_INDEX, 0,
278 			  AUX_SW_AUTOINCREMENT_DISABLE, 1,
279 			  AUX_SW_DATA_RW, 1);
280 
281 	REG_GET(AUX_SW_DATA, AUX_SW_DATA, &reply_result_32);
282 	reply_result_32 = reply_result_32 >> 4;
283 	if (reply_result != NULL)
284 		*reply_result = (uint8_t)reply_result_32;
285 
286 	if (reply_result_32 == 0) { /* ACK */
287 		uint32_t i = 0;
288 
289 		/* First byte was already used to get the command status */
290 		--bytes_replied;
291 
292 		/* Do not overflow buffer */
293 		if (bytes_replied > size)
294 			return -1;
295 
296 		while (i < bytes_replied) {
297 			uint32_t aux_sw_data_val;
298 
299 			REG_GET(AUX_SW_DATA, AUX_SW_DATA, &aux_sw_data_val);
300 			buffer[i] = aux_sw_data_val;
301 			++i;
302 		}
303 
304 		return i;
305 	}
306 
307 	return 0;
308 }
309 
310 static enum aux_channel_operation_result get_channel_status(
311 	struct dce_aux *engine,
312 	uint8_t *returned_bytes)
313 {
314 	struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
315 
316 	uint32_t value;
317 
318 	if (returned_bytes == NULL) {
319 		/*caller pass NULL pointer*/
320 		ASSERT_CRITICAL(false);
321 		return AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN;
322 	}
323 	*returned_bytes = 0;
324 
325 	/* poll to make sure that SW_DONE is asserted */
326 	REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 1,
327 				10, aux110->timeout_period/10);
328 
329 	value = REG_READ(AUX_SW_STATUS);
330 	/* in case HPD is LOW, exit AUX transaction */
331 	if ((value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK))
332 		return AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON;
333 
334 	/* Note that the following bits are set in 'status.bits'
335 	 * during CTS 4.2.1.2 (FW 3.3.1):
336 	 * AUX_SW_RX_MIN_COUNT_VIOL, AUX_SW_RX_INVALID_STOP,
337 	 * AUX_SW_RX_RECV_NO_DET, AUX_SW_RX_RECV_INVALID_H.
338 	 *
339 	 * AUX_SW_RX_MIN_COUNT_VIOL is an internal,
340 	 * HW debugging bit and should be ignored.
341 	 */
342 	if (value & AUX_SW_STATUS__AUX_SW_DONE_MASK) {
343 		if ((value & AUX_SW_STATUS__AUX_SW_RX_TIMEOUT_STATE_MASK) ||
344 			(value & AUX_SW_STATUS__AUX_SW_RX_TIMEOUT_MASK))
345 			return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT;
346 
347 		else if ((value & AUX_SW_STATUS__AUX_SW_RX_INVALID_STOP_MASK) ||
348 			(value & AUX_SW_STATUS__AUX_SW_RX_RECV_NO_DET_MASK) ||
349 			(value &
350 				AUX_SW_STATUS__AUX_SW_RX_RECV_INVALID_H_MASK) ||
351 			(value & AUX_SW_STATUS__AUX_SW_RX_RECV_INVALID_L_MASK))
352 			return AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY;
353 
354 		*returned_bytes = get_reg_field_value(value,
355 				AUX_SW_STATUS,
356 				AUX_SW_REPLY_BYTE_COUNT);
357 
358 		if (*returned_bytes == 0)
359 			return
360 			AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY;
361 		else {
362 			*returned_bytes -= 1;
363 			return AUX_CHANNEL_OPERATION_SUCCEEDED;
364 		}
365 	} else {
366 		/*time_elapsed >= aux_engine->timeout_period
367 		 *  AUX_SW_STATUS__AUX_SW_HPD_DISCON = at this point
368 		 */
369 		ASSERT_CRITICAL(false);
370 		return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT;
371 	}
372 }
373 
374 enum i2caux_engine_type get_engine_type(
375 		const struct dce_aux *engine)
376 {
377 	return I2CAUX_ENGINE_TYPE_AUX;
378 }
379 
380 static bool acquire(
381 	struct dce_aux *engine,
382 	struct ddc *ddc)
383 {
384 	enum gpio_result result;
385 
386 	if (!is_engine_available(engine))
387 		return false;
388 
389 	result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE,
390 		GPIO_DDC_CONFIG_TYPE_MODE_AUX);
391 
392 	if (result != GPIO_RESULT_OK)
393 		return false;
394 
395 	if (!acquire_engine(engine)) {
396 		dal_ddc_close(ddc);
397 		return false;
398 	}
399 
400 	engine->ddc = ddc;
401 
402 	return true;
403 }
404 
405 void dce110_engine_destroy(struct dce_aux **engine)
406 {
407 
408 	struct aux_engine_dce110 *engine110 = FROM_AUX_ENGINE(*engine);
409 
410 	kfree(engine110);
411 	*engine = NULL;
412 
413 }
414 struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110,
415 		struct dc_context *ctx,
416 		uint32_t inst,
417 		uint32_t timeout_period,
418 		const struct dce110_aux_registers *regs)
419 {
420 	aux_engine110->base.ddc = NULL;
421 	aux_engine110->base.ctx = ctx;
422 	aux_engine110->base.delay = 0;
423 	aux_engine110->base.max_defer_write_retry = 0;
424 	aux_engine110->base.inst = inst;
425 	aux_engine110->timeout_period = timeout_period;
426 	aux_engine110->regs = regs;
427 
428 	return &aux_engine110->base;
429 }
430 
431 static enum i2caux_transaction_action i2caux_action_from_payload(struct aux_payload *payload)
432 {
433 	if (payload->i2c_over_aux) {
434 		if (payload->write) {
435 			if (payload->mot)
436 				return I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT;
437 			return I2CAUX_TRANSACTION_ACTION_I2C_WRITE;
438 		}
439 		if (payload->mot)
440 			return I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT;
441 		return I2CAUX_TRANSACTION_ACTION_I2C_READ;
442 	}
443 	if (payload->write)
444 		return I2CAUX_TRANSACTION_ACTION_DP_WRITE;
445 	return I2CAUX_TRANSACTION_ACTION_DP_READ;
446 }
447 
448 int dce_aux_transfer_raw(struct ddc_service *ddc,
449 		struct aux_payload *payload,
450 		enum aux_channel_operation_result *operation_result)
451 {
452 	struct ddc *ddc_pin = ddc->ddc_pin;
453 	struct dce_aux *aux_engine;
454 	struct aux_request_transaction_data aux_req;
455 	struct aux_reply_transaction_data aux_rep;
456 	uint8_t returned_bytes = 0;
457 	int res = -1;
458 	uint32_t status;
459 
460 	memset(&aux_req, 0, sizeof(aux_req));
461 	memset(&aux_rep, 0, sizeof(aux_rep));
462 
463 	aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
464 	if (!acquire(aux_engine, ddc_pin))
465 		return -1;
466 
467 	if (payload->i2c_over_aux)
468 		aux_req.type = AUX_TRANSACTION_TYPE_I2C;
469 	else
470 		aux_req.type = AUX_TRANSACTION_TYPE_DP;
471 
472 	aux_req.action = i2caux_action_from_payload(payload);
473 
474 	aux_req.address = payload->address;
475 	aux_req.delay = payload->defer_delay * 10;
476 	aux_req.length = payload->length;
477 	aux_req.data = payload->data;
478 
479 	submit_channel_request(aux_engine, &aux_req);
480 	*operation_result = get_channel_status(aux_engine, &returned_bytes);
481 
482 	if (*operation_result == AUX_CHANNEL_OPERATION_SUCCEEDED) {
483 		read_channel_reply(aux_engine, payload->length,
484 					 payload->data, payload->reply,
485 					 &status);
486 		res = returned_bytes;
487 	} else {
488 		res = -1;
489 	}
490 
491 	release_engine(aux_engine);
492 	return res;
493 }
494 
495 #define AUX_MAX_RETRIES 7
496 #define AUX_MAX_DEFER_RETRIES 7
497 #define AUX_MAX_I2C_DEFER_RETRIES 7
498 #define AUX_MAX_INVALID_REPLY_RETRIES 2
499 #define AUX_MAX_TIMEOUT_RETRIES 3
500 
501 bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
502 		struct aux_payload *payload)
503 {
504 	int i, ret = 0;
505 	uint8_t reply;
506 	bool payload_reply = true;
507 	enum aux_channel_operation_result operation_result;
508 	int aux_ack_retries = 0,
509 		aux_defer_retries = 0,
510 		aux_i2c_defer_retries = 0,
511 		aux_timeout_retries = 0,
512 		aux_invalid_reply_retries = 0;
513 
514 	if (!payload->reply) {
515 		payload_reply = false;
516 		payload->reply = &reply;
517 	}
518 
519 	for (i = 0; i < AUX_MAX_RETRIES; i++) {
520 		ret = dce_aux_transfer_raw(ddc, payload, &operation_result);
521 		switch (operation_result) {
522 		case AUX_CHANNEL_OPERATION_SUCCEEDED:
523 			aux_timeout_retries = 0;
524 			aux_invalid_reply_retries = 0;
525 
526 			switch (*payload->reply) {
527 			case AUX_TRANSACTION_REPLY_AUX_ACK:
528 				if (!payload->write && payload->length != ret) {
529 					if (++aux_ack_retries >= AUX_MAX_RETRIES)
530 						goto fail;
531 					else
532 						udelay(300);
533 				} else
534 					return true;
535 			break;
536 
537 			case AUX_TRANSACTION_REPLY_AUX_DEFER:
538 			case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK:
539 			case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER:
540 				if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES)
541 					goto fail;
542 				break;
543 
544 			case AUX_TRANSACTION_REPLY_I2C_DEFER:
545 				aux_defer_retries = 0;
546 				if (++aux_i2c_defer_retries >= AUX_MAX_I2C_DEFER_RETRIES)
547 					goto fail;
548 				break;
549 
550 			case AUX_TRANSACTION_REPLY_AUX_NACK:
551 			case AUX_TRANSACTION_REPLY_HPD_DISCON:
552 			default:
553 				goto fail;
554 			}
555 			break;
556 
557 		case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY:
558 			if (++aux_invalid_reply_retries >= AUX_MAX_INVALID_REPLY_RETRIES)
559 				goto fail;
560 			else
561 				udelay(400);
562 			break;
563 
564 		case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT:
565 			if (++aux_timeout_retries >= AUX_MAX_TIMEOUT_RETRIES)
566 				goto fail;
567 			else {
568 				/*
569 				 * DP 1.4, 2.8.2:  AUX Transaction Response/Reply Timeouts
570 				 * According to the DP spec there should be 3 retries total
571 				 * with a 400us wait inbetween each. Hardware already waits
572 				 * for 550us therefore no wait is required here.
573 				 */
574 			}
575 			break;
576 
577 		case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON:
578 		case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN:
579 		default:
580 			goto fail;
581 		}
582 	}
583 
584 fail:
585 	if (!payload_reply)
586 		payload->reply = NULL;
587 	return false;
588 }
589