File Index
Files and directories
Sign in
FILE

dcn31_hpo_dp_link_encoder.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.c C
  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
 45enum {
 46	DP_SAT_UPDATE_MAX_RETRY = 200
 47};
 48
 49void 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
 76void 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
 89void 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
265void dcn31_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 */
282void 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		dcn31_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		dcn31_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		dcn31_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		dcn31_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			100, DP_SAT_UPDATE_MAX_RETRY);
381}
382
383void 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
439static 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
452void 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
494static 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 */
507void 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
544void 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
571void 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
598static 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
611void 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}
~/ Read-only file preview.