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