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