Line data Source code
1 : /*
2 : * Copyright 2020 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 :
27 : #include "dc_bios_types.h"
28 : #include "dcn30_dio_stream_encoder.h"
29 : #include "reg_helper.h"
30 : #include "hw_shared.h"
31 : #include "core_types.h"
32 : #include <linux/delay.h>
33 :
34 :
35 : #define DC_LOGGER \
36 : enc1->base.ctx->logger
37 :
38 : #define REG(reg)\
39 : (enc1->regs->reg)
40 :
41 : #undef FN
42 : #define FN(reg_name, field_name) \
43 : enc1->se_shift->field_name, enc1->se_mask->field_name
44 :
45 : #define VBI_LINE_0 0
46 : #define HDMI_CLOCK_CHANNEL_RATE_MORE_340M 340000
47 :
48 : #define CTX \
49 : enc1->base.ctx
50 :
51 :
52 0 : static void enc3_update_hdmi_info_packet(
53 : struct dcn10_stream_encoder *enc1,
54 : uint32_t packet_index,
55 : const struct dc_info_packet *info_packet)
56 : {
57 : uint32_t cont, send, line;
58 :
59 0 : if (info_packet->valid) {
60 0 : enc1->base.vpg->funcs->update_generic_info_packet(
61 : enc1->base.vpg,
62 : packet_index,
63 : info_packet,
64 : true);
65 :
66 : /* enable transmission of packet(s) -
67 : * packet transmission begins on the next frame */
68 0 : cont = 1;
69 : /* send packet(s) every frame */
70 0 : send = 1;
71 : /* select line number to send packets on */
72 0 : line = 2;
73 : } else {
74 : cont = 0;
75 : send = 0;
76 : line = 0;
77 : }
78 :
79 : /* DP_SEC_GSP[x]_LINE_REFERENCE - keep default value REFER_TO_DP_SOF */
80 :
81 : /* choose which generic packet control to use */
82 0 : switch (packet_index) {
83 : case 0:
84 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
85 : HDMI_GENERIC0_CONT, cont,
86 : HDMI_GENERIC0_SEND, send);
87 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL1,
88 : HDMI_GENERIC0_LINE, line);
89 0 : break;
90 : case 1:
91 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
92 : HDMI_GENERIC1_CONT, cont,
93 : HDMI_GENERIC1_SEND, send);
94 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL1,
95 : HDMI_GENERIC1_LINE, line);
96 0 : break;
97 : case 2:
98 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
99 : HDMI_GENERIC2_CONT, cont,
100 : HDMI_GENERIC2_SEND, send);
101 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL2,
102 : HDMI_GENERIC2_LINE, line);
103 0 : break;
104 : case 3:
105 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
106 : HDMI_GENERIC3_CONT, cont,
107 : HDMI_GENERIC3_SEND, send);
108 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL2,
109 : HDMI_GENERIC3_LINE, line);
110 0 : break;
111 : case 4:
112 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
113 : HDMI_GENERIC4_CONT, cont,
114 : HDMI_GENERIC4_SEND, send);
115 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL3,
116 : HDMI_GENERIC4_LINE, line);
117 0 : break;
118 : case 5:
119 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
120 : HDMI_GENERIC5_CONT, cont,
121 : HDMI_GENERIC5_SEND, send);
122 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL3,
123 : HDMI_GENERIC5_LINE, line);
124 0 : break;
125 : case 6:
126 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
127 : HDMI_GENERIC6_CONT, cont,
128 : HDMI_GENERIC6_SEND, send);
129 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL4,
130 : HDMI_GENERIC6_LINE, line);
131 0 : break;
132 : case 7:
133 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
134 : HDMI_GENERIC7_CONT, cont,
135 : HDMI_GENERIC7_SEND, send);
136 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL4,
137 : HDMI_GENERIC7_LINE, line);
138 0 : break;
139 : case 8:
140 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL6,
141 : HDMI_GENERIC8_CONT, cont,
142 : HDMI_GENERIC8_SEND, send);
143 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL7,
144 : HDMI_GENERIC8_LINE, line);
145 0 : break;
146 : case 9:
147 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL6,
148 : HDMI_GENERIC9_CONT, cont,
149 : HDMI_GENERIC9_SEND, send);
150 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL7,
151 : HDMI_GENERIC9_LINE, line);
152 0 : break;
153 : case 10:
154 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL6,
155 : HDMI_GENERIC10_CONT, cont,
156 : HDMI_GENERIC10_SEND, send);
157 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL8,
158 : HDMI_GENERIC10_LINE, line);
159 0 : break;
160 : case 11:
161 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL6,
162 : HDMI_GENERIC11_CONT, cont,
163 : HDMI_GENERIC11_SEND, send);
164 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL8,
165 : HDMI_GENERIC11_LINE, line);
166 0 : break;
167 : case 12:
168 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL6,
169 : HDMI_GENERIC12_CONT, cont,
170 : HDMI_GENERIC12_SEND, send);
171 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL9,
172 : HDMI_GENERIC12_LINE, line);
173 0 : break;
174 : case 13:
175 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL6,
176 : HDMI_GENERIC13_CONT, cont,
177 : HDMI_GENERIC13_SEND, send);
178 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL9,
179 : HDMI_GENERIC13_LINE, line);
180 0 : break;
181 : case 14:
182 0 : REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL6,
183 : HDMI_GENERIC14_CONT, cont,
184 : HDMI_GENERIC14_SEND, send);
185 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL10,
186 : HDMI_GENERIC14_LINE, line);
187 0 : break;
188 : default:
189 : /* invalid HW packet index */
190 0 : DC_LOG_WARNING(
191 : "Invalid HW packet index: %s()\n",
192 : __func__);
193 0 : return;
194 : }
195 : }
196 :
197 0 : void enc3_stream_encoder_update_hdmi_info_packets(
198 : struct stream_encoder *enc,
199 : const struct encoder_info_frame *info_frame)
200 : {
201 0 : struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
202 :
203 : /* for bring up, disable dp double TODO */
204 0 : REG_UPDATE(HDMI_DB_CONTROL, HDMI_DB_DISABLE, 1);
205 0 : REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1);
206 :
207 : /*Always add mandatory packets first followed by optional ones*/
208 0 : enc3_update_hdmi_info_packet(enc1, 0, &info_frame->avi);
209 0 : enc3_update_hdmi_info_packet(enc1, 5, &info_frame->hfvsif);
210 0 : enc3_update_hdmi_info_packet(enc1, 2, &info_frame->gamut);
211 0 : enc3_update_hdmi_info_packet(enc1, 1, &info_frame->vendor);
212 0 : enc3_update_hdmi_info_packet(enc1, 3, &info_frame->spd);
213 0 : enc3_update_hdmi_info_packet(enc1, 4, &info_frame->hdrsmd);
214 0 : enc3_update_hdmi_info_packet(enc1, 6, &info_frame->vtem);
215 0 : }
216 :
217 0 : void enc3_stream_encoder_stop_hdmi_info_packets(
218 : struct stream_encoder *enc)
219 : {
220 0 : struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
221 :
222 : /* stop generic packets 0,1 on HDMI */
223 0 : REG_SET_4(HDMI_GENERIC_PACKET_CONTROL0, 0,
224 : HDMI_GENERIC0_CONT, 0,
225 : HDMI_GENERIC0_SEND, 0,
226 : HDMI_GENERIC1_CONT, 0,
227 : HDMI_GENERIC1_SEND, 0);
228 0 : REG_SET_2(HDMI_GENERIC_PACKET_CONTROL1, 0,
229 : HDMI_GENERIC0_LINE, 0,
230 : HDMI_GENERIC1_LINE, 0);
231 :
232 : /* stop generic packets 2,3 on HDMI */
233 0 : REG_SET_4(HDMI_GENERIC_PACKET_CONTROL0, 0,
234 : HDMI_GENERIC2_CONT, 0,
235 : HDMI_GENERIC2_SEND, 0,
236 : HDMI_GENERIC3_CONT, 0,
237 : HDMI_GENERIC3_SEND, 0);
238 0 : REG_SET_2(HDMI_GENERIC_PACKET_CONTROL2, 0,
239 : HDMI_GENERIC2_LINE, 0,
240 : HDMI_GENERIC3_LINE, 0);
241 :
242 : /* stop generic packets 4,5 on HDMI */
243 0 : REG_SET_4(HDMI_GENERIC_PACKET_CONTROL0, 0,
244 : HDMI_GENERIC4_CONT, 0,
245 : HDMI_GENERIC4_SEND, 0,
246 : HDMI_GENERIC5_CONT, 0,
247 : HDMI_GENERIC5_SEND, 0);
248 0 : REG_SET_2(HDMI_GENERIC_PACKET_CONTROL3, 0,
249 : HDMI_GENERIC4_LINE, 0,
250 : HDMI_GENERIC5_LINE, 0);
251 :
252 : /* stop generic packets 6,7 on HDMI */
253 0 : REG_SET_4(HDMI_GENERIC_PACKET_CONTROL0, 0,
254 : HDMI_GENERIC6_CONT, 0,
255 : HDMI_GENERIC6_SEND, 0,
256 : HDMI_GENERIC7_CONT, 0,
257 : HDMI_GENERIC7_SEND, 0);
258 0 : REG_SET_2(HDMI_GENERIC_PACKET_CONTROL4, 0,
259 : HDMI_GENERIC6_LINE, 0,
260 : HDMI_GENERIC7_LINE, 0);
261 :
262 : /* stop generic packets 8,9 on HDMI */
263 0 : REG_SET_4(HDMI_GENERIC_PACKET_CONTROL6, 0,
264 : HDMI_GENERIC8_CONT, 0,
265 : HDMI_GENERIC8_SEND, 0,
266 : HDMI_GENERIC9_CONT, 0,
267 : HDMI_GENERIC9_SEND, 0);
268 0 : REG_SET_2(HDMI_GENERIC_PACKET_CONTROL7, 0,
269 : HDMI_GENERIC8_LINE, 0,
270 : HDMI_GENERIC9_LINE, 0);
271 :
272 : /* stop generic packets 10,11 on HDMI */
273 0 : REG_SET_4(HDMI_GENERIC_PACKET_CONTROL6, 0,
274 : HDMI_GENERIC10_CONT, 0,
275 : HDMI_GENERIC10_SEND, 0,
276 : HDMI_GENERIC11_CONT, 0,
277 : HDMI_GENERIC11_SEND, 0);
278 0 : REG_SET_2(HDMI_GENERIC_PACKET_CONTROL8, 0,
279 : HDMI_GENERIC10_LINE, 0,
280 : HDMI_GENERIC11_LINE, 0);
281 :
282 : /* stop generic packets 12,13 on HDMI */
283 0 : REG_SET_4(HDMI_GENERIC_PACKET_CONTROL6, 0,
284 : HDMI_GENERIC12_CONT, 0,
285 : HDMI_GENERIC12_SEND, 0,
286 : HDMI_GENERIC13_CONT, 0,
287 : HDMI_GENERIC13_SEND, 0);
288 0 : REG_SET_2(HDMI_GENERIC_PACKET_CONTROL9, 0,
289 : HDMI_GENERIC12_LINE, 0,
290 : HDMI_GENERIC13_LINE, 0);
291 :
292 : /* stop generic packet 14 on HDMI */
293 0 : REG_SET_2(HDMI_GENERIC_PACKET_CONTROL6, 0,
294 : HDMI_GENERIC14_CONT, 0,
295 : HDMI_GENERIC14_SEND, 0);
296 0 : REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL10,
297 : HDMI_GENERIC14_LINE, 0);
298 0 : }
299 :
300 : /* Set DSC-related configuration.
301 : * dsc_mode: 0 disables DSC, other values enable DSC in specified format
302 : * sc_bytes_per_pixel: Bytes per pixel in u3.28 format
303 : * dsc_slice_width: Slice width in pixels
304 : */
305 0 : static void enc3_dp_set_dsc_config(struct stream_encoder *enc,
306 : enum optc_dsc_mode dsc_mode,
307 : uint32_t dsc_bytes_per_pixel,
308 : uint32_t dsc_slice_width)
309 : {
310 0 : struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
311 :
312 0 : REG_UPDATE_2(DP_DSC_CNTL,
313 : DP_DSC_MODE, dsc_mode,
314 : DP_DSC_SLICE_WIDTH, dsc_slice_width);
315 :
316 0 : REG_SET(DP_DSC_BYTES_PER_PIXEL, 0,
317 : DP_DSC_BYTES_PER_PIXEL, dsc_bytes_per_pixel);
318 0 : }
319 :
320 :
321 0 : void enc3_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,
322 : bool enable,
323 : uint8_t *dsc_packed_pps,
324 : bool immediate_update)
325 : {
326 0 : struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
327 :
328 0 : if (enable) {
329 : struct dc_info_packet pps_sdp;
330 : int i;
331 :
332 : /* Configure for PPS packet size (128 bytes) */
333 0 : REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP11_PPS, 1);
334 :
335 : /* We need turn on clock before programming AFMT block
336 : *
337 : * TODO: We may not need this here anymore since update_generic_info_packet
338 : * no longer touches AFMT
339 : */
340 0 : REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1);
341 :
342 : /* Load PPS into infoframe (SDP) registers */
343 0 : pps_sdp.valid = true;
344 0 : pps_sdp.hb0 = 0;
345 0 : pps_sdp.hb1 = DC_DP_INFOFRAME_TYPE_PPS;
346 0 : pps_sdp.hb2 = 127;
347 0 : pps_sdp.hb3 = 0;
348 :
349 0 : for (i = 0; i < 4; i++) {
350 0 : memcpy(pps_sdp.sb, &dsc_packed_pps[i * 32], 32);
351 0 : enc1->base.vpg->funcs->update_generic_info_packet(
352 : enc1->base.vpg,
353 0 : 11 + i,
354 : &pps_sdp,
355 : immediate_update);
356 : }
357 :
358 : /* SW should make sure VBID[6] update line number is bigger
359 : * than PPS transmit line number
360 : */
361 0 : REG_UPDATE(DP_GSP11_CNTL,
362 : DP_SEC_GSP11_LINE_NUM, 2);
363 0 : REG_UPDATE_2(DP_MSA_VBID_MISC,
364 : DP_VBID6_LINE_REFERENCE, 0,
365 : DP_VBID6_LINE_NUM, 3);
366 :
367 : /* Send PPS data at the line number specified above.
368 : * DP spec requires PPS to be sent only when it changes, however since
369 : * decoder has to be able to handle its change on every frame, we're
370 : * sending it always (i.e. on every frame) to reduce the chance it'd be
371 : * missed by decoder. If it turns out required to send PPS only when it
372 : * changes, we can use DP_SEC_GSP11_SEND register.
373 : */
374 0 : REG_UPDATE(DP_GSP11_CNTL,
375 : DP_SEC_GSP11_ENABLE, 1);
376 0 : REG_UPDATE(DP_SEC_CNTL,
377 : DP_SEC_STREAM_ENABLE, 1);
378 : } else {
379 : /* Disable Generic Stream Packet 11 (GSP) transmission */
380 0 : REG_UPDATE(DP_GSP11_CNTL, DP_SEC_GSP11_ENABLE, 0);
381 0 : REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP11_PPS, 0);
382 : }
383 0 : }
384 :
385 :
386 : /* this function read dsc related register fields to be logged later in dcn10_log_hw_state
387 : * into a dcn_dsc_state struct.
388 : */
389 0 : static void enc3_read_state(struct stream_encoder *enc, struct enc_state *s)
390 : {
391 0 : struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
392 :
393 : //if dsc is enabled, continue to read
394 0 : REG_GET(DP_DSC_CNTL, DP_DSC_MODE, &s->dsc_mode);
395 0 : if (s->dsc_mode) {
396 0 : REG_GET(DP_DSC_CNTL, DP_DSC_SLICE_WIDTH, &s->dsc_slice_width);
397 0 : REG_GET(DP_GSP11_CNTL, DP_SEC_GSP11_LINE_NUM, &s->sec_gsp_pps_line_num);
398 :
399 0 : REG_GET(DP_MSA_VBID_MISC, DP_VBID6_LINE_REFERENCE, &s->vbid6_line_reference);
400 0 : REG_GET(DP_MSA_VBID_MISC, DP_VBID6_LINE_NUM, &s->vbid6_line_num);
401 :
402 0 : REG_GET(DP_GSP11_CNTL, DP_SEC_GSP11_ENABLE, &s->sec_gsp_pps_enable);
403 0 : REG_GET(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, &s->sec_stream_enable);
404 : }
405 0 : }
406 :
407 0 : void enc3_stream_encoder_update_dp_info_packets(
408 : struct stream_encoder *enc,
409 : const struct encoder_info_frame *info_frame)
410 : {
411 0 : struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
412 0 : uint32_t value = 0;
413 0 : uint32_t dmdata_packet_enabled = 0;
414 :
415 0 : if (info_frame->vsc.valid) {
416 0 : enc->vpg->funcs->update_generic_info_packet(
417 : enc->vpg,
418 : 0, /* packetIndex */
419 : &info_frame->vsc,
420 : true);
421 : }
422 : /* TODO: VSC SDP at packetIndex 1 should be restricted only if PSR-SU on.
423 : * There should have another Infopacket type (e.g. vsc_psrsu) for PSR_SU.
424 : * In addition, currently the driver check the valid bit then update and
425 : * send the corresponding Infopacket. For PSR-SU, the SDP only be sent
426 : * while entering PSR-SU mode. So we need another parameter(e.g. send)
427 : * in dc_info_packet to indicate which infopacket should be enabled by
428 : * default here.
429 : */
430 0 : if (info_frame->vsc.valid) {
431 0 : enc->vpg->funcs->update_generic_info_packet(
432 : enc->vpg,
433 : 1, /* packetIndex */
434 : &info_frame->vsc,
435 : true);
436 : }
437 0 : if (info_frame->spd.valid) {
438 0 : enc->vpg->funcs->update_generic_info_packet(
439 : enc->vpg,
440 : 2, /* packetIndex */
441 : &info_frame->spd,
442 : true);
443 : }
444 0 : if (info_frame->hdrsmd.valid) {
445 0 : enc->vpg->funcs->update_generic_info_packet(
446 : enc->vpg,
447 : 3, /* packetIndex */
448 : &info_frame->hdrsmd,
449 : true);
450 : }
451 : /* packetIndex 4 is used for send immediate sdp message, and please
452 : * use other packetIndex (such as 5,6) for other info packet
453 : */
454 :
455 : /* enable/disable transmission of packet(s).
456 : * If enabled, packet transmission begins on the next frame
457 : */
458 0 : REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP0_ENABLE, info_frame->vsc.valid);
459 0 : REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP2_ENABLE, info_frame->spd.valid);
460 0 : REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP3_ENABLE, info_frame->hdrsmd.valid);
461 :
462 : /* This bit is the master enable bit.
463 : * When enabling secondary stream engine,
464 : * this master bit must also be set.
465 : * This register shared with audio info frame.
466 : * Therefore we need to enable master bit
467 : * if at least on of the fields is not 0
468 : */
469 0 : value = REG_READ(DP_SEC_CNTL);
470 0 : if (value)
471 0 : REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
472 :
473 : /* check if dynamic metadata packet transmission is enabled */
474 0 : REG_GET(DP_SEC_METADATA_TRANSMISSION,
475 : DP_SEC_METADATA_PACKET_ENABLE, &dmdata_packet_enabled);
476 :
477 0 : if (dmdata_packet_enabled)
478 0 : REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
479 0 : }
480 :
481 0 : static void enc3_dp_set_odm_combine(
482 : struct stream_encoder *enc,
483 : bool odm_combine)
484 : {
485 0 : struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
486 :
487 0 : REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_COMBINE, odm_combine);
488 0 : }
489 :
490 : /* setup stream encoder in dvi mode */
491 0 : static void enc3_stream_encoder_dvi_set_stream_attribute(
492 : struct stream_encoder *enc,
493 : struct dc_crtc_timing *crtc_timing,
494 : bool is_dual_link)
495 : {
496 0 : struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
497 :
498 0 : if (!enc->ctx->dc->debug.avoid_vbios_exec_table) {
499 0 : struct bp_encoder_control cntl = {0};
500 :
501 0 : cntl.action = ENCODER_CONTROL_SETUP;
502 0 : cntl.engine_id = enc1->base.id;
503 0 : cntl.signal = is_dual_link ?
504 0 : SIGNAL_TYPE_DVI_DUAL_LINK : SIGNAL_TYPE_DVI_SINGLE_LINK;
505 : cntl.enable_dp_audio = false;
506 0 : cntl.pixel_clock = crtc_timing->pix_clk_100hz / 10;
507 0 : cntl.lanes_number = (is_dual_link) ? LANE_COUNT_EIGHT : LANE_COUNT_FOUR;
508 :
509 0 : if (enc1->base.bp->funcs->encoder_control(
510 : enc1->base.bp, &cntl) != BP_RESULT_OK)
511 0 : return;
512 :
513 : } else {
514 :
515 : //Set pattern for clock channel, default vlue 0x63 does not work
516 0 : REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F);
517 :
518 : //DIG_BE_TMDS_DVI_MODE : TMDS-DVI mode is already set in link_encoder_setup
519 :
520 : //DIG_SOURCE_SELECT is already set in dig_connect_to_otg
521 :
522 : /* set DIG_START to 0x1 to reset FIFO */
523 0 : REG_UPDATE(DIG_FE_CNTL, DIG_START, 1);
524 0 : udelay(1);
525 :
526 : /* write 0 to take the FIFO out of reset */
527 0 : REG_UPDATE(DIG_FE_CNTL, DIG_START, 0);
528 : udelay(1);
529 : }
530 :
531 0 : ASSERT(crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB);
532 0 : ASSERT(crtc_timing->display_color_depth == COLOR_DEPTH_888);
533 0 : enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing);
534 : }
535 :
536 : /* setup stream encoder in hdmi mode */
537 0 : static void enc3_stream_encoder_hdmi_set_stream_attribute(
538 : struct stream_encoder *enc,
539 : struct dc_crtc_timing *crtc_timing,
540 : int actual_pix_clk_khz,
541 : bool enable_audio)
542 : {
543 0 : struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
544 :
545 0 : if (!enc->ctx->dc->debug.avoid_vbios_exec_table) {
546 0 : struct bp_encoder_control cntl = {0};
547 :
548 0 : cntl.action = ENCODER_CONTROL_SETUP;
549 0 : cntl.engine_id = enc1->base.id;
550 0 : cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A;
551 0 : cntl.enable_dp_audio = enable_audio;
552 0 : cntl.pixel_clock = actual_pix_clk_khz;
553 0 : cntl.lanes_number = LANE_COUNT_FOUR;
554 :
555 0 : if (enc1->base.bp->funcs->encoder_control(
556 : enc1->base.bp, &cntl) != BP_RESULT_OK)
557 0 : return;
558 :
559 : } else {
560 :
561 : //Set pattern for clock channel, default vlue 0x63 does not work
562 0 : REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F);
563 :
564 : //DIG_BE_TMDS_HDMI_MODE : TMDS-HDMI mode is already set in link_encoder_setup
565 :
566 : //DIG_SOURCE_SELECT is already set in dig_connect_to_otg
567 :
568 : /* set DIG_START to 0x1 to reset FIFO */
569 0 : REG_UPDATE(DIG_FE_CNTL, DIG_START, 1);
570 0 : udelay(1);
571 :
572 : /* write 0 to take the FIFO out of reset */
573 0 : REG_UPDATE(DIG_FE_CNTL, DIG_START, 0);
574 : udelay(1);
575 : }
576 :
577 : /* Configure pixel encoding */
578 0 : enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing);
579 :
580 : /* setup HDMI engine */
581 0 : REG_UPDATE_6(HDMI_CONTROL,
582 : HDMI_PACKET_GEN_VERSION, 1,
583 : HDMI_KEEPOUT_MODE, 1,
584 : HDMI_DEEP_COLOR_ENABLE, 0,
585 : HDMI_DATA_SCRAMBLE_EN, 0,
586 : HDMI_NO_EXTRA_NULL_PACKET_FILLED, 1,
587 : HDMI_CLOCK_CHANNEL_RATE, 0);
588 :
589 : /* Configure color depth */
590 0 : switch (crtc_timing->display_color_depth) {
591 : case COLOR_DEPTH_888:
592 0 : REG_UPDATE(HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, 0);
593 0 : break;
594 : case COLOR_DEPTH_101010:
595 0 : if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
596 0 : REG_UPDATE_2(HDMI_CONTROL,
597 : HDMI_DEEP_COLOR_DEPTH, 1,
598 : HDMI_DEEP_COLOR_ENABLE, 0);
599 : } else {
600 0 : REG_UPDATE_2(HDMI_CONTROL,
601 : HDMI_DEEP_COLOR_DEPTH, 1,
602 : HDMI_DEEP_COLOR_ENABLE, 1);
603 : }
604 : break;
605 : case COLOR_DEPTH_121212:
606 0 : if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
607 0 : REG_UPDATE_2(HDMI_CONTROL,
608 : HDMI_DEEP_COLOR_DEPTH, 2,
609 : HDMI_DEEP_COLOR_ENABLE, 0);
610 : } else {
611 0 : REG_UPDATE_2(HDMI_CONTROL,
612 : HDMI_DEEP_COLOR_DEPTH, 2,
613 : HDMI_DEEP_COLOR_ENABLE, 1);
614 : }
615 : break;
616 : case COLOR_DEPTH_161616:
617 0 : REG_UPDATE_2(HDMI_CONTROL,
618 : HDMI_DEEP_COLOR_DEPTH, 3,
619 : HDMI_DEEP_COLOR_ENABLE, 1);
620 0 : break;
621 : default:
622 : break;
623 : }
624 :
625 0 : if (actual_pix_clk_khz >= HDMI_CLOCK_CHANNEL_RATE_MORE_340M) {
626 : /* enable HDMI data scrambler
627 : * HDMI_CLOCK_CHANNEL_RATE_MORE_340M
628 : * Clock channel frequency is 1/4 of character rate.
629 : */
630 0 : REG_UPDATE_2(HDMI_CONTROL,
631 : HDMI_DATA_SCRAMBLE_EN, 1,
632 : HDMI_CLOCK_CHANNEL_RATE, 1);
633 0 : } else if (crtc_timing->flags.LTE_340MCSC_SCRAMBLE) {
634 :
635 : /* TODO: New feature for DCE11, still need to implement */
636 :
637 : /* enable HDMI data scrambler
638 : * HDMI_CLOCK_CHANNEL_FREQ_EQUAL_TO_CHAR_RATE
639 : * Clock channel frequency is the same
640 : * as character rate
641 : */
642 0 : REG_UPDATE_2(HDMI_CONTROL,
643 : HDMI_DATA_SCRAMBLE_EN, 1,
644 : HDMI_CLOCK_CHANNEL_RATE, 0);
645 : }
646 :
647 :
648 : /* Enable transmission of General Control packet on every frame */
649 0 : REG_UPDATE_3(HDMI_VBI_PACKET_CONTROL,
650 : HDMI_GC_CONT, 1,
651 : HDMI_GC_SEND, 1,
652 : HDMI_NULL_SEND, 1);
653 :
654 : /* Disable Audio Content Protection packet transmission */
655 0 : REG_UPDATE(HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, 0);
656 :
657 : /* following belongs to audio */
658 : /* Enable Audio InfoFrame packet transmission. */
659 0 : REG_UPDATE(HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_SEND, 1);
660 :
661 : /* update double-buffered AUDIO_INFO registers immediately */
662 0 : ASSERT (enc->afmt);
663 0 : enc->afmt->funcs->audio_info_immediate_update(enc->afmt);
664 :
665 : /* Select line number on which to send Audio InfoFrame packets */
666 0 : REG_UPDATE(HDMI_INFOFRAME_CONTROL1, HDMI_AUDIO_INFO_LINE,
667 : VBI_LINE_0 + 2);
668 :
669 : /* set HDMI GC AVMUTE */
670 0 : REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, 0);
671 : }
672 :
673 0 : void enc3_audio_mute_control(
674 : struct stream_encoder *enc,
675 : bool mute)
676 : {
677 0 : ASSERT (enc->afmt);
678 0 : enc->afmt->funcs->audio_mute_control(enc->afmt, mute);
679 0 : }
680 :
681 0 : void enc3_se_dp_audio_setup(
682 : struct stream_encoder *enc,
683 : unsigned int az_inst,
684 : struct audio_info *info)
685 : {
686 0 : ASSERT (enc->afmt);
687 0 : enc->afmt->funcs->se_audio_setup(enc->afmt, az_inst, info);
688 0 : }
689 :
690 : #define DP_SEC_AUD_N__DP_SEC_AUD_N__DEFAULT 0x8000
691 : #define DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUTO_CALC 1
692 :
693 0 : static void enc3_se_setup_dp_audio(
694 : struct stream_encoder *enc)
695 : {
696 0 : struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
697 :
698 : /* --- DP Audio packet configurations --- */
699 :
700 : /* ATP Configuration */
701 0 : REG_SET(DP_SEC_AUD_N, 0,
702 : DP_SEC_AUD_N, DP_SEC_AUD_N__DP_SEC_AUD_N__DEFAULT);
703 :
704 : /* Async/auto-calc timestamp mode */
705 0 : REG_SET(DP_SEC_TIMESTAMP, 0, DP_SEC_TIMESTAMP_MODE,
706 : DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUTO_CALC);
707 :
708 0 : ASSERT (enc->afmt);
709 0 : enc->afmt->funcs->setup_dp_audio(enc->afmt);
710 0 : }
711 :
712 0 : void enc3_se_dp_audio_enable(
713 : struct stream_encoder *enc)
714 : {
715 0 : enc1_se_enable_audio_clock(enc, true);
716 0 : enc3_se_setup_dp_audio(enc);
717 0 : enc1_se_enable_dp_audio(enc);
718 0 : }
719 :
720 0 : static void enc3_se_setup_hdmi_audio(
721 : struct stream_encoder *enc,
722 : const struct audio_crtc_info *crtc_info)
723 : {
724 0 : struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
725 :
726 0 : struct audio_clock_info audio_clock_info = {0};
727 :
728 : /* Setup audio in AFMT - program AFMT block associated with DIO */
729 0 : ASSERT (enc->afmt);
730 0 : enc->afmt->funcs->setup_hdmi_audio(enc->afmt);
731 :
732 : /* HDMI_AUDIO_PACKET_CONTROL */
733 0 : REG_UPDATE(HDMI_AUDIO_PACKET_CONTROL,
734 : HDMI_AUDIO_DELAY_EN, 1);
735 :
736 : /* HDMI_ACR_PACKET_CONTROL */
737 0 : REG_UPDATE_3(HDMI_ACR_PACKET_CONTROL,
738 : HDMI_ACR_AUTO_SEND, 1,
739 : HDMI_ACR_SOURCE, 0,
740 : HDMI_ACR_AUDIO_PRIORITY, 0);
741 :
742 : /* Program audio clock sample/regeneration parameters */
743 0 : get_audio_clock_info(crtc_info->color_depth,
744 : crtc_info->requested_pixel_clock_100Hz,
745 : crtc_info->calculated_pixel_clock_100Hz,
746 : &audio_clock_info);
747 : DC_LOG_HW_AUDIO(
748 : "\n%s:Input::requested_pixel_clock_100Hz = %d" \
749 : "calculated_pixel_clock_100Hz = %d \n", __func__, \
750 : crtc_info->requested_pixel_clock_100Hz, \
751 : crtc_info->calculated_pixel_clock_100Hz);
752 :
753 : /* HDMI_ACR_32_0__HDMI_ACR_CTS_32_MASK */
754 0 : REG_UPDATE(HDMI_ACR_32_0, HDMI_ACR_CTS_32, audio_clock_info.cts_32khz);
755 :
756 : /* HDMI_ACR_32_1__HDMI_ACR_N_32_MASK */
757 0 : REG_UPDATE(HDMI_ACR_32_1, HDMI_ACR_N_32, audio_clock_info.n_32khz);
758 :
759 : /* HDMI_ACR_44_0__HDMI_ACR_CTS_44_MASK */
760 0 : REG_UPDATE(HDMI_ACR_44_0, HDMI_ACR_CTS_44, audio_clock_info.cts_44khz);
761 :
762 : /* HDMI_ACR_44_1__HDMI_ACR_N_44_MASK */
763 0 : REG_UPDATE(HDMI_ACR_44_1, HDMI_ACR_N_44, audio_clock_info.n_44khz);
764 :
765 : /* HDMI_ACR_48_0__HDMI_ACR_CTS_48_MASK */
766 0 : REG_UPDATE(HDMI_ACR_48_0, HDMI_ACR_CTS_48, audio_clock_info.cts_48khz);
767 :
768 : /* HDMI_ACR_48_1__HDMI_ACR_N_48_MASK */
769 0 : REG_UPDATE(HDMI_ACR_48_1, HDMI_ACR_N_48, audio_clock_info.n_48khz);
770 :
771 : /* Video driver cannot know in advance which sample rate will
772 : * be used by HD Audio driver
773 : * HDMI_ACR_PACKET_CONTROL__HDMI_ACR_N_MULTIPLE field is
774 : * programmed below in interruppt callback
775 : */
776 0 : }
777 :
778 0 : void enc3_se_hdmi_audio_setup(
779 : struct stream_encoder *enc,
780 : unsigned int az_inst,
781 : struct audio_info *info,
782 : struct audio_crtc_info *audio_crtc_info)
783 : {
784 0 : enc1_se_enable_audio_clock(enc, true);
785 0 : enc3_se_setup_hdmi_audio(enc, audio_crtc_info);
786 0 : ASSERT (enc->afmt);
787 0 : enc->afmt->funcs->se_audio_setup(enc->afmt, az_inst, info);
788 0 : }
789 :
790 :
791 : static const struct stream_encoder_funcs dcn30_str_enc_funcs = {
792 : .dp_set_odm_combine =
793 : enc3_dp_set_odm_combine,
794 : .dp_set_stream_attribute =
795 : enc2_stream_encoder_dp_set_stream_attribute,
796 : .hdmi_set_stream_attribute =
797 : enc3_stream_encoder_hdmi_set_stream_attribute,
798 : .dvi_set_stream_attribute =
799 : enc3_stream_encoder_dvi_set_stream_attribute,
800 : .set_throttled_vcp_size =
801 : enc1_stream_encoder_set_throttled_vcp_size,
802 : .update_hdmi_info_packets =
803 : enc3_stream_encoder_update_hdmi_info_packets,
804 : .stop_hdmi_info_packets =
805 : enc3_stream_encoder_stop_hdmi_info_packets,
806 : .update_dp_info_packets =
807 : enc3_stream_encoder_update_dp_info_packets,
808 : .stop_dp_info_packets =
809 : enc1_stream_encoder_stop_dp_info_packets,
810 : .dp_blank =
811 : enc1_stream_encoder_dp_blank,
812 : .dp_unblank =
813 : enc2_stream_encoder_dp_unblank,
814 : .audio_mute_control = enc3_audio_mute_control,
815 :
816 : .dp_audio_setup = enc3_se_dp_audio_setup,
817 : .dp_audio_enable = enc3_se_dp_audio_enable,
818 : .dp_audio_disable = enc1_se_dp_audio_disable,
819 :
820 : .hdmi_audio_setup = enc3_se_hdmi_audio_setup,
821 : .hdmi_audio_disable = enc1_se_hdmi_audio_disable,
822 : .setup_stereo_sync = enc1_setup_stereo_sync,
823 : .set_avmute = enc1_stream_encoder_set_avmute,
824 : .dig_connect_to_otg = enc1_dig_connect_to_otg,
825 : .dig_source_otg = enc1_dig_source_otg,
826 :
827 : .dp_get_pixel_format = enc1_stream_encoder_dp_get_pixel_format,
828 :
829 : .enc_read_state = enc3_read_state,
830 : .dp_set_dsc_config = enc3_dp_set_dsc_config,
831 : .dp_set_dsc_pps_info_packet = enc3_dp_set_dsc_pps_info_packet,
832 : .set_dynamic_metadata = enc2_set_dynamic_metadata,
833 : .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute,
834 :
835 : .get_fifo_cal_average_level = enc2_get_fifo_cal_average_level,
836 : };
837 :
838 0 : void dcn30_dio_stream_encoder_construct(
839 : struct dcn10_stream_encoder *enc1,
840 : struct dc_context *ctx,
841 : struct dc_bios *bp,
842 : enum engine_id eng_id,
843 : struct vpg *vpg,
844 : struct afmt *afmt,
845 : const struct dcn10_stream_enc_registers *regs,
846 : const struct dcn10_stream_encoder_shift *se_shift,
847 : const struct dcn10_stream_encoder_mask *se_mask)
848 : {
849 0 : enc1->base.funcs = &dcn30_str_enc_funcs;
850 0 : enc1->base.ctx = ctx;
851 0 : enc1->base.id = eng_id;
852 0 : enc1->base.bp = bp;
853 0 : enc1->base.vpg = vpg;
854 0 : enc1->base.afmt = afmt;
855 0 : enc1->regs = regs;
856 0 : enc1->se_shift = se_shift;
857 0 : enc1->se_mask = se_mask;
858 0 : enc1->base.stream_enc_inst = vpg->inst;
859 0 : }
860 :
|