]> Git Repo - J-linux.git/blob - drivers/gpu/drm/amd/display/dc/link/link_factory.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.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 "link_detection.h"
31 #include "link_resource.h"
32 #include "link_validation.h"
33 #include "link_dpms.h"
34 #include "accessories/link_dp_cts.h"
35 #include "accessories/link_dp_trace.h"
36 #include "protocols/link_ddc.h"
37 #include "protocols/link_dp_capability.h"
38 #include "protocols/link_dp_dpia_bw.h"
39 #include "protocols/link_dp_dpia.h"
40 #include "protocols/link_dp_irq_handler.h"
41 #include "protocols/link_dp_phy.h"
42 #include "protocols/link_dp_training.h"
43 #include "protocols/link_edp_panel_control.h"
44 #include "protocols/link_hpd.h"
45 #include "gpio_service_interface.h"
46 #include "atomfirmware.h"
47
48 #define DC_LOGGER \
49         dc_ctx->logger
50 #define DC_LOGGER_INIT(logger)
51
52 #define LINK_INFO(...) \
53         DC_LOG_HW_HOTPLUG(  \
54                 __VA_ARGS__)
55
56 /* link factory owns the creation/destruction of link structures. */
57 static void construct_link_service_factory(struct link_service *link_srv)
58 {
59
60         link_srv->create_link = link_create;
61         link_srv->destroy_link = link_destroy;
62 }
63
64 /* link_detection manages link detection states and receiver states by using
65  * various link protocols. It also provides helper functions to interpret
66  * certain capabilities or status based on the states it manages or retrieve
67  * them directly from connected receivers.
68  */
69 static void construct_link_service_detection(struct link_service *link_srv)
70 {
71         link_srv->detect_link = link_detect;
72         link_srv->detect_connection_type = link_detect_connection_type;
73         link_srv->add_remote_sink = link_add_remote_sink;
74         link_srv->remove_remote_sink = link_remove_remote_sink;
75         link_srv->get_hpd_state = link_get_hpd_state;
76         link_srv->get_hpd_gpio = link_get_hpd_gpio;
77         link_srv->enable_hpd = link_enable_hpd;
78         link_srv->disable_hpd = link_disable_hpd;
79         link_srv->enable_hpd_filter = link_enable_hpd_filter;
80         link_srv->reset_cur_dp_mst_topology = link_reset_cur_dp_mst_topology;
81         link_srv->get_status = link_get_status;
82         link_srv->is_hdcp1x_supported = link_is_hdcp14;
83         link_srv->is_hdcp2x_supported = link_is_hdcp22;
84         link_srv->clear_dprx_states = link_clear_dprx_states;
85 }
86
87 /* link resource implements accessors to link resource. */
88 static void construct_link_service_resource(struct link_service *link_srv)
89 {
90         link_srv->get_cur_res_map = link_get_cur_res_map;
91         link_srv->restore_res_map = link_restore_res_map;
92         link_srv->get_cur_link_res = link_get_cur_link_res;
93 }
94
95 /* link validation owns timing validation against various link limitations. (ex.
96  * link bandwidth, receiver capability or our hardware capability) It also
97  * provides helper functions exposing bandwidth formulas used in validation.
98  */
99 static void construct_link_service_validation(struct link_service *link_srv)
100 {
101         link_srv->validate_mode_timing = link_validate_mode_timing;
102         link_srv->dp_link_bandwidth_kbps = dp_link_bandwidth_kbps;
103         link_srv->validate_dpia_bandwidth = link_validate_dpia_bandwidth;
104 }
105
106 /* link dpms owns the programming sequence of stream's dpms state associated
107  * with the link and link's enable/disable sequences as result of the stream's
108  * dpms state change.
109  */
110 static void construct_link_service_dpms(struct link_service *link_srv)
111 {
112         link_srv->set_dpms_on = link_set_dpms_on;
113         link_srv->set_dpms_off = link_set_dpms_off;
114         link_srv->resume = link_resume;
115         link_srv->blank_all_dp_displays = link_blank_all_dp_displays;
116         link_srv->blank_all_edp_displays = link_blank_all_edp_displays;
117         link_srv->blank_dp_stream = link_blank_dp_stream;
118         link_srv->increase_mst_payload = link_increase_mst_payload;
119         link_srv->reduce_mst_payload = link_reduce_mst_payload;
120         link_srv->set_dsc_on_stream = link_set_dsc_on_stream;
121         link_srv->set_dsc_enable = link_set_dsc_enable;
122         link_srv->update_dsc_config = link_update_dsc_config;
123 }
124
125 /* link ddc implements generic display communication protocols such as i2c, aux
126  * and scdc. It should not contain any specific applications of these
127  * protocols such as display capability query, detection, or handshaking such as
128  * link training.
129  */
130 static void construct_link_service_ddc(struct link_service *link_srv)
131 {
132         link_srv->create_ddc_service = link_create_ddc_service;
133         link_srv->destroy_ddc_service = link_destroy_ddc_service;
134         link_srv->query_ddc_data = link_query_ddc_data;
135         link_srv->aux_transfer_raw = link_aux_transfer_raw;
136         link_srv->configure_fixed_vs_pe_retimer = link_configure_fixed_vs_pe_retimer;
137         link_srv->aux_transfer_with_retries_no_mutex =
138                         link_aux_transfer_with_retries_no_mutex;
139         link_srv->is_in_aux_transaction_mode = link_is_in_aux_transaction_mode;
140         link_srv->get_aux_defer_delay = link_get_aux_defer_delay;
141 }
142
143 /* link dp capability implements dp specific link capability retrieval sequence.
144  * It is responsible for retrieving, parsing, overriding, deciding capability
145  * obtained from dp link. Link capability consists of encoders, DPRXs, cables,
146  * retimers, usb and all other possible backend capabilities.
147  */
148 static void construct_link_service_dp_capability(struct link_service *link_srv)
149 {
150         link_srv->dp_is_sink_present = dp_is_sink_present;
151         link_srv->dp_is_fec_supported = dp_is_fec_supported;
152         link_srv->dp_is_128b_132b_signal = dp_is_128b_132b_signal;
153         link_srv->dp_get_max_link_enc_cap = dp_get_max_link_enc_cap;
154         link_srv->dp_get_verified_link_cap = dp_get_verified_link_cap;
155         link_srv->dp_get_encoding_format = link_dp_get_encoding_format;
156         link_srv->dp_should_enable_fec = dp_should_enable_fec;
157         link_srv->dp_decide_link_settings = link_decide_link_settings;
158         link_srv->mst_decide_link_encoding_format =
159                         mst_decide_link_encoding_format;
160         link_srv->edp_decide_link_settings = edp_decide_link_settings;
161         link_srv->bw_kbps_from_raw_frl_link_rate_data =
162                         link_bw_kbps_from_raw_frl_link_rate_data;
163         link_srv->dp_overwrite_extended_receiver_cap =
164                         dp_overwrite_extended_receiver_cap;
165         link_srv->dp_decide_lttpr_mode = dp_decide_lttpr_mode;
166 }
167
168 /* link dp phy/dpia implements basic dp phy/dpia functionality such as
169  * enable/disable output and set lane/drive settings. It is responsible for
170  * maintaining and update software state representing current phy/dpia status
171  * such as current link settings.
172  */
173 static void construct_link_service_dp_phy_or_dpia(struct link_service *link_srv)
174 {
175         link_srv->dpia_handle_usb4_bandwidth_allocation_for_link =
176                         dpia_handle_usb4_bandwidth_allocation_for_link;
177         link_srv->dpia_handle_bw_alloc_response = dpia_handle_bw_alloc_response;
178         link_srv->dp_set_drive_settings = dp_set_drive_settings;
179         link_srv->dpcd_write_rx_power_ctrl = dpcd_write_rx_power_ctrl;
180 }
181
182 /* link dp irq handler implements DP HPD short pulse handling sequence according
183  * to DP specifications
184  */
185 static void construct_link_service_dp_irq_handler(struct link_service *link_srv)
186 {
187         link_srv->dp_parse_link_loss_status = dp_parse_link_loss_status;
188         link_srv->dp_should_allow_hpd_rx_irq = dp_should_allow_hpd_rx_irq;
189         link_srv->dp_handle_link_loss = dp_handle_link_loss;
190         link_srv->dp_read_hpd_rx_irq_data = dp_read_hpd_rx_irq_data;
191         link_srv->dp_handle_hpd_rx_irq = dp_handle_hpd_rx_irq;
192 }
193
194 /* link edp panel control implements retrieval and configuration of eDP panel
195  * features such as PSR and ABM and it also manages specs defined eDP panel
196  * power sequences.
197  */
198 static void construct_link_service_edp_panel_control(struct link_service *link_srv)
199 {
200         link_srv->edp_panel_backlight_power_on = edp_panel_backlight_power_on;
201         link_srv->edp_get_backlight_level = edp_get_backlight_level;
202         link_srv->edp_get_backlight_level_nits = edp_get_backlight_level_nits;
203         link_srv->edp_set_backlight_level = edp_set_backlight_level;
204         link_srv->edp_set_backlight_level_nits = edp_set_backlight_level_nits;
205         link_srv->edp_get_target_backlight_pwm = edp_get_target_backlight_pwm;
206         link_srv->edp_get_psr_state = edp_get_psr_state;
207         link_srv->edp_set_psr_allow_active = edp_set_psr_allow_active;
208         link_srv->edp_setup_psr = edp_setup_psr;
209         link_srv->edp_set_sink_vtotal_in_psr_active =
210                         edp_set_sink_vtotal_in_psr_active;
211         link_srv->edp_get_psr_residency = edp_get_psr_residency;
212
213         link_srv->edp_get_replay_state = edp_get_replay_state;
214         link_srv->edp_set_replay_allow_active = edp_set_replay_allow_active;
215         link_srv->edp_setup_replay = edp_setup_replay;
216         link_srv->edp_send_replay_cmd = edp_send_replay_cmd;
217         link_srv->edp_set_coasting_vtotal = edp_set_coasting_vtotal;
218         link_srv->edp_replay_residency = edp_replay_residency;
219         link_srv->edp_set_replay_power_opt_and_coasting_vtotal = edp_set_replay_power_opt_and_coasting_vtotal;
220
221         link_srv->edp_wait_for_t12 = edp_wait_for_t12;
222         link_srv->edp_is_ilr_optimization_required =
223                         edp_is_ilr_optimization_required;
224         link_srv->edp_backlight_enable_aux = edp_backlight_enable_aux;
225         link_srv->edp_add_delay_for_T9 = edp_add_delay_for_T9;
226         link_srv->edp_receiver_ready_T9 = edp_receiver_ready_T9;
227         link_srv->edp_receiver_ready_T7 = edp_receiver_ready_T7;
228         link_srv->edp_power_alpm_dpcd_enable = edp_power_alpm_dpcd_enable;
229         link_srv->edp_set_panel_power = edp_set_panel_power;
230 }
231
232 /* link dp cts implements dp compliance test automation protocols and manual
233  * testing interfaces for debugging and certification purpose.
234  */
235 static void construct_link_service_dp_cts(struct link_service *link_srv)
236 {
237         link_srv->dp_handle_automated_test = dp_handle_automated_test;
238         link_srv->dp_set_test_pattern = dp_set_test_pattern;
239         link_srv->dp_set_preferred_link_settings =
240                         dp_set_preferred_link_settings;
241         link_srv->dp_set_preferred_training_settings =
242                         dp_set_preferred_training_settings;
243 }
244
245 /* link dp trace implements tracing interfaces for tracking major dp sequences
246  * including execution status and timestamps
247  */
248 static void construct_link_service_dp_trace(struct link_service *link_srv)
249 {
250         link_srv->dp_trace_is_initialized = dp_trace_is_initialized;
251         link_srv->dp_trace_set_is_logged_flag = dp_trace_set_is_logged_flag;
252         link_srv->dp_trace_is_logged = dp_trace_is_logged;
253         link_srv->dp_trace_get_lt_end_timestamp = dp_trace_get_lt_end_timestamp;
254         link_srv->dp_trace_get_lt_counts = dp_trace_get_lt_counts;
255         link_srv->dp_trace_get_link_loss_count = dp_trace_get_link_loss_count;
256         link_srv->dp_trace_set_edp_power_timestamp =
257                         dp_trace_set_edp_power_timestamp;
258         link_srv->dp_trace_get_edp_poweron_timestamp =
259                         dp_trace_get_edp_poweron_timestamp;
260         link_srv->dp_trace_get_edp_poweroff_timestamp =
261                         dp_trace_get_edp_poweroff_timestamp;
262         link_srv->dp_trace_source_sequence = dp_trace_source_sequence;
263 }
264
265 static void construct_link_service(struct link_service *link_srv)
266 {
267         /* All link service functions should fall under some sub categories.
268          * If a new function doesn't perfectly fall under an existing sub
269          * category, it must be that you are either adding a whole new aspect of
270          * responsibility to link service or something doesn't belong to link
271          * service. In that case please contact the arch owner to arrange a
272          * design review meeting.
273          */
274         construct_link_service_factory(link_srv);
275         construct_link_service_detection(link_srv);
276         construct_link_service_resource(link_srv);
277         construct_link_service_validation(link_srv);
278         construct_link_service_dpms(link_srv);
279         construct_link_service_ddc(link_srv);
280         construct_link_service_dp_capability(link_srv);
281         construct_link_service_dp_phy_or_dpia(link_srv);
282         construct_link_service_dp_irq_handler(link_srv);
283         construct_link_service_edp_panel_control(link_srv);
284         construct_link_service_dp_cts(link_srv);
285         construct_link_service_dp_trace(link_srv);
286 }
287
288 struct link_service *link_create_link_service(void)
289 {
290         struct link_service *link_srv = kzalloc(sizeof(*link_srv), GFP_KERNEL);
291
292         if (link_srv == NULL)
293                 goto fail;
294
295         construct_link_service(link_srv);
296
297         return link_srv;
298 fail:
299         return NULL;
300 }
301
302 void link_destroy_link_service(struct link_service **link_srv)
303 {
304         kfree(*link_srv);
305         *link_srv = NULL;
306 }
307
308 static enum transmitter translate_encoder_to_transmitter(
309                 struct graphics_object_id encoder)
310 {
311         switch (encoder.id) {
312         case ENCODER_ID_INTERNAL_UNIPHY:
313                 switch (encoder.enum_id) {
314                 case ENUM_ID_1:
315                         return TRANSMITTER_UNIPHY_A;
316                 case ENUM_ID_2:
317                         return TRANSMITTER_UNIPHY_B;
318                 default:
319                         return TRANSMITTER_UNKNOWN;
320                 }
321         break;
322         case ENCODER_ID_INTERNAL_UNIPHY1:
323                 switch (encoder.enum_id) {
324                 case ENUM_ID_1:
325                         return TRANSMITTER_UNIPHY_C;
326                 case ENUM_ID_2:
327                         return TRANSMITTER_UNIPHY_D;
328                 default:
329                         return TRANSMITTER_UNKNOWN;
330                 }
331         break;
332         case ENCODER_ID_INTERNAL_UNIPHY2:
333                 switch (encoder.enum_id) {
334                 case ENUM_ID_1:
335                         return TRANSMITTER_UNIPHY_E;
336                 case ENUM_ID_2:
337                         return TRANSMITTER_UNIPHY_F;
338                 default:
339                         return TRANSMITTER_UNKNOWN;
340                 }
341         break;
342         case ENCODER_ID_INTERNAL_UNIPHY3:
343                 switch (encoder.enum_id) {
344                 case ENUM_ID_1:
345                         return TRANSMITTER_UNIPHY_G;
346                 default:
347                         return TRANSMITTER_UNKNOWN;
348                 }
349         break;
350         case ENCODER_ID_EXTERNAL_NUTMEG:
351                 switch (encoder.enum_id) {
352                 case ENUM_ID_1:
353                         return TRANSMITTER_NUTMEG_CRT;
354                 default:
355                         return TRANSMITTER_UNKNOWN;
356                 }
357         break;
358         case ENCODER_ID_EXTERNAL_TRAVIS:
359                 switch (encoder.enum_id) {
360                 case ENUM_ID_1:
361                         return TRANSMITTER_TRAVIS_CRT;
362                 case ENUM_ID_2:
363                         return TRANSMITTER_TRAVIS_LCD;
364                 default:
365                         return TRANSMITTER_UNKNOWN;
366                 }
367         break;
368         default:
369                 return TRANSMITTER_UNKNOWN;
370         }
371 }
372
373 static void link_destruct(struct dc_link *link)
374 {
375         int i;
376
377         if (link->hpd_gpio) {
378                 dal_gpio_destroy_irq(&link->hpd_gpio);
379                 link->hpd_gpio = NULL;
380         }
381
382         if (link->ddc)
383                 link_destroy_ddc_service(&link->ddc);
384
385         if (link->panel_cntl)
386                 link->panel_cntl->funcs->destroy(&link->panel_cntl);
387
388         if (link->link_enc && !link->is_dig_mapping_flexible) {
389                 /* Update link encoder resource tracking variables. These are used for
390                  * the dynamic assignment of link encoders to streams. Virtual links
391                  * are not assigned encoder resources on creation.
392                  */
393                 if (link->link_id.id != CONNECTOR_ID_VIRTUAL && link->eng_id != ENGINE_ID_UNKNOWN) {
394                         link->dc->res_pool->link_encoders[link->eng_id - ENGINE_ID_DIGA] = NULL;
395                         link->dc->res_pool->dig_link_enc_count--;
396                 }
397                 link->link_enc->funcs->destroy(&link->link_enc);
398         }
399
400         if (link->local_sink)
401                 dc_sink_release(link->local_sink);
402
403         for (i = 0; i < link->sink_count; ++i)
404                 dc_sink_release(link->remote_sinks[i]);
405 }
406
407 static enum channel_id get_ddc_line(struct dc_link *link)
408 {
409         struct ddc *ddc;
410         enum channel_id channel;
411
412         channel = CHANNEL_ID_UNKNOWN;
413
414         ddc = get_ddc_pin(link->ddc);
415
416         if (ddc) {
417                 switch (dal_ddc_get_line(ddc)) {
418                 case GPIO_DDC_LINE_DDC1:
419                         channel = CHANNEL_ID_DDC1;
420                         break;
421                 case GPIO_DDC_LINE_DDC2:
422                         channel = CHANNEL_ID_DDC2;
423                         break;
424                 case GPIO_DDC_LINE_DDC3:
425                         channel = CHANNEL_ID_DDC3;
426                         break;
427                 case GPIO_DDC_LINE_DDC4:
428                         channel = CHANNEL_ID_DDC4;
429                         break;
430                 case GPIO_DDC_LINE_DDC5:
431                         channel = CHANNEL_ID_DDC5;
432                         break;
433                 case GPIO_DDC_LINE_DDC6:
434                         channel = CHANNEL_ID_DDC6;
435                         break;
436                 case GPIO_DDC_LINE_DDC_VGA:
437                         channel = CHANNEL_ID_DDC_VGA;
438                         break;
439                 case GPIO_DDC_LINE_I2C_PAD:
440                         channel = CHANNEL_ID_I2C_PAD;
441                         break;
442                 default:
443                         BREAK_TO_DEBUGGER();
444                         break;
445                 }
446         }
447
448         return channel;
449 }
450
451 static bool construct_phy(struct dc_link *link,
452                               const struct link_init_data *init_params)
453 {
454         uint8_t i;
455         struct ddc_service_init_data ddc_service_init_data = { 0 };
456         struct dc_context *dc_ctx = init_params->ctx;
457         struct encoder_init_data enc_init_data = { 0 };
458         struct panel_cntl_init_data panel_cntl_init_data = { 0 };
459         struct dc_bios *bios = init_params->dc->ctx->dc_bios;
460         const struct dc_vbios_funcs *bp_funcs = bios->funcs;
461         struct bp_disp_connector_caps_info disp_connect_caps_info = { 0 };
462
463         DC_LOGGER_INIT(dc_ctx->logger);
464
465         link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
466         link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID;
467         link->link_status.dpcd_caps = &link->dpcd_caps;
468
469         link->dc = init_params->dc;
470         link->ctx = dc_ctx;
471         link->link_index = init_params->link_index;
472
473         memset(&link->preferred_training_settings, 0,
474                sizeof(struct dc_link_training_overrides));
475         memset(&link->preferred_link_setting, 0,
476                sizeof(struct dc_link_settings));
477
478         link->link_id =
479                 bios->funcs->get_connector_id(bios, init_params->connector_index);
480
481         link->ep_type = DISPLAY_ENDPOINT_PHY;
482
483         DC_LOG_DC("BIOS object table - link_id: %d", link->link_id.id);
484
485         if (bios->funcs->get_disp_connector_caps_info) {
486                 bios->funcs->get_disp_connector_caps_info(bios, link->link_id, &disp_connect_caps_info);
487                 link->is_internal_display = disp_connect_caps_info.INTERNAL_DISPLAY;
488                 DC_LOG_DC("BIOS object table - is_internal_display: %d", link->is_internal_display);
489         }
490
491         if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
492                 dm_output_to_console("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
493                                      __func__, init_params->connector_index,
494                                      link->link_id.type, OBJECT_TYPE_CONNECTOR);
495                 goto create_fail;
496         }
497
498         if (link->dc->res_pool->funcs->link_init)
499                 link->dc->res_pool->funcs->link_init(link);
500
501         link->hpd_gpio = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id,
502                                       link->ctx->gpio_service);
503
504         if (link->hpd_gpio) {
505                 dal_gpio_open(link->hpd_gpio, GPIO_MODE_INTERRUPT);
506                 dal_gpio_unlock_pin(link->hpd_gpio);
507                 link->irq_source_hpd = dal_irq_get_source(link->hpd_gpio);
508
509                 DC_LOG_DC("BIOS object table - hpd_gpio id: %d", link->hpd_gpio->id);
510                 DC_LOG_DC("BIOS object table - hpd_gpio en: %d", link->hpd_gpio->en);
511         }
512
513         switch (link->link_id.id) {
514         case CONNECTOR_ID_HDMI_TYPE_A:
515                 link->connector_signal = SIGNAL_TYPE_HDMI_TYPE_A;
516
517                 break;
518         case CONNECTOR_ID_SINGLE_LINK_DVID:
519         case CONNECTOR_ID_SINGLE_LINK_DVII:
520                 link->connector_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
521                 break;
522         case CONNECTOR_ID_DUAL_LINK_DVID:
523         case CONNECTOR_ID_DUAL_LINK_DVII:
524                 link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
525                 break;
526         case CONNECTOR_ID_DISPLAY_PORT:
527         case CONNECTOR_ID_MXM:
528         case CONNECTOR_ID_USBC:
529                 link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
530
531                 if (link->hpd_gpio)
532                         link->irq_source_hpd_rx =
533                                         dal_irq_get_rx_source(link->hpd_gpio);
534
535                 break;
536         case CONNECTOR_ID_EDP:
537                 link->connector_signal = SIGNAL_TYPE_EDP;
538
539                 if (link->hpd_gpio) {
540                         if (!link->dc->config.allow_edp_hotplug_detection)
541                                 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
542
543                         switch (link->dc->config.allow_edp_hotplug_detection) {
544                         case HPD_EN_FOR_ALL_EDP:
545                                 link->irq_source_hpd_rx =
546                                                 dal_irq_get_rx_source(link->hpd_gpio);
547                                 break;
548                         case HPD_EN_FOR_PRIMARY_EDP_ONLY:
549                                 if (link->link_index == 0)
550                                         link->irq_source_hpd_rx =
551                                                 dal_irq_get_rx_source(link->hpd_gpio);
552                                 else
553                                         link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
554                                 break;
555                         case HPD_EN_FOR_SECONDARY_EDP_ONLY:
556                                 if (link->link_index == 1)
557                                         link->irq_source_hpd_rx =
558                                                 dal_irq_get_rx_source(link->hpd_gpio);
559                                 else
560                                         link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
561                                 break;
562                         default:
563                                 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
564                                 break;
565                         }
566                 }
567
568                 break;
569         case CONNECTOR_ID_LVDS:
570                 link->connector_signal = SIGNAL_TYPE_LVDS;
571                 break;
572         default:
573                 DC_LOG_WARNING("Unsupported Connector type:%d!\n",
574                                link->link_id.id);
575                 goto create_fail;
576         }
577
578         LINK_INFO("Connector[%d] description: signal: %s\n",
579                   init_params->connector_index,
580                   signal_type_to_string(link->connector_signal));
581
582         ddc_service_init_data.ctx = link->ctx;
583         ddc_service_init_data.id = link->link_id;
584         ddc_service_init_data.link = link;
585         link->ddc = link_create_ddc_service(&ddc_service_init_data);
586
587         if (!link->ddc) {
588                 DC_ERROR("Failed to create ddc_service!\n");
589                 goto ddc_create_fail;
590         }
591
592         if (!link->ddc->ddc_pin) {
593                 DC_ERROR("Failed to get I2C info for connector!\n");
594                 goto ddc_create_fail;
595         }
596
597         link->ddc_hw_inst =
598                 dal_ddc_get_line(get_ddc_pin(link->ddc));
599
600         enc_init_data.ctx = dc_ctx;
601         bp_funcs->get_src_obj(dc_ctx->dc_bios, link->link_id, 0,
602                               &enc_init_data.encoder);
603         enc_init_data.connector = link->link_id;
604         enc_init_data.channel = get_ddc_line(link);
605         enc_init_data.hpd_source = get_hpd_line(link);
606
607         link->hpd_src = enc_init_data.hpd_source;
608
609         enc_init_data.transmitter =
610                 translate_encoder_to_transmitter(enc_init_data.encoder);
611         link->link_enc =
612                 link->dc->res_pool->funcs->link_enc_create(dc_ctx, &enc_init_data);
613
614         if (!link->link_enc) {
615                 DC_ERROR("Failed to create link encoder!\n");
616                 goto link_enc_create_fail;
617         }
618
619         DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C);
620         DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE);
621
622         /* Update link encoder tracking variables. These are used for the dynamic
623          * assignment of link encoders to streams.
624          */
625         link->eng_id = link->link_enc->preferred_engine;
626         link->dc->res_pool->link_encoders[link->eng_id - ENGINE_ID_DIGA] = link->link_enc;
627         link->dc->res_pool->dig_link_enc_count++;
628
629         link->link_enc_hw_inst = link->link_enc->transmitter;
630
631         if (link->dc->res_pool->funcs->panel_cntl_create &&
632                 (link->link_id.id == CONNECTOR_ID_EDP ||
633                         link->link_id.id == CONNECTOR_ID_LVDS)) {
634                 panel_cntl_init_data.ctx = dc_ctx;
635                 panel_cntl_init_data.inst = panel_cntl_init_data.ctx->dc_edp_id_count;
636                 panel_cntl_init_data.eng_id = link->eng_id;
637                 link->panel_cntl =
638                         link->dc->res_pool->funcs->panel_cntl_create(
639                                                                 &panel_cntl_init_data);
640                 panel_cntl_init_data.ctx->dc_edp_id_count++;
641
642                 if (link->panel_cntl == NULL) {
643                         DC_ERROR("Failed to create link panel_cntl!\n");
644                         goto panel_cntl_create_fail;
645                 }
646         }
647         for (i = 0; i < 4; i++) {
648                 if (bp_funcs->get_device_tag(dc_ctx->dc_bios,
649                                              link->link_id, i,
650                                              &link->device_tag) != BP_RESULT_OK) {
651                         DC_ERROR("Failed to find device tag!\n");
652                         goto device_tag_fail;
653                 }
654
655                 /* Look for device tag that matches connector signal,
656                  * CRT for rgb, LCD for other supported signal tyes
657                  */
658                 if (!bp_funcs->is_device_id_supported(dc_ctx->dc_bios,
659                                                       link->device_tag.dev_id))
660                         continue;
661                 if (link->device_tag.dev_id.device_type == DEVICE_TYPE_CRT &&
662                     link->connector_signal != SIGNAL_TYPE_RGB)
663                         continue;
664                 if (link->device_tag.dev_id.device_type == DEVICE_TYPE_LCD &&
665                     link->connector_signal == SIGNAL_TYPE_RGB)
666                         continue;
667
668                 DC_LOG_DC("BIOS object table - device_tag.acpi_device: %d", link->device_tag.acpi_device);
669                 DC_LOG_DC("BIOS object table - device_tag.dev_id.device_type: %d", link->device_tag.dev_id.device_type);
670                 DC_LOG_DC("BIOS object table - device_tag.dev_id.enum_id: %d", link->device_tag.dev_id.enum_id);
671                 break;
672         }
673
674         if (bios->integrated_info) {
675                 /* Look for channel mapping corresponding to connector and device tag */
676                 for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; i++) {
677                         struct external_display_path *path =
678                                 &bios->integrated_info->ext_disp_conn_info.path[i];
679
680                         if (path->device_connector_id.enum_id == link->link_id.enum_id &&
681                             path->device_connector_id.id == link->link_id.id &&
682                             path->device_connector_id.type == link->link_id.type) {
683                                 if (link->device_tag.acpi_device != 0 &&
684                                     path->device_acpi_enum == link->device_tag.acpi_device) {
685                                         link->ddi_channel_mapping = path->channel_mapping;
686                                         link->chip_caps = path->caps;
687                                         DC_LOG_DC("BIOS object table - ddi_channel_mapping: 0x%04X",
688                                                   link->ddi_channel_mapping.raw);
689                                         DC_LOG_DC("BIOS object table - chip_caps: %d",
690                                                   link->chip_caps);
691                                 } else if (path->device_tag ==
692                                            link->device_tag.dev_id.raw_device_tag) {
693                                         link->ddi_channel_mapping = path->channel_mapping;
694                                         link->chip_caps = path->caps;
695                                         DC_LOG_DC("BIOS object table - ddi_channel_mapping: 0x%04X",
696                                                   link->ddi_channel_mapping.raw);
697                                         DC_LOG_DC("BIOS object table - chip_caps: %d",
698                                                   link->chip_caps);
699                                 }
700
701                                 if (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) {
702                                         link->bios_forced_drive_settings.VOLTAGE_SWING =
703                                                 (bios->integrated_info->ext_disp_conn_info.fixdpvoltageswing & 0x3);
704                                         link->bios_forced_drive_settings.PRE_EMPHASIS =
705                                                 ((bios->integrated_info->ext_disp_conn_info.fixdpvoltageswing >> 2) & 0x3);
706                                 }
707
708                                 break;
709                         }
710                 }
711         }
712         if (bios->funcs->get_atom_dc_golden_table)
713                 bios->funcs->get_atom_dc_golden_table(bios);
714
715         /*
716          * TODO check if GPIO programmed correctly
717          *
718          * If GPIO isn't programmed correctly HPD might not rise or drain
719          * fast enough, leading to bounces.
720          */
721         program_hpd_filter(link);
722
723         link->psr_settings.psr_vtotal_control_support = false;
724         link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
725
726         DC_LOG_DC("BIOS object table - %s finished successfully.\n", __func__);
727         return true;
728 device_tag_fail:
729         link->link_enc->funcs->destroy(&link->link_enc);
730 link_enc_create_fail:
731         if (link->panel_cntl != NULL)
732                 link->panel_cntl->funcs->destroy(&link->panel_cntl);
733 panel_cntl_create_fail:
734         link_destroy_ddc_service(&link->ddc);
735 ddc_create_fail:
736 create_fail:
737
738         if (link->hpd_gpio) {
739                 dal_gpio_destroy_irq(&link->hpd_gpio);
740                 link->hpd_gpio = NULL;
741         }
742
743         DC_LOG_DC("BIOS object table - %s failed.\n", __func__);
744         return false;
745 }
746
747 static bool construct_dpia(struct dc_link *link,
748                               const struct link_init_data *init_params)
749 {
750         struct ddc_service_init_data ddc_service_init_data = { 0 };
751         struct dc_context *dc_ctx = init_params->ctx;
752
753         DC_LOGGER_INIT(dc_ctx->logger);
754
755         /* Initialized irq source for hpd and hpd rx */
756         link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
757         link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID;
758         link->link_status.dpcd_caps = &link->dpcd_caps;
759
760         link->dc = init_params->dc;
761         link->ctx = dc_ctx;
762         link->link_index = init_params->link_index;
763
764         memset(&link->preferred_training_settings, 0,
765                sizeof(struct dc_link_training_overrides));
766         memset(&link->preferred_link_setting, 0,
767                sizeof(struct dc_link_settings));
768
769         /* Dummy Init for linkid */
770         link->link_id.type = OBJECT_TYPE_CONNECTOR;
771         link->link_id.id = CONNECTOR_ID_DISPLAY_PORT;
772         link->link_id.enum_id = ENUM_ID_1 + init_params->connector_index;
773         link->is_internal_display = false;
774         link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
775         LINK_INFO("Connector[%d] description:signal %d\n",
776                   init_params->connector_index,
777                   link->connector_signal);
778
779         link->ep_type = DISPLAY_ENDPOINT_USB4_DPIA;
780         link->is_dig_mapping_flexible = true;
781
782         /* TODO: Initialize link : funcs->link_init */
783
784         ddc_service_init_data.ctx = link->ctx;
785         ddc_service_init_data.id = link->link_id;
786         ddc_service_init_data.link = link;
787         /* Set indicator for dpia link so that ddc wont be created */
788         ddc_service_init_data.is_dpia_link = true;
789
790         link->ddc = link_create_ddc_service(&ddc_service_init_data);
791         if (!link->ddc) {
792                 DC_ERROR("Failed to create ddc_service!\n");
793                 goto ddc_create_fail;
794         }
795
796         /* Set dpia port index : 0 to number of dpia ports */
797         link->ddc_hw_inst = init_params->connector_index;
798
799         // Assign Dpia preferred eng_id
800         if (link->dc->res_pool->funcs->get_preferred_eng_id_dpia)
801                 link->dpia_preferred_eng_id = link->dc->res_pool->funcs->get_preferred_eng_id_dpia(link->ddc_hw_inst);
802
803         /* TODO: Create link encoder */
804
805         link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
806
807         /* Some docks seem to NAK I2C writes to segment pointer with mot=0. */
808         link->wa_flags.dp_mot_reset_segment = true;
809
810         return true;
811
812 ddc_create_fail:
813         return false;
814 }
815
816 static bool link_construct(struct dc_link *link,
817                               const struct link_init_data *init_params)
818 {
819         /* Handle dpia case */
820         if (init_params->is_dpia_link == true)
821                 return construct_dpia(link, init_params);
822         else
823                 return construct_phy(link, init_params);
824 }
825
826 struct dc_link *link_create(const struct link_init_data *init_params)
827 {
828         struct dc_link *link =
829                         kzalloc(sizeof(*link), GFP_KERNEL);
830
831         if (NULL == link)
832                 goto alloc_fail;
833
834         if (false == link_construct(link, init_params))
835                 goto construct_fail;
836
837         return link;
838
839 construct_fail:
840         kfree(link);
841
842 alloc_fail:
843         return NULL;
844 }
845
846 void link_destroy(struct dc_link **link)
847 {
848         link_destruct(*link);
849         kfree(*link);
850         *link = NULL;
851 }
This page took 0.079459 seconds and 4 git commands to generate.