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