• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/slab.h>
27 
28 #include "dm_services.h"
29 #include "dm_helpers.h"
30 #include "gpio_service_interface.h"
31 #include "include/ddc_service_types.h"
32 #include "include/grph_object_id.h"
33 #include "include/dpcd_defs.h"
34 #include "include/logger_interface.h"
35 #include "include/vector.h"
36 #include "core_types.h"
37 #include "dc_link_ddc.h"
38 #include "dce/dce_aux.h"
39 
40 #define AUX_POWER_UP_WA_DELAY 500
41 #define I2C_OVER_AUX_DEFER_WA_DELAY 70
42 
43 /* CV smart dongle slave address for retrieving supported HDTV modes*/
44 #define CV_SMART_DONGLE_ADDRESS 0x20
45 /* DVI-HDMI dongle slave address for retrieving dongle signature*/
46 #define DVI_HDMI_DONGLE_ADDRESS 0x68
47 struct dvi_hdmi_dongle_signature_data {
48 	int8_t vendor[3];/* "AMD" */
49 	uint8_t version[2];
50 	uint8_t size;
51 	int8_t id[11];/* "6140063500G"*/
52 };
53 /* DP-HDMI dongle slave address for retrieving dongle signature*/
54 #define DP_HDMI_DONGLE_ADDRESS 0x40
55 static const uint8_t dp_hdmi_dongle_signature_str[] = "DP-HDMI ADAPTOR";
56 #define DP_HDMI_DONGLE_SIGNATURE_EOT 0x04
57 
58 struct dp_hdmi_dongle_signature_data {
59 	int8_t id[15];/* "DP-HDMI ADAPTOR"*/
60 	uint8_t eot;/* end of transmition '\x4' */
61 };
62 
63 /* SCDC Address defines (HDMI 2.0)*/
64 #define HDMI_SCDC_WRITE_UPDATE_0_ARRAY 3
65 #define HDMI_SCDC_ADDRESS  0x54
66 #define HDMI_SCDC_SINK_VERSION 0x01
67 #define HDMI_SCDC_SOURCE_VERSION 0x02
68 #define HDMI_SCDC_UPDATE_0 0x10
69 #define HDMI_SCDC_TMDS_CONFIG 0x20
70 #define HDMI_SCDC_SCRAMBLER_STATUS 0x21
71 #define HDMI_SCDC_CONFIG_0 0x30
72 #define HDMI_SCDC_STATUS_FLAGS 0x40
73 #define HDMI_SCDC_ERR_DETECT 0x50
74 #define HDMI_SCDC_TEST_CONFIG 0xC0
75 
76 union hdmi_scdc_update_read_data {
77 	uint8_t byte[2];
78 	struct {
79 		uint8_t STATUS_UPDATE:1;
80 		uint8_t CED_UPDATE:1;
81 		uint8_t RR_TEST:1;
82 		uint8_t RESERVED:5;
83 		uint8_t RESERVED2:8;
84 	} fields;
85 };
86 
87 union hdmi_scdc_status_flags_data {
88 	uint8_t byte[2];
89 	struct {
90 		uint8_t CLOCK_DETECTED:1;
91 		uint8_t CH0_LOCKED:1;
92 		uint8_t CH1_LOCKED:1;
93 		uint8_t CH2_LOCKED:1;
94 		uint8_t RESERVED:4;
95 		uint8_t RESERVED2:8;
96 		uint8_t RESERVED3:8;
97 
98 	} fields;
99 };
100 
101 union hdmi_scdc_ced_data {
102 	uint8_t byte[7];
103 	struct {
104 		uint8_t CH0_8LOW:8;
105 		uint8_t CH0_7HIGH:7;
106 		uint8_t CH0_VALID:1;
107 		uint8_t CH1_8LOW:8;
108 		uint8_t CH1_7HIGH:7;
109 		uint8_t CH1_VALID:1;
110 		uint8_t CH2_8LOW:8;
111 		uint8_t CH2_7HIGH:7;
112 		uint8_t CH2_VALID:1;
113 		uint8_t CHECKSUM:8;
114 		uint8_t RESERVED:8;
115 		uint8_t RESERVED2:8;
116 		uint8_t RESERVED3:8;
117 		uint8_t RESERVED4:4;
118 	} fields;
119 };
120 
121 struct i2c_payloads {
122 	struct vector payloads;
123 };
124 
125 struct aux_payloads {
126 	struct vector payloads;
127 };
128 
dal_ddc_i2c_payloads_create(struct dc_context * ctx,uint32_t count)129 static struct i2c_payloads *dal_ddc_i2c_payloads_create(struct dc_context *ctx, uint32_t count)
130 {
131 	struct i2c_payloads *payloads;
132 
133 	payloads = kzalloc(sizeof(struct i2c_payloads), GFP_KERNEL);
134 
135 	if (!payloads)
136 		return NULL;
137 
138 	if (dal_vector_construct(
139 		&payloads->payloads, ctx, count, sizeof(struct i2c_payload)))
140 		return payloads;
141 
142 	kfree(payloads);
143 	return NULL;
144 
145 }
146 
dal_ddc_i2c_payloads_get(struct i2c_payloads * p)147 static struct i2c_payload *dal_ddc_i2c_payloads_get(struct i2c_payloads *p)
148 {
149 	return (struct i2c_payload *)p->payloads.container;
150 }
151 
dal_ddc_i2c_payloads_get_count(struct i2c_payloads * p)152 static uint32_t dal_ddc_i2c_payloads_get_count(struct i2c_payloads *p)
153 {
154 	return p->payloads.count;
155 }
156 
dal_ddc_i2c_payloads_destroy(struct i2c_payloads ** p)157 static void dal_ddc_i2c_payloads_destroy(struct i2c_payloads **p)
158 {
159 	if (!p || !*p)
160 		return;
161 	dal_vector_destruct(&(*p)->payloads);
162 	kfree(*p);
163 	*p = NULL;
164 
165 }
166 
167 #define DDC_MIN(a, b) (((a) < (b)) ? (a) : (b))
168 
dal_ddc_i2c_payloads_add(struct i2c_payloads * payloads,uint32_t address,uint32_t len,uint8_t * data,bool write)169 void dal_ddc_i2c_payloads_add(
170 	struct i2c_payloads *payloads,
171 	uint32_t address,
172 	uint32_t len,
173 	uint8_t *data,
174 	bool write)
175 {
176 	uint32_t payload_size = EDID_SEGMENT_SIZE;
177 	uint32_t pos;
178 
179 	for (pos = 0; pos < len; pos += payload_size) {
180 		struct i2c_payload payload = {
181 			.write = write,
182 			.address = address,
183 			.length = DDC_MIN(payload_size, len - pos),
184 			.data = data + pos };
185 		dal_vector_append(&payloads->payloads, &payload);
186 	}
187 
188 }
189 
construct(struct ddc_service * ddc_service,struct ddc_service_init_data * init_data)190 static void construct(
191 	struct ddc_service *ddc_service,
192 	struct ddc_service_init_data *init_data)
193 {
194 	enum connector_id connector_id =
195 		dal_graphics_object_id_get_connector_id(init_data->id);
196 
197 	struct gpio_service *gpio_service = init_data->ctx->gpio_service;
198 	struct graphics_object_i2c_info i2c_info;
199 	struct gpio_ddc_hw_info hw_info;
200 	struct dc_bios *dcb = init_data->ctx->dc_bios;
201 
202 	ddc_service->link = init_data->link;
203 	ddc_service->ctx = init_data->ctx;
204 
205 	if (BP_RESULT_OK != dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info)) {
206 		ddc_service->ddc_pin = NULL;
207 	} else {
208 		hw_info.ddc_channel = i2c_info.i2c_line;
209 		hw_info.hw_supported = i2c_info.i2c_hw_assist;
210 
211 		ddc_service->ddc_pin = dal_gpio_create_ddc(
212 			gpio_service,
213 			i2c_info.gpio_info.clk_a_register_index,
214 			1 << i2c_info.gpio_info.clk_a_shift,
215 			&hw_info);
216 	}
217 
218 	ddc_service->flags.EDID_QUERY_DONE_ONCE = false;
219 	ddc_service->flags.FORCE_READ_REPEATED_START = false;
220 	ddc_service->flags.EDID_STRESS_READ = false;
221 
222 	ddc_service->flags.IS_INTERNAL_DISPLAY =
223 		connector_id == CONNECTOR_ID_EDP ||
224 		connector_id == CONNECTOR_ID_LVDS;
225 
226 	ddc_service->wa.raw = 0;
227 }
228 
dal_ddc_service_create(struct ddc_service_init_data * init_data)229 struct ddc_service *dal_ddc_service_create(
230 	struct ddc_service_init_data *init_data)
231 {
232 	struct ddc_service *ddc_service;
233 
234 	ddc_service = kzalloc(sizeof(struct ddc_service), GFP_KERNEL);
235 
236 	if (!ddc_service)
237 		return NULL;
238 
239 	construct(ddc_service, init_data);
240 	return ddc_service;
241 }
242 
destruct(struct ddc_service * ddc)243 static void destruct(struct ddc_service *ddc)
244 {
245 	if (ddc->ddc_pin)
246 		dal_gpio_destroy_ddc(&ddc->ddc_pin);
247 }
248 
dal_ddc_service_destroy(struct ddc_service ** ddc)249 void dal_ddc_service_destroy(struct ddc_service **ddc)
250 {
251 	if (!ddc || !*ddc) {
252 		BREAK_TO_DEBUGGER();
253 		return;
254 	}
255 	destruct(*ddc);
256 	kfree(*ddc);
257 	*ddc = NULL;
258 }
259 
dal_ddc_service_get_type(struct ddc_service * ddc)260 enum ddc_service_type dal_ddc_service_get_type(struct ddc_service *ddc)
261 {
262 	return DDC_SERVICE_TYPE_CONNECTOR;
263 }
264 
dal_ddc_service_set_transaction_type(struct ddc_service * ddc,enum ddc_transaction_type type)265 void dal_ddc_service_set_transaction_type(
266 	struct ddc_service *ddc,
267 	enum ddc_transaction_type type)
268 {
269 	ddc->transaction_type = type;
270 }
271 
dal_ddc_service_is_in_aux_transaction_mode(struct ddc_service * ddc)272 bool dal_ddc_service_is_in_aux_transaction_mode(struct ddc_service *ddc)
273 {
274 	switch (ddc->transaction_type) {
275 	case DDC_TRANSACTION_TYPE_I2C_OVER_AUX:
276 	case DDC_TRANSACTION_TYPE_I2C_OVER_AUX_WITH_DEFER:
277 	case DDC_TRANSACTION_TYPE_I2C_OVER_AUX_RETRY_DEFER:
278 		return true;
279 	default:
280 		break;
281 	}
282 	return false;
283 }
284 
ddc_service_set_dongle_type(struct ddc_service * ddc,enum display_dongle_type dongle_type)285 void ddc_service_set_dongle_type(struct ddc_service *ddc,
286 		enum display_dongle_type dongle_type)
287 {
288 	ddc->dongle_type = dongle_type;
289 }
290 
defer_delay_converter_wa(struct ddc_service * ddc,uint32_t defer_delay)291 static uint32_t defer_delay_converter_wa(
292 	struct ddc_service *ddc,
293 	uint32_t defer_delay)
294 {
295 	struct dc_link *link = ddc->link;
296 
297 	if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_0080E1 &&
298 		!memcmp(link->dpcd_caps.branch_dev_name,
299 			DP_DVI_CONVERTER_ID_4,
300 			sizeof(link->dpcd_caps.branch_dev_name)))
301 		return defer_delay > I2C_OVER_AUX_DEFER_WA_DELAY ?
302 			defer_delay : I2C_OVER_AUX_DEFER_WA_DELAY;
303 
304 	return defer_delay;
305 }
306 
307 #define DP_TRANSLATOR_DELAY 5
308 
get_defer_delay(struct ddc_service * ddc)309 uint32_t get_defer_delay(struct ddc_service *ddc)
310 {
311 	uint32_t defer_delay = 0;
312 
313 	switch (ddc->transaction_type) {
314 	case DDC_TRANSACTION_TYPE_I2C_OVER_AUX:
315 		if ((DISPLAY_DONGLE_DP_VGA_CONVERTER == ddc->dongle_type) ||
316 			(DISPLAY_DONGLE_DP_DVI_CONVERTER == ddc->dongle_type) ||
317 			(DISPLAY_DONGLE_DP_HDMI_CONVERTER ==
318 				ddc->dongle_type)) {
319 
320 			defer_delay = DP_TRANSLATOR_DELAY;
321 
322 			defer_delay =
323 				defer_delay_converter_wa(ddc, defer_delay);
324 
325 		} else /*sink has a delay different from an Active Converter*/
326 			defer_delay = 0;
327 		break;
328 	case DDC_TRANSACTION_TYPE_I2C_OVER_AUX_WITH_DEFER:
329 		defer_delay = DP_TRANSLATOR_DELAY;
330 		break;
331 	default:
332 		break;
333 	}
334 	return defer_delay;
335 }
336 
i2c_read(struct ddc_service * ddc,uint32_t address,uint8_t * buffer,uint32_t len)337 static bool i2c_read(
338 	struct ddc_service *ddc,
339 	uint32_t address,
340 	uint8_t *buffer,
341 	uint32_t len)
342 {
343 	uint8_t offs_data = 0;
344 	struct i2c_payload payloads[2] = {
345 		{
346 		.write = true,
347 		.address = address,
348 		.length = 1,
349 		.data = &offs_data },
350 		{
351 		.write = false,
352 		.address = address,
353 		.length = len,
354 		.data = buffer } };
355 
356 	struct i2c_command command = {
357 		.payloads = payloads,
358 		.number_of_payloads = 2,
359 		.engine = DDC_I2C_COMMAND_ENGINE,
360 		.speed = ddc->ctx->dc->caps.i2c_speed_in_khz };
361 
362 	return dm_helpers_submit_i2c(
363 			ddc->ctx,
364 			ddc->link,
365 			&command);
366 }
367 
dal_ddc_service_i2c_query_dp_dual_mode_adaptor(struct ddc_service * ddc,struct display_sink_capability * sink_cap)368 void dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
369 	struct ddc_service *ddc,
370 	struct display_sink_capability *sink_cap)
371 {
372 	uint8_t i;
373 	bool is_valid_hdmi_signature;
374 	enum display_dongle_type *dongle = &sink_cap->dongle_type;
375 	uint8_t type2_dongle_buf[DP_ADAPTOR_TYPE2_SIZE];
376 	bool is_type2_dongle = false;
377 	int retry_count = 2;
378 	struct dp_hdmi_dongle_signature_data *dongle_signature;
379 
380 	/* Assume we have no valid DP passive dongle connected */
381 	*dongle = DISPLAY_DONGLE_NONE;
382 	sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK;
383 
384 	/* Read DP-HDMI dongle I2c (no response interpreted as DP-DVI dongle)*/
385 	if (!i2c_read(
386 		ddc,
387 		DP_HDMI_DONGLE_ADDRESS,
388 		type2_dongle_buf,
389 		sizeof(type2_dongle_buf))) {
390 		/* Passive HDMI dongles can sometimes fail here without retrying*/
391 		while (retry_count > 0) {
392 			if (i2c_read(ddc,
393 				DP_HDMI_DONGLE_ADDRESS,
394 				type2_dongle_buf,
395 				sizeof(type2_dongle_buf)))
396 				break;
397 			retry_count--;
398 		}
399 		if (retry_count == 0) {
400 			*dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
401 			sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
402 
403 			CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf),
404 					"DP-DVI passive dongle %dMhz: ",
405 					DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
406 			return;
407 		}
408 	}
409 
410 	/* Check if Type 2 dongle.*/
411 	if (type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_ID] == DP_ADAPTOR_TYPE2_ID)
412 		is_type2_dongle = true;
413 
414 	dongle_signature =
415 		(struct dp_hdmi_dongle_signature_data *)type2_dongle_buf;
416 
417 	is_valid_hdmi_signature = true;
418 
419 	/* Check EOT */
420 	if (dongle_signature->eot != DP_HDMI_DONGLE_SIGNATURE_EOT) {
421 		is_valid_hdmi_signature = false;
422 	}
423 
424 	/* Check signature */
425 	for (i = 0; i < sizeof(dongle_signature->id); ++i) {
426 		/* If its not the right signature,
427 		 * skip mismatch in subversion byte.*/
428 		if (dongle_signature->id[i] !=
429 			dp_hdmi_dongle_signature_str[i] && i != 3) {
430 
431 			if (is_type2_dongle) {
432 				is_valid_hdmi_signature = false;
433 				break;
434 			}
435 
436 		}
437 	}
438 
439 	if (is_type2_dongle) {
440 		uint32_t max_tmds_clk =
441 			type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK];
442 
443 		max_tmds_clk = max_tmds_clk * 2 + max_tmds_clk / 2;
444 
445 		if (0 == max_tmds_clk ||
446 				max_tmds_clk < DP_ADAPTOR_TYPE2_MIN_TMDS_CLK ||
447 				max_tmds_clk > DP_ADAPTOR_TYPE2_MAX_TMDS_CLK) {
448 			*dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
449 
450 			CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
451 					sizeof(type2_dongle_buf),
452 					"DP-DVI passive dongle %dMhz: ",
453 					DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
454 		} else {
455 			if (is_valid_hdmi_signature == true) {
456 				*dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
457 
458 				CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
459 						sizeof(type2_dongle_buf),
460 						"Type 2 DP-HDMI passive dongle %dMhz: ",
461 						max_tmds_clk);
462 			} else {
463 				*dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
464 
465 				CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
466 						sizeof(type2_dongle_buf),
467 						"Type 2 DP-HDMI passive dongle (no signature) %dMhz: ",
468 						max_tmds_clk);
469 
470 			}
471 
472 			/* Multiply by 1000 to convert to kHz. */
473 			sink_cap->max_hdmi_pixel_clock =
474 				max_tmds_clk * 1000;
475 		}
476 
477 	} else {
478 		if (is_valid_hdmi_signature == true) {
479 			*dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
480 
481 			CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
482 					sizeof(type2_dongle_buf),
483 					"Type 1 DP-HDMI passive dongle %dMhz: ",
484 					sink_cap->max_hdmi_pixel_clock / 1000);
485 		} else {
486 			*dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
487 
488 			CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
489 					sizeof(type2_dongle_buf),
490 					"Type 1 DP-HDMI passive dongle (no signature) %dMhz: ",
491 					sink_cap->max_hdmi_pixel_clock / 1000);
492 		}
493 	}
494 
495 	return;
496 }
497 
498 enum {
499 	DP_SINK_CAP_SIZE =
500 		DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV + 1
501 };
502 
dal_ddc_service_query_ddc_data(struct ddc_service * ddc,uint32_t address,uint8_t * write_buf,uint32_t write_size,uint8_t * read_buf,uint32_t read_size)503 bool dal_ddc_service_query_ddc_data(
504 	struct ddc_service *ddc,
505 	uint32_t address,
506 	uint8_t *write_buf,
507 	uint32_t write_size,
508 	uint8_t *read_buf,
509 	uint32_t read_size)
510 {
511 	bool ret;
512 	uint32_t payload_size =
513 		dal_ddc_service_is_in_aux_transaction_mode(ddc) ?
514 			DEFAULT_AUX_MAX_DATA_SIZE : EDID_SEGMENT_SIZE;
515 
516 	uint32_t write_payloads =
517 		(write_size + payload_size - 1) / payload_size;
518 
519 	uint32_t read_payloads =
520 		(read_size + payload_size - 1) / payload_size;
521 
522 	uint32_t payloads_num = write_payloads + read_payloads;
523 
524 	if (write_size > EDID_SEGMENT_SIZE || read_size > EDID_SEGMENT_SIZE)
525 		return false;
526 
527 	/*TODO: len of payload data for i2c and aux is uint8!!!!,
528 	 *  but we want to read 256 over i2c!!!!*/
529 	if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) {
530 		struct aux_payload write_payload = {
531 			.i2c_over_aux = true,
532 			.write = true,
533 			.mot = true,
534 			.address = address,
535 			.length = write_size,
536 			.data = write_buf,
537 			.reply = NULL,
538 			.defer_delay = get_defer_delay(ddc),
539 		};
540 
541 		struct aux_payload read_payload = {
542 			.i2c_over_aux = true,
543 			.write = false,
544 			.mot = false,
545 			.address = address,
546 			.length = read_size,
547 			.data = read_buf,
548 			.reply = NULL,
549 			.defer_delay = get_defer_delay(ddc),
550 		};
551 
552 		ret = dc_link_aux_transfer_with_retries(ddc, &write_payload);
553 
554 		if (!ret)
555 			return false;
556 
557 		ret = dc_link_aux_transfer_with_retries(ddc, &read_payload);
558 	} else {
559 		struct i2c_payloads *payloads =
560 			dal_ddc_i2c_payloads_create(ddc->ctx, payloads_num);
561 
562 		struct i2c_command command = {
563 			.payloads = dal_ddc_i2c_payloads_get(payloads),
564 			.number_of_payloads = 0,
565 			.engine = DDC_I2C_COMMAND_ENGINE,
566 			.speed = ddc->ctx->dc->caps.i2c_speed_in_khz };
567 
568 		dal_ddc_i2c_payloads_add(
569 			payloads, address, write_size, write_buf, true);
570 
571 		dal_ddc_i2c_payloads_add(
572 			payloads, address, read_size, read_buf, false);
573 
574 		command.number_of_payloads =
575 			dal_ddc_i2c_payloads_get_count(payloads);
576 
577 		ret = dm_helpers_submit_i2c(
578 				ddc->ctx,
579 				ddc->link,
580 				&command);
581 
582 		dal_ddc_i2c_payloads_destroy(&payloads);
583 	}
584 
585 	return ret;
586 }
587 
588 /* dc_link_aux_transfer_raw() - Attempt to transfer
589  * the given aux payload.  This function does not perform
590  * retries or handle error states.  The reply is returned
591  * in the payload->reply and the result through
592  * *operation_result.  Returns the number of bytes transferred,
593  * or -1 on a failure.
594  */
dc_link_aux_transfer_raw(struct ddc_service * ddc,struct aux_payload * payload,enum aux_channel_operation_result * operation_result)595 int dc_link_aux_transfer_raw(struct ddc_service *ddc,
596 		struct aux_payload *payload,
597 		enum aux_channel_operation_result *operation_result)
598 {
599 	return dce_aux_transfer_raw(ddc, payload, operation_result);
600 }
601 
602 /* dc_link_aux_transfer_with_retries() - Attempt to submit an
603  * aux payload, retrying on timeouts, defers, and busy states
604  * as outlined in the DP spec.  Returns true if the request
605  * was successful.
606  *
607  * Unless you want to implement your own retry semantics, this
608  * is probably the one you want.
609  */
dc_link_aux_transfer_with_retries(struct ddc_service * ddc,struct aux_payload * payload)610 bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc,
611 		struct aux_payload *payload)
612 {
613 	return dce_aux_transfer_with_retries(ddc, payload);
614 }
615 
616 /*test only function*/
dal_ddc_service_set_ddc_pin(struct ddc_service * ddc_service,struct ddc * ddc)617 void dal_ddc_service_set_ddc_pin(
618 	struct ddc_service *ddc_service,
619 	struct ddc *ddc)
620 {
621 	ddc_service->ddc_pin = ddc;
622 }
623 
dal_ddc_service_get_ddc_pin(struct ddc_service * ddc_service)624 struct ddc *dal_ddc_service_get_ddc_pin(struct ddc_service *ddc_service)
625 {
626 	return ddc_service->ddc_pin;
627 }
628 
dal_ddc_service_write_scdc_data(struct ddc_service * ddc_service,uint32_t pix_clk,bool lte_340_scramble)629 void dal_ddc_service_write_scdc_data(struct ddc_service *ddc_service,
630 		uint32_t pix_clk,
631 		bool lte_340_scramble)
632 {
633 	bool over_340_mhz = pix_clk > 340000 ? 1 : 0;
634 	uint8_t slave_address = HDMI_SCDC_ADDRESS;
635 	uint8_t offset = HDMI_SCDC_SINK_VERSION;
636 	uint8_t sink_version = 0;
637 	uint8_t write_buffer[2] = {0};
638 	/*Lower than 340 Scramble bit from SCDC caps*/
639 
640 	dal_ddc_service_query_ddc_data(ddc_service, slave_address, &offset,
641 			sizeof(offset), &sink_version, sizeof(sink_version));
642 	if (sink_version == 1) {
643 		/*Source Version = 1*/
644 		write_buffer[0] = HDMI_SCDC_SOURCE_VERSION;
645 		write_buffer[1] = 1;
646 		dal_ddc_service_query_ddc_data(ddc_service, slave_address,
647 				write_buffer, sizeof(write_buffer), NULL, 0);
648 		/*Read Request from SCDC caps*/
649 	}
650 	write_buffer[0] = HDMI_SCDC_TMDS_CONFIG;
651 
652 	if (over_340_mhz) {
653 		write_buffer[1] = 3;
654 	} else if (lte_340_scramble) {
655 		write_buffer[1] = 1;
656 	} else {
657 		write_buffer[1] = 0;
658 	}
659 	dal_ddc_service_query_ddc_data(ddc_service, slave_address, write_buffer,
660 			sizeof(write_buffer), NULL, 0);
661 }
662 
dal_ddc_service_read_scdc_data(struct ddc_service * ddc_service)663 void dal_ddc_service_read_scdc_data(struct ddc_service *ddc_service)
664 {
665 	uint8_t slave_address = HDMI_SCDC_ADDRESS;
666 	uint8_t offset = HDMI_SCDC_TMDS_CONFIG;
667 	uint8_t tmds_config = 0;
668 
669 	dal_ddc_service_query_ddc_data(ddc_service, slave_address, &offset,
670 			sizeof(offset), &tmds_config, sizeof(tmds_config));
671 	if (tmds_config & 0x1) {
672 		union hdmi_scdc_status_flags_data status_data = { {0} };
673 		uint8_t scramble_status = 0;
674 
675 		offset = HDMI_SCDC_SCRAMBLER_STATUS;
676 		dal_ddc_service_query_ddc_data(ddc_service, slave_address,
677 				&offset, sizeof(offset), &scramble_status,
678 				sizeof(scramble_status));
679 		offset = HDMI_SCDC_STATUS_FLAGS;
680 		dal_ddc_service_query_ddc_data(ddc_service, slave_address,
681 				&offset, sizeof(offset), status_data.byte,
682 				sizeof(status_data.byte));
683 	}
684 }
685 
686