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