drm/amd/display: break down dc_link.c
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / link / link_factory.c
1 /*
2  * Copyright 2023 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 /* FILE POLICY AND INTENDED USAGE:
27  * This file owns the creation/destruction of link structure.
28  */
29 #include "link_factory.h"
30 #include "protocols/link_ddc.h"
31 #include "protocols/link_edp_panel_control.h"
32 #include "protocols/link_hpd.h"
33 #include "gpio_service_interface.h"
34 #include "atomfirmware.h"
35
36 #define DC_LOGGER_INIT(logger)
37
38 #define LINK_INFO(...) \
39         DC_LOG_HW_HOTPLUG(  \
40                 __VA_ARGS__)
41
42 static enum transmitter translate_encoder_to_transmitter(struct graphics_object_id encoder)
43 {
44         switch (encoder.id) {
45         case ENCODER_ID_INTERNAL_UNIPHY:
46                 switch (encoder.enum_id) {
47                 case ENUM_ID_1:
48                         return TRANSMITTER_UNIPHY_A;
49                 case ENUM_ID_2:
50                         return TRANSMITTER_UNIPHY_B;
51                 default:
52                         return TRANSMITTER_UNKNOWN;
53                 }
54         break;
55         case ENCODER_ID_INTERNAL_UNIPHY1:
56                 switch (encoder.enum_id) {
57                 case ENUM_ID_1:
58                         return TRANSMITTER_UNIPHY_C;
59                 case ENUM_ID_2:
60                         return TRANSMITTER_UNIPHY_D;
61                 default:
62                         return TRANSMITTER_UNKNOWN;
63                 }
64         break;
65         case ENCODER_ID_INTERNAL_UNIPHY2:
66                 switch (encoder.enum_id) {
67                 case ENUM_ID_1:
68                         return TRANSMITTER_UNIPHY_E;
69                 case ENUM_ID_2:
70                         return TRANSMITTER_UNIPHY_F;
71                 default:
72                         return TRANSMITTER_UNKNOWN;
73                 }
74         break;
75         case ENCODER_ID_INTERNAL_UNIPHY3:
76                 switch (encoder.enum_id) {
77                 case ENUM_ID_1:
78                         return TRANSMITTER_UNIPHY_G;
79                 default:
80                         return TRANSMITTER_UNKNOWN;
81                 }
82         break;
83         case ENCODER_ID_EXTERNAL_NUTMEG:
84                 switch (encoder.enum_id) {
85                 case ENUM_ID_1:
86                         return TRANSMITTER_NUTMEG_CRT;
87                 default:
88                         return TRANSMITTER_UNKNOWN;
89                 }
90         break;
91         case ENCODER_ID_EXTERNAL_TRAVIS:
92                 switch (encoder.enum_id) {
93                 case ENUM_ID_1:
94                         return TRANSMITTER_TRAVIS_CRT;
95                 case ENUM_ID_2:
96                         return TRANSMITTER_TRAVIS_LCD;
97                 default:
98                         return TRANSMITTER_UNKNOWN;
99                 }
100         break;
101         default:
102                 return TRANSMITTER_UNKNOWN;
103         }
104 }
105
106 static void link_destruct(struct dc_link *link)
107 {
108         int i;
109
110         if (link->hpd_gpio) {
111                 dal_gpio_destroy_irq(&link->hpd_gpio);
112                 link->hpd_gpio = NULL;
113         }
114
115         if (link->ddc)
116                 link_destroy_ddc_service(&link->ddc);
117
118         if (link->panel_cntl)
119                 link->panel_cntl->funcs->destroy(&link->panel_cntl);
120
121         if (link->link_enc) {
122                 /* Update link encoder resource tracking variables. These are used for
123                  * the dynamic assignment of link encoders to streams. Virtual links
124                  * are not assigned encoder resources on creation.
125                  */
126                 if (link->link_id.id != CONNECTOR_ID_VIRTUAL) {
127                         link->dc->res_pool->link_encoders[link->eng_id - ENGINE_ID_DIGA] = NULL;
128                         link->dc->res_pool->dig_link_enc_count--;
129                 }
130                 link->link_enc->funcs->destroy(&link->link_enc);
131         }
132
133         if (link->local_sink)
134                 dc_sink_release(link->local_sink);
135
136         for (i = 0; i < link->sink_count; ++i)
137                 dc_sink_release(link->remote_sinks[i]);
138 }
139
140 static enum channel_id get_ddc_line(struct dc_link *link)
141 {
142         struct ddc *ddc;
143         enum channel_id channel;
144
145                 channel = CHANNEL_ID_UNKNOWN;
146
147         ddc = get_ddc_pin(link->ddc);
148
149         if (ddc) {
150                 switch (dal_ddc_get_line(ddc)) {
151                 case GPIO_DDC_LINE_DDC1:
152                         channel = CHANNEL_ID_DDC1;
153                         break;
154                 case GPIO_DDC_LINE_DDC2:
155                         channel = CHANNEL_ID_DDC2;
156                         break;
157                 case GPIO_DDC_LINE_DDC3:
158                         channel = CHANNEL_ID_DDC3;
159                         break;
160                 case GPIO_DDC_LINE_DDC4:
161                         channel = CHANNEL_ID_DDC4;
162                         break;
163                 case GPIO_DDC_LINE_DDC5:
164                         channel = CHANNEL_ID_DDC5;
165                         break;
166                 case GPIO_DDC_LINE_DDC6:
167                         channel = CHANNEL_ID_DDC6;
168                         break;
169                 case GPIO_DDC_LINE_DDC_VGA:
170                         channel = CHANNEL_ID_DDC_VGA;
171                         break;
172                 case GPIO_DDC_LINE_I2C_PAD:
173                         channel = CHANNEL_ID_I2C_PAD;
174                         break;
175                 default:
176                         BREAK_TO_DEBUGGER();
177                         break;
178                 }
179         }
180
181         return channel;
182 }
183
184 static bool dc_link_construct_phy(struct dc_link *link,
185                               const struct link_init_data *init_params)
186 {
187         uint8_t i;
188         struct ddc_service_init_data ddc_service_init_data = { 0 };
189         struct dc_context *dc_ctx = init_params->ctx;
190         struct encoder_init_data enc_init_data = { 0 };
191         struct panel_cntl_init_data panel_cntl_init_data = { 0 };
192         struct integrated_info info = { 0 };
193         struct dc_bios *bios = init_params->dc->ctx->dc_bios;
194         const struct dc_vbios_funcs *bp_funcs = bios->funcs;
195         struct bp_disp_connector_caps_info disp_connect_caps_info = { 0 };
196
197         DC_LOGGER_INIT(dc_ctx->logger);
198
199                 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
200                 link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID;
201         link->link_status.dpcd_caps = &link->dpcd_caps;
202
203         link->dc = init_params->dc;
204         link->ctx = dc_ctx;
205         link->link_index = init_params->link_index;
206
207         memset(&link->preferred_training_settings, 0,
208                sizeof(struct dc_link_training_overrides));
209         memset(&link->preferred_link_setting, 0,
210                sizeof(struct dc_link_settings));
211
212         link->link_id =
213                 bios->funcs->get_connector_id(bios, init_params->connector_index);
214
215         link->ep_type = DISPLAY_ENDPOINT_PHY;
216
217         DC_LOG_DC("BIOS object table - link_id: %d", link->link_id.id);
218
219         if (bios->funcs->get_disp_connector_caps_info) {
220                 bios->funcs->get_disp_connector_caps_info(bios, link->link_id, &disp_connect_caps_info);
221                 link->is_internal_display = disp_connect_caps_info.INTERNAL_DISPLAY;
222                 DC_LOG_DC("BIOS object table - is_internal_display: %d", link->is_internal_display);
223         }
224
225         if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
226                 dm_output_to_console("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
227                                      __func__, init_params->connector_index,
228                                      link->link_id.type, OBJECT_TYPE_CONNECTOR);
229                 goto create_fail;
230         }
231
232         if (link->dc->res_pool->funcs->link_init)
233                 link->dc->res_pool->funcs->link_init(link);
234
235         link->hpd_gpio = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id,
236                                       link->ctx->gpio_service);
237
238         if (link->hpd_gpio) {
239                 dal_gpio_open(link->hpd_gpio, GPIO_MODE_INTERRUPT);
240                 dal_gpio_unlock_pin(link->hpd_gpio);
241                 link->irq_source_hpd = dal_irq_get_source(link->hpd_gpio);
242
243                 DC_LOG_DC("BIOS object table - hpd_gpio id: %d", link->hpd_gpio->id);
244                 DC_LOG_DC("BIOS object table - hpd_gpio en: %d", link->hpd_gpio->en);
245         }
246
247         switch (link->link_id.id) {
248         case CONNECTOR_ID_HDMI_TYPE_A:
249                 link->connector_signal = SIGNAL_TYPE_HDMI_TYPE_A;
250
251                 break;
252         case CONNECTOR_ID_SINGLE_LINK_DVID:
253         case CONNECTOR_ID_SINGLE_LINK_DVII:
254                 link->connector_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
255                 break;
256         case CONNECTOR_ID_DUAL_LINK_DVID:
257         case CONNECTOR_ID_DUAL_LINK_DVII:
258                 link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
259                 break;
260         case CONNECTOR_ID_DISPLAY_PORT:
261         case CONNECTOR_ID_USBC:
262                 link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
263
264                 if (link->hpd_gpio)
265                         link->irq_source_hpd_rx =
266                                         dal_irq_get_rx_source(link->hpd_gpio);
267
268                 break;
269         case CONNECTOR_ID_EDP:
270                 link->connector_signal = SIGNAL_TYPE_EDP;
271
272                 if (link->hpd_gpio) {
273                         if (!link->dc->config.allow_edp_hotplug_detection)
274                                 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
275
276                         switch (link->dc->config.allow_edp_hotplug_detection) {
277                         case 1: // only the 1st eDP handles hotplug
278                                 if (link->link_index == 0)
279                                         link->irq_source_hpd_rx =
280                                                 dal_irq_get_rx_source(link->hpd_gpio);
281                                 else
282                                         link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
283                                 break;
284                         case 2: // only the 2nd eDP handles hotplug
285                                 if (link->link_index == 1)
286                                         link->irq_source_hpd_rx =
287                                                 dal_irq_get_rx_source(link->hpd_gpio);
288                                 else
289                                         link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
290                                 break;
291                         default:
292                                 break;
293                         }
294                 }
295
296                 break;
297         case CONNECTOR_ID_LVDS:
298                 link->connector_signal = SIGNAL_TYPE_LVDS;
299                 break;
300         default:
301                 DC_LOG_WARNING("Unsupported Connector type:%d!\n",
302                                link->link_id.id);
303                 goto create_fail;
304         }
305
306         /* TODO: #DAL3 Implement id to str function.*/
307         LINK_INFO("Connector[%d] description:"
308                   "signal %d\n",
309                   init_params->connector_index,
310                   link->connector_signal);
311
312         ddc_service_init_data.ctx = link->ctx;
313         ddc_service_init_data.id = link->link_id;
314         ddc_service_init_data.link = link;
315         link->ddc = link_create_ddc_service(&ddc_service_init_data);
316
317         if (!link->ddc) {
318                 DC_ERROR("Failed to create ddc_service!\n");
319                 goto ddc_create_fail;
320         }
321
322         if (!link->ddc->ddc_pin) {
323                 DC_ERROR("Failed to get I2C info for connector!\n");
324                 goto ddc_create_fail;
325         }
326
327         link->ddc_hw_inst =
328                 dal_ddc_get_line(get_ddc_pin(link->ddc));
329
330
331         if (link->dc->res_pool->funcs->panel_cntl_create &&
332                 (link->link_id.id == CONNECTOR_ID_EDP ||
333                         link->link_id.id == CONNECTOR_ID_LVDS)) {
334                 panel_cntl_init_data.ctx = dc_ctx;
335                 panel_cntl_init_data.inst =
336                         panel_cntl_init_data.ctx->dc_edp_id_count;
337                 link->panel_cntl =
338                         link->dc->res_pool->funcs->panel_cntl_create(
339                                                                 &panel_cntl_init_data);
340                 panel_cntl_init_data.ctx->dc_edp_id_count++;
341
342                 if (link->panel_cntl == NULL) {
343                         DC_ERROR("Failed to create link panel_cntl!\n");
344                         goto panel_cntl_create_fail;
345                 }
346         }
347
348         enc_init_data.ctx = dc_ctx;
349         bp_funcs->get_src_obj(dc_ctx->dc_bios, link->link_id, 0,
350                               &enc_init_data.encoder);
351         enc_init_data.connector = link->link_id;
352         enc_init_data.channel = get_ddc_line(link);
353         enc_init_data.hpd_source = get_hpd_line(link);
354
355         link->hpd_src = enc_init_data.hpd_source;
356
357         enc_init_data.transmitter =
358                 translate_encoder_to_transmitter(enc_init_data.encoder);
359         link->link_enc =
360                 link->dc->res_pool->funcs->link_enc_create(dc_ctx, &enc_init_data);
361
362         DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C);
363         DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE);
364
365         if (!link->link_enc) {
366                 DC_ERROR("Failed to create link encoder!\n");
367                 goto link_enc_create_fail;
368         }
369
370         /* Update link encoder tracking variables. These are used for the dynamic
371          * assignment of link encoders to streams.
372          */
373         link->eng_id = link->link_enc->preferred_engine;
374         link->dc->res_pool->link_encoders[link->eng_id - ENGINE_ID_DIGA] = link->link_enc;
375         link->dc->res_pool->dig_link_enc_count++;
376
377         link->link_enc_hw_inst = link->link_enc->transmitter;
378         for (i = 0; i < 4; i++) {
379                 if (bp_funcs->get_device_tag(dc_ctx->dc_bios,
380                                              link->link_id, i,
381                                              &link->device_tag) != BP_RESULT_OK) {
382                         DC_ERROR("Failed to find device tag!\n");
383                         goto device_tag_fail;
384                 }
385
386                 /* Look for device tag that matches connector signal,
387                  * CRT for rgb, LCD for other supported signal tyes
388                  */
389                 if (!bp_funcs->is_device_id_supported(dc_ctx->dc_bios,
390                                                       link->device_tag.dev_id))
391                         continue;
392                 if (link->device_tag.dev_id.device_type == DEVICE_TYPE_CRT &&
393                     link->connector_signal != SIGNAL_TYPE_RGB)
394                         continue;
395                 if (link->device_tag.dev_id.device_type == DEVICE_TYPE_LCD &&
396                     link->connector_signal == SIGNAL_TYPE_RGB)
397                         continue;
398
399                 DC_LOG_DC("BIOS object table - device_tag.acpi_device: %d", link->device_tag.acpi_device);
400                 DC_LOG_DC("BIOS object table - device_tag.dev_id.device_type: %d", link->device_tag.dev_id.device_type);
401                 DC_LOG_DC("BIOS object table - device_tag.dev_id.enum_id: %d", link->device_tag.dev_id.enum_id);
402                 break;
403         }
404
405         if (bios->integrated_info)
406                 info = *bios->integrated_info;
407
408         /* Look for channel mapping corresponding to connector and device tag */
409         for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; i++) {
410                 struct external_display_path *path =
411                         &info.ext_disp_conn_info.path[i];
412
413                 if (path->device_connector_id.enum_id == link->link_id.enum_id &&
414                     path->device_connector_id.id == link->link_id.id &&
415                     path->device_connector_id.type == link->link_id.type) {
416                         if (link->device_tag.acpi_device != 0 &&
417                             path->device_acpi_enum == link->device_tag.acpi_device) {
418                                 link->ddi_channel_mapping = path->channel_mapping;
419                                 link->chip_caps = path->caps;
420                                 DC_LOG_DC("BIOS object table - ddi_channel_mapping: 0x%04X", link->ddi_channel_mapping.raw);
421                                 DC_LOG_DC("BIOS object table - chip_caps: %d", link->chip_caps);
422                         } else if (path->device_tag ==
423                                    link->device_tag.dev_id.raw_device_tag) {
424                                 link->ddi_channel_mapping = path->channel_mapping;
425                                 link->chip_caps = path->caps;
426                                 DC_LOG_DC("BIOS object table - ddi_channel_mapping: 0x%04X", link->ddi_channel_mapping.raw);
427                                 DC_LOG_DC("BIOS object table - chip_caps: %d", link->chip_caps);
428                         }
429
430                         if (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) {
431                                 link->bios_forced_drive_settings.VOLTAGE_SWING =
432                                                 (info.ext_disp_conn_info.fixdpvoltageswing & 0x3);
433                                 link->bios_forced_drive_settings.PRE_EMPHASIS =
434                                                 ((info.ext_disp_conn_info.fixdpvoltageswing >> 2) & 0x3);
435                         }
436
437                         break;
438                 }
439         }
440
441         if (bios->funcs->get_atom_dc_golden_table)
442                 bios->funcs->get_atom_dc_golden_table(bios);
443
444         /*
445          * TODO check if GPIO programmed correctly
446          *
447          * If GPIO isn't programmed correctly HPD might not rise or drain
448          * fast enough, leading to bounces.
449          */
450         program_hpd_filter(link);
451
452         link->psr_settings.psr_vtotal_control_support = false;
453         link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
454
455         DC_LOG_DC("BIOS object table - dc_link_contruct finished successfully.\n");
456         return true;
457 device_tag_fail:
458         link->link_enc->funcs->destroy(&link->link_enc);
459 link_enc_create_fail:
460         if (link->panel_cntl != NULL)
461                 link->panel_cntl->funcs->destroy(&link->panel_cntl);
462 panel_cntl_create_fail:
463         link_destroy_ddc_service(&link->ddc);
464 ddc_create_fail:
465 create_fail:
466
467         if (link->hpd_gpio) {
468                 dal_gpio_destroy_irq(&link->hpd_gpio);
469                 link->hpd_gpio = NULL;
470         }
471
472         DC_LOG_DC("BIOS object table - dc_link_contruct failed.\n");
473         return false;
474 }
475
476 static bool dc_link_construct_dpia(struct dc_link *link,
477                               const struct link_init_data *init_params)
478 {
479         struct ddc_service_init_data ddc_service_init_data = { 0 };
480         struct dc_context *dc_ctx = init_params->ctx;
481
482         DC_LOGGER_INIT(dc_ctx->logger);
483
484         /* Initialized irq source for hpd and hpd rx */
485         link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
486         link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID;
487         link->link_status.dpcd_caps = &link->dpcd_caps;
488
489         link->dc = init_params->dc;
490         link->ctx = dc_ctx;
491         link->link_index = init_params->link_index;
492
493         memset(&link->preferred_training_settings, 0,
494                sizeof(struct dc_link_training_overrides));
495         memset(&link->preferred_link_setting, 0,
496                sizeof(struct dc_link_settings));
497
498         /* Dummy Init for linkid */
499         link->link_id.type = OBJECT_TYPE_CONNECTOR;
500         link->link_id.id = CONNECTOR_ID_DISPLAY_PORT;
501         link->link_id.enum_id = ENUM_ID_1 + init_params->connector_index;
502         link->is_internal_display = false;
503         link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
504         LINK_INFO("Connector[%d] description:signal %d\n",
505                   init_params->connector_index,
506                   link->connector_signal);
507
508         link->ep_type = DISPLAY_ENDPOINT_USB4_DPIA;
509         link->is_dig_mapping_flexible = true;
510
511         /* TODO: Initialize link : funcs->link_init */
512
513         ddc_service_init_data.ctx = link->ctx;
514         ddc_service_init_data.id = link->link_id;
515         ddc_service_init_data.link = link;
516         /* Set indicator for dpia link so that ddc wont be created */
517         ddc_service_init_data.is_dpia_link = true;
518
519         link->ddc = link_create_ddc_service(&ddc_service_init_data);
520         if (!link->ddc) {
521                 DC_ERROR("Failed to create ddc_service!\n");
522                 goto ddc_create_fail;
523         }
524
525         /* Set dpia port index : 0 to number of dpia ports */
526         link->ddc_hw_inst = init_params->connector_index;
527
528         /* TODO: Create link encoder */
529
530         link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
531
532         /* Some docks seem to NAK I2C writes to segment pointer with mot=0. */
533         link->wa_flags.dp_mot_reset_segment = true;
534
535         return true;
536
537 ddc_create_fail:
538         return false;
539 }
540
541 static bool link_construct(struct dc_link *link,
542                               const struct link_init_data *init_params)
543 {
544         /* Handle dpia case */
545         if (init_params->is_dpia_link == true)
546                 return dc_link_construct_dpia(link, init_params);
547         else
548                 return dc_link_construct_phy(link, init_params);
549 }
550
551 struct dc_link *link_create(const struct link_init_data *init_params)
552 {
553         struct dc_link *link =
554                         kzalloc(sizeof(*link), GFP_KERNEL);
555
556         if (NULL == link)
557                 goto alloc_fail;
558
559         if (false == link_construct(link, init_params))
560                 goto construct_fail;
561
562         return link;
563
564 construct_fail:
565         kfree(link);
566
567 alloc_fail:
568         return NULL;
569 }
570
571 void link_destroy(struct dc_link **link)
572 {
573         link_destruct(*link);
574         kfree(*link);
575         *link = NULL;
576 }
577