1 | /* SPDX-License-Identifier: MIT */ |
2 | /* |
3 | * Copyright 2023 Advanced Micro Devices, Inc. |
4 | * |
5 | * Permission is hereby granted, free of charge, to any person obtaining a |
6 | * copy of this software and associated documentation files (the "Software"), |
7 | * to deal in the Software without restriction, including without limitation |
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
9 | * and/or sell copies of the Software, and to permit persons to whom the |
10 | * Software is furnished to do so, subject to the following conditions: |
11 | * |
12 | * The above copyright notice and this permission notice shall be included in |
13 | * all copies or substantial portions of the Software. |
14 | * |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
21 | * OTHER DEALINGS IN THE SOFTWARE. |
22 | * |
23 | */ |
24 | |
25 | |
26 | #include "dc_bios_types.h" |
27 | #include "dcn30/dcn30_dio_stream_encoder.h" |
28 | #include "dcn314/dcn314_dio_stream_encoder.h" |
29 | #include "dcn32/dcn32_dio_stream_encoder.h" |
30 | #include "dcn35_dio_stream_encoder.h" |
31 | #include "reg_helper.h" |
32 | #include "hw_shared.h" |
33 | #include "link.h" |
34 | #include "dpcd_defs.h" |
35 | |
36 | #define DC_LOGGER \ |
37 | enc1->base.ctx->logger |
38 | |
39 | #define REG(reg)\ |
40 | (enc1->regs->reg) |
41 | |
42 | #undef FN |
43 | #define FN(reg_name, field_name) \ |
44 | enc1->se_shift->field_name, enc1->se_mask->field_name |
45 | |
46 | #define VBI_LINE_0 0 |
47 | #define HDMI_CLOCK_CHANNEL_RATE_MORE_340M 340000 |
48 | |
49 | #define CTX \ |
50 | enc1->base.ctx |
51 | /* setup stream encoder in dvi mode */ |
52 | static void enc35_stream_encoder_dvi_set_stream_attribute( |
53 | struct stream_encoder *enc, |
54 | struct dc_crtc_timing *crtc_timing, |
55 | bool is_dual_link) |
56 | { |
57 | struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); |
58 | |
59 | if (!enc->ctx->dc->debug.avoid_vbios_exec_table) { |
60 | struct bp_encoder_control cntl = {0}; |
61 | |
62 | cntl.action = ENCODER_CONTROL_SETUP; |
63 | cntl.engine_id = enc1->base.id; |
64 | cntl.signal = is_dual_link ? |
65 | SIGNAL_TYPE_DVI_DUAL_LINK : SIGNAL_TYPE_DVI_SINGLE_LINK; |
66 | cntl.enable_dp_audio = false; |
67 | cntl.pixel_clock = crtc_timing->pix_clk_100hz / 10; |
68 | cntl.lanes_number = (is_dual_link) ? LANE_COUNT_EIGHT : LANE_COUNT_FOUR; |
69 | |
70 | if (enc1->base.bp->funcs->encoder_control( |
71 | enc1->base.bp, &cntl) != BP_RESULT_OK) |
72 | return; |
73 | |
74 | } else { |
75 | |
76 | //Set pattern for clock channel, default vlue 0x63 does not work |
77 | REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F); |
78 | |
79 | //DIG_BE_TMDS_DVI_MODE : TMDS-DVI mode is already set in link_encoder_setup |
80 | |
81 | //DIG_SOURCE_SELECT is already set in dig_connect_to_otg |
82 | |
83 | /* DIG_START is removed from the register spec */ |
84 | } |
85 | |
86 | ASSERT(crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB); |
87 | ASSERT(crtc_timing->display_color_depth == COLOR_DEPTH_888); |
88 | enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing); |
89 | } |
90 | /* setup stream encoder in hdmi mode */ |
91 | static void enc35_stream_encoder_hdmi_set_stream_attribute( |
92 | struct stream_encoder *enc, |
93 | struct dc_crtc_timing *crtc_timing, |
94 | int actual_pix_clk_khz, |
95 | bool enable_audio) |
96 | { |
97 | struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); |
98 | |
99 | if (!enc->ctx->dc->debug.avoid_vbios_exec_table) { |
100 | struct bp_encoder_control cntl = {0}; |
101 | |
102 | cntl.action = ENCODER_CONTROL_SETUP; |
103 | cntl.engine_id = enc1->base.id; |
104 | cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A; |
105 | cntl.enable_dp_audio = enable_audio; |
106 | cntl.pixel_clock = actual_pix_clk_khz; |
107 | cntl.lanes_number = LANE_COUNT_FOUR; |
108 | |
109 | if (enc1->base.bp->funcs->encoder_control( |
110 | enc1->base.bp, &cntl) != BP_RESULT_OK) |
111 | return; |
112 | |
113 | } else { |
114 | |
115 | //Set pattern for clock channel, default vlue 0x63 does not work |
116 | REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F); |
117 | |
118 | //DIG_BE_TMDS_HDMI_MODE : TMDS-HDMI mode is already set in link_encoder_setup |
119 | |
120 | //DIG_SOURCE_SELECT is already set in dig_connect_to_otg |
121 | |
122 | /* DIG_START is removed from the register spec */ |
123 | enc314_enable_fifo(enc); |
124 | } |
125 | |
126 | /* Configure pixel encoding */ |
127 | enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing); |
128 | |
129 | /* setup HDMI engine */ |
130 | REG_UPDATE_6(HDMI_CONTROL, |
131 | HDMI_PACKET_GEN_VERSION, 1, |
132 | HDMI_KEEPOUT_MODE, 1, |
133 | HDMI_DEEP_COLOR_ENABLE, 0, |
134 | HDMI_DATA_SCRAMBLE_EN, 0, |
135 | HDMI_NO_EXTRA_NULL_PACKET_FILLED, 1, |
136 | HDMI_CLOCK_CHANNEL_RATE, 0); |
137 | |
138 | /* Configure color depth */ |
139 | switch (crtc_timing->display_color_depth) { |
140 | case COLOR_DEPTH_888: |
141 | REG_UPDATE(HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, 0); |
142 | break; |
143 | case COLOR_DEPTH_101010: |
144 | if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) { |
145 | REG_UPDATE_2(HDMI_CONTROL, |
146 | HDMI_DEEP_COLOR_DEPTH, 1, |
147 | HDMI_DEEP_COLOR_ENABLE, 0); |
148 | } else { |
149 | REG_UPDATE_2(HDMI_CONTROL, |
150 | HDMI_DEEP_COLOR_DEPTH, 1, |
151 | HDMI_DEEP_COLOR_ENABLE, 1); |
152 | } |
153 | break; |
154 | case COLOR_DEPTH_121212: |
155 | if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) { |
156 | REG_UPDATE_2(HDMI_CONTROL, |
157 | HDMI_DEEP_COLOR_DEPTH, 2, |
158 | HDMI_DEEP_COLOR_ENABLE, 0); |
159 | } else { |
160 | REG_UPDATE_2(HDMI_CONTROL, |
161 | HDMI_DEEP_COLOR_DEPTH, 2, |
162 | HDMI_DEEP_COLOR_ENABLE, 1); |
163 | } |
164 | break; |
165 | case COLOR_DEPTH_161616: |
166 | REG_UPDATE_2(HDMI_CONTROL, |
167 | HDMI_DEEP_COLOR_DEPTH, 3, |
168 | HDMI_DEEP_COLOR_ENABLE, 1); |
169 | break; |
170 | default: |
171 | break; |
172 | } |
173 | |
174 | if (actual_pix_clk_khz >= HDMI_CLOCK_CHANNEL_RATE_MORE_340M) { |
175 | /* enable HDMI data scrambler |
176 | * HDMI_CLOCK_CHANNEL_RATE_MORE_340M |
177 | * Clock channel frequency is 1/4 of character rate. |
178 | */ |
179 | REG_UPDATE_2(HDMI_CONTROL, |
180 | HDMI_DATA_SCRAMBLE_EN, 1, |
181 | HDMI_CLOCK_CHANNEL_RATE, 1); |
182 | } else if (crtc_timing->flags.LTE_340MCSC_SCRAMBLE) { |
183 | |
184 | /* TODO: New feature for DCE11, still need to implement */ |
185 | |
186 | /* enable HDMI data scrambler |
187 | * HDMI_CLOCK_CHANNEL_FREQ_EQUAL_TO_CHAR_RATE |
188 | * Clock channel frequency is the same |
189 | * as character rate |
190 | */ |
191 | REG_UPDATE_2(HDMI_CONTROL, |
192 | HDMI_DATA_SCRAMBLE_EN, 1, |
193 | HDMI_CLOCK_CHANNEL_RATE, 0); |
194 | } |
195 | |
196 | |
197 | /* Enable transmission of General Control packet on every frame */ |
198 | REG_UPDATE_3(HDMI_VBI_PACKET_CONTROL, |
199 | HDMI_GC_CONT, 1, |
200 | HDMI_GC_SEND, 1, |
201 | HDMI_NULL_SEND, 1); |
202 | |
203 | /* Disable Audio Content Protection packet transmission */ |
204 | REG_UPDATE(HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, 0); |
205 | |
206 | /* following belongs to audio */ |
207 | /* Enable Audio InfoFrame packet transmission. */ |
208 | REG_UPDATE(HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_SEND, 1); |
209 | |
210 | /* update double-buffered AUDIO_INFO registers immediately */ |
211 | ASSERT(enc->afmt); |
212 | enc->afmt->funcs->audio_info_immediate_update(enc->afmt); |
213 | |
214 | /* Select line number on which to send Audio InfoFrame packets */ |
215 | REG_UPDATE(HDMI_INFOFRAME_CONTROL1, HDMI_AUDIO_INFO_LINE, |
216 | VBI_LINE_0 + 2); |
217 | |
218 | /* set HDMI GC AVMUTE */ |
219 | REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, 0); |
220 | switch (crtc_timing->pixel_encoding) { |
221 | case PIXEL_ENCODING_YCBCR422: |
222 | REG_UPDATE(HDMI_CONTROL, TMDS_PIXEL_ENCODING, 1); |
223 | break; |
224 | default: |
225 | REG_UPDATE(HDMI_CONTROL, TMDS_PIXEL_ENCODING, 0); |
226 | break; |
227 | } |
228 | REG_UPDATE(HDMI_CONTROL, TMDS_COLOR_FORMAT, 0); |
229 | } |
230 | |
231 | |
232 | |
233 | static void enc35_stream_encoder_enable( |
234 | struct stream_encoder *enc, |
235 | enum signal_type signal, |
236 | bool enable) |
237 | { |
238 | struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); |
239 | |
240 | if (enable) { |
241 | switch (signal) { |
242 | case SIGNAL_TYPE_DVI_SINGLE_LINK: |
243 | case SIGNAL_TYPE_DVI_DUAL_LINK: |
244 | /* TMDS-DVI */ |
245 | REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_MODE, 2); |
246 | break; |
247 | case SIGNAL_TYPE_HDMI_TYPE_A: |
248 | /* TMDS-HDMI */ |
249 | REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_MODE, 3); |
250 | break; |
251 | case SIGNAL_TYPE_DISPLAY_PORT_MST: |
252 | /* DP MST */ |
253 | REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_MODE, 5); |
254 | break; |
255 | case SIGNAL_TYPE_EDP: |
256 | case SIGNAL_TYPE_DISPLAY_PORT: |
257 | /* DP SST */ |
258 | REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_MODE, 0); |
259 | break; |
260 | default: |
261 | /* invalid mode ! */ |
262 | ASSERT_CRITICAL(false); |
263 | } |
264 | } |
265 | } |
266 | |
267 | static bool is_two_pixels_per_containter(const struct dc_crtc_timing *timing) |
268 | { |
269 | bool two_pix = timing->pixel_encoding == PIXEL_ENCODING_YCBCR420; |
270 | |
271 | two_pix = two_pix || (timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422 |
272 | && !timing->dsc_cfg.ycbcr422_simple); |
273 | return two_pix; |
274 | } |
275 | |
276 | static bool is_h_timing_divisible_by_2(const struct dc_crtc_timing *timing) |
277 | { |
278 | /* math borrowed from function of same name in inc/resource |
279 | * checks if h_timing is divisible by 2 |
280 | */ |
281 | |
282 | bool divisible = false; |
283 | uint16_t h_blank_start = 0; |
284 | uint16_t h_blank_end = 0; |
285 | |
286 | if (timing) { |
287 | h_blank_start = timing->h_total - timing->h_front_porch; |
288 | h_blank_end = h_blank_start - timing->h_addressable; |
289 | |
290 | /* HTOTAL, Hblank start/end, and Hsync start/end all must be |
291 | * divisible by 2 in order for the horizontal timing params |
292 | * to be considered divisible by 2. Hsync start is always 0. |
293 | */ |
294 | divisible = (timing->h_total % 2 == 0) && |
295 | (h_blank_start % 2 == 0) && |
296 | (h_blank_end % 2 == 0) && |
297 | (timing->h_sync_width % 2 == 0); |
298 | } |
299 | return divisible; |
300 | } |
301 | |
302 | static bool is_dp_dig_pixel_rate_div_policy(struct dc *dc, const struct dc_crtc_timing *timing) |
303 | { |
304 | /* should be functionally the same as dcn32_is_dp_dig_pixel_rate_div_policy for DP encoders*/ |
305 | return is_h_timing_divisible_by_2(timing) && |
306 | dc->debug.enable_dp_dig_pixel_rate_div_policy; |
307 | } |
308 | |
309 | static void enc35_stream_encoder_dp_unblank( |
310 | struct dc_link *link, |
311 | struct stream_encoder *enc, |
312 | const struct encoder_unblank_param *param) |
313 | { |
314 | struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); |
315 | struct dc *dc = enc->ctx->dc; |
316 | |
317 | if (param->link_settings.link_rate != LINK_RATE_UNKNOWN) { |
318 | uint32_t n_vid = 0x8000; |
319 | uint32_t m_vid; |
320 | uint32_t n_multiply = 0; |
321 | uint32_t pix_per_cycle = 0; |
322 | uint64_t m_vid_l = n_vid; |
323 | |
324 | /* YCbCr 4:2:0 : Computed VID_M will be 2X the input rate */ |
325 | if (is_two_pixels_per_containter(timing: ¶m->timing) || param->opp_cnt > 1 |
326 | || is_dp_dig_pixel_rate_div_policy(dc, timing: ¶m->timing)) { |
327 | /*this logic should be the same in get_pixel_clock_parameters() */ |
328 | n_multiply = 1; |
329 | pix_per_cycle = 1; |
330 | } |
331 | /* M / N = Fstream / Flink |
332 | * m_vid / n_vid = pixel rate / link rate |
333 | */ |
334 | |
335 | m_vid_l *= param->timing.pix_clk_100hz / 10; |
336 | m_vid_l = div_u64(dividend: m_vid_l, |
337 | divisor: param->link_settings.link_rate |
338 | * LINK_RATE_REF_FREQ_IN_KHZ); |
339 | |
340 | m_vid = (uint32_t) m_vid_l; |
341 | |
342 | /* enable auto measurement */ |
343 | |
344 | REG_UPDATE(DP_VID_TIMING, DP_VID_M_N_GEN_EN, 0); |
345 | |
346 | /* auto measurement need 1 full 0x8000 symbol cycle to kick in, |
347 | * therefore program initial value for Mvid and Nvid |
348 | */ |
349 | |
350 | REG_UPDATE(DP_VID_N, DP_VID_N, n_vid); |
351 | |
352 | REG_UPDATE(DP_VID_M, DP_VID_M, m_vid); |
353 | |
354 | REG_UPDATE_2(DP_VID_TIMING, |
355 | DP_VID_M_N_GEN_EN, 1, |
356 | DP_VID_N_MUL, n_multiply); |
357 | |
358 | REG_UPDATE(DP_PIXEL_FORMAT, |
359 | DP_PIXEL_PER_CYCLE_PROCESSING_MODE, |
360 | pix_per_cycle); |
361 | } |
362 | |
363 | /* make sure stream is disabled before resetting steer fifo */ |
364 | REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, false); |
365 | REG_WAIT(DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, 0, 10, 5000); |
366 | |
367 | /* DIG_START is removed from the register spec */ |
368 | |
369 | /* switch DP encoder to CRTC data, but reset it the fifo first. It may happen |
370 | * that it overflows during mode transition, and sometimes doesn't recover. |
371 | */ |
372 | REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 1); |
373 | udelay(10); |
374 | |
375 | REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0); |
376 | |
377 | /* wait 100us for DIG/DP logic to prime |
378 | * (i.e. a few video lines) |
379 | */ |
380 | udelay(100); |
381 | |
382 | /* the hardware would start sending video at the start of the next DP |
383 | * frame (i.e. rising edge of the vblank). |
384 | * NOTE: We used to program DP_VID_STREAM_DIS_DEFER = 2 here, but this |
385 | * register has no effect on enable transition! HW always makes sure |
386 | * VID_STREAM enable at start of next frame, and this is not |
387 | * programmable |
388 | */ |
389 | |
390 | REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true); |
391 | |
392 | /* |
393 | * DIG Resync FIFO now needs to be explicitly enabled. |
394 | * This should come after DP_VID_STREAM_ENABLE per HW docs. |
395 | */ |
396 | enc314_enable_fifo(enc); |
397 | |
398 | link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM); |
399 | } |
400 | |
401 | static void enc35_stream_encoder_map_to_link( |
402 | struct stream_encoder *enc, |
403 | uint32_t stream_enc_inst, |
404 | uint32_t link_enc_inst) |
405 | { |
406 | struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); |
407 | |
408 | ASSERT(stream_enc_inst < 5 && link_enc_inst < 5); |
409 | REG_UPDATE(STREAM_MAPPER_CONTROL, |
410 | DIG_STREAM_LINK_TARGET, link_enc_inst); |
411 | } |
412 | |
413 | static void enc35_reset_fifo(struct stream_encoder *enc, bool reset) |
414 | { |
415 | struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); |
416 | uint32_t reset_val = reset ? 1 : 0; |
417 | uint32_t is_symclk_on; |
418 | |
419 | REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, reset_val); |
420 | REG_GET(DIG_FE_CLK_CNTL, DIG_FE_SYMCLK_FE_G_CLOCK_ON, &is_symclk_on); |
421 | |
422 | if (is_symclk_on) |
423 | REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, reset_val, 10, 5000); |
424 | else |
425 | udelay(10); |
426 | } |
427 | |
428 | static void enc35_disable_fifo(struct stream_encoder *enc) |
429 | { |
430 | struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); |
431 | |
432 | REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 0); |
433 | REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 0); |
434 | REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 0); |
435 | } |
436 | |
437 | static void enc35_enable_fifo(struct stream_encoder *enc) |
438 | { |
439 | struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); |
440 | |
441 | REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, 0x7); |
442 | REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 1); |
443 | REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 1); |
444 | |
445 | enc35_reset_fifo(enc, reset: true); |
446 | enc35_reset_fifo(enc, reset: false); |
447 | |
448 | REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 1); |
449 | } |
450 | |
451 | static const struct stream_encoder_funcs dcn35_str_enc_funcs = { |
452 | .dp_set_odm_combine = |
453 | enc314_dp_set_odm_combine, |
454 | .dp_set_stream_attribute = |
455 | enc2_stream_encoder_dp_set_stream_attribute, |
456 | .hdmi_set_stream_attribute = |
457 | enc35_stream_encoder_hdmi_set_stream_attribute, |
458 | .dvi_set_stream_attribute = |
459 | enc35_stream_encoder_dvi_set_stream_attribute, |
460 | .set_throttled_vcp_size = |
461 | enc1_stream_encoder_set_throttled_vcp_size, |
462 | .update_hdmi_info_packets = |
463 | enc3_stream_encoder_update_hdmi_info_packets, |
464 | .stop_hdmi_info_packets = |
465 | enc3_stream_encoder_stop_hdmi_info_packets, |
466 | .update_dp_info_packets_sdp_line_num = |
467 | enc3_stream_encoder_update_dp_info_packets_sdp_line_num, |
468 | .update_dp_info_packets = |
469 | enc3_stream_encoder_update_dp_info_packets, |
470 | .stop_dp_info_packets = |
471 | enc1_stream_encoder_stop_dp_info_packets, |
472 | .dp_blank = |
473 | enc314_stream_encoder_dp_blank, |
474 | .dp_unblank = |
475 | enc35_stream_encoder_dp_unblank, |
476 | .audio_mute_control = enc3_audio_mute_control, |
477 | |
478 | .dp_audio_setup = enc3_se_dp_audio_setup, |
479 | .dp_audio_enable = enc3_se_dp_audio_enable, |
480 | .dp_audio_disable = enc1_se_dp_audio_disable, |
481 | |
482 | .hdmi_audio_setup = enc3_se_hdmi_audio_setup, |
483 | .hdmi_audio_disable = enc1_se_hdmi_audio_disable, |
484 | .setup_stereo_sync = enc1_setup_stereo_sync, |
485 | .set_avmute = enc1_stream_encoder_set_avmute, |
486 | .dig_connect_to_otg = enc1_dig_connect_to_otg, |
487 | .dig_source_otg = enc1_dig_source_otg, |
488 | |
489 | .dp_get_pixel_format = enc1_stream_encoder_dp_get_pixel_format, |
490 | |
491 | .enc_read_state = enc314_read_state, |
492 | .dp_set_dsc_config = enc314_dp_set_dsc_config, |
493 | .dp_set_dsc_pps_info_packet = enc3_dp_set_dsc_pps_info_packet, |
494 | .set_dynamic_metadata = enc2_set_dynamic_metadata, |
495 | .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute, |
496 | .dig_stream_enable = enc35_stream_encoder_enable, |
497 | |
498 | .set_input_mode = enc314_set_dig_input_mode, |
499 | .enable_fifo = enc35_enable_fifo, |
500 | .disable_fifo = enc35_disable_fifo, |
501 | .map_stream_to_link = enc35_stream_encoder_map_to_link, |
502 | }; |
503 | |
504 | void dcn35_dio_stream_encoder_construct( |
505 | struct dcn10_stream_encoder *enc1, |
506 | struct dc_context *ctx, |
507 | struct dc_bios *bp, |
508 | enum engine_id eng_id, |
509 | struct vpg *vpg, |
510 | struct afmt *afmt, |
511 | const struct dcn10_stream_enc_registers *regs, |
512 | const struct dcn10_stream_encoder_shift *se_shift, |
513 | const struct dcn10_stream_encoder_mask *se_mask) |
514 | { |
515 | enc1->base.funcs = &dcn35_str_enc_funcs; |
516 | enc1->base.ctx = ctx; |
517 | enc1->base.id = eng_id; |
518 | enc1->base.bp = bp; |
519 | enc1->base.vpg = vpg; |
520 | enc1->base.afmt = afmt; |
521 | enc1->regs = regs; |
522 | enc1->se_shift = se_shift; |
523 | enc1->se_mask = se_mask; |
524 | enc1->base.stream_enc_inst = vpg->inst; |
525 | } |
526 | |
527 | |