1f0cd0a34SEric Bernstein /*
2f0cd0a34SEric Bernstein  * Copyright 2012-15 Advanced Micro Devices, Inc.
3f0cd0a34SEric Bernstein  *
4f0cd0a34SEric Bernstein  * Permission is hereby granted, free of charge, to any person obtaining a
5f0cd0a34SEric Bernstein  * copy of this software and associated documentation files (the "Software"),
6f0cd0a34SEric Bernstein  * to deal in the Software without restriction, including without limitation
7f0cd0a34SEric Bernstein  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f0cd0a34SEric Bernstein  * and/or sell copies of the Software, and to permit persons to whom the
9f0cd0a34SEric Bernstein  * Software is furnished to do so, subject to the following conditions:
10f0cd0a34SEric Bernstein  *
11f0cd0a34SEric Bernstein  * The above copyright notice and this permission notice shall be included in
12f0cd0a34SEric Bernstein  * all copies or substantial portions of the Software.
13f0cd0a34SEric Bernstein  *
14f0cd0a34SEric Bernstein  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15f0cd0a34SEric Bernstein  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16f0cd0a34SEric Bernstein  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17f0cd0a34SEric Bernstein  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18f0cd0a34SEric Bernstein  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19f0cd0a34SEric Bernstein  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20f0cd0a34SEric Bernstein  * OTHER DEALINGS IN THE SOFTWARE.
21f0cd0a34SEric Bernstein  *
22f0cd0a34SEric Bernstein  * Authors: AMD
23f0cd0a34SEric Bernstein  *
24f0cd0a34SEric Bernstein  */
25f0cd0a34SEric Bernstein 
26c366be54SSam Ravnborg #include <linux/delay.h>
274fc4dca8SSam Ravnborg #include <linux/slab.h>
28c366be54SSam Ravnborg 
29f0cd0a34SEric Bernstein #include "reg_helper.h"
30f0cd0a34SEric Bernstein 
31f0cd0a34SEric Bernstein #include "core_types.h"
32f0cd0a34SEric Bernstein #include "link_encoder.h"
33f0cd0a34SEric Bernstein #include "dcn10_link_encoder.h"
34f0cd0a34SEric Bernstein #include "stream_encoder.h"
35f0cd0a34SEric Bernstein #include "i2caux_interface.h"
36f0cd0a34SEric Bernstein #include "dc_bios_types.h"
37f0cd0a34SEric Bernstein 
38f0cd0a34SEric Bernstein #include "gpio_service_interface.h"
39f0cd0a34SEric Bernstein 
40f0cd0a34SEric Bernstein #define CTX \
41f0cd0a34SEric Bernstein 	enc10->base.ctx
42f0cd0a34SEric Bernstein #define DC_LOGGER \
43f0cd0a34SEric Bernstein 	enc10->base.ctx->logger
44f0cd0a34SEric Bernstein 
45f0cd0a34SEric Bernstein #define REG(reg)\
46f0cd0a34SEric Bernstein 	(enc10->link_regs->reg)
47f0cd0a34SEric Bernstein 
48f0cd0a34SEric Bernstein #undef FN
49f0cd0a34SEric Bernstein #define FN(reg_name, field_name) \
50f0cd0a34SEric Bernstein 	enc10->link_shift->field_name, enc10->link_mask->field_name
51f0cd0a34SEric Bernstein 
52f0cd0a34SEric Bernstein 
53f0cd0a34SEric Bernstein /*
54f0cd0a34SEric Bernstein  * @brief
55f0cd0a34SEric Bernstein  * Trigger Source Select
56f0cd0a34SEric Bernstein  * ASIC-dependent, actual values for register programming
57f0cd0a34SEric Bernstein  */
58f0cd0a34SEric Bernstein #define DCN10_DIG_FE_SOURCE_SELECT_INVALID 0x0
59f0cd0a34SEric Bernstein #define DCN10_DIG_FE_SOURCE_SELECT_DIGA 0x1
60f0cd0a34SEric Bernstein #define DCN10_DIG_FE_SOURCE_SELECT_DIGB 0x2
61f0cd0a34SEric Bernstein #define DCN10_DIG_FE_SOURCE_SELECT_DIGC 0x4
62f0cd0a34SEric Bernstein #define DCN10_DIG_FE_SOURCE_SELECT_DIGD 0x08
63f0cd0a34SEric Bernstein #define DCN10_DIG_FE_SOURCE_SELECT_DIGE 0x10
64f0cd0a34SEric Bernstein #define DCN10_DIG_FE_SOURCE_SELECT_DIGF 0x20
65f0cd0a34SEric Bernstein #define DCN10_DIG_FE_SOURCE_SELECT_DIGG 0x40
66f0cd0a34SEric Bernstein 
67f0cd0a34SEric Bernstein enum {
68f0cd0a34SEric Bernstein 	DP_MST_UPDATE_MAX_RETRY = 50
69f0cd0a34SEric Bernstein };
70f0cd0a34SEric Bernstein 
71f0cd0a34SEric Bernstein static const struct link_encoder_funcs dcn10_lnk_enc_funcs = {
72f0cd0a34SEric Bernstein 	.validate_output_with_stream =
73f0cd0a34SEric Bernstein 		dcn10_link_encoder_validate_output_with_stream,
74f0cd0a34SEric Bernstein 	.hw_init = dcn10_link_encoder_hw_init,
75f0cd0a34SEric Bernstein 	.setup = dcn10_link_encoder_setup,
76f0cd0a34SEric Bernstein 	.enable_tmds_output = dcn10_link_encoder_enable_tmds_output,
77f0cd0a34SEric Bernstein 	.enable_dp_output = dcn10_link_encoder_enable_dp_output,
78f0cd0a34SEric Bernstein 	.enable_dp_mst_output = dcn10_link_encoder_enable_dp_mst_output,
79f0cd0a34SEric Bernstein 	.disable_output = dcn10_link_encoder_disable_output,
80f0cd0a34SEric Bernstein 	.dp_set_lane_settings = dcn10_link_encoder_dp_set_lane_settings,
81f0cd0a34SEric Bernstein 	.dp_set_phy_pattern = dcn10_link_encoder_dp_set_phy_pattern,
82f0cd0a34SEric Bernstein 	.update_mst_stream_allocation_table =
83f0cd0a34SEric Bernstein 		dcn10_link_encoder_update_mst_stream_allocation_table,
84f0cd0a34SEric Bernstein 	.psr_program_dp_dphy_fast_training =
85f0cd0a34SEric Bernstein 			dcn10_psr_program_dp_dphy_fast_training,
86f0cd0a34SEric Bernstein 	.psr_program_secondary_packet = dcn10_psr_program_secondary_packet,
87f0cd0a34SEric Bernstein 	.connect_dig_be_to_fe = dcn10_link_encoder_connect_dig_be_to_fe,
88f0cd0a34SEric Bernstein 	.enable_hpd = dcn10_link_encoder_enable_hpd,
89f0cd0a34SEric Bernstein 	.disable_hpd = dcn10_link_encoder_disable_hpd,
90f0cd0a34SEric Bernstein 	.is_dig_enabled = dcn10_is_dig_enabled,
9168f1a00cSAnthony Koo 	.get_dig_frontend = dcn10_get_dig_frontend,
9278d9b95eSCharlene Liu 	.get_dig_mode = dcn10_get_dig_mode,
93f0cd0a34SEric Bernstein 	.destroy = dcn10_link_encoder_destroy
94f0cd0a34SEric Bernstein };
95f0cd0a34SEric Bernstein 
96f0cd0a34SEric Bernstein static enum bp_result link_transmitter_control(
97f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10,
98f0cd0a34SEric Bernstein 	struct bp_transmitter_control *cntl)
99f0cd0a34SEric Bernstein {
100f0cd0a34SEric Bernstein 	enum bp_result result;
101f0cd0a34SEric Bernstein 	struct dc_bios *bp = enc10->base.ctx->dc_bios;
102f0cd0a34SEric Bernstein 
103f0cd0a34SEric Bernstein 	result = bp->funcs->transmitter_control(bp, cntl);
104f0cd0a34SEric Bernstein 
105f0cd0a34SEric Bernstein 	return result;
106f0cd0a34SEric Bernstein }
107f0cd0a34SEric Bernstein 
108f0cd0a34SEric Bernstein static void enable_phy_bypass_mode(
109f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10,
110f0cd0a34SEric Bernstein 	bool enable)
111f0cd0a34SEric Bernstein {
112f0cd0a34SEric Bernstein 	/* This register resides in DP back end block;
113f0cd0a34SEric Bernstein 	 * transmitter is used for the offset
114f0cd0a34SEric Bernstein 	 */
115f0cd0a34SEric Bernstein 	REG_UPDATE(DP_DPHY_CNTL, DPHY_BYPASS, enable);
116f0cd0a34SEric Bernstein 
117f0cd0a34SEric Bernstein }
118f0cd0a34SEric Bernstein 
119f0cd0a34SEric Bernstein static void disable_prbs_symbols(
120f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10,
121f0cd0a34SEric Bernstein 	bool disable)
122f0cd0a34SEric Bernstein {
123f0cd0a34SEric Bernstein 	/* This register resides in DP back end block;
124f0cd0a34SEric Bernstein 	 * transmitter is used for the offset
125f0cd0a34SEric Bernstein 	 */
126f0cd0a34SEric Bernstein 	REG_UPDATE_4(DP_DPHY_CNTL,
127f0cd0a34SEric Bernstein 			DPHY_ATEST_SEL_LANE0, disable,
128f0cd0a34SEric Bernstein 			DPHY_ATEST_SEL_LANE1, disable,
129f0cd0a34SEric Bernstein 			DPHY_ATEST_SEL_LANE2, disable,
130f0cd0a34SEric Bernstein 			DPHY_ATEST_SEL_LANE3, disable);
131f0cd0a34SEric Bernstein }
132f0cd0a34SEric Bernstein 
133f0cd0a34SEric Bernstein static void disable_prbs_mode(
134f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10)
135f0cd0a34SEric Bernstein {
136f0cd0a34SEric Bernstein 	REG_UPDATE(DP_DPHY_PRBS_CNTL, DPHY_PRBS_EN, 0);
137f0cd0a34SEric Bernstein }
138f0cd0a34SEric Bernstein 
139f0cd0a34SEric Bernstein static void program_pattern_symbols(
140f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10,
141f0cd0a34SEric Bernstein 	uint16_t pattern_symbols[8])
142f0cd0a34SEric Bernstein {
143f0cd0a34SEric Bernstein 	/* This register resides in DP back end block;
144f0cd0a34SEric Bernstein 	 * transmitter is used for the offset
145f0cd0a34SEric Bernstein 	 */
146f0cd0a34SEric Bernstein 	REG_SET_3(DP_DPHY_SYM0, 0,
147f0cd0a34SEric Bernstein 			DPHY_SYM1, pattern_symbols[0],
148f0cd0a34SEric Bernstein 			DPHY_SYM2, pattern_symbols[1],
149f0cd0a34SEric Bernstein 			DPHY_SYM3, pattern_symbols[2]);
150f0cd0a34SEric Bernstein 
151f0cd0a34SEric Bernstein 	/* This register resides in DP back end block;
152f0cd0a34SEric Bernstein 	 * transmitter is used for the offset
153f0cd0a34SEric Bernstein 	 */
154f0cd0a34SEric Bernstein 	REG_SET_3(DP_DPHY_SYM1, 0,
155f0cd0a34SEric Bernstein 			DPHY_SYM4, pattern_symbols[3],
156f0cd0a34SEric Bernstein 			DPHY_SYM5, pattern_symbols[4],
157f0cd0a34SEric Bernstein 			DPHY_SYM6, pattern_symbols[5]);
158f0cd0a34SEric Bernstein 
159f0cd0a34SEric Bernstein 	/* This register resides in DP back end block;
160f0cd0a34SEric Bernstein 	 * transmitter is used for the offset
161f0cd0a34SEric Bernstein 	 */
162f0cd0a34SEric Bernstein 	REG_SET_2(DP_DPHY_SYM2, 0,
163f0cd0a34SEric Bernstein 			DPHY_SYM7, pattern_symbols[6],
164f0cd0a34SEric Bernstein 			DPHY_SYM8, pattern_symbols[7]);
165f0cd0a34SEric Bernstein }
166f0cd0a34SEric Bernstein 
167f0cd0a34SEric Bernstein static void set_dp_phy_pattern_d102(
168f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10)
169f0cd0a34SEric Bernstein {
170f0cd0a34SEric Bernstein 	/* Disable PHY Bypass mode to setup the test pattern */
171f0cd0a34SEric Bernstein 	enable_phy_bypass_mode(enc10, false);
172f0cd0a34SEric Bernstein 
173f0cd0a34SEric Bernstein 	/* For 10-bit PRBS or debug symbols
174f0cd0a34SEric Bernstein 	 * please use the following sequence:
175f0cd0a34SEric Bernstein 	 *
176f0cd0a34SEric Bernstein 	 * Enable debug symbols on the lanes
177f0cd0a34SEric Bernstein 	 */
178f0cd0a34SEric Bernstein 	disable_prbs_symbols(enc10, true);
179f0cd0a34SEric Bernstein 
180f0cd0a34SEric Bernstein 	/* Disable PRBS mode */
181f0cd0a34SEric Bernstein 	disable_prbs_mode(enc10);
182f0cd0a34SEric Bernstein 
183f0cd0a34SEric Bernstein 	/* Program debug symbols to be output */
184f0cd0a34SEric Bernstein 	{
185f0cd0a34SEric Bernstein 		uint16_t pattern_symbols[8] = {
186f0cd0a34SEric Bernstein 			0x2AA, 0x2AA, 0x2AA, 0x2AA,
187f0cd0a34SEric Bernstein 			0x2AA, 0x2AA, 0x2AA, 0x2AA
188f0cd0a34SEric Bernstein 		};
189f0cd0a34SEric Bernstein 
190f0cd0a34SEric Bernstein 		program_pattern_symbols(enc10, pattern_symbols);
191f0cd0a34SEric Bernstein 	}
192f0cd0a34SEric Bernstein 
193f0cd0a34SEric Bernstein 	/* Enable phy bypass mode to enable the test pattern */
194f0cd0a34SEric Bernstein 
195f0cd0a34SEric Bernstein 	enable_phy_bypass_mode(enc10, true);
196f0cd0a34SEric Bernstein }
197f0cd0a34SEric Bernstein 
198f0cd0a34SEric Bernstein static void set_link_training_complete(
199f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10,
200f0cd0a34SEric Bernstein 	bool complete)
201f0cd0a34SEric Bernstein {
202f0cd0a34SEric Bernstein 	/* This register resides in DP back end block;
203f0cd0a34SEric Bernstein 	 * transmitter is used for the offset
204f0cd0a34SEric Bernstein 	 */
205f0cd0a34SEric Bernstein 	REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, complete);
206f0cd0a34SEric Bernstein 
207f0cd0a34SEric Bernstein }
208f0cd0a34SEric Bernstein 
209f0cd0a34SEric Bernstein void dcn10_link_encoder_set_dp_phy_pattern_training_pattern(
210f0cd0a34SEric Bernstein 	struct link_encoder *enc,
211f0cd0a34SEric Bernstein 	uint32_t index)
212f0cd0a34SEric Bernstein {
213f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
214f0cd0a34SEric Bernstein 	/* Write Training Pattern */
215f0cd0a34SEric Bernstein 
216f0cd0a34SEric Bernstein 	REG_WRITE(DP_DPHY_TRAINING_PATTERN_SEL, index);
217f0cd0a34SEric Bernstein 
218f0cd0a34SEric Bernstein 	/* Set HW Register Training Complete to false */
219f0cd0a34SEric Bernstein 
220f0cd0a34SEric Bernstein 	set_link_training_complete(enc10, false);
221f0cd0a34SEric Bernstein 
222f0cd0a34SEric Bernstein 	/* Disable PHY Bypass mode to output Training Pattern */
223f0cd0a34SEric Bernstein 
224f0cd0a34SEric Bernstein 	enable_phy_bypass_mode(enc10, false);
225f0cd0a34SEric Bernstein 
226f0cd0a34SEric Bernstein 	/* Disable PRBS mode */
227f0cd0a34SEric Bernstein 	disable_prbs_mode(enc10);
228f0cd0a34SEric Bernstein }
229f0cd0a34SEric Bernstein 
230f0cd0a34SEric Bernstein static void setup_panel_mode(
231f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10,
232f0cd0a34SEric Bernstein 	enum dp_panel_mode panel_mode)
233f0cd0a34SEric Bernstein {
234f0cd0a34SEric Bernstein 	uint32_t value;
235f0cd0a34SEric Bernstein 
2360bfb01ceSEric Bernstein 	if (!REG(DP_DPHY_INTERNAL_CTRL))
2370bfb01ceSEric Bernstein 		return;
2380bfb01ceSEric Bernstein 
239f0cd0a34SEric Bernstein 	value = REG_READ(DP_DPHY_INTERNAL_CTRL);
240f0cd0a34SEric Bernstein 
241f0cd0a34SEric Bernstein 	switch (panel_mode) {
242f0cd0a34SEric Bernstein 	case DP_PANEL_MODE_EDP:
243f0cd0a34SEric Bernstein 		value = 0x1;
244f0cd0a34SEric Bernstein 		break;
245f0cd0a34SEric Bernstein 	case DP_PANEL_MODE_SPECIAL:
246f0cd0a34SEric Bernstein 		value = 0x11;
247f0cd0a34SEric Bernstein 		break;
248f0cd0a34SEric Bernstein 	default:
249f0cd0a34SEric Bernstein 		value = 0x0;
250f0cd0a34SEric Bernstein 		break;
251f0cd0a34SEric Bernstein 	}
252f0cd0a34SEric Bernstein 
253f0cd0a34SEric Bernstein 	REG_WRITE(DP_DPHY_INTERNAL_CTRL, value);
254f0cd0a34SEric Bernstein }
255f0cd0a34SEric Bernstein 
256f0cd0a34SEric Bernstein static void set_dp_phy_pattern_symbol_error(
257f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10)
258f0cd0a34SEric Bernstein {
259f0cd0a34SEric Bernstein 	/* Disable PHY Bypass mode to setup the test pattern */
260f0cd0a34SEric Bernstein 	enable_phy_bypass_mode(enc10, false);
261f0cd0a34SEric Bernstein 
262f0cd0a34SEric Bernstein 	/* program correct panel mode*/
263f0cd0a34SEric Bernstein 	setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
264f0cd0a34SEric Bernstein 
265f0cd0a34SEric Bernstein 	/* A PRBS23 pattern is used for most DP electrical measurements. */
266f0cd0a34SEric Bernstein 
267f0cd0a34SEric Bernstein 	/* Enable PRBS symbols on the lanes */
268f0cd0a34SEric Bernstein 	disable_prbs_symbols(enc10, false);
269f0cd0a34SEric Bernstein 
270f0cd0a34SEric Bernstein 	/* For PRBS23 Set bit DPHY_PRBS_SEL=1 and Set bit DPHY_PRBS_EN=1 */
271f0cd0a34SEric Bernstein 	REG_UPDATE_2(DP_DPHY_PRBS_CNTL,
272f0cd0a34SEric Bernstein 			DPHY_PRBS_SEL, 1,
273f0cd0a34SEric Bernstein 			DPHY_PRBS_EN, 1);
274f0cd0a34SEric Bernstein 
275f0cd0a34SEric Bernstein 	/* Enable phy bypass mode to enable the test pattern */
276f0cd0a34SEric Bernstein 	enable_phy_bypass_mode(enc10, true);
277f0cd0a34SEric Bernstein }
278f0cd0a34SEric Bernstein 
279f0cd0a34SEric Bernstein static void set_dp_phy_pattern_prbs7(
280f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10)
281f0cd0a34SEric Bernstein {
282f0cd0a34SEric Bernstein 	/* Disable PHY Bypass mode to setup the test pattern */
283f0cd0a34SEric Bernstein 	enable_phy_bypass_mode(enc10, false);
284f0cd0a34SEric Bernstein 
285f0cd0a34SEric Bernstein 	/* A PRBS7 pattern is used for most DP electrical measurements. */
286f0cd0a34SEric Bernstein 
287f0cd0a34SEric Bernstein 	/* Enable PRBS symbols on the lanes */
288f0cd0a34SEric Bernstein 	disable_prbs_symbols(enc10, false);
289f0cd0a34SEric Bernstein 
290f0cd0a34SEric Bernstein 	/* For PRBS7 Set bit DPHY_PRBS_SEL=0 and Set bit DPHY_PRBS_EN=1 */
291f0cd0a34SEric Bernstein 	REG_UPDATE_2(DP_DPHY_PRBS_CNTL,
292f0cd0a34SEric Bernstein 			DPHY_PRBS_SEL, 0,
293f0cd0a34SEric Bernstein 			DPHY_PRBS_EN, 1);
294f0cd0a34SEric Bernstein 
295f0cd0a34SEric Bernstein 	/* Enable phy bypass mode to enable the test pattern */
296f0cd0a34SEric Bernstein 	enable_phy_bypass_mode(enc10, true);
297f0cd0a34SEric Bernstein }
298f0cd0a34SEric Bernstein 
299f0cd0a34SEric Bernstein static void set_dp_phy_pattern_80bit_custom(
300f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10,
301f0cd0a34SEric Bernstein 	const uint8_t *pattern)
302f0cd0a34SEric Bernstein {
303f0cd0a34SEric Bernstein 	/* Disable PHY Bypass mode to setup the test pattern */
304f0cd0a34SEric Bernstein 	enable_phy_bypass_mode(enc10, false);
305f0cd0a34SEric Bernstein 
306f0cd0a34SEric Bernstein 	/* Enable debug symbols on the lanes */
307f0cd0a34SEric Bernstein 
308f0cd0a34SEric Bernstein 	disable_prbs_symbols(enc10, true);
309f0cd0a34SEric Bernstein 
310f0cd0a34SEric Bernstein 	/* Enable PHY bypass mode to enable the test pattern */
311f0cd0a34SEric Bernstein 	/* TODO is it really needed ? */
312f0cd0a34SEric Bernstein 
313f0cd0a34SEric Bernstein 	enable_phy_bypass_mode(enc10, true);
314f0cd0a34SEric Bernstein 
315f0cd0a34SEric Bernstein 	/* Program 80 bit custom pattern */
316f0cd0a34SEric Bernstein 	{
317f0cd0a34SEric Bernstein 		uint16_t pattern_symbols[8];
318f0cd0a34SEric Bernstein 
319f0cd0a34SEric Bernstein 		pattern_symbols[0] =
320f0cd0a34SEric Bernstein 			((pattern[1] & 0x03) << 8) | pattern[0];
321f0cd0a34SEric Bernstein 		pattern_symbols[1] =
322f0cd0a34SEric Bernstein 			((pattern[2] & 0x0f) << 6) | ((pattern[1] >> 2) & 0x3f);
323f0cd0a34SEric Bernstein 		pattern_symbols[2] =
324f0cd0a34SEric Bernstein 			((pattern[3] & 0x3f) << 4) | ((pattern[2] >> 4) & 0x0f);
325f0cd0a34SEric Bernstein 		pattern_symbols[3] =
326f0cd0a34SEric Bernstein 			(pattern[4] << 2) | ((pattern[3] >> 6) & 0x03);
327f0cd0a34SEric Bernstein 		pattern_symbols[4] =
328f0cd0a34SEric Bernstein 			((pattern[6] & 0x03) << 8) | pattern[5];
329f0cd0a34SEric Bernstein 		pattern_symbols[5] =
330f0cd0a34SEric Bernstein 			((pattern[7] & 0x0f) << 6) | ((pattern[6] >> 2) & 0x3f);
331f0cd0a34SEric Bernstein 		pattern_symbols[6] =
332f0cd0a34SEric Bernstein 			((pattern[8] & 0x3f) << 4) | ((pattern[7] >> 4) & 0x0f);
333f0cd0a34SEric Bernstein 		pattern_symbols[7] =
334f0cd0a34SEric Bernstein 			(pattern[9] << 2) | ((pattern[8] >> 6) & 0x03);
335f0cd0a34SEric Bernstein 
336f0cd0a34SEric Bernstein 		program_pattern_symbols(enc10, pattern_symbols);
337f0cd0a34SEric Bernstein 	}
338f0cd0a34SEric Bernstein 
339f0cd0a34SEric Bernstein 	/* Enable phy bypass mode to enable the test pattern */
340f0cd0a34SEric Bernstein 
341f0cd0a34SEric Bernstein 	enable_phy_bypass_mode(enc10, true);
342f0cd0a34SEric Bernstein }
343f0cd0a34SEric Bernstein 
344f0cd0a34SEric Bernstein static void set_dp_phy_pattern_hbr2_compliance_cp2520_2(
345f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10,
346f0cd0a34SEric Bernstein 	unsigned int cp2520_pattern)
347f0cd0a34SEric Bernstein {
348f0cd0a34SEric Bernstein 
349f0cd0a34SEric Bernstein 	/* previously there is a register DP_HBR2_EYE_PATTERN
350f0cd0a34SEric Bernstein 	 * that is enabled to get the pattern.
351f0cd0a34SEric Bernstein 	 * But it does not work with the latest spec change,
352f0cd0a34SEric Bernstein 	 * so we are programming the following registers manually.
353f0cd0a34SEric Bernstein 	 *
354f0cd0a34SEric Bernstein 	 * The following settings have been confirmed
355f0cd0a34SEric Bernstein 	 * by Nick Chorney and Sandra Liu
356f0cd0a34SEric Bernstein 	 */
357f0cd0a34SEric Bernstein 
358f0cd0a34SEric Bernstein 	/* Disable PHY Bypass mode to setup the test pattern */
359f0cd0a34SEric Bernstein 
360f0cd0a34SEric Bernstein 	enable_phy_bypass_mode(enc10, false);
361f0cd0a34SEric Bernstein 
362f0cd0a34SEric Bernstein 	/* Setup DIG encoder in DP SST mode */
363f0cd0a34SEric Bernstein 	enc10->base.funcs->setup(&enc10->base, SIGNAL_TYPE_DISPLAY_PORT);
364f0cd0a34SEric Bernstein 
365f0cd0a34SEric Bernstein 	/* ensure normal panel mode. */
366f0cd0a34SEric Bernstein 	setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
367f0cd0a34SEric Bernstein 
368f0cd0a34SEric Bernstein 	/* no vbid after BS (SR)
369f0cd0a34SEric Bernstein 	 * DP_LINK_FRAMING_CNTL changed history Sandra Liu
370f0cd0a34SEric Bernstein 	 * 11000260 / 11000104 / 110000FC
371f0cd0a34SEric Bernstein 	 */
372f0cd0a34SEric Bernstein 	REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
373f0cd0a34SEric Bernstein 			DP_IDLE_BS_INTERVAL, 0xFC,
374f0cd0a34SEric Bernstein 			DP_VBID_DISABLE, 1,
375f0cd0a34SEric Bernstein 			DP_VID_ENHANCED_FRAME_MODE, 1);
376f0cd0a34SEric Bernstein 
377f0cd0a34SEric Bernstein 	/* swap every BS with SR */
378f0cd0a34SEric Bernstein 	REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, 0);
379f0cd0a34SEric Bernstein 
380f0cd0a34SEric Bernstein 	/* select cp2520 patterns */
381f0cd0a34SEric Bernstein 	if (REG(DP_DPHY_HBR2_PATTERN_CONTROL))
382f0cd0a34SEric Bernstein 		REG_UPDATE(DP_DPHY_HBR2_PATTERN_CONTROL,
383f0cd0a34SEric Bernstein 				DP_DPHY_HBR2_PATTERN_CONTROL, cp2520_pattern);
384f0cd0a34SEric Bernstein 	else
385f0cd0a34SEric Bernstein 		/* pre-DCE11 can only generate CP2520 pattern 2 */
386f0cd0a34SEric Bernstein 		ASSERT(cp2520_pattern == 2);
387f0cd0a34SEric Bernstein 
388f0cd0a34SEric Bernstein 	/* set link training complete */
389f0cd0a34SEric Bernstein 	set_link_training_complete(enc10, true);
390f0cd0a34SEric Bernstein 
391f0cd0a34SEric Bernstein 	/* disable video stream */
392f0cd0a34SEric Bernstein 	REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0);
393f0cd0a34SEric Bernstein 
394f0cd0a34SEric Bernstein 	/* Disable PHY Bypass mode to setup the test pattern */
395f0cd0a34SEric Bernstein 	enable_phy_bypass_mode(enc10, false);
396f0cd0a34SEric Bernstein }
397f0cd0a34SEric Bernstein 
398f0cd0a34SEric Bernstein static void set_dp_phy_pattern_passthrough_mode(
399f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10,
400f0cd0a34SEric Bernstein 	enum dp_panel_mode panel_mode)
401f0cd0a34SEric Bernstein {
402f0cd0a34SEric Bernstein 	/* program correct panel mode */
403f0cd0a34SEric Bernstein 	setup_panel_mode(enc10, panel_mode);
404f0cd0a34SEric Bernstein 
405f0cd0a34SEric Bernstein 	/* restore LINK_FRAMING_CNTL and DPHY_SCRAMBLER_BS_COUNT
406f0cd0a34SEric Bernstein 	 * in case we were doing HBR2 compliance pattern before
407f0cd0a34SEric Bernstein 	 */
408f0cd0a34SEric Bernstein 	REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
409f0cd0a34SEric Bernstein 			DP_IDLE_BS_INTERVAL, 0x2000,
410f0cd0a34SEric Bernstein 			DP_VBID_DISABLE, 0,
411f0cd0a34SEric Bernstein 			DP_VID_ENHANCED_FRAME_MODE, 1);
412f0cd0a34SEric Bernstein 
413f0cd0a34SEric Bernstein 	REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, 0x1FF);
414f0cd0a34SEric Bernstein 
415f0cd0a34SEric Bernstein 	/* set link training complete */
416f0cd0a34SEric Bernstein 	set_link_training_complete(enc10, true);
417f0cd0a34SEric Bernstein 
418f0cd0a34SEric Bernstein 	/* Disable PHY Bypass mode to setup the test pattern */
419f0cd0a34SEric Bernstein 	enable_phy_bypass_mode(enc10, false);
420f0cd0a34SEric Bernstein 
421f0cd0a34SEric Bernstein 	/* Disable PRBS mode */
422f0cd0a34SEric Bernstein 	disable_prbs_mode(enc10);
423f0cd0a34SEric Bernstein }
424f0cd0a34SEric Bernstein 
425f0cd0a34SEric Bernstein /* return value is bit-vector */
426f0cd0a34SEric Bernstein static uint8_t get_frontend_source(
427f0cd0a34SEric Bernstein 	enum engine_id engine)
428f0cd0a34SEric Bernstein {
429f0cd0a34SEric Bernstein 	switch (engine) {
430f0cd0a34SEric Bernstein 	case ENGINE_ID_DIGA:
431f0cd0a34SEric Bernstein 		return DCN10_DIG_FE_SOURCE_SELECT_DIGA;
432f0cd0a34SEric Bernstein 	case ENGINE_ID_DIGB:
433f0cd0a34SEric Bernstein 		return DCN10_DIG_FE_SOURCE_SELECT_DIGB;
434f0cd0a34SEric Bernstein 	case ENGINE_ID_DIGC:
435f0cd0a34SEric Bernstein 		return DCN10_DIG_FE_SOURCE_SELECT_DIGC;
436f0cd0a34SEric Bernstein 	case ENGINE_ID_DIGD:
437f0cd0a34SEric Bernstein 		return DCN10_DIG_FE_SOURCE_SELECT_DIGD;
438f0cd0a34SEric Bernstein 	case ENGINE_ID_DIGE:
439f0cd0a34SEric Bernstein 		return DCN10_DIG_FE_SOURCE_SELECT_DIGE;
440f0cd0a34SEric Bernstein 	case ENGINE_ID_DIGF:
441f0cd0a34SEric Bernstein 		return DCN10_DIG_FE_SOURCE_SELECT_DIGF;
442f0cd0a34SEric Bernstein 	case ENGINE_ID_DIGG:
443f0cd0a34SEric Bernstein 		return DCN10_DIG_FE_SOURCE_SELECT_DIGG;
444f0cd0a34SEric Bernstein 	default:
445f0cd0a34SEric Bernstein 		ASSERT_CRITICAL(false);
446f0cd0a34SEric Bernstein 		return DCN10_DIG_FE_SOURCE_SELECT_INVALID;
447f0cd0a34SEric Bernstein 	}
448f0cd0a34SEric Bernstein }
449f0cd0a34SEric Bernstein 
4505ec43edaSMartin Leung unsigned int dcn10_get_dig_frontend(struct link_encoder *enc)
4515ec43edaSMartin Leung {
4525ec43edaSMartin Leung 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
4535ec43edaSMartin Leung 	int32_t value;
4545ec43edaSMartin Leung 	enum engine_id result;
4555ec43edaSMartin Leung 
4565ec43edaSMartin Leung 	REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &value);
4575ec43edaSMartin Leung 
4585ec43edaSMartin Leung 	switch (value) {
4595ec43edaSMartin Leung 	case DCN10_DIG_FE_SOURCE_SELECT_DIGA:
4605ec43edaSMartin Leung 		result = ENGINE_ID_DIGA;
4615ec43edaSMartin Leung 		break;
4625ec43edaSMartin Leung 	case DCN10_DIG_FE_SOURCE_SELECT_DIGB:
4635ec43edaSMartin Leung 		result = ENGINE_ID_DIGB;
4645ec43edaSMartin Leung 		break;
4655ec43edaSMartin Leung 	case DCN10_DIG_FE_SOURCE_SELECT_DIGC:
4665ec43edaSMartin Leung 		result = ENGINE_ID_DIGC;
4675ec43edaSMartin Leung 		break;
4685ec43edaSMartin Leung 	case DCN10_DIG_FE_SOURCE_SELECT_DIGD:
4695ec43edaSMartin Leung 		result = ENGINE_ID_DIGD;
4705ec43edaSMartin Leung 		break;
4715ec43edaSMartin Leung 	case DCN10_DIG_FE_SOURCE_SELECT_DIGE:
4725ec43edaSMartin Leung 		result = ENGINE_ID_DIGE;
4735ec43edaSMartin Leung 		break;
4745ec43edaSMartin Leung 	case DCN10_DIG_FE_SOURCE_SELECT_DIGF:
4755ec43edaSMartin Leung 		result = ENGINE_ID_DIGF;
4765ec43edaSMartin Leung 		break;
4775ec43edaSMartin Leung 	case DCN10_DIG_FE_SOURCE_SELECT_DIGG:
4785ec43edaSMartin Leung 		result = ENGINE_ID_DIGG;
4795ec43edaSMartin Leung 		break;
4805ec43edaSMartin Leung 	default:
4815ec43edaSMartin Leung 		// invalid source select DIG
4825ec43edaSMartin Leung 		ASSERT(false);
4835ec43edaSMartin Leung 		result = ENGINE_ID_UNKNOWN;
4845ec43edaSMartin Leung 	}
4855ec43edaSMartin Leung 
4865ec43edaSMartin Leung 	return result;
4875ec43edaSMartin Leung 
4885ec43edaSMartin Leung }
4895ec43edaSMartin Leung 
4902ee7c03cSDmytro Laktyushkin void enc1_configure_encoder(
491f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10,
492f0cd0a34SEric Bernstein 	const struct dc_link_settings *link_settings)
493f0cd0a34SEric Bernstein {
494f0cd0a34SEric Bernstein 	/* set number of lanes */
495f0cd0a34SEric Bernstein 	REG_SET(DP_CONFIG, 0,
496f0cd0a34SEric Bernstein 			DP_UDI_LANES, link_settings->lane_count - LANE_COUNT_ONE);
497f0cd0a34SEric Bernstein 
498f0cd0a34SEric Bernstein 	/* setup scrambler */
499f0cd0a34SEric Bernstein 	REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1);
500f0cd0a34SEric Bernstein }
501f0cd0a34SEric Bernstein 
502f0cd0a34SEric Bernstein void dcn10_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
503f0cd0a34SEric Bernstein 			bool exit_link_training_required)
504f0cd0a34SEric Bernstein {
505f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
506f0cd0a34SEric Bernstein 
507f0cd0a34SEric Bernstein 	if (exit_link_training_required)
508f0cd0a34SEric Bernstein 		REG_UPDATE(DP_DPHY_FAST_TRAINING,
509f0cd0a34SEric Bernstein 				DPHY_RX_FAST_TRAINING_CAPABLE, 1);
510f0cd0a34SEric Bernstein 	else {
511f0cd0a34SEric Bernstein 		REG_UPDATE(DP_DPHY_FAST_TRAINING,
512f0cd0a34SEric Bernstein 				DPHY_RX_FAST_TRAINING_CAPABLE, 0);
513f0cd0a34SEric Bernstein 		/*In DCE 11, we are able to pre-program a Force SR register
514f0cd0a34SEric Bernstein 		 * to be able to trigger SR symbol after 5 idle patterns
515f0cd0a34SEric Bernstein 		 * transmitted. Upon PSR Exit, DMCU can trigger
516f0cd0a34SEric Bernstein 		 * DPHY_LOAD_BS_COUNT_START = 1. Upon writing 1 to
517f0cd0a34SEric Bernstein 		 * DPHY_LOAD_BS_COUNT_START and the internal counter
518f0cd0a34SEric Bernstein 		 * reaches DPHY_LOAD_BS_COUNT, the next BS symbol will be
519f0cd0a34SEric Bernstein 		 * replaced by SR symbol once.
520f0cd0a34SEric Bernstein 		 */
521f0cd0a34SEric Bernstein 
522f0cd0a34SEric Bernstein 		REG_UPDATE(DP_DPHY_BS_SR_SWAP_CNTL, DPHY_LOAD_BS_COUNT, 0x5);
523f0cd0a34SEric Bernstein 	}
524f0cd0a34SEric Bernstein }
525f0cd0a34SEric Bernstein 
526f0cd0a34SEric Bernstein void dcn10_psr_program_secondary_packet(struct link_encoder *enc,
527f0cd0a34SEric Bernstein 			unsigned int sdp_transmit_line_num_deadline)
528f0cd0a34SEric Bernstein {
529f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
530f0cd0a34SEric Bernstein 
531f0cd0a34SEric Bernstein 	REG_UPDATE_2(DP_SEC_CNTL1,
532f0cd0a34SEric Bernstein 		DP_SEC_GSP0_LINE_NUM, sdp_transmit_line_num_deadline,
533f0cd0a34SEric Bernstein 		DP_SEC_GSP0_PRIORITY, 1);
534f0cd0a34SEric Bernstein }
535f0cd0a34SEric Bernstein 
536f0cd0a34SEric Bernstein bool dcn10_is_dig_enabled(struct link_encoder *enc)
537f0cd0a34SEric Bernstein {
538f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
539f0cd0a34SEric Bernstein 	uint32_t value;
540f0cd0a34SEric Bernstein 
541f0cd0a34SEric Bernstein 	REG_GET(DIG_BE_EN_CNTL, DIG_ENABLE, &value);
542f0cd0a34SEric Bernstein 	return value;
543f0cd0a34SEric Bernstein }
544f0cd0a34SEric Bernstein 
545f0cd0a34SEric Bernstein static void link_encoder_disable(struct dcn10_link_encoder *enc10)
546f0cd0a34SEric Bernstein {
547f0cd0a34SEric Bernstein 	/* reset training pattern */
548f0cd0a34SEric Bernstein 	REG_SET(DP_DPHY_TRAINING_PATTERN_SEL, 0,
549f0cd0a34SEric Bernstein 			DPHY_TRAINING_PATTERN_SEL, 0);
550f0cd0a34SEric Bernstein 
551f0cd0a34SEric Bernstein 	/* reset training complete */
552f0cd0a34SEric Bernstein 	REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, 0);
553f0cd0a34SEric Bernstein 
554f0cd0a34SEric Bernstein 	/* reset panel mode */
555f0cd0a34SEric Bernstein 	setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
556f0cd0a34SEric Bernstein }
557f0cd0a34SEric Bernstein 
558f0cd0a34SEric Bernstein static void hpd_initialize(
559f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10)
560f0cd0a34SEric Bernstein {
561f0cd0a34SEric Bernstein 	/* Associate HPD with DIG_BE */
562f0cd0a34SEric Bernstein 	enum hpd_source_id hpd_source = enc10->base.hpd_source;
563f0cd0a34SEric Bernstein 
564f0cd0a34SEric Bernstein 	REG_UPDATE(DIG_BE_CNTL, DIG_HPD_SELECT, hpd_source);
565f0cd0a34SEric Bernstein }
566f0cd0a34SEric Bernstein 
567f0cd0a34SEric Bernstein bool dcn10_link_encoder_validate_dvi_output(
568f0cd0a34SEric Bernstein 	const struct dcn10_link_encoder *enc10,
569f0cd0a34SEric Bernstein 	enum signal_type connector_signal,
570f0cd0a34SEric Bernstein 	enum signal_type signal,
571f0cd0a34SEric Bernstein 	const struct dc_crtc_timing *crtc_timing)
572f0cd0a34SEric Bernstein {
573f0cd0a34SEric Bernstein 	uint32_t max_pixel_clock = TMDS_MAX_PIXEL_CLOCK;
574f0cd0a34SEric Bernstein 
575f0cd0a34SEric Bernstein 	if (signal == SIGNAL_TYPE_DVI_DUAL_LINK)
576f0cd0a34SEric Bernstein 		max_pixel_clock *= 2;
577f0cd0a34SEric Bernstein 
578f0cd0a34SEric Bernstein 	/* This handles the case of HDMI downgrade to DVI we don't want to
579f0cd0a34SEric Bernstein 	 * we don't want to cap the pixel clock if the DDI is not DVI.
580f0cd0a34SEric Bernstein 	 */
581f0cd0a34SEric Bernstein 	if (connector_signal != SIGNAL_TYPE_DVI_DUAL_LINK &&
582f0cd0a34SEric Bernstein 			connector_signal != SIGNAL_TYPE_DVI_SINGLE_LINK)
583f0cd0a34SEric Bernstein 		max_pixel_clock = enc10->base.features.max_hdmi_pixel_clock;
584f0cd0a34SEric Bernstein 
585f0cd0a34SEric Bernstein 	/* DVI only support RGB pixel encoding */
586f0cd0a34SEric Bernstein 	if (crtc_timing->pixel_encoding != PIXEL_ENCODING_RGB)
587f0cd0a34SEric Bernstein 		return false;
588f0cd0a34SEric Bernstein 
589f0cd0a34SEric Bernstein 	/*connect DVI via adpater's HDMI connector*/
590f0cd0a34SEric Bernstein 	if ((connector_signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
591f0cd0a34SEric Bernstein 		connector_signal == SIGNAL_TYPE_HDMI_TYPE_A) &&
592f0cd0a34SEric Bernstein 		signal != SIGNAL_TYPE_HDMI_TYPE_A &&
593380604e2SKen Chalmers 		crtc_timing->pix_clk_100hz > (TMDS_MAX_PIXEL_CLOCK * 10))
594f0cd0a34SEric Bernstein 		return false;
595380604e2SKen Chalmers 	if (crtc_timing->pix_clk_100hz < (TMDS_MIN_PIXEL_CLOCK * 10))
596f0cd0a34SEric Bernstein 		return false;
597f0cd0a34SEric Bernstein 
598380604e2SKen Chalmers 	if (crtc_timing->pix_clk_100hz > (max_pixel_clock * 10))
599f0cd0a34SEric Bernstein 		return false;
600f0cd0a34SEric Bernstein 
601f0cd0a34SEric Bernstein 	/* DVI supports 6/8bpp single-link and 10/16bpp dual-link */
602f0cd0a34SEric Bernstein 	switch (crtc_timing->display_color_depth) {
603f0cd0a34SEric Bernstein 	case COLOR_DEPTH_666:
604f0cd0a34SEric Bernstein 	case COLOR_DEPTH_888:
605f0cd0a34SEric Bernstein 	break;
606f0cd0a34SEric Bernstein 	case COLOR_DEPTH_101010:
607f0cd0a34SEric Bernstein 	case COLOR_DEPTH_161616:
608f0cd0a34SEric Bernstein 		if (signal != SIGNAL_TYPE_DVI_DUAL_LINK)
609f0cd0a34SEric Bernstein 			return false;
610f0cd0a34SEric Bernstein 	break;
611f0cd0a34SEric Bernstein 	default:
612f0cd0a34SEric Bernstein 		return false;
613f0cd0a34SEric Bernstein 	}
614f0cd0a34SEric Bernstein 
615f0cd0a34SEric Bernstein 	return true;
616f0cd0a34SEric Bernstein }
617f0cd0a34SEric Bernstein 
618f0cd0a34SEric Bernstein static bool dcn10_link_encoder_validate_hdmi_output(
619f0cd0a34SEric Bernstein 	const struct dcn10_link_encoder *enc10,
620f0cd0a34SEric Bernstein 	const struct dc_crtc_timing *crtc_timing,
621380604e2SKen Chalmers 	int adjusted_pix_clk_100hz)
622f0cd0a34SEric Bernstein {
623f0cd0a34SEric Bernstein 	enum dc_color_depth max_deep_color =
624f0cd0a34SEric Bernstein 			enc10->base.features.max_hdmi_deep_color;
625f0cd0a34SEric Bernstein 
626f0cd0a34SEric Bernstein 	if (max_deep_color < crtc_timing->display_color_depth)
627f0cd0a34SEric Bernstein 		return false;
628f0cd0a34SEric Bernstein 
629f0cd0a34SEric Bernstein 	if (crtc_timing->display_color_depth < COLOR_DEPTH_888)
630f0cd0a34SEric Bernstein 		return false;
631380604e2SKen Chalmers 	if (adjusted_pix_clk_100hz < (TMDS_MIN_PIXEL_CLOCK * 10))
632f0cd0a34SEric Bernstein 		return false;
633f0cd0a34SEric Bernstein 
634380604e2SKen Chalmers 	if ((adjusted_pix_clk_100hz == 0) ||
635380604e2SKen Chalmers 		(adjusted_pix_clk_100hz > (enc10->base.features.max_hdmi_pixel_clock * 10)))
636f0cd0a34SEric Bernstein 		return false;
637f0cd0a34SEric Bernstein 
638f0cd0a34SEric Bernstein 	/* DCE11 HW does not support 420 */
6399ea59d5aSEric Bernstein 	if (!enc10->base.features.hdmi_ycbcr420_supported &&
640f0cd0a34SEric Bernstein 			crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
641f0cd0a34SEric Bernstein 		return false;
642f0cd0a34SEric Bernstein 
643f0cd0a34SEric Bernstein 	if (!enc10->base.features.flags.bits.HDMI_6GB_EN &&
644380604e2SKen Chalmers 		adjusted_pix_clk_100hz >= 3000000)
645f0cd0a34SEric Bernstein 		return false;
6468fc0a0d4SCharlene Liu 	if (enc10->base.ctx->dc->debug.hdmi20_disable &&
6478fc0a0d4SCharlene Liu 		crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
6488fc0a0d4SCharlene Liu 		return false;
649f0cd0a34SEric Bernstein 	return true;
650f0cd0a34SEric Bernstein }
651f0cd0a34SEric Bernstein 
652f0cd0a34SEric Bernstein bool dcn10_link_encoder_validate_dp_output(
653f0cd0a34SEric Bernstein 	const struct dcn10_link_encoder *enc10,
654f0cd0a34SEric Bernstein 	const struct dc_crtc_timing *crtc_timing)
655f0cd0a34SEric Bernstein {
6569ea59d5aSEric Bernstein 	if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
6579ea59d5aSEric Bernstein 		if (!enc10->base.features.dp_ycbcr420_supported)
658b7cd6487SEric Yang 			return false;
6599ea59d5aSEric Bernstein 	}
660b7cd6487SEric Yang 
661f0cd0a34SEric Bernstein 	return true;
662f0cd0a34SEric Bernstein }
663f0cd0a34SEric Bernstein 
664f0cd0a34SEric Bernstein void dcn10_link_encoder_construct(
665f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10,
666f0cd0a34SEric Bernstein 	const struct encoder_init_data *init_data,
667f0cd0a34SEric Bernstein 	const struct encoder_feature_support *enc_features,
668f0cd0a34SEric Bernstein 	const struct dcn10_link_enc_registers *link_regs,
669f0cd0a34SEric Bernstein 	const struct dcn10_link_enc_aux_registers *aux_regs,
670f0cd0a34SEric Bernstein 	const struct dcn10_link_enc_hpd_registers *hpd_regs,
671f0cd0a34SEric Bernstein 	const struct dcn10_link_enc_shift *link_shift,
672f0cd0a34SEric Bernstein 	const struct dcn10_link_enc_mask *link_mask)
673f0cd0a34SEric Bernstein {
674f0cd0a34SEric Bernstein 	struct bp_encoder_cap_info bp_cap_info = {0};
675f0cd0a34SEric Bernstein 	const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs;
676f0cd0a34SEric Bernstein 	enum bp_result result = BP_RESULT_OK;
677f0cd0a34SEric Bernstein 
678f0cd0a34SEric Bernstein 	enc10->base.funcs = &dcn10_lnk_enc_funcs;
679f0cd0a34SEric Bernstein 	enc10->base.ctx = init_data->ctx;
680f0cd0a34SEric Bernstein 	enc10->base.id = init_data->encoder;
681f0cd0a34SEric Bernstein 
682f0cd0a34SEric Bernstein 	enc10->base.hpd_source = init_data->hpd_source;
683f0cd0a34SEric Bernstein 	enc10->base.connector = init_data->connector;
684f0cd0a34SEric Bernstein 
685f0cd0a34SEric Bernstein 	enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
686f0cd0a34SEric Bernstein 
687f0cd0a34SEric Bernstein 	enc10->base.features = *enc_features;
688f0cd0a34SEric Bernstein 
689f0cd0a34SEric Bernstein 	enc10->base.transmitter = init_data->transmitter;
690f0cd0a34SEric Bernstein 
691f0cd0a34SEric Bernstein 	/* set the flag to indicate whether driver poll the I2C data pin
692f0cd0a34SEric Bernstein 	 * while doing the DP sink detect
693f0cd0a34SEric Bernstein 	 */
694f0cd0a34SEric Bernstein 
695f0cd0a34SEric Bernstein /*	if (dal_adapter_service_is_feature_supported(as,
696f0cd0a34SEric Bernstein 		FEATURE_DP_SINK_DETECT_POLL_DATA_PIN))
697f0cd0a34SEric Bernstein 		enc10->base.features.flags.bits.
698f0cd0a34SEric Bernstein 			DP_SINK_DETECT_POLL_DATA_PIN = true;*/
699f0cd0a34SEric Bernstein 
700f0cd0a34SEric Bernstein 	enc10->base.output_signals =
701f0cd0a34SEric Bernstein 		SIGNAL_TYPE_DVI_SINGLE_LINK |
702f0cd0a34SEric Bernstein 		SIGNAL_TYPE_DVI_DUAL_LINK |
703f0cd0a34SEric Bernstein 		SIGNAL_TYPE_LVDS |
704f0cd0a34SEric Bernstein 		SIGNAL_TYPE_DISPLAY_PORT |
705f0cd0a34SEric Bernstein 		SIGNAL_TYPE_DISPLAY_PORT_MST |
706f0cd0a34SEric Bernstein 		SIGNAL_TYPE_EDP |
707f0cd0a34SEric Bernstein 		SIGNAL_TYPE_HDMI_TYPE_A;
708f0cd0a34SEric Bernstein 
709f0cd0a34SEric Bernstein 	/* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE.
710f0cd0a34SEric Bernstein 	 * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY.
711f0cd0a34SEric Bernstein 	 * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer
712f0cd0a34SEric Bernstein 	 * DIG is per UNIPHY and used by SST DP, eDP, HDMI, DVI and LVDS.
713f0cd0a34SEric Bernstein 	 * Prefer DIG assignment is decided by board design.
714f0cd0a34SEric Bernstein 	 * For DCE 8.0, there are only max 6 UNIPHYs, we assume board design
715f0cd0a34SEric Bernstein 	 * and VBIOS will filter out 7 UNIPHY for DCE 8.0.
716f0cd0a34SEric Bernstein 	 * By this, adding DIGG should not hurt DCE 8.0.
717f0cd0a34SEric Bernstein 	 * This will let DCE 8.1 share DCE 8.0 as much as possible
718f0cd0a34SEric Bernstein 	 */
719f0cd0a34SEric Bernstein 
720f0cd0a34SEric Bernstein 	enc10->link_regs = link_regs;
721f0cd0a34SEric Bernstein 	enc10->aux_regs = aux_regs;
722f0cd0a34SEric Bernstein 	enc10->hpd_regs = hpd_regs;
723f0cd0a34SEric Bernstein 	enc10->link_shift = link_shift;
724f0cd0a34SEric Bernstein 	enc10->link_mask = link_mask;
725f0cd0a34SEric Bernstein 
726f0cd0a34SEric Bernstein 	switch (enc10->base.transmitter) {
727f0cd0a34SEric Bernstein 	case TRANSMITTER_UNIPHY_A:
728f0cd0a34SEric Bernstein 		enc10->base.preferred_engine = ENGINE_ID_DIGA;
729f0cd0a34SEric Bernstein 	break;
730f0cd0a34SEric Bernstein 	case TRANSMITTER_UNIPHY_B:
731f0cd0a34SEric Bernstein 		enc10->base.preferred_engine = ENGINE_ID_DIGB;
732f0cd0a34SEric Bernstein 	break;
733f0cd0a34SEric Bernstein 	case TRANSMITTER_UNIPHY_C:
734f0cd0a34SEric Bernstein 		enc10->base.preferred_engine = ENGINE_ID_DIGC;
735f0cd0a34SEric Bernstein 	break;
736f0cd0a34SEric Bernstein 	case TRANSMITTER_UNIPHY_D:
737f0cd0a34SEric Bernstein 		enc10->base.preferred_engine = ENGINE_ID_DIGD;
738f0cd0a34SEric Bernstein 	break;
739f0cd0a34SEric Bernstein 	case TRANSMITTER_UNIPHY_E:
740f0cd0a34SEric Bernstein 		enc10->base.preferred_engine = ENGINE_ID_DIGE;
741f0cd0a34SEric Bernstein 	break;
742f0cd0a34SEric Bernstein 	case TRANSMITTER_UNIPHY_F:
743f0cd0a34SEric Bernstein 		enc10->base.preferred_engine = ENGINE_ID_DIGF;
744f0cd0a34SEric Bernstein 	break;
745f0cd0a34SEric Bernstein 	case TRANSMITTER_UNIPHY_G:
746f0cd0a34SEric Bernstein 		enc10->base.preferred_engine = ENGINE_ID_DIGG;
747f0cd0a34SEric Bernstein 	break;
748f0cd0a34SEric Bernstein 	default:
749f0cd0a34SEric Bernstein 		ASSERT_CRITICAL(false);
750f0cd0a34SEric Bernstein 		enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
751f0cd0a34SEric Bernstein 	}
752f0cd0a34SEric Bernstein 
753f0cd0a34SEric Bernstein 	/* default to one to mirror Windows behavior */
754f0cd0a34SEric Bernstein 	enc10->base.features.flags.bits.HDMI_6GB_EN = 1;
755f0cd0a34SEric Bernstein 
756f0cd0a34SEric Bernstein 	result = bp_funcs->get_encoder_cap_info(enc10->base.ctx->dc_bios,
757f0cd0a34SEric Bernstein 						enc10->base.id, &bp_cap_info);
758f0cd0a34SEric Bernstein 
759f0cd0a34SEric Bernstein 	/* Override features with DCE-specific values */
760f0cd0a34SEric Bernstein 	if (result == BP_RESULT_OK) {
761f0cd0a34SEric Bernstein 		enc10->base.features.flags.bits.IS_HBR2_CAPABLE =
762f0cd0a34SEric Bernstein 				bp_cap_info.DP_HBR2_EN;
763f0cd0a34SEric Bernstein 		enc10->base.features.flags.bits.IS_HBR3_CAPABLE =
764f0cd0a34SEric Bernstein 				bp_cap_info.DP_HBR3_EN;
765f0cd0a34SEric Bernstein 		enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
76664827cadSSamson Tam 		enc10->base.features.flags.bits.DP_IS_USB_C =
76764827cadSSamson Tam 				bp_cap_info.DP_IS_USB_C;
768f0cd0a34SEric Bernstein 	} else {
769f0cd0a34SEric Bernstein 		DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
770f0cd0a34SEric Bernstein 				__func__,
771f0cd0a34SEric Bernstein 				result);
772f0cd0a34SEric Bernstein 	}
7738fc0a0d4SCharlene Liu 	if (enc10->base.ctx->dc->debug.hdmi20_disable) {
7748fc0a0d4SCharlene Liu 		enc10->base.features.flags.bits.HDMI_6GB_EN = 0;
7758fc0a0d4SCharlene Liu 	}
776f0cd0a34SEric Bernstein }
777f0cd0a34SEric Bernstein 
778f0cd0a34SEric Bernstein bool dcn10_link_encoder_validate_output_with_stream(
779f0cd0a34SEric Bernstein 	struct link_encoder *enc,
780f0cd0a34SEric Bernstein 	const struct dc_stream_state *stream)
781f0cd0a34SEric Bernstein {
782f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
783f0cd0a34SEric Bernstein 	bool is_valid;
784f0cd0a34SEric Bernstein 
785f0cd0a34SEric Bernstein 	switch (stream->signal) {
786f0cd0a34SEric Bernstein 	case SIGNAL_TYPE_DVI_SINGLE_LINK:
787f0cd0a34SEric Bernstein 	case SIGNAL_TYPE_DVI_DUAL_LINK:
788f0cd0a34SEric Bernstein 		is_valid = dcn10_link_encoder_validate_dvi_output(
789f0cd0a34SEric Bernstein 			enc10,
790ceb3dbb4SJun Lei 			stream->link->connector_signal,
791f0cd0a34SEric Bernstein 			stream->signal,
792f0cd0a34SEric Bernstein 			&stream->timing);
793f0cd0a34SEric Bernstein 	break;
794f0cd0a34SEric Bernstein 	case SIGNAL_TYPE_HDMI_TYPE_A:
795f0cd0a34SEric Bernstein 		is_valid = dcn10_link_encoder_validate_hdmi_output(
796f0cd0a34SEric Bernstein 				enc10,
797f0cd0a34SEric Bernstein 				&stream->timing,
798380604e2SKen Chalmers 				stream->phy_pix_clk * 10);
799f0cd0a34SEric Bernstein 	break;
800f0cd0a34SEric Bernstein 	case SIGNAL_TYPE_DISPLAY_PORT:
801f0cd0a34SEric Bernstein 	case SIGNAL_TYPE_DISPLAY_PORT_MST:
802f0cd0a34SEric Bernstein 		is_valid = dcn10_link_encoder_validate_dp_output(
803f0cd0a34SEric Bernstein 					enc10, &stream->timing);
804f0cd0a34SEric Bernstein 	break;
805f0cd0a34SEric Bernstein 	case SIGNAL_TYPE_EDP:
806f0cd0a34SEric Bernstein 		is_valid = (stream->timing.pixel_encoding == PIXEL_ENCODING_RGB) ? true : false;
807f0cd0a34SEric Bernstein 	break;
808f0cd0a34SEric Bernstein 	case SIGNAL_TYPE_VIRTUAL:
809f0cd0a34SEric Bernstein 		is_valid = true;
810f0cd0a34SEric Bernstein 		break;
811f0cd0a34SEric Bernstein 	default:
812f0cd0a34SEric Bernstein 		is_valid = false;
813f0cd0a34SEric Bernstein 	break;
814f0cd0a34SEric Bernstein 	}
815f0cd0a34SEric Bernstein 
816f0cd0a34SEric Bernstein 	return is_valid;
817f0cd0a34SEric Bernstein }
818f0cd0a34SEric Bernstein 
819f0cd0a34SEric Bernstein void dcn10_link_encoder_hw_init(
820f0cd0a34SEric Bernstein 	struct link_encoder *enc)
821f0cd0a34SEric Bernstein {
822f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
823f0cd0a34SEric Bernstein 	struct bp_transmitter_control cntl = { 0 };
824f0cd0a34SEric Bernstein 	enum bp_result result;
825f0cd0a34SEric Bernstein 
826f0cd0a34SEric Bernstein 	cntl.action = TRANSMITTER_CONTROL_INIT;
827f0cd0a34SEric Bernstein 	cntl.engine_id = ENGINE_ID_UNKNOWN;
828f0cd0a34SEric Bernstein 	cntl.transmitter = enc10->base.transmitter;
829f0cd0a34SEric Bernstein 	cntl.connector_obj_id = enc10->base.connector;
830f0cd0a34SEric Bernstein 	cntl.lanes_number = LANE_COUNT_FOUR;
831f0cd0a34SEric Bernstein 	cntl.coherent = false;
832f0cd0a34SEric Bernstein 	cntl.hpd_sel = enc10->base.hpd_source;
833f0cd0a34SEric Bernstein 
834f0cd0a34SEric Bernstein 	if (enc10->base.connector.id == CONNECTOR_ID_EDP)
835f0cd0a34SEric Bernstein 		cntl.signal = SIGNAL_TYPE_EDP;
836f0cd0a34SEric Bernstein 
837f0cd0a34SEric Bernstein 	result = link_transmitter_control(enc10, &cntl);
838f0cd0a34SEric Bernstein 
839f0cd0a34SEric Bernstein 	if (result != BP_RESULT_OK) {
840f0cd0a34SEric Bernstein 		DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
841f0cd0a34SEric Bernstein 			__func__);
842f0cd0a34SEric Bernstein 		BREAK_TO_DEBUGGER();
843f0cd0a34SEric Bernstein 		return;
844f0cd0a34SEric Bernstein 	}
845f0cd0a34SEric Bernstein 
846f0cd0a34SEric Bernstein 	if (enc10->base.connector.id == CONNECTOR_ID_LVDS) {
847f0cd0a34SEric Bernstein 		cntl.action = TRANSMITTER_CONTROL_BACKLIGHT_BRIGHTNESS;
848f0cd0a34SEric Bernstein 
849f0cd0a34SEric Bernstein 		result = link_transmitter_control(enc10, &cntl);
850f0cd0a34SEric Bernstein 
851f0cd0a34SEric Bernstein 		ASSERT(result == BP_RESULT_OK);
852f0cd0a34SEric Bernstein 
853f0cd0a34SEric Bernstein 	}
854ac99243cSYongqiang Sun 	dcn10_aux_initialize(enc10);
855f0cd0a34SEric Bernstein 
856f0cd0a34SEric Bernstein 	/* reinitialize HPD.
857f0cd0a34SEric Bernstein 	 * hpd_initialize() will pass DIG_FE id to HW context.
858f0cd0a34SEric Bernstein 	 * All other routine within HW context will use fe_engine_offset
859f0cd0a34SEric Bernstein 	 * as DIG_FE id even caller pass DIG_FE id.
860f0cd0a34SEric Bernstein 	 * So this routine must be called first.
861f0cd0a34SEric Bernstein 	 */
862f0cd0a34SEric Bernstein 	hpd_initialize(enc10);
863f0cd0a34SEric Bernstein }
864f0cd0a34SEric Bernstein 
865f0cd0a34SEric Bernstein void dcn10_link_encoder_destroy(struct link_encoder **enc)
866f0cd0a34SEric Bernstein {
867f0cd0a34SEric Bernstein 	kfree(TO_DCN10_LINK_ENC(*enc));
868f0cd0a34SEric Bernstein 	*enc = NULL;
869f0cd0a34SEric Bernstein }
870f0cd0a34SEric Bernstein 
871f0cd0a34SEric Bernstein void dcn10_link_encoder_setup(
872f0cd0a34SEric Bernstein 	struct link_encoder *enc,
873f0cd0a34SEric Bernstein 	enum signal_type signal)
874f0cd0a34SEric Bernstein {
875f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
876f0cd0a34SEric Bernstein 
877f0cd0a34SEric Bernstein 	switch (signal) {
878f0cd0a34SEric Bernstein 	case SIGNAL_TYPE_EDP:
879f0cd0a34SEric Bernstein 	case SIGNAL_TYPE_DISPLAY_PORT:
880f0cd0a34SEric Bernstein 		/* DP SST */
881f0cd0a34SEric Bernstein 		REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 0);
882f0cd0a34SEric Bernstein 		break;
883f0cd0a34SEric Bernstein 	case SIGNAL_TYPE_LVDS:
884f0cd0a34SEric Bernstein 		/* LVDS */
885f0cd0a34SEric Bernstein 		REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 1);
886f0cd0a34SEric Bernstein 		break;
887f0cd0a34SEric Bernstein 	case SIGNAL_TYPE_DVI_SINGLE_LINK:
888f0cd0a34SEric Bernstein 	case SIGNAL_TYPE_DVI_DUAL_LINK:
889f0cd0a34SEric Bernstein 		/* TMDS-DVI */
890f0cd0a34SEric Bernstein 		REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 2);
891f0cd0a34SEric Bernstein 		break;
892f0cd0a34SEric Bernstein 	case SIGNAL_TYPE_HDMI_TYPE_A:
893f0cd0a34SEric Bernstein 		/* TMDS-HDMI */
894f0cd0a34SEric Bernstein 		REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 3);
895f0cd0a34SEric Bernstein 		break;
896f0cd0a34SEric Bernstein 	case SIGNAL_TYPE_DISPLAY_PORT_MST:
897f0cd0a34SEric Bernstein 		/* DP MST */
898f0cd0a34SEric Bernstein 		REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 5);
899f0cd0a34SEric Bernstein 		break;
900f0cd0a34SEric Bernstein 	default:
901f0cd0a34SEric Bernstein 		ASSERT_CRITICAL(false);
902f0cd0a34SEric Bernstein 		/* invalid mode ! */
903f0cd0a34SEric Bernstein 		break;
904f0cd0a34SEric Bernstein 	}
905f0cd0a34SEric Bernstein 
906f0cd0a34SEric Bernstein }
907f0cd0a34SEric Bernstein 
908f0cd0a34SEric Bernstein /* TODO: still need depth or just pass in adjusted pixel clock? */
909f0cd0a34SEric Bernstein void dcn10_link_encoder_enable_tmds_output(
910f0cd0a34SEric Bernstein 	struct link_encoder *enc,
911f0cd0a34SEric Bernstein 	enum clock_source_id clock_source,
912f0cd0a34SEric Bernstein 	enum dc_color_depth color_depth,
913f0cd0a34SEric Bernstein 	enum signal_type signal,
914f0cd0a34SEric Bernstein 	uint32_t pixel_clock)
915f0cd0a34SEric Bernstein {
916f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
917f0cd0a34SEric Bernstein 	struct bp_transmitter_control cntl = { 0 };
918f0cd0a34SEric Bernstein 	enum bp_result result;
919f0cd0a34SEric Bernstein 
920f0cd0a34SEric Bernstein 	/* Enable the PHY */
921f0cd0a34SEric Bernstein 
922f0cd0a34SEric Bernstein 	cntl.action = TRANSMITTER_CONTROL_ENABLE;
923f0cd0a34SEric Bernstein 	cntl.engine_id = enc->preferred_engine;
924f0cd0a34SEric Bernstein 	cntl.transmitter = enc10->base.transmitter;
925f0cd0a34SEric Bernstein 	cntl.pll_id = clock_source;
926f0cd0a34SEric Bernstein 	cntl.signal = signal;
927f0cd0a34SEric Bernstein 	if (cntl.signal == SIGNAL_TYPE_DVI_DUAL_LINK)
928f0cd0a34SEric Bernstein 		cntl.lanes_number = 8;
929f0cd0a34SEric Bernstein 	else
930f0cd0a34SEric Bernstein 		cntl.lanes_number = 4;
931f0cd0a34SEric Bernstein 
932f0cd0a34SEric Bernstein 	cntl.hpd_sel = enc10->base.hpd_source;
933f0cd0a34SEric Bernstein 
934f0cd0a34SEric Bernstein 	cntl.pixel_clock = pixel_clock;
935f0cd0a34SEric Bernstein 	cntl.color_depth = color_depth;
936f0cd0a34SEric Bernstein 
937f0cd0a34SEric Bernstein 	result = link_transmitter_control(enc10, &cntl);
938f0cd0a34SEric Bernstein 
939f0cd0a34SEric Bernstein 	if (result != BP_RESULT_OK) {
940f0cd0a34SEric Bernstein 		DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
941f0cd0a34SEric Bernstein 			__func__);
942f0cd0a34SEric Bernstein 		BREAK_TO_DEBUGGER();
943f0cd0a34SEric Bernstein 	}
944f0cd0a34SEric Bernstein }
945f0cd0a34SEric Bernstein 
946f0cd0a34SEric Bernstein /* enables DP PHY output */
947f0cd0a34SEric Bernstein void dcn10_link_encoder_enable_dp_output(
948f0cd0a34SEric Bernstein 	struct link_encoder *enc,
949f0cd0a34SEric Bernstein 	const struct dc_link_settings *link_settings,
950f0cd0a34SEric Bernstein 	enum clock_source_id clock_source)
951f0cd0a34SEric Bernstein {
952f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
953f0cd0a34SEric Bernstein 	struct bp_transmitter_control cntl = { 0 };
954f0cd0a34SEric Bernstein 	enum bp_result result;
955f0cd0a34SEric Bernstein 
956f0cd0a34SEric Bernstein 	/* Enable the PHY */
957f0cd0a34SEric Bernstein 
958f0cd0a34SEric Bernstein 	/* number_of_lanes is used for pixel clock adjust,
959f0cd0a34SEric Bernstein 	 * but it's not passed to asic_control.
960f0cd0a34SEric Bernstein 	 * We need to set number of lanes manually.
961f0cd0a34SEric Bernstein 	 */
9622ee7c03cSDmytro Laktyushkin 	enc1_configure_encoder(enc10, link_settings);
963f0cd0a34SEric Bernstein 
964f0cd0a34SEric Bernstein 	cntl.action = TRANSMITTER_CONTROL_ENABLE;
965f0cd0a34SEric Bernstein 	cntl.engine_id = enc->preferred_engine;
966f0cd0a34SEric Bernstein 	cntl.transmitter = enc10->base.transmitter;
967f0cd0a34SEric Bernstein 	cntl.pll_id = clock_source;
968f0cd0a34SEric Bernstein 	cntl.signal = SIGNAL_TYPE_DISPLAY_PORT;
969f0cd0a34SEric Bernstein 	cntl.lanes_number = link_settings->lane_count;
970f0cd0a34SEric Bernstein 	cntl.hpd_sel = enc10->base.hpd_source;
971f0cd0a34SEric Bernstein 	cntl.pixel_clock = link_settings->link_rate
972f0cd0a34SEric Bernstein 						* LINK_RATE_REF_FREQ_IN_KHZ;
973f0cd0a34SEric Bernstein 	/* TODO: check if undefined works */
974f0cd0a34SEric Bernstein 	cntl.color_depth = COLOR_DEPTH_UNDEFINED;
975f0cd0a34SEric Bernstein 
976f0cd0a34SEric Bernstein 	result = link_transmitter_control(enc10, &cntl);
977f0cd0a34SEric Bernstein 
978f0cd0a34SEric Bernstein 	if (result != BP_RESULT_OK) {
979f0cd0a34SEric Bernstein 		DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
980f0cd0a34SEric Bernstein 			__func__);
981f0cd0a34SEric Bernstein 		BREAK_TO_DEBUGGER();
982f0cd0a34SEric Bernstein 	}
983f0cd0a34SEric Bernstein }
984f0cd0a34SEric Bernstein 
985f0cd0a34SEric Bernstein /* enables DP PHY output in MST mode */
986f0cd0a34SEric Bernstein void dcn10_link_encoder_enable_dp_mst_output(
987f0cd0a34SEric Bernstein 	struct link_encoder *enc,
988f0cd0a34SEric Bernstein 	const struct dc_link_settings *link_settings,
989f0cd0a34SEric Bernstein 	enum clock_source_id clock_source)
990f0cd0a34SEric Bernstein {
991f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
992f0cd0a34SEric Bernstein 	struct bp_transmitter_control cntl = { 0 };
993f0cd0a34SEric Bernstein 	enum bp_result result;
994f0cd0a34SEric Bernstein 
995f0cd0a34SEric Bernstein 	/* Enable the PHY */
996f0cd0a34SEric Bernstein 
997f0cd0a34SEric Bernstein 	/* number_of_lanes is used for pixel clock adjust,
998f0cd0a34SEric Bernstein 	 * but it's not passed to asic_control.
999f0cd0a34SEric Bernstein 	 * We need to set number of lanes manually.
1000f0cd0a34SEric Bernstein 	 */
10012ee7c03cSDmytro Laktyushkin 	enc1_configure_encoder(enc10, link_settings);
1002f0cd0a34SEric Bernstein 
1003f0cd0a34SEric Bernstein 	cntl.action = TRANSMITTER_CONTROL_ENABLE;
1004f0cd0a34SEric Bernstein 	cntl.engine_id = ENGINE_ID_UNKNOWN;
1005f0cd0a34SEric Bernstein 	cntl.transmitter = enc10->base.transmitter;
1006f0cd0a34SEric Bernstein 	cntl.pll_id = clock_source;
1007f0cd0a34SEric Bernstein 	cntl.signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
1008f0cd0a34SEric Bernstein 	cntl.lanes_number = link_settings->lane_count;
1009f0cd0a34SEric Bernstein 	cntl.hpd_sel = enc10->base.hpd_source;
1010f0cd0a34SEric Bernstein 	cntl.pixel_clock = link_settings->link_rate
1011f0cd0a34SEric Bernstein 						* LINK_RATE_REF_FREQ_IN_KHZ;
1012f0cd0a34SEric Bernstein 	/* TODO: check if undefined works */
1013f0cd0a34SEric Bernstein 	cntl.color_depth = COLOR_DEPTH_UNDEFINED;
1014f0cd0a34SEric Bernstein 
1015f0cd0a34SEric Bernstein 	result = link_transmitter_control(enc10, &cntl);
1016f0cd0a34SEric Bernstein 
1017f0cd0a34SEric Bernstein 	if (result != BP_RESULT_OK) {
1018f0cd0a34SEric Bernstein 		DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
1019f0cd0a34SEric Bernstein 			__func__);
1020f0cd0a34SEric Bernstein 		BREAK_TO_DEBUGGER();
1021f0cd0a34SEric Bernstein 	}
1022f0cd0a34SEric Bernstein }
1023f0cd0a34SEric Bernstein /*
1024f0cd0a34SEric Bernstein  * @brief
1025f0cd0a34SEric Bernstein  * Disable transmitter and its encoder
1026f0cd0a34SEric Bernstein  */
1027f0cd0a34SEric Bernstein void dcn10_link_encoder_disable_output(
1028f0cd0a34SEric Bernstein 	struct link_encoder *enc,
1029f0cd0a34SEric Bernstein 	enum signal_type signal)
1030f0cd0a34SEric Bernstein {
1031f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1032f0cd0a34SEric Bernstein 	struct bp_transmitter_control cntl = { 0 };
1033f0cd0a34SEric Bernstein 	enum bp_result result;
1034f0cd0a34SEric Bernstein 
1035f0cd0a34SEric Bernstein 	if (!dcn10_is_dig_enabled(enc)) {
1036f0cd0a34SEric Bernstein 		/* OF_SKIP_POWER_DOWN_INACTIVE_ENCODER */
10377e17cb4bSCharlene Liu 	/*in DP_Alt_No_Connect case, we turn off the dig already,
10387e17cb4bSCharlene Liu 	after excuation the PHY w/a sequence, not allow touch PHY any more*/
1039f0cd0a34SEric Bernstein 		return;
1040f0cd0a34SEric Bernstein 	}
1041f0cd0a34SEric Bernstein 	/* Power-down RX and disable GPU PHY should be paired.
1042f0cd0a34SEric Bernstein 	 * Disabling PHY without powering down RX may cause
1043f0cd0a34SEric Bernstein 	 * symbol lock loss, on which we will get DP Sink interrupt.
1044f0cd0a34SEric Bernstein 	 */
1045f0cd0a34SEric Bernstein 
1046f0cd0a34SEric Bernstein 	/* There is a case for the DP active dongles
1047f0cd0a34SEric Bernstein 	 * where we want to disable the PHY but keep RX powered,
1048f0cd0a34SEric Bernstein 	 * for those we need to ignore DP Sink interrupt
1049f0cd0a34SEric Bernstein 	 * by checking lane count that has been set
1050f0cd0a34SEric Bernstein 	 * on the last do_enable_output().
1051f0cd0a34SEric Bernstein 	 */
1052f0cd0a34SEric Bernstein 
1053f0cd0a34SEric Bernstein 	/* disable transmitter */
1054f0cd0a34SEric Bernstein 	cntl.action = TRANSMITTER_CONTROL_DISABLE;
1055f0cd0a34SEric Bernstein 	cntl.transmitter = enc10->base.transmitter;
1056f0cd0a34SEric Bernstein 	cntl.hpd_sel = enc10->base.hpd_source;
1057f0cd0a34SEric Bernstein 	cntl.signal = signal;
1058f0cd0a34SEric Bernstein 	cntl.connector_obj_id = enc10->base.connector;
1059f0cd0a34SEric Bernstein 
1060f0cd0a34SEric Bernstein 	result = link_transmitter_control(enc10, &cntl);
1061f0cd0a34SEric Bernstein 
1062f0cd0a34SEric Bernstein 	if (result != BP_RESULT_OK) {
1063f0cd0a34SEric Bernstein 		DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
1064f0cd0a34SEric Bernstein 			__func__);
1065f0cd0a34SEric Bernstein 		BREAK_TO_DEBUGGER();
1066f0cd0a34SEric Bernstein 		return;
1067f0cd0a34SEric Bernstein 	}
1068f0cd0a34SEric Bernstein 
1069f0cd0a34SEric Bernstein 	/* disable encoder */
1070f0cd0a34SEric Bernstein 	if (dc_is_dp_signal(signal))
1071f0cd0a34SEric Bernstein 		link_encoder_disable(enc10);
1072f0cd0a34SEric Bernstein }
1073f0cd0a34SEric Bernstein 
1074f0cd0a34SEric Bernstein void dcn10_link_encoder_dp_set_lane_settings(
1075f0cd0a34SEric Bernstein 	struct link_encoder *enc,
1076f0cd0a34SEric Bernstein 	const struct link_training_settings *link_settings)
1077f0cd0a34SEric Bernstein {
1078f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1079f0cd0a34SEric Bernstein 	union dpcd_training_lane_set training_lane_set = { { 0 } };
1080f0cd0a34SEric Bernstein 	int32_t lane = 0;
1081f0cd0a34SEric Bernstein 	struct bp_transmitter_control cntl = { 0 };
1082f0cd0a34SEric Bernstein 
1083f0cd0a34SEric Bernstein 	if (!link_settings) {
1084f0cd0a34SEric Bernstein 		BREAK_TO_DEBUGGER();
1085f0cd0a34SEric Bernstein 		return;
1086f0cd0a34SEric Bernstein 	}
1087f0cd0a34SEric Bernstein 
1088f0cd0a34SEric Bernstein 	cntl.action = TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS;
1089f0cd0a34SEric Bernstein 	cntl.transmitter = enc10->base.transmitter;
1090f0cd0a34SEric Bernstein 	cntl.connector_obj_id = enc10->base.connector;
1091f0cd0a34SEric Bernstein 	cntl.lanes_number = link_settings->link_settings.lane_count;
1092f0cd0a34SEric Bernstein 	cntl.hpd_sel = enc10->base.hpd_source;
1093f0cd0a34SEric Bernstein 	cntl.pixel_clock = link_settings->link_settings.link_rate *
1094f0cd0a34SEric Bernstein 						LINK_RATE_REF_FREQ_IN_KHZ;
1095f0cd0a34SEric Bernstein 
1096f0cd0a34SEric Bernstein 	for (lane = 0; lane < link_settings->link_settings.lane_count; lane++) {
1097f0cd0a34SEric Bernstein 		/* translate lane settings */
1098f0cd0a34SEric Bernstein 
1099f0cd0a34SEric Bernstein 		training_lane_set.bits.VOLTAGE_SWING_SET =
1100f0cd0a34SEric Bernstein 			link_settings->lane_settings[lane].VOLTAGE_SWING;
1101f0cd0a34SEric Bernstein 		training_lane_set.bits.PRE_EMPHASIS_SET =
1102f0cd0a34SEric Bernstein 			link_settings->lane_settings[lane].PRE_EMPHASIS;
1103f0cd0a34SEric Bernstein 
1104f0cd0a34SEric Bernstein 		/* post cursor 2 setting only applies to HBR2 link rate */
1105f0cd0a34SEric Bernstein 		if (link_settings->link_settings.link_rate == LINK_RATE_HIGH2) {
1106f0cd0a34SEric Bernstein 			/* this is passed to VBIOS
1107f0cd0a34SEric Bernstein 			 * to program post cursor 2 level
1108f0cd0a34SEric Bernstein 			 */
1109f0cd0a34SEric Bernstein 			training_lane_set.bits.POST_CURSOR2_SET =
1110f0cd0a34SEric Bernstein 				link_settings->lane_settings[lane].POST_CURSOR2;
1111f0cd0a34SEric Bernstein 		}
1112f0cd0a34SEric Bernstein 
1113f0cd0a34SEric Bernstein 		cntl.lane_select = lane;
1114f0cd0a34SEric Bernstein 		cntl.lane_settings = training_lane_set.raw;
1115f0cd0a34SEric Bernstein 
1116f0cd0a34SEric Bernstein 		/* call VBIOS table to set voltage swing and pre-emphasis */
1117f0cd0a34SEric Bernstein 		link_transmitter_control(enc10, &cntl);
1118f0cd0a34SEric Bernstein 	}
1119f0cd0a34SEric Bernstein }
1120f0cd0a34SEric Bernstein 
1121f0cd0a34SEric Bernstein /* set DP PHY test and training patterns */
1122f0cd0a34SEric Bernstein void dcn10_link_encoder_dp_set_phy_pattern(
1123f0cd0a34SEric Bernstein 	struct link_encoder *enc,
1124f0cd0a34SEric Bernstein 	const struct encoder_set_dp_phy_pattern_param *param)
1125f0cd0a34SEric Bernstein {
1126f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1127f0cd0a34SEric Bernstein 
1128f0cd0a34SEric Bernstein 	switch (param->dp_phy_pattern) {
1129f0cd0a34SEric Bernstein 	case DP_TEST_PATTERN_TRAINING_PATTERN1:
1130f0cd0a34SEric Bernstein 		dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 0);
1131f0cd0a34SEric Bernstein 		break;
1132f0cd0a34SEric Bernstein 	case DP_TEST_PATTERN_TRAINING_PATTERN2:
1133f0cd0a34SEric Bernstein 		dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 1);
1134f0cd0a34SEric Bernstein 		break;
1135f0cd0a34SEric Bernstein 	case DP_TEST_PATTERN_TRAINING_PATTERN3:
1136f0cd0a34SEric Bernstein 		dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 2);
1137f0cd0a34SEric Bernstein 		break;
1138f0cd0a34SEric Bernstein 	case DP_TEST_PATTERN_TRAINING_PATTERN4:
1139f0cd0a34SEric Bernstein 		dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 3);
1140f0cd0a34SEric Bernstein 		break;
1141f0cd0a34SEric Bernstein 	case DP_TEST_PATTERN_D102:
1142f0cd0a34SEric Bernstein 		set_dp_phy_pattern_d102(enc10);
1143f0cd0a34SEric Bernstein 		break;
1144f0cd0a34SEric Bernstein 	case DP_TEST_PATTERN_SYMBOL_ERROR:
1145f0cd0a34SEric Bernstein 		set_dp_phy_pattern_symbol_error(enc10);
1146f0cd0a34SEric Bernstein 		break;
1147f0cd0a34SEric Bernstein 	case DP_TEST_PATTERN_PRBS7:
1148f0cd0a34SEric Bernstein 		set_dp_phy_pattern_prbs7(enc10);
1149f0cd0a34SEric Bernstein 		break;
1150f0cd0a34SEric Bernstein 	case DP_TEST_PATTERN_80BIT_CUSTOM:
1151f0cd0a34SEric Bernstein 		set_dp_phy_pattern_80bit_custom(
1152f0cd0a34SEric Bernstein 			enc10, param->custom_pattern);
1153f0cd0a34SEric Bernstein 		break;
1154f0cd0a34SEric Bernstein 	case DP_TEST_PATTERN_CP2520_1:
1155f0cd0a34SEric Bernstein 		set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 1);
1156f0cd0a34SEric Bernstein 		break;
1157f0cd0a34SEric Bernstein 	case DP_TEST_PATTERN_CP2520_2:
1158f0cd0a34SEric Bernstein 		set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 2);
1159f0cd0a34SEric Bernstein 		break;
1160f0cd0a34SEric Bernstein 	case DP_TEST_PATTERN_CP2520_3:
1161f0cd0a34SEric Bernstein 		set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 3);
1162f0cd0a34SEric Bernstein 		break;
1163f0cd0a34SEric Bernstein 	case DP_TEST_PATTERN_VIDEO_MODE: {
1164f0cd0a34SEric Bernstein 		set_dp_phy_pattern_passthrough_mode(
1165f0cd0a34SEric Bernstein 			enc10, param->dp_panel_mode);
1166f0cd0a34SEric Bernstein 		break;
1167f0cd0a34SEric Bernstein 	}
1168f0cd0a34SEric Bernstein 
1169f0cd0a34SEric Bernstein 	default:
1170f0cd0a34SEric Bernstein 		/* invalid phy pattern */
1171f0cd0a34SEric Bernstein 		ASSERT_CRITICAL(false);
1172f0cd0a34SEric Bernstein 		break;
1173f0cd0a34SEric Bernstein 	}
1174f0cd0a34SEric Bernstein }
1175f0cd0a34SEric Bernstein 
1176f0cd0a34SEric Bernstein static void fill_stream_allocation_row_info(
1177f0cd0a34SEric Bernstein 	const struct link_mst_stream_allocation *stream_allocation,
1178f0cd0a34SEric Bernstein 	uint32_t *src,
1179f0cd0a34SEric Bernstein 	uint32_t *slots)
1180f0cd0a34SEric Bernstein {
1181f0cd0a34SEric Bernstein 	const struct stream_encoder *stream_enc = stream_allocation->stream_enc;
1182f0cd0a34SEric Bernstein 
1183f0cd0a34SEric Bernstein 	if (stream_enc) {
1184f0cd0a34SEric Bernstein 		*src = stream_enc->id;
1185f0cd0a34SEric Bernstein 		*slots = stream_allocation->slot_count;
1186f0cd0a34SEric Bernstein 	} else {
1187f0cd0a34SEric Bernstein 		*src = 0;
1188f0cd0a34SEric Bernstein 		*slots = 0;
1189f0cd0a34SEric Bernstein 	}
1190f0cd0a34SEric Bernstein }
1191f0cd0a34SEric Bernstein 
1192f0cd0a34SEric Bernstein /* programs DP MST VC payload allocation */
1193f0cd0a34SEric Bernstein void dcn10_link_encoder_update_mst_stream_allocation_table(
1194f0cd0a34SEric Bernstein 	struct link_encoder *enc,
1195f0cd0a34SEric Bernstein 	const struct link_mst_stream_allocation_table *table)
1196f0cd0a34SEric Bernstein {
1197f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1198f0cd0a34SEric Bernstein 	uint32_t value0 = 0;
1199f0cd0a34SEric Bernstein 	uint32_t value1 = 0;
1200f0cd0a34SEric Bernstein 	uint32_t value2 = 0;
1201f0cd0a34SEric Bernstein 	uint32_t slots = 0;
1202f0cd0a34SEric Bernstein 	uint32_t src = 0;
1203f0cd0a34SEric Bernstein 	uint32_t retries = 0;
1204f0cd0a34SEric Bernstein 
1205f0cd0a34SEric Bernstein 	/* For CZ, there are only 3 pipes. So Virtual channel is up 3.*/
1206f0cd0a34SEric Bernstein 
1207f0cd0a34SEric Bernstein 	/* --- Set MSE Stream Attribute -
1208f0cd0a34SEric Bernstein 	 * Setup VC Payload Table on Tx Side,
1209f0cd0a34SEric Bernstein 	 * Issue allocation change trigger
1210f0cd0a34SEric Bernstein 	 * to commit payload on both tx and rx side
1211f0cd0a34SEric Bernstein 	 */
1212f0cd0a34SEric Bernstein 
1213f0cd0a34SEric Bernstein 	/* we should clean-up table each time */
1214f0cd0a34SEric Bernstein 
1215f0cd0a34SEric Bernstein 	if (table->stream_count >= 1) {
1216f0cd0a34SEric Bernstein 		fill_stream_allocation_row_info(
1217f0cd0a34SEric Bernstein 			&table->stream_allocations[0],
1218f0cd0a34SEric Bernstein 			&src,
1219f0cd0a34SEric Bernstein 			&slots);
1220f0cd0a34SEric Bernstein 	} else {
1221f0cd0a34SEric Bernstein 		src = 0;
1222f0cd0a34SEric Bernstein 		slots = 0;
1223f0cd0a34SEric Bernstein 	}
1224f0cd0a34SEric Bernstein 
1225f0cd0a34SEric Bernstein 	REG_UPDATE_2(DP_MSE_SAT0,
1226f0cd0a34SEric Bernstein 			DP_MSE_SAT_SRC0, src,
1227f0cd0a34SEric Bernstein 			DP_MSE_SAT_SLOT_COUNT0, slots);
1228f0cd0a34SEric Bernstein 
1229f0cd0a34SEric Bernstein 	if (table->stream_count >= 2) {
1230f0cd0a34SEric Bernstein 		fill_stream_allocation_row_info(
1231f0cd0a34SEric Bernstein 			&table->stream_allocations[1],
1232f0cd0a34SEric Bernstein 			&src,
1233f0cd0a34SEric Bernstein 			&slots);
1234f0cd0a34SEric Bernstein 	} else {
1235f0cd0a34SEric Bernstein 		src = 0;
1236f0cd0a34SEric Bernstein 		slots = 0;
1237f0cd0a34SEric Bernstein 	}
1238f0cd0a34SEric Bernstein 
1239f0cd0a34SEric Bernstein 	REG_UPDATE_2(DP_MSE_SAT0,
1240f0cd0a34SEric Bernstein 			DP_MSE_SAT_SRC1, src,
1241f0cd0a34SEric Bernstein 			DP_MSE_SAT_SLOT_COUNT1, slots);
1242f0cd0a34SEric Bernstein 
1243f0cd0a34SEric Bernstein 	if (table->stream_count >= 3) {
1244f0cd0a34SEric Bernstein 		fill_stream_allocation_row_info(
1245f0cd0a34SEric Bernstein 			&table->stream_allocations[2],
1246f0cd0a34SEric Bernstein 			&src,
1247f0cd0a34SEric Bernstein 			&slots);
1248f0cd0a34SEric Bernstein 	} else {
1249f0cd0a34SEric Bernstein 		src = 0;
1250f0cd0a34SEric Bernstein 		slots = 0;
1251f0cd0a34SEric Bernstein 	}
1252f0cd0a34SEric Bernstein 
1253f0cd0a34SEric Bernstein 	REG_UPDATE_2(DP_MSE_SAT1,
1254f0cd0a34SEric Bernstein 			DP_MSE_SAT_SRC2, src,
1255f0cd0a34SEric Bernstein 			DP_MSE_SAT_SLOT_COUNT2, slots);
1256f0cd0a34SEric Bernstein 
1257f0cd0a34SEric Bernstein 	if (table->stream_count >= 4) {
1258f0cd0a34SEric Bernstein 		fill_stream_allocation_row_info(
1259f0cd0a34SEric Bernstein 			&table->stream_allocations[3],
1260f0cd0a34SEric Bernstein 			&src,
1261f0cd0a34SEric Bernstein 			&slots);
1262f0cd0a34SEric Bernstein 	} else {
1263f0cd0a34SEric Bernstein 		src = 0;
1264f0cd0a34SEric Bernstein 		slots = 0;
1265f0cd0a34SEric Bernstein 	}
1266f0cd0a34SEric Bernstein 
1267f0cd0a34SEric Bernstein 	REG_UPDATE_2(DP_MSE_SAT1,
1268f0cd0a34SEric Bernstein 			DP_MSE_SAT_SRC3, src,
1269f0cd0a34SEric Bernstein 			DP_MSE_SAT_SLOT_COUNT3, slots);
1270f0cd0a34SEric Bernstein 
1271f0cd0a34SEric Bernstein 	/* --- wait for transaction finish */
1272f0cd0a34SEric Bernstein 
1273f0cd0a34SEric Bernstein 	/* send allocation change trigger (ACT) ?
1274f0cd0a34SEric Bernstein 	 * this step first sends the ACT,
1275f0cd0a34SEric Bernstein 	 * then double buffers the SAT into the hardware
1276f0cd0a34SEric Bernstein 	 * making the new allocation active on the DP MST mode link
1277f0cd0a34SEric Bernstein 	 */
1278f0cd0a34SEric Bernstein 
1279f0cd0a34SEric Bernstein 	/* DP_MSE_SAT_UPDATE:
1280f0cd0a34SEric Bernstein 	 * 0 - No Action
1281f0cd0a34SEric Bernstein 	 * 1 - Update SAT with trigger
1282f0cd0a34SEric Bernstein 	 * 2 - Update SAT without trigger
1283f0cd0a34SEric Bernstein 	 */
1284f0cd0a34SEric Bernstein 	REG_UPDATE(DP_MSE_SAT_UPDATE,
1285f0cd0a34SEric Bernstein 			DP_MSE_SAT_UPDATE, 1);
1286f0cd0a34SEric Bernstein 
1287f0cd0a34SEric Bernstein 	/* wait for update to complete
1288f0cd0a34SEric Bernstein 	 * (i.e. DP_MSE_SAT_UPDATE field is reset to 0)
1289f0cd0a34SEric Bernstein 	 * then wait for the transmission
1290f0cd0a34SEric Bernstein 	 * of at least 16 MTP headers on immediate local link.
1291f0cd0a34SEric Bernstein 	 * i.e. DP_MSE_16_MTP_KEEPOUT field (read only) is reset to 0
1292f0cd0a34SEric Bernstein 	 * a value of 1 indicates that DP MST mode
1293f0cd0a34SEric Bernstein 	 * is in the 16 MTP keepout region after a VC has been added.
1294f0cd0a34SEric Bernstein 	 * MST stream bandwidth (VC rate) can be configured
1295f0cd0a34SEric Bernstein 	 * after this bit is cleared
1296f0cd0a34SEric Bernstein 	 */
1297f0cd0a34SEric Bernstein 	do {
1298f0cd0a34SEric Bernstein 		udelay(10);
1299f0cd0a34SEric Bernstein 
1300f0cd0a34SEric Bernstein 		value0 = REG_READ(DP_MSE_SAT_UPDATE);
1301f0cd0a34SEric Bernstein 
1302f0cd0a34SEric Bernstein 		REG_GET(DP_MSE_SAT_UPDATE,
1303f0cd0a34SEric Bernstein 				DP_MSE_SAT_UPDATE, &value1);
1304f0cd0a34SEric Bernstein 
1305f0cd0a34SEric Bernstein 		REG_GET(DP_MSE_SAT_UPDATE,
1306f0cd0a34SEric Bernstein 				DP_MSE_16_MTP_KEEPOUT, &value2);
1307f0cd0a34SEric Bernstein 
1308f0cd0a34SEric Bernstein 		/* bit field DP_MSE_SAT_UPDATE is set to 1 already */
1309f0cd0a34SEric Bernstein 		if (!value1 && !value2)
1310f0cd0a34SEric Bernstein 			break;
1311f0cd0a34SEric Bernstein 		++retries;
1312f0cd0a34SEric Bernstein 	} while (retries < DP_MST_UPDATE_MAX_RETRY);
1313f0cd0a34SEric Bernstein }
1314f0cd0a34SEric Bernstein 
1315f0cd0a34SEric Bernstein void dcn10_link_encoder_connect_dig_be_to_fe(
1316f0cd0a34SEric Bernstein 	struct link_encoder *enc,
1317f0cd0a34SEric Bernstein 	enum engine_id engine,
1318f0cd0a34SEric Bernstein 	bool connect)
1319f0cd0a34SEric Bernstein {
1320f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1321f0cd0a34SEric Bernstein 	uint32_t field;
1322f0cd0a34SEric Bernstein 
1323f0cd0a34SEric Bernstein 	if (engine != ENGINE_ID_UNKNOWN) {
1324f0cd0a34SEric Bernstein 
1325f0cd0a34SEric Bernstein 		REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &field);
1326f0cd0a34SEric Bernstein 
1327f0cd0a34SEric Bernstein 		if (connect)
1328f0cd0a34SEric Bernstein 			field |= get_frontend_source(engine);
1329f0cd0a34SEric Bernstein 		else
1330f0cd0a34SEric Bernstein 			field &= ~get_frontend_source(engine);
1331f0cd0a34SEric Bernstein 
1332f0cd0a34SEric Bernstein 		REG_UPDATE(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, field);
1333f0cd0a34SEric Bernstein 	}
1334f0cd0a34SEric Bernstein }
1335f0cd0a34SEric Bernstein 
1336f0cd0a34SEric Bernstein 
1337f0cd0a34SEric Bernstein #define HPD_REG(reg)\
1338f0cd0a34SEric Bernstein 	(enc10->hpd_regs->reg)
1339f0cd0a34SEric Bernstein 
1340f0cd0a34SEric Bernstein #define HPD_REG_READ(reg_name) \
1341f0cd0a34SEric Bernstein 		dm_read_reg(CTX, HPD_REG(reg_name))
1342f0cd0a34SEric Bernstein 
1343f0cd0a34SEric Bernstein #define HPD_REG_UPDATE_N(reg_name, n, ...)	\
1344f0cd0a34SEric Bernstein 		generic_reg_update_ex(CTX, \
1345f0cd0a34SEric Bernstein 				HPD_REG(reg_name), \
1346f0cd0a34SEric Bernstein 				n, __VA_ARGS__)
1347f0cd0a34SEric Bernstein 
1348f0cd0a34SEric Bernstein #define HPD_REG_UPDATE(reg_name, field, val)	\
1349f0cd0a34SEric Bernstein 		HPD_REG_UPDATE_N(reg_name, 1, \
1350f0cd0a34SEric Bernstein 				FN(reg_name, field), val)
1351f0cd0a34SEric Bernstein 
1352f0cd0a34SEric Bernstein void dcn10_link_encoder_enable_hpd(struct link_encoder *enc)
1353f0cd0a34SEric Bernstein {
1354f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1355f0cd0a34SEric Bernstein 
1356f0cd0a34SEric Bernstein 	HPD_REG_UPDATE(DC_HPD_CONTROL,
1357f0cd0a34SEric Bernstein 			DC_HPD_EN, 1);
1358f0cd0a34SEric Bernstein }
1359f0cd0a34SEric Bernstein 
1360f0cd0a34SEric Bernstein void dcn10_link_encoder_disable_hpd(struct link_encoder *enc)
1361f0cd0a34SEric Bernstein {
1362f0cd0a34SEric Bernstein 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1363f0cd0a34SEric Bernstein 
1364f0cd0a34SEric Bernstein 	HPD_REG_UPDATE(DC_HPD_CONTROL,
1365f0cd0a34SEric Bernstein 			DC_HPD_EN, 0);
1366f0cd0a34SEric Bernstein }
1367f0cd0a34SEric Bernstein 
1368f0cd0a34SEric Bernstein 
1369f0cd0a34SEric Bernstein #define AUX_REG(reg)\
1370f0cd0a34SEric Bernstein 	(enc10->aux_regs->reg)
1371f0cd0a34SEric Bernstein 
1372f0cd0a34SEric Bernstein #define AUX_REG_READ(reg_name) \
1373f0cd0a34SEric Bernstein 		dm_read_reg(CTX, AUX_REG(reg_name))
1374f0cd0a34SEric Bernstein 
1375f0cd0a34SEric Bernstein #define AUX_REG_UPDATE_N(reg_name, n, ...)	\
1376f0cd0a34SEric Bernstein 		generic_reg_update_ex(CTX, \
1377f0cd0a34SEric Bernstein 				AUX_REG(reg_name), \
1378f0cd0a34SEric Bernstein 				n, __VA_ARGS__)
1379f0cd0a34SEric Bernstein 
1380f0cd0a34SEric Bernstein #define AUX_REG_UPDATE(reg_name, field, val)	\
1381f0cd0a34SEric Bernstein 		AUX_REG_UPDATE_N(reg_name, 1, \
1382f0cd0a34SEric Bernstein 				FN(reg_name, field), val)
1383f0cd0a34SEric Bernstein 
1384f0cd0a34SEric Bernstein #define AUX_REG_UPDATE_2(reg, f1, v1, f2, v2)	\
1385f0cd0a34SEric Bernstein 		AUX_REG_UPDATE_N(reg, 2,\
1386f0cd0a34SEric Bernstein 				FN(reg, f1), v1,\
1387f0cd0a34SEric Bernstein 				FN(reg, f2), v2)
1388f0cd0a34SEric Bernstein 
1389ac99243cSYongqiang Sun void dcn10_aux_initialize(struct dcn10_link_encoder *enc10)
1390f0cd0a34SEric Bernstein {
1391f0cd0a34SEric Bernstein 	enum hpd_source_id hpd_source = enc10->base.hpd_source;
1392f0cd0a34SEric Bernstein 
1393f0cd0a34SEric Bernstein 	AUX_REG_UPDATE_2(AUX_CONTROL,
1394f0cd0a34SEric Bernstein 			AUX_HPD_SEL, hpd_source,
1395f0cd0a34SEric Bernstein 			AUX_LS_READ_EN, 0);
1396f0cd0a34SEric Bernstein 
1397f0cd0a34SEric Bernstein 	/* 1/4 window (the maximum allowed) */
1398f0cd0a34SEric Bernstein 	AUX_REG_UPDATE(AUX_DPHY_RX_CONTROL0,
1399ff1232a9SDaniel He 			AUX_RX_RECEIVE_WINDOW, 0);
1400f0cd0a34SEric Bernstein }
140178d9b95eSCharlene Liu 
140278d9b95eSCharlene Liu enum signal_type dcn10_get_dig_mode(
140378d9b95eSCharlene Liu 	struct link_encoder *enc)
140478d9b95eSCharlene Liu {
140578d9b95eSCharlene Liu 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
140678d9b95eSCharlene Liu 	uint32_t value;
140778d9b95eSCharlene Liu 	REG_GET(DIG_BE_CNTL, DIG_MODE, &value);
140878d9b95eSCharlene Liu 	switch (value) {
140978d9b95eSCharlene Liu 	case 1:
141078d9b95eSCharlene Liu 		return SIGNAL_TYPE_DISPLAY_PORT;
141178d9b95eSCharlene Liu 	case 2:
141278d9b95eSCharlene Liu 		return SIGNAL_TYPE_DVI_SINGLE_LINK;
141378d9b95eSCharlene Liu 	case 3:
141478d9b95eSCharlene Liu 		return SIGNAL_TYPE_HDMI_TYPE_A;
141578d9b95eSCharlene Liu 	case 5:
141678d9b95eSCharlene Liu 		return SIGNAL_TYPE_DISPLAY_PORT_MST;
141778d9b95eSCharlene Liu 	default:
141878d9b95eSCharlene Liu 		return SIGNAL_TYPE_NONE;
141978d9b95eSCharlene Liu 	}
142078d9b95eSCharlene Liu 	return SIGNAL_TYPE_NONE;
142178d9b95eSCharlene Liu }
142278d9b95eSCharlene Liu 
1423