1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
44#define CV_SMART_DONGLE_ADDRESS 0x20
45
46#define DVI_HDMI_DONGLE_ADDRESS 0x68
47struct dvi_hdmi_dongle_signature_data {
48 int8_t vendor[3];
49 uint8_t version[2];
50 uint8_t size;
51 int8_t id[11];
52};
53
54#define DP_HDMI_DONGLE_ADDRESS 0x40
55static const uint8_t dp_hdmi_dongle_signature_str[] = "DP-HDMI ADAPTOR";
56#define DP_HDMI_DONGLE_SIGNATURE_EOT 0x04
57
58struct dp_hdmi_dongle_signature_data {
59 int8_t id[15];
60 uint8_t eot;
61};
62
63
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
76union 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
87union 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
101union 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
121struct i2c_payloads {
122 struct vector payloads;
123};
124
125struct aux_payloads {
126 struct vector payloads;
127};
128
129static 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
147static struct i2c_payload *dal_ddc_i2c_payloads_get(struct i2c_payloads *p)
148{
149 return (struct i2c_payload *)p->payloads.container;
150}
151
152static uint32_t dal_ddc_i2c_payloads_get_count(struct i2c_payloads *p)
153{
154 return p->payloads.count;
155}
156
157static 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
169void 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
190static 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
229struct 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
243static void destruct(struct ddc_service *ddc)
244{
245 if (ddc->ddc_pin)
246 dal_gpio_destroy_ddc(&ddc->ddc_pin);
247}
248
249void 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
260enum ddc_service_type dal_ddc_service_get_type(struct ddc_service *ddc)
261{
262 return DDC_SERVICE_TYPE_CONNECTOR;
263}
264
265void 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
272bool 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
285void 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
291static 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_4 &&
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
309uint32_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
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
337static 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
368void 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 struct dp_hdmi_dongle_signature_data *dongle_signature;
378
379
380 *dongle = DISPLAY_DONGLE_NONE;
381 sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK;
382
383
384 if (!i2c_read(
385 ddc,
386 DP_HDMI_DONGLE_ADDRESS,
387 type2_dongle_buf,
388 sizeof(type2_dongle_buf))) {
389 *dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
390 sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
391
392 CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf),
393 "DP-DVI passive dongle %dMhz: ",
394 DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
395 return;
396 }
397
398
399 if (type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_ID] == DP_ADAPTOR_TYPE2_ID)
400 is_type2_dongle = true;
401
402 dongle_signature =
403 (struct dp_hdmi_dongle_signature_data *)type2_dongle_buf;
404
405 is_valid_hdmi_signature = true;
406
407
408 if (dongle_signature->eot != DP_HDMI_DONGLE_SIGNATURE_EOT) {
409 is_valid_hdmi_signature = false;
410 }
411
412
413 for (i = 0; i < sizeof(dongle_signature->id); ++i) {
414
415
416 if (dongle_signature->id[i] !=
417 dp_hdmi_dongle_signature_str[i] && i != 3) {
418
419 if (is_type2_dongle) {
420 is_valid_hdmi_signature = false;
421 break;
422 }
423
424 }
425 }
426
427 if (is_type2_dongle) {
428 uint32_t max_tmds_clk =
429 type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK];
430
431 max_tmds_clk = max_tmds_clk * 2 + max_tmds_clk / 2;
432
433 if (0 == max_tmds_clk ||
434 max_tmds_clk < DP_ADAPTOR_TYPE2_MIN_TMDS_CLK ||
435 max_tmds_clk > DP_ADAPTOR_TYPE2_MAX_TMDS_CLK) {
436 *dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
437
438 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
439 sizeof(type2_dongle_buf),
440 "DP-DVI passive dongle %dMhz: ",
441 DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
442 } else {
443 if (is_valid_hdmi_signature == true) {
444 *dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
445
446 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
447 sizeof(type2_dongle_buf),
448 "Type 2 DP-HDMI passive dongle %dMhz: ",
449 max_tmds_clk);
450 } else {
451 *dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
452
453 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
454 sizeof(type2_dongle_buf),
455 "Type 2 DP-HDMI passive dongle (no signature) %dMhz: ",
456 max_tmds_clk);
457
458 }
459
460
461 sink_cap->max_hdmi_pixel_clock =
462 max_tmds_clk * 1000;
463 }
464
465 } else {
466 if (is_valid_hdmi_signature == true) {
467 *dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
468
469 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
470 sizeof(type2_dongle_buf),
471 "Type 1 DP-HDMI passive dongle %dMhz: ",
472 sink_cap->max_hdmi_pixel_clock / 1000);
473 } else {
474 *dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
475
476 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
477 sizeof(type2_dongle_buf),
478 "Type 1 DP-HDMI passive dongle (no signature) %dMhz: ",
479 sink_cap->max_hdmi_pixel_clock / 1000);
480 }
481 }
482
483 return;
484}
485
486enum {
487 DP_SINK_CAP_SIZE =
488 DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV + 1
489};
490
491bool dal_ddc_service_query_ddc_data(
492 struct ddc_service *ddc,
493 uint32_t address,
494 uint8_t *write_buf,
495 uint32_t write_size,
496 uint8_t *read_buf,
497 uint32_t read_size)
498{
499 bool ret;
500 uint32_t payload_size =
501 dal_ddc_service_is_in_aux_transaction_mode(ddc) ?
502 DEFAULT_AUX_MAX_DATA_SIZE : EDID_SEGMENT_SIZE;
503
504 uint32_t write_payloads =
505 (write_size + payload_size - 1) / payload_size;
506
507 uint32_t read_payloads =
508 (read_size + payload_size - 1) / payload_size;
509
510 uint32_t payloads_num = write_payloads + read_payloads;
511
512 if (write_size > EDID_SEGMENT_SIZE || read_size > EDID_SEGMENT_SIZE)
513 return false;
514
515
516
517 if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) {
518 struct aux_payload write_payload = {
519 .i2c_over_aux = true,
520 .write = true,
521 .mot = true,
522 .address = address,
523 .length = write_size,
524 .data = write_buf,
525 .reply = NULL,
526 .defer_delay = get_defer_delay(ddc),
527 };
528
529 struct aux_payload read_payload = {
530 .i2c_over_aux = true,
531 .write = false,
532 .mot = false,
533 .address = address,
534 .length = read_size,
535 .data = read_buf,
536 .reply = NULL,
537 .defer_delay = get_defer_delay(ddc),
538 };
539
540 ret = dc_link_aux_transfer_with_retries(ddc, &write_payload);
541
542 if (!ret)
543 return false;
544
545 ret = dc_link_aux_transfer_with_retries(ddc, &read_payload);
546 } else {
547 struct i2c_payloads *payloads =
548 dal_ddc_i2c_payloads_create(ddc->ctx, payloads_num);
549
550 struct i2c_command command = {
551 .payloads = dal_ddc_i2c_payloads_get(payloads),
552 .number_of_payloads = 0,
553 .engine = DDC_I2C_COMMAND_ENGINE,
554 .speed = ddc->ctx->dc->caps.i2c_speed_in_khz };
555
556 dal_ddc_i2c_payloads_add(
557 payloads, address, write_size, write_buf, true);
558
559 dal_ddc_i2c_payloads_add(
560 payloads, address, read_size, read_buf, false);
561
562 command.number_of_payloads =
563 dal_ddc_i2c_payloads_get_count(payloads);
564
565 ret = dm_helpers_submit_i2c(
566 ddc->ctx,
567 ddc->link,
568 &command);
569
570 dal_ddc_i2c_payloads_destroy(&payloads);
571 }
572
573 return ret;
574}
575
576
577
578
579
580
581
582
583int dc_link_aux_transfer_raw(struct ddc_service *ddc,
584 struct aux_payload *payload,
585 enum aux_channel_operation_result *operation_result)
586{
587 return dce_aux_transfer_raw(ddc, payload, operation_result);
588}
589
590
591
592
593
594
595
596
597
598bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc,
599 struct aux_payload *payload)
600{
601 return dce_aux_transfer_with_retries(ddc, payload);
602}
603
604
605void dal_ddc_service_set_ddc_pin(
606 struct ddc_service *ddc_service,
607 struct ddc *ddc)
608{
609 ddc_service->ddc_pin = ddc;
610}
611
612struct ddc *dal_ddc_service_get_ddc_pin(struct ddc_service *ddc_service)
613{
614 return ddc_service->ddc_pin;
615}
616
617void dal_ddc_service_write_scdc_data(struct ddc_service *ddc_service,
618 uint32_t pix_clk,
619 bool lte_340_scramble)
620{
621 bool over_340_mhz = pix_clk > 340000 ? 1 : 0;
622 uint8_t slave_address = HDMI_SCDC_ADDRESS;
623 uint8_t offset = HDMI_SCDC_SINK_VERSION;
624 uint8_t sink_version = 0;
625 uint8_t write_buffer[2] = {0};
626
627
628 dal_ddc_service_query_ddc_data(ddc_service, slave_address, &offset,
629 sizeof(offset), &sink_version, sizeof(sink_version));
630 if (sink_version == 1) {
631
632 write_buffer[0] = HDMI_SCDC_SOURCE_VERSION;
633 write_buffer[1] = 1;
634 dal_ddc_service_query_ddc_data(ddc_service, slave_address,
635 write_buffer, sizeof(write_buffer), NULL, 0);
636
637 }
638 write_buffer[0] = HDMI_SCDC_TMDS_CONFIG;
639
640 if (over_340_mhz) {
641 write_buffer[1] = 3;
642 } else if (lte_340_scramble) {
643 write_buffer[1] = 1;
644 } else {
645 write_buffer[1] = 0;
646 }
647 dal_ddc_service_query_ddc_data(ddc_service, slave_address, write_buffer,
648 sizeof(write_buffer), NULL, 0);
649}
650
651void dal_ddc_service_read_scdc_data(struct ddc_service *ddc_service)
652{
653 uint8_t slave_address = HDMI_SCDC_ADDRESS;
654 uint8_t offset = HDMI_SCDC_TMDS_CONFIG;
655 uint8_t tmds_config = 0;
656
657 dal_ddc_service_query_ddc_data(ddc_service, slave_address, &offset,
658 sizeof(offset), &tmds_config, sizeof(tmds_config));
659 if (tmds_config & 0x1) {
660 union hdmi_scdc_status_flags_data status_data = { {0} };
661 uint8_t scramble_status = 0;
662
663 offset = HDMI_SCDC_SCRAMBLER_STATUS;
664 dal_ddc_service_query_ddc_data(ddc_service, slave_address,
665 &offset, sizeof(offset), &scramble_status,
666 sizeof(scramble_status));
667 offset = HDMI_SCDC_STATUS_FLAGS;
668 dal_ddc_service_query_ddc_data(ddc_service, slave_address,
669 &offset, sizeof(offset), status_data.byte,
670 sizeof(status_data.byte));
671 }
672}
673
674