1 /*
2 * Copyright 2019 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 #include "dc_bios_types.h"
27 #include "dcn31_hpo_dp_link_encoder.h"
28 #include "reg_helper.h"
29 #include "dc_link.h"
30 #include "stream_encoder.h"
31
32 #define DC_LOGGER \
33 enc3->base.ctx->logger
34
35 #define REG(reg)\
36 (enc3->regs->reg)
37
38 #undef FN
39 #define FN(reg_name, field_name) \
40 enc3->hpo_le_shift->field_name, enc3->hpo_le_mask->field_name
41
42
43 #define CTX \
44 enc3->base.ctx
45
46 enum {
47 DP_SAT_UPDATE_MAX_RETRY = 200
48 };
49
dcn31_hpo_dp_link_enc_enable(struct hpo_dp_link_encoder * enc,enum dc_lane_count num_lanes)50 void dcn31_hpo_dp_link_enc_enable(
51 struct hpo_dp_link_encoder *enc,
52 enum dc_lane_count num_lanes)
53 {
54 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);
55 uint32_t dp_link_enabled;
56
57 /* get current status of link enabled */
58 REG_GET(DP_DPHY_SYM32_STATUS,
59 STATUS, &dp_link_enabled);
60
61 /* Enable clocks first */
62 REG_UPDATE(DP_LINK_ENC_CLOCK_CONTROL, DP_LINK_ENC_CLOCK_EN, 1);
63
64 /* Reset DPHY. Only reset if going from disable to enable */
65 if (!dp_link_enabled) {
66 REG_UPDATE(DP_DPHY_SYM32_CONTROL, DPHY_RESET, 1);
67 REG_UPDATE(DP_DPHY_SYM32_CONTROL, DPHY_RESET, 0);
68 }
69
70 /* Configure DPHY settings */
71 REG_UPDATE_3(DP_DPHY_SYM32_CONTROL,
72 DPHY_ENABLE, 1,
73 PRECODER_ENABLE, 1,
74 NUM_LANES, num_lanes == LANE_COUNT_ONE ? 0 : num_lanes == LANE_COUNT_TWO ? 1 : 3);
75 }
76
dcn31_hpo_dp_link_enc_disable(struct hpo_dp_link_encoder * enc)77 void dcn31_hpo_dp_link_enc_disable(
78 struct hpo_dp_link_encoder *enc)
79 {
80 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);
81
82 /* Configure DPHY settings */
83 REG_UPDATE(DP_DPHY_SYM32_CONTROL,
84 DPHY_ENABLE, 0);
85
86 /* Shut down clock last */
87 REG_UPDATE(DP_LINK_ENC_CLOCK_CONTROL, DP_LINK_ENC_CLOCK_EN, 0);
88 }
89
dcn31_hpo_dp_link_enc_set_link_test_pattern(struct hpo_dp_link_encoder * enc,struct encoder_set_dp_phy_pattern_param * tp_params)90 void dcn31_hpo_dp_link_enc_set_link_test_pattern(
91 struct hpo_dp_link_encoder *enc,
92 struct encoder_set_dp_phy_pattern_param *tp_params)
93 {
94 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);
95 uint32_t tp_custom;
96
97 switch (tp_params->dp_phy_pattern) {
98 case DP_TEST_PATTERN_VIDEO_MODE:
99 REG_UPDATE(DP_DPHY_SYM32_CONTROL,
100 MODE, DP2_LINK_ACTIVE);
101 break;
102 case DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE:
103 REG_UPDATE(DP_DPHY_SYM32_CONTROL,
104 MODE, DP2_LINK_TRAINING_TPS1);
105 break;
106 case DP_TEST_PATTERN_128b_132b_TPS2_TRAINING_MODE:
107 REG_UPDATE(DP_DPHY_SYM32_CONTROL,
108 MODE, DP2_LINK_TRAINING_TPS2);
109 break;
110 case DP_TEST_PATTERN_128b_132b_TPS1:
111 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
112 TP_SELECT0, DP_DPHY_TP_SELECT_TPS1,
113 TP_SELECT1, DP_DPHY_TP_SELECT_TPS1,
114 TP_SELECT2, DP_DPHY_TP_SELECT_TPS1,
115 TP_SELECT3, DP_DPHY_TP_SELECT_TPS1);
116 REG_UPDATE(DP_DPHY_SYM32_CONTROL,
117 MODE, DP2_TEST_PATTERN);
118 break;
119 case DP_TEST_PATTERN_128b_132b_TPS2:
120 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
121 TP_SELECT0, DP_DPHY_TP_SELECT_TPS2,
122 TP_SELECT1, DP_DPHY_TP_SELECT_TPS2,
123 TP_SELECT2, DP_DPHY_TP_SELECT_TPS2,
124 TP_SELECT3, DP_DPHY_TP_SELECT_TPS2);
125 REG_UPDATE(DP_DPHY_SYM32_CONTROL,
126 MODE, DP2_TEST_PATTERN);
127 break;
128 case DP_TEST_PATTERN_PRBS7:
129 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
130 TP_PRBS_SEL0, DP_DPHY_TP_PRBS7,
131 TP_PRBS_SEL1, DP_DPHY_TP_PRBS7,
132 TP_PRBS_SEL2, DP_DPHY_TP_PRBS7,
133 TP_PRBS_SEL3, DP_DPHY_TP_PRBS7);
134 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
135 TP_SELECT0, DP_DPHY_TP_SELECT_PRBS,
136 TP_SELECT1, DP_DPHY_TP_SELECT_PRBS,
137 TP_SELECT2, DP_DPHY_TP_SELECT_PRBS,
138 TP_SELECT3, DP_DPHY_TP_SELECT_PRBS);
139 REG_UPDATE(DP_DPHY_SYM32_CONTROL,
140 MODE, DP2_TEST_PATTERN);
141 break;
142 case DP_TEST_PATTERN_PRBS9:
143 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
144 TP_PRBS_SEL0, DP_DPHY_TP_PRBS9,
145 TP_PRBS_SEL1, DP_DPHY_TP_PRBS9,
146 TP_PRBS_SEL2, DP_DPHY_TP_PRBS9,
147 TP_PRBS_SEL3, DP_DPHY_TP_PRBS9);
148 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
149 TP_SELECT0, DP_DPHY_TP_SELECT_PRBS,
150 TP_SELECT1, DP_DPHY_TP_SELECT_PRBS,
151 TP_SELECT2, DP_DPHY_TP_SELECT_PRBS,
152 TP_SELECT3, DP_DPHY_TP_SELECT_PRBS);
153 REG_UPDATE(DP_DPHY_SYM32_CONTROL,
154 MODE, DP2_TEST_PATTERN);
155 break;
156 case DP_TEST_PATTERN_PRBS11:
157 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
158 TP_PRBS_SEL0, DP_DPHY_TP_PRBS11,
159 TP_PRBS_SEL1, DP_DPHY_TP_PRBS11,
160 TP_PRBS_SEL2, DP_DPHY_TP_PRBS11,
161 TP_PRBS_SEL3, DP_DPHY_TP_PRBS11);
162 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
163 TP_SELECT0, DP_DPHY_TP_SELECT_PRBS,
164 TP_SELECT1, DP_DPHY_TP_SELECT_PRBS,
165 TP_SELECT2, DP_DPHY_TP_SELECT_PRBS,
166 TP_SELECT3, DP_DPHY_TP_SELECT_PRBS);
167 REG_UPDATE(DP_DPHY_SYM32_CONTROL,
168 MODE, DP2_TEST_PATTERN);
169 break;
170 case DP_TEST_PATTERN_PRBS15:
171 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
172 TP_PRBS_SEL0, DP_DPHY_TP_PRBS15,
173 TP_PRBS_SEL1, DP_DPHY_TP_PRBS15,
174 TP_PRBS_SEL2, DP_DPHY_TP_PRBS15,
175 TP_PRBS_SEL3, DP_DPHY_TP_PRBS15);
176 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
177 TP_SELECT0, DP_DPHY_TP_SELECT_PRBS,
178 TP_SELECT1, DP_DPHY_TP_SELECT_PRBS,
179 TP_SELECT2, DP_DPHY_TP_SELECT_PRBS,
180 TP_SELECT3, DP_DPHY_TP_SELECT_PRBS);
181 REG_UPDATE(DP_DPHY_SYM32_CONTROL,
182 MODE, DP2_TEST_PATTERN);
183 break;
184 case DP_TEST_PATTERN_PRBS23:
185 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
186 TP_PRBS_SEL0, DP_DPHY_TP_PRBS23,
187 TP_PRBS_SEL1, DP_DPHY_TP_PRBS23,
188 TP_PRBS_SEL2, DP_DPHY_TP_PRBS23,
189 TP_PRBS_SEL3, DP_DPHY_TP_PRBS23);
190 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
191 TP_SELECT0, DP_DPHY_TP_SELECT_PRBS,
192 TP_SELECT1, DP_DPHY_TP_SELECT_PRBS,
193 TP_SELECT2, DP_DPHY_TP_SELECT_PRBS,
194 TP_SELECT3, DP_DPHY_TP_SELECT_PRBS);
195 REG_UPDATE(DP_DPHY_SYM32_CONTROL,
196 MODE, DP2_TEST_PATTERN);
197 break;
198 case DP_TEST_PATTERN_PRBS31:
199 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
200 TP_PRBS_SEL0, DP_DPHY_TP_PRBS31,
201 TP_PRBS_SEL1, DP_DPHY_TP_PRBS31,
202 TP_PRBS_SEL2, DP_DPHY_TP_PRBS31,
203 TP_PRBS_SEL3, DP_DPHY_TP_PRBS31);
204 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
205 TP_SELECT0, DP_DPHY_TP_SELECT_PRBS,
206 TP_SELECT1, DP_DPHY_TP_SELECT_PRBS,
207 TP_SELECT2, DP_DPHY_TP_SELECT_PRBS,
208 TP_SELECT3, DP_DPHY_TP_SELECT_PRBS);
209 REG_UPDATE(DP_DPHY_SYM32_CONTROL,
210 MODE, DP2_TEST_PATTERN);
211 break;
212 case DP_TEST_PATTERN_264BIT_CUSTOM:
213 tp_custom = (tp_params->custom_pattern[2] << 16) | (tp_params->custom_pattern[1] << 8) | tp_params->custom_pattern[0];
214 REG_SET(DP_DPHY_SYM32_TP_CUSTOM0, 0, TP_CUSTOM, tp_custom);
215 tp_custom = (tp_params->custom_pattern[5] << 16) | (tp_params->custom_pattern[4] << 8) | tp_params->custom_pattern[3];
216 REG_SET(DP_DPHY_SYM32_TP_CUSTOM1, 0, TP_CUSTOM, tp_custom);
217 tp_custom = (tp_params->custom_pattern[8] << 16) | (tp_params->custom_pattern[7] << 8) | tp_params->custom_pattern[6];
218 REG_SET(DP_DPHY_SYM32_TP_CUSTOM2, 0, TP_CUSTOM, tp_custom);
219 tp_custom = (tp_params->custom_pattern[11] << 16) | (tp_params->custom_pattern[10] << 8) | tp_params->custom_pattern[9];
220 REG_SET(DP_DPHY_SYM32_TP_CUSTOM3, 0, TP_CUSTOM, tp_custom);
221 tp_custom = (tp_params->custom_pattern[14] << 16) | (tp_params->custom_pattern[13] << 8) | tp_params->custom_pattern[12];
222 REG_SET(DP_DPHY_SYM32_TP_CUSTOM4, 0, TP_CUSTOM, tp_custom);
223 tp_custom = (tp_params->custom_pattern[17] << 16) | (tp_params->custom_pattern[16] << 8) | tp_params->custom_pattern[15];
224 REG_SET(DP_DPHY_SYM32_TP_CUSTOM5, 0, TP_CUSTOM, tp_custom);
225 tp_custom = (tp_params->custom_pattern[20] << 16) | (tp_params->custom_pattern[19] << 8) | tp_params->custom_pattern[18];
226 REG_SET(DP_DPHY_SYM32_TP_CUSTOM6, 0, TP_CUSTOM, tp_custom);
227 tp_custom = (tp_params->custom_pattern[23] << 16) | (tp_params->custom_pattern[22] << 8) | tp_params->custom_pattern[21];
228 REG_SET(DP_DPHY_SYM32_TP_CUSTOM7, 0, TP_CUSTOM, tp_custom);
229 tp_custom = (tp_params->custom_pattern[26] << 16) | (tp_params->custom_pattern[25] << 8) | tp_params->custom_pattern[24];
230 REG_SET(DP_DPHY_SYM32_TP_CUSTOM8, 0, TP_CUSTOM, tp_custom);
231 tp_custom = (tp_params->custom_pattern[29] << 16) | (tp_params->custom_pattern[28] << 8) | tp_params->custom_pattern[27];
232 REG_SET(DP_DPHY_SYM32_TP_CUSTOM9, 0, TP_CUSTOM, tp_custom);
233 tp_custom = (tp_params->custom_pattern[32] << 16) | (tp_params->custom_pattern[31] << 8) | tp_params->custom_pattern[30];
234 REG_SET(DP_DPHY_SYM32_TP_CUSTOM10, 0, TP_CUSTOM, tp_custom);
235
236 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
237 TP_SELECT0, DP_DPHY_TP_SELECT_CUSTOM,
238 TP_SELECT1, DP_DPHY_TP_SELECT_CUSTOM,
239 TP_SELECT2, DP_DPHY_TP_SELECT_CUSTOM,
240 TP_SELECT3, DP_DPHY_TP_SELECT_CUSTOM);
241
242 REG_UPDATE(DP_DPHY_SYM32_CONTROL,
243 MODE, DP2_TEST_PATTERN);
244 break;
245 case DP_TEST_PATTERN_SQUARE:
246 case DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED:
247 case DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED:
248 case DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED:
249 REG_SET(DP_DPHY_SYM32_TP_SQ_PULSE, 0,
250 TP_SQ_PULSE_WIDTH, tp_params->custom_pattern[0]);
251
252 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
253 TP_SELECT0, DP_DPHY_TP_SELECT_SQUARE,
254 TP_SELECT1, DP_DPHY_TP_SELECT_SQUARE,
255 TP_SELECT2, DP_DPHY_TP_SELECT_SQUARE,
256 TP_SELECT3, DP_DPHY_TP_SELECT_SQUARE);
257
258 REG_UPDATE(DP_DPHY_SYM32_CONTROL,
259 MODE, DP2_TEST_PATTERN);
260 break;
261 default:
262 break;
263 }
264 }
265
fill_stream_allocation_row_info(const struct link_mst_stream_allocation * stream_allocation,uint32_t * src,uint32_t * slots)266 static void fill_stream_allocation_row_info(
267 const struct link_mst_stream_allocation *stream_allocation,
268 uint32_t *src,
269 uint32_t *slots)
270 {
271 const struct hpo_dp_stream_encoder *stream_enc = stream_allocation->hpo_dp_stream_enc;
272
273 if (stream_enc && (stream_enc->id >= ENGINE_ID_HPO_DP_0)) {
274 *src = stream_enc->id - ENGINE_ID_HPO_DP_0;
275 *slots = stream_allocation->slot_count;
276 } else {
277 *src = 0;
278 *slots = 0;
279 }
280 }
281
282 /* programs DP VC payload allocation */
dcn31_hpo_dp_link_enc_update_stream_allocation_table(struct hpo_dp_link_encoder * enc,const struct link_mst_stream_allocation_table * table)283 void dcn31_hpo_dp_link_enc_update_stream_allocation_table(
284 struct hpo_dp_link_encoder *enc,
285 const struct link_mst_stream_allocation_table *table)
286 {
287 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);
288 uint32_t slots = 0;
289 uint32_t src = 0;
290
291 /* --- Set MSE Stream Attribute -
292 * Setup VC Payload Table on Tx Side,
293 * Issue allocation change trigger
294 * to commit payload on both tx and rx side
295 */
296
297 /* we should clean-up table each time */
298
299 if (table->stream_count >= 1) {
300 fill_stream_allocation_row_info(
301 &table->stream_allocations[0],
302 &src,
303 &slots);
304 } else {
305 src = 0;
306 slots = 0;
307 }
308
309 REG_UPDATE_2(DP_DPHY_SYM32_SAT_VC0,
310 SAT_STREAM_SOURCE, src,
311 SAT_SLOT_COUNT, slots);
312
313 if (table->stream_count >= 2) {
314 fill_stream_allocation_row_info(
315 &table->stream_allocations[1],
316 &src,
317 &slots);
318 } else {
319 src = 0;
320 slots = 0;
321 }
322
323 REG_UPDATE_2(DP_DPHY_SYM32_SAT_VC1,
324 SAT_STREAM_SOURCE, src,
325 SAT_SLOT_COUNT, slots);
326
327 if (table->stream_count >= 3) {
328 fill_stream_allocation_row_info(
329 &table->stream_allocations[2],
330 &src,
331 &slots);
332 } else {
333 src = 0;
334 slots = 0;
335 }
336
337 REG_UPDATE_2(DP_DPHY_SYM32_SAT_VC2,
338 SAT_STREAM_SOURCE, src,
339 SAT_SLOT_COUNT, slots);
340
341 if (table->stream_count >= 4) {
342 fill_stream_allocation_row_info(
343 &table->stream_allocations[3],
344 &src,
345 &slots);
346 } else {
347 src = 0;
348 slots = 0;
349 }
350
351 REG_UPDATE_2(DP_DPHY_SYM32_SAT_VC3,
352 SAT_STREAM_SOURCE, src,
353 SAT_SLOT_COUNT, slots);
354
355 /* --- wait for transaction finish */
356
357 /* send allocation change trigger (ACT)
358 * this step first sends the ACT,
359 * then double buffers the SAT into the hardware
360 * making the new allocation active on the DP MST mode link
361 */
362
363 /* SAT_UPDATE:
364 * 0 - No Action
365 * 1 - Update SAT with trigger
366 * 2 - Update SAT without trigger
367 */
368 REG_UPDATE(DP_DPHY_SYM32_SAT_UPDATE,
369 SAT_UPDATE, 1);
370
371 /* wait for update to complete
372 * (i.e. SAT_UPDATE_PENDING field is set to 0)
373 * No need for HW to enforce keepout.
374 */
375 /* Best case and worst case wait time for SAT_UPDATE_PENDING
376 * best: 109 us
377 * worst: 868 us
378 */
379 REG_WAIT(DP_DPHY_SYM32_STATUS,
380 SAT_UPDATE_PENDING, 0,
381 10, DP_SAT_UPDATE_MAX_RETRY);
382 }
383
dcn31_hpo_dp_link_enc_set_throttled_vcp_size(struct hpo_dp_link_encoder * enc,uint32_t stream_encoder_inst,struct fixed31_32 avg_time_slots_per_mtp)384 void dcn31_hpo_dp_link_enc_set_throttled_vcp_size(
385 struct hpo_dp_link_encoder *enc,
386 uint32_t stream_encoder_inst,
387 struct fixed31_32 avg_time_slots_per_mtp)
388 {
389 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);
390 uint32_t x = dc_fixpt_floor(
391 avg_time_slots_per_mtp);
392 uint32_t y = dc_fixpt_ceil(
393 dc_fixpt_shl(
394 dc_fixpt_sub_int(
395 avg_time_slots_per_mtp,
396 x),
397 25));
398
399 switch (stream_encoder_inst) {
400 case 0:
401 REG_SET_2(DP_DPHY_SYM32_VC_RATE_CNTL0, 0,
402 STREAM_VC_RATE_X, x,
403 STREAM_VC_RATE_Y, y);
404 break;
405 case 1:
406 REG_SET_2(DP_DPHY_SYM32_VC_RATE_CNTL1, 0,
407 STREAM_VC_RATE_X, x,
408 STREAM_VC_RATE_Y, y);
409 break;
410 case 2:
411 REG_SET_2(DP_DPHY_SYM32_VC_RATE_CNTL2, 0,
412 STREAM_VC_RATE_X, x,
413 STREAM_VC_RATE_Y, y);
414 break;
415 case 3:
416 REG_SET_2(DP_DPHY_SYM32_VC_RATE_CNTL3, 0,
417 STREAM_VC_RATE_X, x,
418 STREAM_VC_RATE_Y, y);
419 break;
420 default:
421 ASSERT(0);
422 }
423
424 /* Best case and worst case wait time for RATE_UPDATE_PENDING
425 * best: 116 ns
426 * worst: 903 ns
427 */
428 /* wait for update to be completed on the link */
429 REG_WAIT(DP_DPHY_SYM32_STATUS,
430 RATE_UPDATE_PENDING, 0,
431 1, 10);
432 }
433
dcn31_hpo_dp_link_enc_is_in_alt_mode(struct hpo_dp_link_encoder * enc)434 static bool dcn31_hpo_dp_link_enc_is_in_alt_mode(
435 struct hpo_dp_link_encoder *enc)
436 {
437 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);
438 uint32_t dp_alt_mode_disable = 0;
439
440 ASSERT((enc->transmitter >= TRANSMITTER_UNIPHY_A) && (enc->transmitter <= TRANSMITTER_UNIPHY_E));
441
442 /* if value == 1 alt mode is disabled, otherwise it is enabled */
443 REG_GET(RDPCSTX_PHY_CNTL6[enc->transmitter], RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
444 return (dp_alt_mode_disable == 0);
445 }
446
dcn31_hpo_dp_link_enc_read_state(struct hpo_dp_link_encoder * enc,struct hpo_dp_link_enc_state * state)447 void dcn31_hpo_dp_link_enc_read_state(
448 struct hpo_dp_link_encoder *enc,
449 struct hpo_dp_link_enc_state *state)
450 {
451 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);
452
453 ASSERT(state);
454
455 REG_GET(DP_DPHY_SYM32_STATUS,
456 STATUS, &state->link_enc_enabled);
457 REG_GET(DP_DPHY_SYM32_CONTROL,
458 NUM_LANES, &state->lane_count);
459 REG_GET(DP_DPHY_SYM32_CONTROL,
460 MODE, (uint32_t *)&state->link_mode);
461
462 REG_GET_2(DP_DPHY_SYM32_SAT_VC0,
463 SAT_STREAM_SOURCE, &state->stream_src[0],
464 SAT_SLOT_COUNT, &state->slot_count[0]);
465 REG_GET_2(DP_DPHY_SYM32_SAT_VC1,
466 SAT_STREAM_SOURCE, &state->stream_src[1],
467 SAT_SLOT_COUNT, &state->slot_count[1]);
468 REG_GET_2(DP_DPHY_SYM32_SAT_VC2,
469 SAT_STREAM_SOURCE, &state->stream_src[2],
470 SAT_SLOT_COUNT, &state->slot_count[2]);
471 REG_GET_2(DP_DPHY_SYM32_SAT_VC3,
472 SAT_STREAM_SOURCE, &state->stream_src[3],
473 SAT_SLOT_COUNT, &state->slot_count[3]);
474
475 REG_GET_2(DP_DPHY_SYM32_VC_RATE_CNTL0,
476 STREAM_VC_RATE_X, &state->vc_rate_x[0],
477 STREAM_VC_RATE_Y, &state->vc_rate_y[0]);
478 REG_GET_2(DP_DPHY_SYM32_VC_RATE_CNTL1,
479 STREAM_VC_RATE_X, &state->vc_rate_x[1],
480 STREAM_VC_RATE_Y, &state->vc_rate_y[1]);
481 REG_GET_2(DP_DPHY_SYM32_VC_RATE_CNTL2,
482 STREAM_VC_RATE_X, &state->vc_rate_x[2],
483 STREAM_VC_RATE_Y, &state->vc_rate_y[2]);
484 REG_GET_2(DP_DPHY_SYM32_VC_RATE_CNTL3,
485 STREAM_VC_RATE_X, &state->vc_rate_x[3],
486 STREAM_VC_RATE_Y, &state->vc_rate_y[3]);
487 }
488
link_transmitter_control(struct dcn31_hpo_dp_link_encoder * enc3,struct bp_transmitter_control * cntl)489 static enum bp_result link_transmitter_control(
490 struct dcn31_hpo_dp_link_encoder *enc3,
491 struct bp_transmitter_control *cntl)
492 {
493 enum bp_result result;
494 struct dc_bios *bp = enc3->base.ctx->dc_bios;
495
496 result = bp->funcs->transmitter_control(bp, cntl);
497
498 return result;
499 }
500
501 /* enables DP PHY output for 128b132b encoding */
dcn31_hpo_dp_link_enc_enable_dp_output(struct hpo_dp_link_encoder * enc,const struct dc_link_settings * link_settings,enum transmitter transmitter,enum hpd_source_id hpd_source)502 void dcn31_hpo_dp_link_enc_enable_dp_output(
503 struct hpo_dp_link_encoder *enc,
504 const struct dc_link_settings *link_settings,
505 enum transmitter transmitter,
506 enum hpd_source_id hpd_source)
507 {
508 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);
509 struct bp_transmitter_control cntl = { 0 };
510 enum bp_result result;
511
512 /* Set the transmitter */
513 enc3->base.transmitter = transmitter;
514
515 /* Set the hpd source */
516 enc3->base.hpd_source = hpd_source;
517
518 /* Enable the PHY */
519 cntl.action = TRANSMITTER_CONTROL_ENABLE;
520 cntl.engine_id = ENGINE_ID_UNKNOWN;
521 cntl.transmitter = enc3->base.transmitter;
522 //cntl.pll_id = clock_source;
523 cntl.signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
524 cntl.lanes_number = link_settings->lane_count;
525 cntl.hpd_sel = enc3->base.hpd_source;
526 cntl.pixel_clock = link_settings->link_rate * 1000;
527 cntl.color_depth = COLOR_DEPTH_UNDEFINED;
528 cntl.hpo_engine_id = enc->inst + ENGINE_ID_HPO_DP_0;
529
530 result = link_transmitter_control(enc3, &cntl);
531
532 if (result != BP_RESULT_OK) {
533 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
534 __func__);
535 BREAK_TO_DEBUGGER();
536 }
537 }
538
dcn31_hpo_dp_link_enc_disable_output(struct hpo_dp_link_encoder * enc,enum signal_type signal)539 void dcn31_hpo_dp_link_enc_disable_output(
540 struct hpo_dp_link_encoder *enc,
541 enum signal_type signal)
542 {
543 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);
544 struct bp_transmitter_control cntl = { 0 };
545 enum bp_result result;
546
547 /* disable transmitter */
548 cntl.action = TRANSMITTER_CONTROL_DISABLE;
549 cntl.transmitter = enc3->base.transmitter;
550 cntl.hpd_sel = enc3->base.hpd_source;
551 cntl.signal = signal;
552
553 result = link_transmitter_control(enc3, &cntl);
554
555 if (result != BP_RESULT_OK) {
556 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
557 __func__);
558 BREAK_TO_DEBUGGER();
559 return;
560 }
561
562 /* disable encoder */
563 dcn31_hpo_dp_link_enc_disable(enc);
564 }
565
dcn31_hpo_dp_link_enc_set_ffe(struct hpo_dp_link_encoder * enc,const struct dc_link_settings * link_settings,uint8_t ffe_preset)566 void dcn31_hpo_dp_link_enc_set_ffe(
567 struct hpo_dp_link_encoder *enc,
568 const struct dc_link_settings *link_settings,
569 uint8_t ffe_preset)
570 {
571 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);
572 struct bp_transmitter_control cntl = { 0 };
573 enum bp_result result;
574
575 /* disable transmitter */
576 cntl.transmitter = enc3->base.transmitter;
577 cntl.action = TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS;
578 cntl.signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
579 cntl.lanes_number = link_settings->lane_count;
580 cntl.pixel_clock = link_settings->link_rate * 1000;
581 cntl.lane_settings = ffe_preset;
582
583 result = link_transmitter_control(enc3, &cntl);
584
585 if (result != BP_RESULT_OK) {
586 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
587 __func__);
588 BREAK_TO_DEBUGGER();
589 return;
590 }
591 }
592
593 static struct hpo_dp_link_encoder_funcs dcn31_hpo_dp_link_encoder_funcs = {
594 .enable_link_phy = dcn31_hpo_dp_link_enc_enable_dp_output,
595 .disable_link_phy = dcn31_hpo_dp_link_enc_disable_output,
596 .link_enable = dcn31_hpo_dp_link_enc_enable,
597 .link_disable = dcn31_hpo_dp_link_enc_disable,
598 .set_link_test_pattern = dcn31_hpo_dp_link_enc_set_link_test_pattern,
599 .update_stream_allocation_table = dcn31_hpo_dp_link_enc_update_stream_allocation_table,
600 .set_throttled_vcp_size = dcn31_hpo_dp_link_enc_set_throttled_vcp_size,
601 .is_in_alt_mode = dcn31_hpo_dp_link_enc_is_in_alt_mode,
602 .read_state = dcn31_hpo_dp_link_enc_read_state,
603 .set_ffe = dcn31_hpo_dp_link_enc_set_ffe,
604 };
605
hpo_dp_link_encoder31_construct(struct dcn31_hpo_dp_link_encoder * enc31,struct dc_context * ctx,uint32_t inst,const struct dcn31_hpo_dp_link_encoder_registers * hpo_le_regs,const struct dcn31_hpo_dp_link_encoder_shift * hpo_le_shift,const struct dcn31_hpo_dp_link_encoder_mask * hpo_le_mask)606 void hpo_dp_link_encoder31_construct(struct dcn31_hpo_dp_link_encoder *enc31,
607 struct dc_context *ctx,
608 uint32_t inst,
609 const struct dcn31_hpo_dp_link_encoder_registers *hpo_le_regs,
610 const struct dcn31_hpo_dp_link_encoder_shift *hpo_le_shift,
611 const struct dcn31_hpo_dp_link_encoder_mask *hpo_le_mask)
612 {
613 enc31->base.ctx = ctx;
614
615 enc31->base.inst = inst;
616 enc31->base.funcs = &dcn31_hpo_dp_link_encoder_funcs;
617 enc31->base.hpd_source = HPD_SOURCEID_UNKNOWN;
618 enc31->base.transmitter = TRANSMITTER_UNKNOWN;
619
620 enc31->regs = hpo_le_regs;
621 enc31->hpo_le_shift = hpo_le_shift;
622 enc31->hpo_le_mask = hpo_le_mask;
623 }
624