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 - %s finished successfully.\n", __func__);
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 - %s failed.\n", __func__);
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 
578