Merge tag 'drm-misc-next-fixes-2023-09-01' of git://anongit.freedesktop.org/drm/drm...
[platform/kernel/linux-rpi.git] / drivers / gpu / drm / amd / display / dc / link / accessories / link_dp_cts.c
1 /*
2  * Copyright 2022 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 #include "link_dp_cts.h"
26 #include "link/link_resource.h"
27 #include "link/protocols/link_dpcd.h"
28 #include "link/protocols/link_dp_training.h"
29 #include "link/protocols/link_dp_phy.h"
30 #include "link/protocols/link_dp_training_fixed_vs_pe_retimer.h"
31 #include "link/protocols/link_dp_capability.h"
32 #include "link/link_dpms.h"
33 #include "resource.h"
34 #include "dm_helpers.h"
35 #include "dc_dmub_srv.h"
36 #include "dce/dmub_hw_lock_mgr.h"
37
38 #define DC_LOGGER \
39         link->ctx->logger
40
41 static enum dc_link_rate get_link_rate_from_test_link_rate(uint8_t test_rate)
42 {
43         switch (test_rate) {
44         case DP_TEST_LINK_RATE_RBR:
45                 return LINK_RATE_LOW;
46         case DP_TEST_LINK_RATE_HBR:
47                 return LINK_RATE_HIGH;
48         case DP_TEST_LINK_RATE_HBR2:
49                 return LINK_RATE_HIGH2;
50         case DP_TEST_LINK_RATE_HBR3:
51                 return LINK_RATE_HIGH3;
52         case DP_TEST_LINK_RATE_UHBR10:
53                 return LINK_RATE_UHBR10;
54         case DP_TEST_LINK_RATE_UHBR20:
55                 return LINK_RATE_UHBR20;
56         case DP_TEST_LINK_RATE_UHBR13_5:
57                 return LINK_RATE_UHBR13_5;
58         default:
59                 return LINK_RATE_UNKNOWN;
60         }
61 }
62
63 static bool is_dp_phy_sqaure_pattern(enum dp_test_pattern test_pattern)
64 {
65         return (DP_TEST_PATTERN_SQUARE_BEGIN <= test_pattern &&
66                         test_pattern <= DP_TEST_PATTERN_SQUARE_END);
67 }
68
69 static bool is_dp_phy_pattern(enum dp_test_pattern test_pattern)
70 {
71         if ((DP_TEST_PATTERN_PHY_PATTERN_BEGIN <= test_pattern &&
72                         test_pattern <= DP_TEST_PATTERN_PHY_PATTERN_END) ||
73                         test_pattern == DP_TEST_PATTERN_VIDEO_MODE)
74                 return true;
75         else
76                 return false;
77 }
78
79 static void dp_retrain_link_dp_test(struct dc_link *link,
80                         struct dc_link_settings *link_setting,
81                         bool skip_video_pattern)
82 {
83         struct pipe_ctx *pipes[MAX_PIPES];
84         struct dc_state *state = link->dc->current_state;
85         uint8_t count;
86         int i;
87
88         udelay(100);
89
90         link_get_master_pipes_with_dpms_on(link, state, &count, pipes);
91
92         for (i = 0; i < count; i++) {
93                 link_set_dpms_off(pipes[i]);
94                 pipes[i]->link_config.dp_link_settings = *link_setting;
95                 update_dp_encoder_resources_for_test_harness(
96                                 link->dc,
97                                 state,
98                                 pipes[i]);
99         }
100
101         for (i = count-1; i >= 0; i--)
102                 link_set_dpms_on(state, pipes[i]);
103 }
104
105 static void dp_test_send_link_training(struct dc_link *link)
106 {
107         struct dc_link_settings link_settings = {0};
108         uint8_t test_rate = 0;
109
110         core_link_read_dpcd(
111                         link,
112                         DP_TEST_LANE_COUNT,
113                         (unsigned char *)(&link_settings.lane_count),
114                         1);
115         core_link_read_dpcd(
116                         link,
117                         DP_TEST_LINK_RATE,
118                         &test_rate,
119                         1);
120         link_settings.link_rate = get_link_rate_from_test_link_rate(test_rate);
121
122         /* Set preferred link settings */
123         link->verified_link_cap.lane_count = link_settings.lane_count;
124         link->verified_link_cap.link_rate = link_settings.link_rate;
125
126         dp_retrain_link_dp_test(link, &link_settings, false);
127 }
128
129 static void dp_test_get_audio_test_data(struct dc_link *link, bool disable_video)
130 {
131         union audio_test_mode            dpcd_test_mode = {0};
132         struct audio_test_pattern_type   dpcd_pattern_type = {0};
133         union audio_test_pattern_period  dpcd_pattern_period[AUDIO_CHANNELS_COUNT] = {0};
134         enum dp_test_pattern test_pattern = DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
135
136         struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
137         struct pipe_ctx *pipe_ctx = &pipes[0];
138         unsigned int channel_count;
139         unsigned int channel = 0;
140         unsigned int modes = 0;
141         unsigned int sampling_rate_in_hz = 0;
142
143         // get audio test mode and test pattern parameters
144         core_link_read_dpcd(
145                 link,
146                 DP_TEST_AUDIO_MODE,
147                 &dpcd_test_mode.raw,
148                 sizeof(dpcd_test_mode));
149
150         core_link_read_dpcd(
151                 link,
152                 DP_TEST_AUDIO_PATTERN_TYPE,
153                 &dpcd_pattern_type.value,
154                 sizeof(dpcd_pattern_type));
155
156         channel_count = min(dpcd_test_mode.bits.channel_count + 1, AUDIO_CHANNELS_COUNT);
157
158         // read pattern periods for requested channels when sawTooth pattern is requested
159         if (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH ||
160                         dpcd_pattern_type.value == AUDIO_TEST_PATTERN_OPERATOR_DEFINED) {
161
162                 test_pattern = (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH) ?
163                                 DP_TEST_PATTERN_AUDIO_SAWTOOTH : DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
164                 // read period for each channel
165                 for (channel = 0; channel < channel_count; channel++) {
166                         core_link_read_dpcd(
167                                                         link,
168                                                         DP_TEST_AUDIO_PERIOD_CH1 + channel,
169                                                         &dpcd_pattern_period[channel].raw,
170                                                         sizeof(dpcd_pattern_period[channel]));
171                 }
172         }
173
174         // translate sampling rate
175         switch (dpcd_test_mode.bits.sampling_rate) {
176         case AUDIO_SAMPLING_RATE_32KHZ:
177                 sampling_rate_in_hz = 32000;
178                 break;
179         case AUDIO_SAMPLING_RATE_44_1KHZ:
180                 sampling_rate_in_hz = 44100;
181                 break;
182         case AUDIO_SAMPLING_RATE_48KHZ:
183                 sampling_rate_in_hz = 48000;
184                 break;
185         case AUDIO_SAMPLING_RATE_88_2KHZ:
186                 sampling_rate_in_hz = 88200;
187                 break;
188         case AUDIO_SAMPLING_RATE_96KHZ:
189                 sampling_rate_in_hz = 96000;
190                 break;
191         case AUDIO_SAMPLING_RATE_176_4KHZ:
192                 sampling_rate_in_hz = 176400;
193                 break;
194         case AUDIO_SAMPLING_RATE_192KHZ:
195                 sampling_rate_in_hz = 192000;
196                 break;
197         default:
198                 sampling_rate_in_hz = 0;
199                 break;
200         }
201
202         link->audio_test_data.flags.test_requested = 1;
203         link->audio_test_data.flags.disable_video = disable_video;
204         link->audio_test_data.sampling_rate = sampling_rate_in_hz;
205         link->audio_test_data.channel_count = channel_count;
206         link->audio_test_data.pattern_type = test_pattern;
207
208         if (test_pattern == DP_TEST_PATTERN_AUDIO_SAWTOOTH) {
209                 for (modes = 0; modes < pipe_ctx->stream->audio_info.mode_count; modes++) {
210                         link->audio_test_data.pattern_period[modes] = dpcd_pattern_period[modes].bits.pattern_period;
211                 }
212         }
213 }
214
215 /* TODO Raven hbr2 compliance eye output is unstable
216  * (toggling on and off) with debugger break
217  * This caueses intermittent PHY automation failure
218  * Need to look into the root cause */
219 static void dp_test_send_phy_test_pattern(struct dc_link *link)
220 {
221         union phy_test_pattern dpcd_test_pattern;
222         union lane_adjust dpcd_lane_adjustment[2];
223         unsigned char dpcd_post_cursor_2_adjustment = 0;
224         unsigned char test_pattern_buffer[
225                         (DP_TEST_264BIT_CUSTOM_PATTERN_263_256 -
226                         DP_TEST_264BIT_CUSTOM_PATTERN_7_0)+1] = {0};
227         unsigned int test_pattern_size = 0;
228         enum dp_test_pattern test_pattern;
229         union lane_adjust dpcd_lane_adjust;
230         unsigned int lane;
231         struct link_training_settings link_training_settings;
232         unsigned char no_preshoot = 0;
233         unsigned char no_deemphasis = 0;
234
235         dpcd_test_pattern.raw = 0;
236         memset(dpcd_lane_adjustment, 0, sizeof(dpcd_lane_adjustment));
237         memset(&link_training_settings, 0, sizeof(link_training_settings));
238
239         /* get phy test pattern and pattern parameters from DP receiver */
240         core_link_read_dpcd(
241                         link,
242                         DP_PHY_TEST_PATTERN,
243                         &dpcd_test_pattern.raw,
244                         sizeof(dpcd_test_pattern));
245         core_link_read_dpcd(
246                         link,
247                         DP_ADJUST_REQUEST_LANE0_1,
248                         &dpcd_lane_adjustment[0].raw,
249                         sizeof(dpcd_lane_adjustment));
250
251         /* prepare link training settings */
252         link_training_settings.link_settings = link->cur_link_settings;
253
254         link_training_settings.lttpr_mode = dp_decide_lttpr_mode(link, &link->cur_link_settings);
255
256         if ((link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
257                         link_training_settings.lttpr_mode == LTTPR_MODE_TRANSPARENT)
258                 dp_fixed_vs_pe_read_lane_adjust(
259                                 link,
260                                 link_training_settings.dpcd_lane_settings);
261
262         /*get post cursor 2 parameters
263          * For DP 1.1a or eariler, this DPCD register's value is 0
264          * For DP 1.2 or later:
265          * Bits 1:0 = POST_CURSOR2_LANE0; Bits 3:2 = POST_CURSOR2_LANE1
266          * Bits 5:4 = POST_CURSOR2_LANE2; Bits 7:6 = POST_CURSOR2_LANE3
267          */
268         core_link_read_dpcd(
269                         link,
270                         DP_ADJUST_REQUEST_POST_CURSOR2,
271                         &dpcd_post_cursor_2_adjustment,
272                         sizeof(dpcd_post_cursor_2_adjustment));
273
274         /* translate request */
275         switch (dpcd_test_pattern.bits.PATTERN) {
276         case PHY_TEST_PATTERN_D10_2:
277                 test_pattern = DP_TEST_PATTERN_D102;
278                 break;
279         case PHY_TEST_PATTERN_SYMBOL_ERROR:
280                 test_pattern = DP_TEST_PATTERN_SYMBOL_ERROR;
281                 break;
282         case PHY_TEST_PATTERN_PRBS7:
283                 test_pattern = DP_TEST_PATTERN_PRBS7;
284                 break;
285         case PHY_TEST_PATTERN_80BIT_CUSTOM:
286                 test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
287                 break;
288         case PHY_TEST_PATTERN_CP2520_1:
289                 /* CP2520 pattern is unstable, temporarily use TPS4 instead */
290                 test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
291                                 DP_TEST_PATTERN_TRAINING_PATTERN4 :
292                                 DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
293                 break;
294         case PHY_TEST_PATTERN_CP2520_2:
295                 /* CP2520 pattern is unstable, temporarily use TPS4 instead */
296                 test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
297                                 DP_TEST_PATTERN_TRAINING_PATTERN4 :
298                                 DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
299                 break;
300         case PHY_TEST_PATTERN_CP2520_3:
301                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
302                 break;
303         case PHY_TEST_PATTERN_128b_132b_TPS1:
304                 test_pattern = DP_TEST_PATTERN_128b_132b_TPS1;
305                 break;
306         case PHY_TEST_PATTERN_128b_132b_TPS2:
307                 test_pattern = DP_TEST_PATTERN_128b_132b_TPS2;
308                 break;
309         case PHY_TEST_PATTERN_PRBS9:
310                 test_pattern = DP_TEST_PATTERN_PRBS9;
311                 break;
312         case PHY_TEST_PATTERN_PRBS11:
313                 test_pattern = DP_TEST_PATTERN_PRBS11;
314                 break;
315         case PHY_TEST_PATTERN_PRBS15:
316                 test_pattern = DP_TEST_PATTERN_PRBS15;
317                 break;
318         case PHY_TEST_PATTERN_PRBS23:
319                 test_pattern = DP_TEST_PATTERN_PRBS23;
320                 break;
321         case PHY_TEST_PATTERN_PRBS31:
322                 test_pattern = DP_TEST_PATTERN_PRBS31;
323                 break;
324         case PHY_TEST_PATTERN_264BIT_CUSTOM:
325                 test_pattern = DP_TEST_PATTERN_264BIT_CUSTOM;
326                 break;
327         case PHY_TEST_PATTERN_SQUARE:
328                 test_pattern = DP_TEST_PATTERN_SQUARE;
329                 break;
330         case PHY_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED:
331                 test_pattern = DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED;
332                 no_preshoot = 1;
333                 break;
334         case PHY_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED:
335                 test_pattern = DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED;
336                 no_deemphasis = 1;
337                 break;
338         case PHY_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED:
339                 test_pattern = DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED;
340                 no_preshoot = 1;
341                 no_deemphasis = 1;
342                 break;
343         default:
344                 test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
345         break;
346         }
347
348         if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM) {
349                 test_pattern_size = (DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
350                                 DP_TEST_80BIT_CUSTOM_PATTERN_7_0) + 1;
351                 core_link_read_dpcd(
352                                 link,
353                                 DP_TEST_80BIT_CUSTOM_PATTERN_7_0,
354                                 test_pattern_buffer,
355                                 test_pattern_size);
356         }
357
358         if (is_dp_phy_sqaure_pattern(test_pattern)) {
359                 test_pattern_size = 1; // Square pattern data is 1 byte (DP spec)
360                 core_link_read_dpcd(
361                                 link,
362                                 DP_PHY_SQUARE_PATTERN,
363                                 test_pattern_buffer,
364                                 test_pattern_size);
365         }
366
367         if (test_pattern == DP_TEST_PATTERN_264BIT_CUSTOM) {
368                 test_pattern_size = (DP_TEST_264BIT_CUSTOM_PATTERN_263_256-
369                                 DP_TEST_264BIT_CUSTOM_PATTERN_7_0) + 1;
370                 core_link_read_dpcd(
371                                 link,
372                                 DP_TEST_264BIT_CUSTOM_PATTERN_7_0,
373                                 test_pattern_buffer,
374                                 test_pattern_size);
375         }
376
377         for (lane = 0; lane <
378                 (unsigned int)(link->cur_link_settings.lane_count);
379                 lane++) {
380                 dpcd_lane_adjust.raw =
381                         dp_get_nibble_at_index(&dpcd_lane_adjustment[0].raw, lane);
382                 if (link_dp_get_encoding_format(&link->cur_link_settings) ==
383                                 DP_8b_10b_ENCODING) {
384                         link_training_settings.hw_lane_settings[lane].VOLTAGE_SWING =
385                                 (enum dc_voltage_swing)
386                                 (dpcd_lane_adjust.bits.VOLTAGE_SWING_LANE);
387                         link_training_settings.hw_lane_settings[lane].PRE_EMPHASIS =
388                                 (enum dc_pre_emphasis)
389                                 (dpcd_lane_adjust.bits.PRE_EMPHASIS_LANE);
390                         link_training_settings.hw_lane_settings[lane].POST_CURSOR2 =
391                                 (enum dc_post_cursor2)
392                                 ((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03);
393                 } else if (link_dp_get_encoding_format(&link->cur_link_settings) ==
394                                 DP_128b_132b_ENCODING) {
395                         link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.level =
396                                         dpcd_lane_adjust.tx_ffe.PRESET_VALUE;
397                         link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.no_preshoot = no_preshoot;
398                         link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.no_deemphasis = no_deemphasis;
399                 }
400         }
401
402         dp_hw_to_dpcd_lane_settings(&link_training_settings,
403                         link_training_settings.hw_lane_settings,
404                         link_training_settings.dpcd_lane_settings);
405         /*Usage: Measure DP physical lane signal
406          * by DP SI test equipment automatically.
407          * PHY test pattern request is generated by equipment via HPD interrupt.
408          * HPD needs to be active all the time. HPD should be active
409          * all the time. Do not touch it.
410          * forward request to DS
411          */
412         dp_set_test_pattern(
413                 link,
414                 test_pattern,
415                 DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED,
416                 &link_training_settings,
417                 test_pattern_buffer,
418                 test_pattern_size);
419 }
420
421 static void set_crtc_test_pattern(struct dc_link *link,
422                                 struct pipe_ctx *pipe_ctx,
423                                 enum dp_test_pattern test_pattern,
424                                 enum dp_test_pattern_color_space test_pattern_color_space)
425 {
426         enum controller_dp_test_pattern controller_test_pattern;
427         enum dc_color_depth color_depth = pipe_ctx->
428                 stream->timing.display_color_depth;
429         struct bit_depth_reduction_params params;
430         struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
431         struct pipe_ctx *odm_pipe;
432         int odm_cnt = 1;
433         int h_active = pipe_ctx->stream->timing.h_addressable +
434                 pipe_ctx->stream->timing.h_border_left +
435                 pipe_ctx->stream->timing.h_border_right;
436         int v_active = pipe_ctx->stream->timing.v_addressable +
437                 pipe_ctx->stream->timing.v_border_bottom +
438                 pipe_ctx->stream->timing.v_border_top;
439         int odm_slice_width, last_odm_slice_width, offset = 0;
440
441         memset(&params, 0, sizeof(params));
442
443         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
444                 odm_cnt++;
445
446         odm_slice_width = h_active / odm_cnt;
447         last_odm_slice_width = h_active - odm_slice_width * (odm_cnt - 1);
448
449         switch (test_pattern) {
450         case DP_TEST_PATTERN_COLOR_SQUARES:
451                 controller_test_pattern =
452                                 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
453         break;
454         case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
455                 controller_test_pattern =
456                                 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA;
457         break;
458         case DP_TEST_PATTERN_VERTICAL_BARS:
459                 controller_test_pattern =
460                                 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS;
461         break;
462         case DP_TEST_PATTERN_HORIZONTAL_BARS:
463                 controller_test_pattern =
464                                 CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS;
465         break;
466         case DP_TEST_PATTERN_COLOR_RAMP:
467                 controller_test_pattern =
468                                 CONTROLLER_DP_TEST_PATTERN_COLORRAMP;
469         break;
470         default:
471                 controller_test_pattern =
472                                 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
473         break;
474         }
475
476         switch (test_pattern) {
477         case DP_TEST_PATTERN_COLOR_SQUARES:
478         case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
479         case DP_TEST_PATTERN_VERTICAL_BARS:
480         case DP_TEST_PATTERN_HORIZONTAL_BARS:
481         case DP_TEST_PATTERN_COLOR_RAMP:
482         {
483                 /* disable bit depth reduction */
484                 pipe_ctx->stream->bit_depth_params = params;
485                 if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) {
486                         opp->funcs->opp_program_bit_depth_reduction(opp, &params);
487                         pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
488                                 controller_test_pattern, color_depth);
489                 } else if (link->dc->hwss.set_disp_pattern_generator) {
490                         enum controller_dp_color_space controller_color_space;
491                         struct output_pixel_processor *odm_opp;
492
493                         switch (test_pattern_color_space) {
494                         case DP_TEST_PATTERN_COLOR_SPACE_RGB:
495                                 controller_color_space = CONTROLLER_DP_COLOR_SPACE_RGB;
496                                 break;
497                         case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
498                                 controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR601;
499                                 break;
500                         case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
501                                 controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR709;
502                                 break;
503                         case DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED:
504                         default:
505                                 controller_color_space = CONTROLLER_DP_COLOR_SPACE_UDEFINED;
506                                 DC_LOG_ERROR("%s: Color space must be defined for test pattern", __func__);
507                                 ASSERT(0);
508                                 break;
509                         }
510
511                         odm_pipe = pipe_ctx;
512                         while (odm_pipe->next_odm_pipe) {
513                                 odm_opp = odm_pipe->stream_res.opp;
514                                 odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
515                                 link->dc->hwss.set_disp_pattern_generator(link->dc,
516                                                 odm_pipe,
517                                                 controller_test_pattern,
518                                                 controller_color_space,
519                                                 color_depth,
520                                                 NULL,
521                                                 odm_slice_width,
522                                                 v_active,
523                                                 offset);
524                                 offset += odm_slice_width;
525                                 odm_pipe = odm_pipe->next_odm_pipe;
526                         }
527                         odm_opp = odm_pipe->stream_res.opp;
528                         odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
529                         link->dc->hwss.set_disp_pattern_generator(link->dc,
530                                         odm_pipe,
531                                         controller_test_pattern,
532                                         controller_color_space,
533                                         color_depth,
534                                         NULL,
535                                         last_odm_slice_width,
536                                         v_active,
537                                         offset);
538                 }
539         }
540         break;
541         case DP_TEST_PATTERN_VIDEO_MODE:
542         {
543                 /* restore bitdepth reduction */
544                 resource_build_bit_depth_reduction_params(pipe_ctx->stream, &params);
545                 pipe_ctx->stream->bit_depth_params = params;
546                 if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) {
547                         opp->funcs->opp_program_bit_depth_reduction(opp, &params);
548                         pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
549                                         CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
550                                         color_depth);
551                 } else if (link->dc->hwss.set_disp_pattern_generator) {
552                         struct output_pixel_processor *odm_opp;
553
554                         odm_pipe = pipe_ctx;
555                         while (odm_pipe->next_odm_pipe) {
556                                 odm_opp = odm_pipe->stream_res.opp;
557                                 odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
558                                 link->dc->hwss.set_disp_pattern_generator(link->dc,
559                                                 odm_pipe,
560                                                 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
561                                                 CONTROLLER_DP_COLOR_SPACE_UDEFINED,
562                                                 color_depth,
563                                                 NULL,
564                                                 odm_slice_width,
565                                                 v_active,
566                                                 offset);
567                                 offset += odm_slice_width;
568                                 odm_pipe = odm_pipe->next_odm_pipe;
569                         }
570                         odm_opp = odm_pipe->stream_res.opp;
571                         odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
572                         link->dc->hwss.set_disp_pattern_generator(link->dc,
573                                         odm_pipe,
574                                         CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
575                                         CONTROLLER_DP_COLOR_SPACE_UDEFINED,
576                                         color_depth,
577                                         NULL,
578                                         last_odm_slice_width,
579                                         v_active,
580                                         offset);
581                 }
582         }
583         break;
584
585         default:
586         break;
587         }
588 }
589
590 void dp_handle_automated_test(struct dc_link *link)
591 {
592         union test_request test_request;
593         union test_response test_response;
594
595         memset(&test_request, 0, sizeof(test_request));
596         memset(&test_response, 0, sizeof(test_response));
597
598         core_link_read_dpcd(
599                 link,
600                 DP_TEST_REQUEST,
601                 &test_request.raw,
602                 sizeof(union test_request));
603         if (test_request.bits.LINK_TRAINING) {
604                 /* ACK first to let DP RX test box monitor LT sequence */
605                 test_response.bits.ACK = 1;
606                 core_link_write_dpcd(
607                         link,
608                         DP_TEST_RESPONSE,
609                         &test_response.raw,
610                         sizeof(test_response));
611                 dp_test_send_link_training(link);
612                 /* no acknowledge request is needed again */
613                 test_response.bits.ACK = 0;
614         }
615         if (test_request.bits.LINK_TEST_PATTRN) {
616                 union test_misc dpcd_test_params;
617                 union link_test_pattern dpcd_test_pattern;
618
619                 memset(&dpcd_test_pattern, 0, sizeof(dpcd_test_pattern));
620                 memset(&dpcd_test_params, 0, sizeof(dpcd_test_params));
621
622                 /* get link test pattern and pattern parameters */
623                 core_link_read_dpcd(
624                                 link,
625                                 DP_TEST_PATTERN,
626                                 &dpcd_test_pattern.raw,
627                                 sizeof(dpcd_test_pattern));
628                 core_link_read_dpcd(
629                                 link,
630                                 DP_TEST_MISC0,
631                                 &dpcd_test_params.raw,
632                                 sizeof(dpcd_test_params));
633                 test_response.bits.ACK = dm_helpers_dp_handle_test_pattern_request(link->ctx, link,
634                                 dpcd_test_pattern, dpcd_test_params) ? 1 : 0;
635         }
636
637         if (test_request.bits.AUDIO_TEST_PATTERN) {
638                 dp_test_get_audio_test_data(link, test_request.bits.TEST_AUDIO_DISABLED_VIDEO);
639                 test_response.bits.ACK = 1;
640         }
641
642         if (test_request.bits.PHY_TEST_PATTERN) {
643                 dp_test_send_phy_test_pattern(link);
644                 test_response.bits.ACK = 1;
645         }
646
647         /* send request acknowledgment */
648         if (test_response.bits.ACK)
649                 core_link_write_dpcd(
650                         link,
651                         DP_TEST_RESPONSE,
652                         &test_response.raw,
653                         sizeof(test_response));
654 }
655
656 bool dp_set_test_pattern(
657         struct dc_link *link,
658         enum dp_test_pattern test_pattern,
659         enum dp_test_pattern_color_space test_pattern_color_space,
660         const struct link_training_settings *p_link_settings,
661         const unsigned char *p_custom_pattern,
662         unsigned int cust_pattern_size)
663 {
664         struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
665         struct pipe_ctx *pipe_ctx = NULL;
666         unsigned int lane;
667         unsigned int i;
668         unsigned char link_qual_pattern[LANE_COUNT_DP_MAX] = {0};
669         union dpcd_training_pattern training_pattern;
670         enum dpcd_phy_test_patterns pattern;
671
672         memset(&training_pattern, 0, sizeof(training_pattern));
673
674         for (i = 0; i < MAX_PIPES; i++) {
675                 if (pipes[i].stream == NULL)
676                         continue;
677
678                 if (resource_is_pipe_type(&pipes[i], OTG_MASTER) &&
679                                 pipes[i].stream->link == link) {
680                         pipe_ctx = &pipes[i];
681                         break;
682                 }
683         }
684
685         if (pipe_ctx == NULL)
686                 return false;
687
688         /* Reset CRTC Test Pattern if it is currently running and request is VideoMode */
689         if (link->test_pattern_enabled && test_pattern ==
690                         DP_TEST_PATTERN_VIDEO_MODE) {
691                 /* Set CRTC Test Pattern */
692                 set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
693                 dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern,
694                                 (uint8_t *)p_custom_pattern,
695                                 (uint32_t)cust_pattern_size);
696
697                 /* Unblank Stream */
698                 link->dc->hwss.unblank_stream(
699                         pipe_ctx,
700                         &link->verified_link_cap);
701                 /* TODO:m_pHwss->MuteAudioEndpoint
702                  * (pPathMode->pDisplayPath, false);
703                  */
704
705                 /* Reset Test Pattern state */
706                 link->test_pattern_enabled = false;
707                 link->current_test_pattern = test_pattern;
708
709                 return true;
710         }
711
712         /* Check for PHY Test Patterns */
713         if (is_dp_phy_pattern(test_pattern)) {
714                 /* Set DPCD Lane Settings before running test pattern */
715                 if (p_link_settings != NULL) {
716                         if ((link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
717                                         p_link_settings->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
718                                 dp_fixed_vs_pe_set_retimer_lane_settings(
719                                                 link,
720                                                 p_link_settings->dpcd_lane_settings,
721                                                 p_link_settings->link_settings.lane_count);
722                         } else {
723                                 dp_set_hw_lane_settings(link, &pipe_ctx->link_res, p_link_settings, DPRX);
724                         }
725                         dpcd_set_lane_settings(link, p_link_settings, DPRX);
726                 }
727
728                 /* Blank stream if running test pattern */
729                 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
730                         /*TODO:
731                          * m_pHwss->
732                          * MuteAudioEndpoint(pPathMode->pDisplayPath, true);
733                          */
734                         /* Blank stream */
735                         link->dc->hwss.blank_stream(pipe_ctx);
736                 }
737
738                 dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern,
739                                 (uint8_t *)p_custom_pattern,
740                                 (uint32_t)cust_pattern_size);
741
742                 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
743                         /* Set Test Pattern state */
744                         link->test_pattern_enabled = true;
745                         link->current_test_pattern = test_pattern;
746                         if (p_link_settings != NULL)
747                                 dpcd_set_link_settings(link,
748                                                 p_link_settings);
749                 }
750
751                 switch (test_pattern) {
752                 case DP_TEST_PATTERN_VIDEO_MODE:
753                         pattern = PHY_TEST_PATTERN_NONE;
754                         break;
755                 case DP_TEST_PATTERN_D102:
756                         pattern = PHY_TEST_PATTERN_D10_2;
757                         break;
758                 case DP_TEST_PATTERN_SYMBOL_ERROR:
759                         pattern = PHY_TEST_PATTERN_SYMBOL_ERROR;
760                         break;
761                 case DP_TEST_PATTERN_PRBS7:
762                         pattern = PHY_TEST_PATTERN_PRBS7;
763                         break;
764                 case DP_TEST_PATTERN_80BIT_CUSTOM:
765                         pattern = PHY_TEST_PATTERN_80BIT_CUSTOM;
766                         break;
767                 case DP_TEST_PATTERN_CP2520_1:
768                         pattern = PHY_TEST_PATTERN_CP2520_1;
769                         break;
770                 case DP_TEST_PATTERN_CP2520_2:
771                         pattern = PHY_TEST_PATTERN_CP2520_2;
772                         break;
773                 case DP_TEST_PATTERN_CP2520_3:
774                         pattern = PHY_TEST_PATTERN_CP2520_3;
775                         break;
776                 case DP_TEST_PATTERN_128b_132b_TPS1:
777                         pattern = PHY_TEST_PATTERN_128b_132b_TPS1;
778                         break;
779                 case DP_TEST_PATTERN_128b_132b_TPS2:
780                         pattern = PHY_TEST_PATTERN_128b_132b_TPS2;
781                         break;
782                 case DP_TEST_PATTERN_PRBS9:
783                         pattern = PHY_TEST_PATTERN_PRBS9;
784                         break;
785                 case DP_TEST_PATTERN_PRBS11:
786                         pattern = PHY_TEST_PATTERN_PRBS11;
787                         break;
788                 case DP_TEST_PATTERN_PRBS15:
789                         pattern = PHY_TEST_PATTERN_PRBS15;
790                         break;
791                 case DP_TEST_PATTERN_PRBS23:
792                         pattern = PHY_TEST_PATTERN_PRBS23;
793                         break;
794                 case DP_TEST_PATTERN_PRBS31:
795                         pattern = PHY_TEST_PATTERN_PRBS31;
796                         break;
797                 case DP_TEST_PATTERN_264BIT_CUSTOM:
798                         pattern = PHY_TEST_PATTERN_264BIT_CUSTOM;
799                         break;
800                 case DP_TEST_PATTERN_SQUARE:
801                         pattern = PHY_TEST_PATTERN_SQUARE;
802                         break;
803                 case DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED:
804                         pattern = PHY_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED;
805                         break;
806                 case DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED:
807                         pattern = PHY_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED;
808                         break;
809                 case DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED:
810                         pattern = PHY_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED;
811                         break;
812                 default:
813                         return false;
814                 }
815
816                 if (test_pattern == DP_TEST_PATTERN_VIDEO_MODE
817                 /*TODO:&& !pPathMode->pDisplayPath->IsTargetPoweredOn()*/)
818                         return false;
819
820                 if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
821                         if (is_dp_phy_sqaure_pattern(test_pattern))
822                                 core_link_write_dpcd(link,
823                                                 DP_LINK_SQUARE_PATTERN,
824                                                 p_custom_pattern,
825                                                 1);
826
827                         /* tell receiver that we are sending qualification
828                          * pattern DP 1.2 or later - DP receiver's link quality
829                          * pattern is set using DPCD LINK_QUAL_LANEx_SET
830                          * register (0x10B~0x10E)\
831                          */
832                         for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++)
833                                 link_qual_pattern[lane] =
834                                                 (unsigned char)(pattern);
835
836                         core_link_write_dpcd(link,
837                                         DP_LINK_QUAL_LANE0_SET,
838                                         link_qual_pattern,
839                                         sizeof(link_qual_pattern));
840                 } else if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_10 ||
841                            link->dpcd_caps.dpcd_rev.raw == 0) {
842                         /* tell receiver that we are sending qualification
843                          * pattern DP 1.1a or earlier - DP receiver's link
844                          * quality pattern is set using
845                          * DPCD TRAINING_PATTERN_SET -> LINK_QUAL_PATTERN_SET
846                          * register (0x102). We will use v_1.3 when we are
847                          * setting test pattern for DP 1.1.
848                          */
849                         core_link_read_dpcd(link, DP_TRAINING_PATTERN_SET,
850                                             &training_pattern.raw,
851                                             sizeof(training_pattern));
852                         training_pattern.v1_3.LINK_QUAL_PATTERN_SET = pattern;
853                         core_link_write_dpcd(link, DP_TRAINING_PATTERN_SET,
854                                              &training_pattern.raw,
855                                              sizeof(training_pattern));
856                 }
857         } else {
858                 enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
859
860                 switch (test_pattern_color_space) {
861                 case DP_TEST_PATTERN_COLOR_SPACE_RGB:
862                         color_space = COLOR_SPACE_SRGB;
863                         if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
864                                 color_space = COLOR_SPACE_SRGB_LIMITED;
865                         break;
866
867                 case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
868                         color_space = COLOR_SPACE_YCBCR601;
869                         if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
870                                 color_space = COLOR_SPACE_YCBCR601_LIMITED;
871                         break;
872                 case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
873                         color_space = COLOR_SPACE_YCBCR709;
874                         if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
875                                 color_space = COLOR_SPACE_YCBCR709_LIMITED;
876                         break;
877                 default:
878                         break;
879                 }
880
881                 if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable) {
882                         if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
883                                 union dmub_hw_lock_flags hw_locks = { 0 };
884                                 struct dmub_hw_lock_inst_flags inst_flags = { 0 };
885
886                                 hw_locks.bits.lock_dig = 1;
887                                 inst_flags.dig_inst = pipe_ctx->stream_res.tg->inst;
888
889                                 dmub_hw_lock_mgr_cmd(link->ctx->dmub_srv,
890                                                         true,
891                                                         &hw_locks,
892                                                         &inst_flags);
893                         } else
894                                 pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable(
895                                                 pipe_ctx->stream_res.tg);
896                 }
897
898                 pipe_ctx->stream_res.tg->funcs->lock(pipe_ctx->stream_res.tg);
899                 /* update MSA to requested color space */
900                 pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(pipe_ctx->stream_res.stream_enc,
901                                 &pipe_ctx->stream->timing,
902                                 color_space,
903                                 pipe_ctx->stream->use_vsc_sdp_for_colorimetry,
904                                 link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP);
905
906                 if (pipe_ctx->stream->use_vsc_sdp_for_colorimetry) {
907                         if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
908                                 pipe_ctx->stream->vsc_infopacket.sb[17] |= (1 << 7); // sb17 bit 7 Dynamic Range: 0 = VESA range, 1 = CTA range
909                         else
910                                 pipe_ctx->stream->vsc_infopacket.sb[17] &= ~(1 << 7);
911                         resource_build_info_frame(pipe_ctx);
912                         link->dc->hwss.update_info_frame(pipe_ctx);
913                 }
914
915                 /* CRTC Patterns */
916                 set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
917                 pipe_ctx->stream_res.tg->funcs->unlock(pipe_ctx->stream_res.tg);
918                 pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
919                                 CRTC_STATE_VACTIVE);
920                 pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
921                                 CRTC_STATE_VBLANK);
922                 pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
923                                 CRTC_STATE_VACTIVE);
924
925                 if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_disable) {
926                         if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
927                                 union dmub_hw_lock_flags hw_locks = { 0 };
928                                 struct dmub_hw_lock_inst_flags inst_flags = { 0 };
929
930                                 hw_locks.bits.lock_dig = 1;
931                                 inst_flags.dig_inst = pipe_ctx->stream_res.tg->inst;
932
933                                 dmub_hw_lock_mgr_cmd(link->ctx->dmub_srv,
934                                                         false,
935                                                         &hw_locks,
936                                                         &inst_flags);
937                         } else
938                                 pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_disable(
939                                                 pipe_ctx->stream_res.tg);
940                 }
941
942                 /* Set Test Pattern state */
943                 link->test_pattern_enabled = true;
944                 link->current_test_pattern = test_pattern;
945         }
946
947         return true;
948 }
949
950 void dp_set_preferred_link_settings(struct dc *dc,
951                 struct dc_link_settings *link_setting,
952                 struct dc_link *link)
953 {
954         int i;
955         struct pipe_ctx *pipe;
956         struct dc_stream_state *link_stream;
957         struct dc_link_settings store_settings = *link_setting;
958
959         link->preferred_link_setting = store_settings;
960
961         /* Retrain with preferred link settings only relevant for
962          * DP signal type
963          * Check for non-DP signal or if passive dongle present
964          */
965         if (!dc_is_dp_signal(link->connector_signal) ||
966                 link->dongle_max_pix_clk > 0)
967                 return;
968
969         for (i = 0; i < MAX_PIPES; i++) {
970                 pipe = &dc->current_state->res_ctx.pipe_ctx[i];
971                 if (pipe->stream && pipe->stream->link) {
972                         if (pipe->stream->link == link) {
973                                 link_stream = pipe->stream;
974                                 break;
975                         }
976                 }
977         }
978
979         /* Stream not found */
980         if (i == MAX_PIPES)
981                 return;
982
983         /* Cannot retrain link if backend is off */
984         if (link_stream->dpms_off)
985                 return;
986
987         if (link_decide_link_settings(link_stream, &store_settings))
988                 dp_retrain_link_dp_test(link, &store_settings, false);
989 }
990
991 void dp_set_preferred_training_settings(struct dc *dc,
992                 struct dc_link_settings *link_setting,
993                 struct dc_link_training_overrides *lt_overrides,
994                 struct dc_link *link,
995                 bool skip_immediate_retrain)
996 {
997         if (lt_overrides != NULL)
998                 link->preferred_training_settings = *lt_overrides;
999         else
1000                 memset(&link->preferred_training_settings, 0, sizeof(link->preferred_training_settings));
1001
1002         if (link_setting != NULL) {
1003                 link->preferred_link_setting = *link_setting;
1004         } else {
1005                 link->preferred_link_setting.lane_count = LANE_COUNT_UNKNOWN;
1006                 link->preferred_link_setting.link_rate = LINK_RATE_UNKNOWN;
1007         }
1008
1009         if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
1010                         link->type == dc_connection_mst_branch)
1011                 dm_helpers_dp_mst_update_branch_bandwidth(dc->ctx, link);
1012
1013         /* Retrain now, or wait until next stream update to apply */
1014         if (skip_immediate_retrain == false)
1015                 dp_set_preferred_link_settings(dc, &link->preferred_link_setting, link);
1016 }