xref: /openbmc/linux/drivers/gpu/drm/i915/display/g4x_dp.c (revision 4cca9676)
1917c2899SVille Syrjälä // SPDX-License-Identifier: MIT
2917c2899SVille Syrjälä /*
3917c2899SVille Syrjälä  * Copyright © 2020 Intel Corporation
4917c2899SVille Syrjälä  *
5917c2899SVille Syrjälä  * DisplayPort support for G4x,ILK,SNB,IVB,VLV,CHV (HSW+ handled by the DDI code).
6917c2899SVille Syrjälä  */
7917c2899SVille Syrjälä 
8f79a568aSLucas De Marchi #include <linux/string_helpers.h>
9f79a568aSLucas De Marchi 
10917c2899SVille Syrjälä #include "g4x_dp.h"
11801543b2SJani Nikula #include "i915_reg.h"
12917c2899SVille Syrjälä #include "intel_audio.h"
136cc42fbeSJani Nikula #include "intel_backlight.h"
14917c2899SVille Syrjälä #include "intel_connector.h"
15fd2b94a5SJani Nikula #include "intel_crtc.h"
167785ae0bSVille Syrjälä #include "intel_de.h"
17979e1b32SImre Deak #include "intel_display_power.h"
18917c2899SVille Syrjälä #include "intel_display_types.h"
19917c2899SVille Syrjälä #include "intel_dp.h"
20bb45217fSVille Syrjälä #include "intel_dp_aux.h"
21917c2899SVille Syrjälä #include "intel_dp_link_training.h"
22917c2899SVille Syrjälä #include "intel_dpio_phy.h"
23917c2899SVille Syrjälä #include "intel_fifo_underrun.h"
24917c2899SVille Syrjälä #include "intel_hdmi.h"
25917c2899SVille Syrjälä #include "intel_hotplug.h"
26a68819ccSVille Syrjälä #include "intel_pch_display.h"
27917c2899SVille Syrjälä #include "intel_pps.h"
281eecf31eSJani Nikula #include "vlv_sideband.h"
29917c2899SVille Syrjälä 
3015deead9SVille Syrjälä static const struct dpll g4x_dpll[] = {
3115deead9SVille Syrjälä 	{ .dot = 162000, .p1 = 2, .p2 = 10, .n = 2, .m1 = 23, .m2 = 8, },
3215deead9SVille Syrjälä 	{ .dot = 270000, .p1 = 1, .p2 = 10, .n = 1, .m1 = 14, .m2 = 2, },
33917c2899SVille Syrjälä };
34917c2899SVille Syrjälä 
3515deead9SVille Syrjälä static const struct dpll pch_dpll[] = {
3615deead9SVille Syrjälä 	{ .dot = 162000, .p1 = 2, .p2 = 10, .n = 1, .m1 = 12, .m2 = 9, },
3715deead9SVille Syrjälä 	{ .dot = 270000, .p1 = 1, .p2 = 10, .n = 2, .m1 = 14, .m2 = 8, },
38917c2899SVille Syrjälä };
39917c2899SVille Syrjälä 
4015deead9SVille Syrjälä static const struct dpll vlv_dpll[] = {
4115deead9SVille Syrjälä 	{ .dot = 162000, .p1 = 3, .p2 = 2, .n = 5, .m1 = 3, .m2 = 81, },
4215deead9SVille Syrjälä 	{ .dot = 270000, .p1 = 2, .p2 = 2, .n = 1, .m1 = 2, .m2 = 27, },
43917c2899SVille Syrjälä };
44917c2899SVille Syrjälä 
4515deead9SVille Syrjälä static const struct dpll chv_dpll[] = {
4615deead9SVille Syrjälä 	/* m2 is .22 binary fixed point  */
4715deead9SVille Syrjälä 	{ .dot = 162000, .p1 = 4, .p2 = 2, .n = 1, .m1 = 2, .m2 = 0x819999a /* 32.4 */ },
4815deead9SVille Syrjälä 	{ .dot = 270000, .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 /* 27.0 */ },
49917c2899SVille Syrjälä };
50917c2899SVille Syrjälä 
51917c2899SVille Syrjälä const struct dpll *vlv_get_dpll(struct drm_i915_private *i915)
52917c2899SVille Syrjälä {
5315deead9SVille Syrjälä 	return IS_CHERRYVIEW(i915) ? &chv_dpll[0] : &vlv_dpll[0];
54917c2899SVille Syrjälä }
55917c2899SVille Syrjälä 
56053ffdd1SVille Syrjälä void g4x_dp_set_clock(struct intel_encoder *encoder,
57917c2899SVille Syrjälä 		      struct intel_crtc_state *pipe_config)
58917c2899SVille Syrjälä {
59917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
6015deead9SVille Syrjälä 	const struct dpll *divisor = NULL;
61917c2899SVille Syrjälä 	int i, count = 0;
62917c2899SVille Syrjälä 
63917c2899SVille Syrjälä 	if (IS_G4X(dev_priv)) {
64917c2899SVille Syrjälä 		divisor = g4x_dpll;
65917c2899SVille Syrjälä 		count = ARRAY_SIZE(g4x_dpll);
66917c2899SVille Syrjälä 	} else if (HAS_PCH_SPLIT(dev_priv)) {
67917c2899SVille Syrjälä 		divisor = pch_dpll;
68917c2899SVille Syrjälä 		count = ARRAY_SIZE(pch_dpll);
69917c2899SVille Syrjälä 	} else if (IS_CHERRYVIEW(dev_priv)) {
70917c2899SVille Syrjälä 		divisor = chv_dpll;
71917c2899SVille Syrjälä 		count = ARRAY_SIZE(chv_dpll);
72917c2899SVille Syrjälä 	} else if (IS_VALLEYVIEW(dev_priv)) {
73917c2899SVille Syrjälä 		divisor = vlv_dpll;
74917c2899SVille Syrjälä 		count = ARRAY_SIZE(vlv_dpll);
75917c2899SVille Syrjälä 	}
76917c2899SVille Syrjälä 
77917c2899SVille Syrjälä 	if (divisor && count) {
78917c2899SVille Syrjälä 		for (i = 0; i < count; i++) {
7915deead9SVille Syrjälä 			if (pipe_config->port_clock == divisor[i].dot) {
8015deead9SVille Syrjälä 				pipe_config->dpll = divisor[i];
81917c2899SVille Syrjälä 				pipe_config->clock_set = true;
82917c2899SVille Syrjälä 				break;
83917c2899SVille Syrjälä 			}
84917c2899SVille Syrjälä 		}
85917c2899SVille Syrjälä 	}
86917c2899SVille Syrjälä }
87917c2899SVille Syrjälä 
88917c2899SVille Syrjälä static void intel_dp_prepare(struct intel_encoder *encoder,
89917c2899SVille Syrjälä 			     const struct intel_crtc_state *pipe_config)
90917c2899SVille Syrjälä {
91917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
92917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
93917c2899SVille Syrjälä 	enum port port = encoder->port;
94917c2899SVille Syrjälä 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
95917c2899SVille Syrjälä 	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
96917c2899SVille Syrjälä 
97917c2899SVille Syrjälä 	intel_dp_set_link_params(intel_dp,
98917c2899SVille Syrjälä 				 pipe_config->port_clock,
99917c2899SVille Syrjälä 				 pipe_config->lane_count);
100917c2899SVille Syrjälä 
101917c2899SVille Syrjälä 	/*
102917c2899SVille Syrjälä 	 * There are four kinds of DP registers:
103917c2899SVille Syrjälä 	 * IBX PCH
104917c2899SVille Syrjälä 	 * SNB CPU
105917c2899SVille Syrjälä 	 * IVB CPU
106917c2899SVille Syrjälä 	 * CPT PCH
107917c2899SVille Syrjälä 	 *
108917c2899SVille Syrjälä 	 * IBX PCH and CPU are the same for almost everything,
109917c2899SVille Syrjälä 	 * except that the CPU DP PLL is configured in this
110917c2899SVille Syrjälä 	 * register
111917c2899SVille Syrjälä 	 *
112917c2899SVille Syrjälä 	 * CPT PCH is quite different, having many bits moved
113917c2899SVille Syrjälä 	 * to the TRANS_DP_CTL register instead. That
114917c2899SVille Syrjälä 	 * configuration happens (oddly) in ilk_pch_enable
115917c2899SVille Syrjälä 	 */
116917c2899SVille Syrjälä 
117917c2899SVille Syrjälä 	/* Preserve the BIOS-computed detected bit. This is
118917c2899SVille Syrjälä 	 * supposed to be read-only.
119917c2899SVille Syrjälä 	 */
120917c2899SVille Syrjälä 	intel_dp->DP = intel_de_read(dev_priv, intel_dp->output_reg) & DP_DETECTED;
121917c2899SVille Syrjälä 
122917c2899SVille Syrjälä 	/* Handle DP bits in common between all three register formats */
123917c2899SVille Syrjälä 	intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
124917c2899SVille Syrjälä 	intel_dp->DP |= DP_PORT_WIDTH(pipe_config->lane_count);
125917c2899SVille Syrjälä 
126917c2899SVille Syrjälä 	/* Split out the IBX/CPU vs CPT settings */
127917c2899SVille Syrjälä 
128917c2899SVille Syrjälä 	if (IS_IVYBRIDGE(dev_priv) && port == PORT_A) {
129917c2899SVille Syrjälä 		if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
130917c2899SVille Syrjälä 			intel_dp->DP |= DP_SYNC_HS_HIGH;
131917c2899SVille Syrjälä 		if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
132917c2899SVille Syrjälä 			intel_dp->DP |= DP_SYNC_VS_HIGH;
133917c2899SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
134917c2899SVille Syrjälä 
135917c2899SVille Syrjälä 		if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
136917c2899SVille Syrjälä 			intel_dp->DP |= DP_ENHANCED_FRAMING;
137917c2899SVille Syrjälä 
138917c2899SVille Syrjälä 		intel_dp->DP |= DP_PIPE_SEL_IVB(crtc->pipe);
139917c2899SVille Syrjälä 	} else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) {
140917c2899SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
141917c2899SVille Syrjälä 
14259ea2887SAndrzej Hajda 		intel_de_rmw(dev_priv, TRANS_DP_CTL(crtc->pipe),
14359ea2887SAndrzej Hajda 			     TRANS_DP_ENH_FRAMING,
14459ea2887SAndrzej Hajda 			     drm_dp_enhanced_frame_cap(intel_dp->dpcd) ?
14559ea2887SAndrzej Hajda 			     TRANS_DP_ENH_FRAMING : 0);
146917c2899SVille Syrjälä 	} else {
147917c2899SVille Syrjälä 		if (IS_G4X(dev_priv) && pipe_config->limited_color_range)
148917c2899SVille Syrjälä 			intel_dp->DP |= DP_COLOR_RANGE_16_235;
149917c2899SVille Syrjälä 
150917c2899SVille Syrjälä 		if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
151917c2899SVille Syrjälä 			intel_dp->DP |= DP_SYNC_HS_HIGH;
152917c2899SVille Syrjälä 		if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
153917c2899SVille Syrjälä 			intel_dp->DP |= DP_SYNC_VS_HIGH;
154917c2899SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_OFF;
155917c2899SVille Syrjälä 
156917c2899SVille Syrjälä 		if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
157917c2899SVille Syrjälä 			intel_dp->DP |= DP_ENHANCED_FRAMING;
158917c2899SVille Syrjälä 
159917c2899SVille Syrjälä 		if (IS_CHERRYVIEW(dev_priv))
160917c2899SVille Syrjälä 			intel_dp->DP |= DP_PIPE_SEL_CHV(crtc->pipe);
161917c2899SVille Syrjälä 		else
162917c2899SVille Syrjälä 			intel_dp->DP |= DP_PIPE_SEL(crtc->pipe);
163917c2899SVille Syrjälä 	}
164917c2899SVille Syrjälä }
165917c2899SVille Syrjälä 
166917c2899SVille Syrjälä static void assert_dp_port(struct intel_dp *intel_dp, bool state)
167917c2899SVille Syrjälä {
168917c2899SVille Syrjälä 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
169917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
170917c2899SVille Syrjälä 	bool cur_state = intel_de_read(dev_priv, intel_dp->output_reg) & DP_PORT_EN;
171917c2899SVille Syrjälä 
1726b9bd7c3SJani Nikula 	I915_STATE_WARN(dev_priv, cur_state != state,
173917c2899SVille Syrjälä 			"[ENCODER:%d:%s] state assertion failure (expected %s, current %s)\n",
174917c2899SVille Syrjälä 			dig_port->base.base.base.id, dig_port->base.base.name,
175f79a568aSLucas De Marchi 			str_on_off(state), str_on_off(cur_state));
176917c2899SVille Syrjälä }
177917c2899SVille Syrjälä #define assert_dp_port_disabled(d) assert_dp_port((d), false)
178917c2899SVille Syrjälä 
179917c2899SVille Syrjälä static void assert_edp_pll(struct drm_i915_private *dev_priv, bool state)
180917c2899SVille Syrjälä {
181917c2899SVille Syrjälä 	bool cur_state = intel_de_read(dev_priv, DP_A) & DP_PLL_ENABLE;
182917c2899SVille Syrjälä 
1836b9bd7c3SJani Nikula 	I915_STATE_WARN(dev_priv, cur_state != state,
184917c2899SVille Syrjälä 			"eDP PLL state assertion failure (expected %s, current %s)\n",
185f79a568aSLucas De Marchi 			str_on_off(state), str_on_off(cur_state));
186917c2899SVille Syrjälä }
187917c2899SVille Syrjälä #define assert_edp_pll_enabled(d) assert_edp_pll((d), true)
188917c2899SVille Syrjälä #define assert_edp_pll_disabled(d) assert_edp_pll((d), false)
189917c2899SVille Syrjälä 
190917c2899SVille Syrjälä static void ilk_edp_pll_on(struct intel_dp *intel_dp,
191917c2899SVille Syrjälä 			   const struct intel_crtc_state *pipe_config)
192917c2899SVille Syrjälä {
193917c2899SVille Syrjälä 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
194917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
195917c2899SVille Syrjälä 
1968c66081bSVille Syrjälä 	assert_transcoder_disabled(dev_priv, pipe_config->cpu_transcoder);
197917c2899SVille Syrjälä 	assert_dp_port_disabled(intel_dp);
198917c2899SVille Syrjälä 	assert_edp_pll_disabled(dev_priv);
199917c2899SVille Syrjälä 
200917c2899SVille Syrjälä 	drm_dbg_kms(&dev_priv->drm, "enabling eDP PLL for clock %d\n",
201917c2899SVille Syrjälä 		    pipe_config->port_clock);
202917c2899SVille Syrjälä 
203917c2899SVille Syrjälä 	intel_dp->DP &= ~DP_PLL_FREQ_MASK;
204917c2899SVille Syrjälä 
205917c2899SVille Syrjälä 	if (pipe_config->port_clock == 162000)
206917c2899SVille Syrjälä 		intel_dp->DP |= DP_PLL_FREQ_162MHZ;
207917c2899SVille Syrjälä 	else
208917c2899SVille Syrjälä 		intel_dp->DP |= DP_PLL_FREQ_270MHZ;
209917c2899SVille Syrjälä 
210917c2899SVille Syrjälä 	intel_de_write(dev_priv, DP_A, intel_dp->DP);
211917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, DP_A);
212917c2899SVille Syrjälä 	udelay(500);
213917c2899SVille Syrjälä 
214917c2899SVille Syrjälä 	/*
215917c2899SVille Syrjälä 	 * [DevILK] Work around required when enabling DP PLL
216917c2899SVille Syrjälä 	 * while a pipe is enabled going to FDI:
217917c2899SVille Syrjälä 	 * 1. Wait for the start of vertical blank on the enabled pipe going to FDI
218917c2899SVille Syrjälä 	 * 2. Program DP PLL enable
219917c2899SVille Syrjälä 	 */
220d47d29a6SMatt Roper 	if (IS_IRONLAKE(dev_priv))
221917c2899SVille Syrjälä 		intel_wait_for_vblank_if_active(dev_priv, !crtc->pipe);
222917c2899SVille Syrjälä 
223917c2899SVille Syrjälä 	intel_dp->DP |= DP_PLL_ENABLE;
224917c2899SVille Syrjälä 
225917c2899SVille Syrjälä 	intel_de_write(dev_priv, DP_A, intel_dp->DP);
226917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, DP_A);
227917c2899SVille Syrjälä 	udelay(200);
228917c2899SVille Syrjälä }
229917c2899SVille Syrjälä 
230917c2899SVille Syrjälä static void ilk_edp_pll_off(struct intel_dp *intel_dp,
231917c2899SVille Syrjälä 			    const struct intel_crtc_state *old_crtc_state)
232917c2899SVille Syrjälä {
233917c2899SVille Syrjälä 	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
234917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
235917c2899SVille Syrjälä 
2368c66081bSVille Syrjälä 	assert_transcoder_disabled(dev_priv, old_crtc_state->cpu_transcoder);
237917c2899SVille Syrjälä 	assert_dp_port_disabled(intel_dp);
238917c2899SVille Syrjälä 	assert_edp_pll_enabled(dev_priv);
239917c2899SVille Syrjälä 
240917c2899SVille Syrjälä 	drm_dbg_kms(&dev_priv->drm, "disabling eDP PLL\n");
241917c2899SVille Syrjälä 
242917c2899SVille Syrjälä 	intel_dp->DP &= ~DP_PLL_ENABLE;
243917c2899SVille Syrjälä 
244917c2899SVille Syrjälä 	intel_de_write(dev_priv, DP_A, intel_dp->DP);
245917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, DP_A);
246917c2899SVille Syrjälä 	udelay(200);
247917c2899SVille Syrjälä }
248917c2899SVille Syrjälä 
249917c2899SVille Syrjälä static bool cpt_dp_port_selected(struct drm_i915_private *dev_priv,
250917c2899SVille Syrjälä 				 enum port port, enum pipe *pipe)
251917c2899SVille Syrjälä {
252917c2899SVille Syrjälä 	enum pipe p;
253917c2899SVille Syrjälä 
254917c2899SVille Syrjälä 	for_each_pipe(dev_priv, p) {
255917c2899SVille Syrjälä 		u32 val = intel_de_read(dev_priv, TRANS_DP_CTL(p));
256917c2899SVille Syrjälä 
257917c2899SVille Syrjälä 		if ((val & TRANS_DP_PORT_SEL_MASK) == TRANS_DP_PORT_SEL(port)) {
258917c2899SVille Syrjälä 			*pipe = p;
259917c2899SVille Syrjälä 			return true;
260917c2899SVille Syrjälä 		}
261917c2899SVille Syrjälä 	}
262917c2899SVille Syrjälä 
263917c2899SVille Syrjälä 	drm_dbg_kms(&dev_priv->drm, "No pipe for DP port %c found\n",
264917c2899SVille Syrjälä 		    port_name(port));
265917c2899SVille Syrjälä 
266917c2899SVille Syrjälä 	/* must initialize pipe to something for the asserts */
267917c2899SVille Syrjälä 	*pipe = PIPE_A;
268917c2899SVille Syrjälä 
269917c2899SVille Syrjälä 	return false;
270917c2899SVille Syrjälä }
271917c2899SVille Syrjälä 
272053ffdd1SVille Syrjälä bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv,
273917c2899SVille Syrjälä 			 i915_reg_t dp_reg, enum port port,
274917c2899SVille Syrjälä 			 enum pipe *pipe)
275917c2899SVille Syrjälä {
276917c2899SVille Syrjälä 	bool ret;
277917c2899SVille Syrjälä 	u32 val;
278917c2899SVille Syrjälä 
279917c2899SVille Syrjälä 	val = intel_de_read(dev_priv, dp_reg);
280917c2899SVille Syrjälä 
281917c2899SVille Syrjälä 	ret = val & DP_PORT_EN;
282917c2899SVille Syrjälä 
283917c2899SVille Syrjälä 	/* asserts want to know the pipe even if the port is disabled */
284917c2899SVille Syrjälä 	if (IS_IVYBRIDGE(dev_priv) && port == PORT_A)
285917c2899SVille Syrjälä 		*pipe = (val & DP_PIPE_SEL_MASK_IVB) >> DP_PIPE_SEL_SHIFT_IVB;
286917c2899SVille Syrjälä 	else if (HAS_PCH_CPT(dev_priv) && port != PORT_A)
287917c2899SVille Syrjälä 		ret &= cpt_dp_port_selected(dev_priv, port, pipe);
288917c2899SVille Syrjälä 	else if (IS_CHERRYVIEW(dev_priv))
289917c2899SVille Syrjälä 		*pipe = (val & DP_PIPE_SEL_MASK_CHV) >> DP_PIPE_SEL_SHIFT_CHV;
290917c2899SVille Syrjälä 	else
291917c2899SVille Syrjälä 		*pipe = (val & DP_PIPE_SEL_MASK) >> DP_PIPE_SEL_SHIFT;
292917c2899SVille Syrjälä 
293917c2899SVille Syrjälä 	return ret;
294917c2899SVille Syrjälä }
295917c2899SVille Syrjälä 
296917c2899SVille Syrjälä static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
297917c2899SVille Syrjälä 				  enum pipe *pipe)
298917c2899SVille Syrjälä {
299917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
300917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
301917c2899SVille Syrjälä 	intel_wakeref_t wakeref;
302917c2899SVille Syrjälä 	bool ret;
303917c2899SVille Syrjälä 
304917c2899SVille Syrjälä 	wakeref = intel_display_power_get_if_enabled(dev_priv,
305917c2899SVille Syrjälä 						     encoder->power_domain);
306917c2899SVille Syrjälä 	if (!wakeref)
307917c2899SVille Syrjälä 		return false;
308917c2899SVille Syrjälä 
309053ffdd1SVille Syrjälä 	ret = g4x_dp_port_enabled(dev_priv, intel_dp->output_reg,
310917c2899SVille Syrjälä 				  encoder->port, pipe);
311917c2899SVille Syrjälä 
312917c2899SVille Syrjälä 	intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
313917c2899SVille Syrjälä 
314917c2899SVille Syrjälä 	return ret;
315917c2899SVille Syrjälä }
316917c2899SVille Syrjälä 
3176149cb68SVille Syrjälä static void g4x_dp_get_m_n(struct intel_crtc_state *crtc_state)
3186149cb68SVille Syrjälä {
3196149cb68SVille Syrjälä 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3206149cb68SVille Syrjälä 
3215cd06644SVille Syrjälä 	if (crtc_state->has_pch_encoder) {
32223015f6fSVille Syrjälä 		intel_pch_transcoder_get_m1_n1(crtc, &crtc_state->dp_m_n);
32323015f6fSVille Syrjälä 		intel_pch_transcoder_get_m2_n2(crtc, &crtc_state->dp_m2_n2);
3245cd06644SVille Syrjälä 	} else {
3255cd06644SVille Syrjälä 		intel_cpu_transcoder_get_m1_n1(crtc, crtc_state->cpu_transcoder,
3265cd06644SVille Syrjälä 					       &crtc_state->dp_m_n);
3275cd06644SVille Syrjälä 		intel_cpu_transcoder_get_m2_n2(crtc, crtc_state->cpu_transcoder,
3286149cb68SVille Syrjälä 					       &crtc_state->dp_m2_n2);
3296149cb68SVille Syrjälä 	}
3305cd06644SVille Syrjälä }
3316149cb68SVille Syrjälä 
332917c2899SVille Syrjälä static void intel_dp_get_config(struct intel_encoder *encoder,
333917c2899SVille Syrjälä 				struct intel_crtc_state *pipe_config)
334917c2899SVille Syrjälä {
335917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
336917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
337917c2899SVille Syrjälä 	u32 tmp, flags = 0;
338917c2899SVille Syrjälä 	enum port port = encoder->port;
339917c2899SVille Syrjälä 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
340917c2899SVille Syrjälä 
341917c2899SVille Syrjälä 	if (encoder->type == INTEL_OUTPUT_EDP)
342917c2899SVille Syrjälä 		pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP);
343917c2899SVille Syrjälä 	else
344917c2899SVille Syrjälä 		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP);
345917c2899SVille Syrjälä 
346917c2899SVille Syrjälä 	tmp = intel_de_read(dev_priv, intel_dp->output_reg);
347917c2899SVille Syrjälä 
348917c2899SVille Syrjälä 	pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A;
349917c2899SVille Syrjälä 
350917c2899SVille Syrjälä 	if (HAS_PCH_CPT(dev_priv) && port != PORT_A) {
351917c2899SVille Syrjälä 		u32 trans_dp = intel_de_read(dev_priv,
352917c2899SVille Syrjälä 					     TRANS_DP_CTL(crtc->pipe));
353917c2899SVille Syrjälä 
354917c2899SVille Syrjälä 		if (trans_dp & TRANS_DP_HSYNC_ACTIVE_HIGH)
355917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_PHSYNC;
356917c2899SVille Syrjälä 		else
357917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_NHSYNC;
358917c2899SVille Syrjälä 
359917c2899SVille Syrjälä 		if (trans_dp & TRANS_DP_VSYNC_ACTIVE_HIGH)
360917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_PVSYNC;
361917c2899SVille Syrjälä 		else
362917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_NVSYNC;
363917c2899SVille Syrjälä 	} else {
364917c2899SVille Syrjälä 		if (tmp & DP_SYNC_HS_HIGH)
365917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_PHSYNC;
366917c2899SVille Syrjälä 		else
367917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_NHSYNC;
368917c2899SVille Syrjälä 
369917c2899SVille Syrjälä 		if (tmp & DP_SYNC_VS_HIGH)
370917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_PVSYNC;
371917c2899SVille Syrjälä 		else
372917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_NVSYNC;
373917c2899SVille Syrjälä 	}
374917c2899SVille Syrjälä 
375917c2899SVille Syrjälä 	pipe_config->hw.adjusted_mode.flags |= flags;
376917c2899SVille Syrjälä 
377917c2899SVille Syrjälä 	if (IS_G4X(dev_priv) && tmp & DP_COLOR_RANGE_16_235)
378917c2899SVille Syrjälä 		pipe_config->limited_color_range = true;
379917c2899SVille Syrjälä 
380917c2899SVille Syrjälä 	pipe_config->lane_count =
381917c2899SVille Syrjälä 		((tmp & DP_PORT_WIDTH_MASK) >> DP_PORT_WIDTH_SHIFT) + 1;
382917c2899SVille Syrjälä 
3836149cb68SVille Syrjälä 	g4x_dp_get_m_n(pipe_config);
384917c2899SVille Syrjälä 
385917c2899SVille Syrjälä 	if (port == PORT_A) {
386917c2899SVille Syrjälä 		if ((intel_de_read(dev_priv, DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_162MHZ)
387917c2899SVille Syrjälä 			pipe_config->port_clock = 162000;
388917c2899SVille Syrjälä 		else
389917c2899SVille Syrjälä 			pipe_config->port_clock = 270000;
390917c2899SVille Syrjälä 	}
391917c2899SVille Syrjälä 
392917c2899SVille Syrjälä 	pipe_config->hw.adjusted_mode.crtc_clock =
393917c2899SVille Syrjälä 		intel_dotclock_calculate(pipe_config->port_clock,
394917c2899SVille Syrjälä 					 &pipe_config->dp_m_n);
395917c2899SVille Syrjälä 
396822e5ae7SVille Syrjälä 	if (intel_dp_is_edp(intel_dp))
397822e5ae7SVille Syrjälä 		intel_edp_fixup_vbt_bpp(encoder, pipe_config->pipe_bpp);
39861a60df6SVille Syrjälä 
39961a60df6SVille Syrjälä 	intel_audio_codec_get_config(encoder, pipe_config);
400917c2899SVille Syrjälä }
401917c2899SVille Syrjälä 
402917c2899SVille Syrjälä static void
403917c2899SVille Syrjälä intel_dp_link_down(struct intel_encoder *encoder,
404917c2899SVille Syrjälä 		   const struct intel_crtc_state *old_crtc_state)
405917c2899SVille Syrjälä {
406917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
407917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
408917c2899SVille Syrjälä 	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
409917c2899SVille Syrjälä 	enum port port = encoder->port;
410917c2899SVille Syrjälä 
411917c2899SVille Syrjälä 	if (drm_WARN_ON(&dev_priv->drm,
412917c2899SVille Syrjälä 			(intel_de_read(dev_priv, intel_dp->output_reg) &
413917c2899SVille Syrjälä 			 DP_PORT_EN) == 0))
414917c2899SVille Syrjälä 		return;
415917c2899SVille Syrjälä 
416917c2899SVille Syrjälä 	drm_dbg_kms(&dev_priv->drm, "\n");
417917c2899SVille Syrjälä 
418917c2899SVille Syrjälä 	if ((IS_IVYBRIDGE(dev_priv) && port == PORT_A) ||
419917c2899SVille Syrjälä 	    (HAS_PCH_CPT(dev_priv) && port != PORT_A)) {
420cbf02c50SVille Syrjälä 		intel_dp->DP &= ~DP_LINK_TRAIN_MASK_CPT;
421cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE_CPT;
422917c2899SVille Syrjälä 	} else {
423cbf02c50SVille Syrjälä 		intel_dp->DP &= ~DP_LINK_TRAIN_MASK;
424cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE;
425917c2899SVille Syrjälä 	}
426cbf02c50SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
427917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
428917c2899SVille Syrjälä 
429cbf02c50SVille Syrjälä 	intel_dp->DP &= ~(DP_PORT_EN | DP_AUDIO_OUTPUT_ENABLE);
430cbf02c50SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
431917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
432917c2899SVille Syrjälä 
433917c2899SVille Syrjälä 	/*
434917c2899SVille Syrjälä 	 * HW workaround for IBX, we need to move the port
435917c2899SVille Syrjälä 	 * to transcoder A after disabling it to allow the
436917c2899SVille Syrjälä 	 * matching HDMI port to be enabled on transcoder A.
437917c2899SVille Syrjälä 	 */
438917c2899SVille Syrjälä 	if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B && port != PORT_A) {
439917c2899SVille Syrjälä 		/*
440917c2899SVille Syrjälä 		 * We get CPU/PCH FIFO underruns on the other pipe when
441917c2899SVille Syrjälä 		 * doing the workaround. Sweep them under the rug.
442917c2899SVille Syrjälä 		 */
443917c2899SVille Syrjälä 		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false);
444917c2899SVille Syrjälä 		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
445917c2899SVille Syrjälä 
446917c2899SVille Syrjälä 		/* always enable with pattern 1 (as per spec) */
447cbf02c50SVille Syrjälä 		intel_dp->DP &= ~(DP_PIPE_SEL_MASK | DP_LINK_TRAIN_MASK);
448cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_PORT_EN | DP_PIPE_SEL(PIPE_A) |
449917c2899SVille Syrjälä 			DP_LINK_TRAIN_PAT_1;
450cbf02c50SVille Syrjälä 		intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
451917c2899SVille Syrjälä 		intel_de_posting_read(dev_priv, intel_dp->output_reg);
452917c2899SVille Syrjälä 
453cbf02c50SVille Syrjälä 		intel_dp->DP &= ~DP_PORT_EN;
454cbf02c50SVille Syrjälä 		intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
455917c2899SVille Syrjälä 		intel_de_posting_read(dev_priv, intel_dp->output_reg);
456917c2899SVille Syrjälä 
457917c2899SVille Syrjälä 		intel_wait_for_vblank_if_active(dev_priv, PIPE_A);
458917c2899SVille Syrjälä 		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true);
459917c2899SVille Syrjälä 		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
460917c2899SVille Syrjälä 	}
461917c2899SVille Syrjälä 
462917c2899SVille Syrjälä 	msleep(intel_dp->pps.panel_power_down_delay);
463917c2899SVille Syrjälä 
464917c2899SVille Syrjälä 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
465917c2899SVille Syrjälä 		intel_wakeref_t wakeref;
466917c2899SVille Syrjälä 
467917c2899SVille Syrjälä 		with_intel_pps_lock(intel_dp, wakeref)
468917c2899SVille Syrjälä 			intel_dp->pps.active_pipe = INVALID_PIPE;
469917c2899SVille Syrjälä 	}
470917c2899SVille Syrjälä }
471917c2899SVille Syrjälä 
472917c2899SVille Syrjälä static void intel_disable_dp(struct intel_atomic_state *state,
473917c2899SVille Syrjälä 			     struct intel_encoder *encoder,
474917c2899SVille Syrjälä 			     const struct intel_crtc_state *old_crtc_state,
475917c2899SVille Syrjälä 			     const struct drm_connector_state *old_conn_state)
476917c2899SVille Syrjälä {
477917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
478917c2899SVille Syrjälä 
479917c2899SVille Syrjälä 	intel_dp->link_trained = false;
480917c2899SVille Syrjälä 
481179db7c1SJani Nikula 	intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
482917c2899SVille Syrjälä 
483917c2899SVille Syrjälä 	/*
484917c2899SVille Syrjälä 	 * Make sure the panel is off before trying to change the mode.
485917c2899SVille Syrjälä 	 * But also ensure that we have vdd while we switch off the panel.
486917c2899SVille Syrjälä 	 */
487917c2899SVille Syrjälä 	intel_pps_vdd_on(intel_dp);
488917c2899SVille Syrjälä 	intel_edp_backlight_off(old_conn_state);
489917c2899SVille Syrjälä 	intel_dp_set_power(intel_dp, DP_SET_POWER_D3);
490917c2899SVille Syrjälä 	intel_pps_off(intel_dp);
491917c2899SVille Syrjälä }
492917c2899SVille Syrjälä 
493917c2899SVille Syrjälä static void g4x_disable_dp(struct intel_atomic_state *state,
494917c2899SVille Syrjälä 			   struct intel_encoder *encoder,
495917c2899SVille Syrjälä 			   const struct intel_crtc_state *old_crtc_state,
496917c2899SVille Syrjälä 			   const struct drm_connector_state *old_conn_state)
497917c2899SVille Syrjälä {
498917c2899SVille Syrjälä 	intel_disable_dp(state, encoder, old_crtc_state, old_conn_state);
499917c2899SVille Syrjälä }
500917c2899SVille Syrjälä 
501917c2899SVille Syrjälä static void vlv_disable_dp(struct intel_atomic_state *state,
502917c2899SVille Syrjälä 			   struct intel_encoder *encoder,
503917c2899SVille Syrjälä 			   const struct intel_crtc_state *old_crtc_state,
504917c2899SVille Syrjälä 			   const struct drm_connector_state *old_conn_state)
505917c2899SVille Syrjälä {
506917c2899SVille Syrjälä 	intel_disable_dp(state, encoder, old_crtc_state, old_conn_state);
507917c2899SVille Syrjälä }
508917c2899SVille Syrjälä 
509917c2899SVille Syrjälä static void g4x_post_disable_dp(struct intel_atomic_state *state,
510917c2899SVille Syrjälä 				struct intel_encoder *encoder,
511917c2899SVille Syrjälä 				const struct intel_crtc_state *old_crtc_state,
512917c2899SVille Syrjälä 				const struct drm_connector_state *old_conn_state)
513917c2899SVille Syrjälä {
514917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
515917c2899SVille Syrjälä 	enum port port = encoder->port;
516917c2899SVille Syrjälä 
517917c2899SVille Syrjälä 	/*
518917c2899SVille Syrjälä 	 * Bspec does not list a specific disable sequence for g4x DP.
519917c2899SVille Syrjälä 	 * Follow the ilk+ sequence (disable pipe before the port) for
520917c2899SVille Syrjälä 	 * g4x DP as it does not suffer from underruns like the normal
521917c2899SVille Syrjälä 	 * g4x modeset sequence (disable pipe after the port).
522917c2899SVille Syrjälä 	 */
523917c2899SVille Syrjälä 	intel_dp_link_down(encoder, old_crtc_state);
524917c2899SVille Syrjälä 
525917c2899SVille Syrjälä 	/* Only ilk+ has port A */
526917c2899SVille Syrjälä 	if (port == PORT_A)
527917c2899SVille Syrjälä 		ilk_edp_pll_off(intel_dp, old_crtc_state);
528917c2899SVille Syrjälä }
529917c2899SVille Syrjälä 
530917c2899SVille Syrjälä static void vlv_post_disable_dp(struct intel_atomic_state *state,
531917c2899SVille Syrjälä 				struct intel_encoder *encoder,
532917c2899SVille Syrjälä 				const struct intel_crtc_state *old_crtc_state,
533917c2899SVille Syrjälä 				const struct drm_connector_state *old_conn_state)
534917c2899SVille Syrjälä {
535917c2899SVille Syrjälä 	intel_dp_link_down(encoder, old_crtc_state);
536917c2899SVille Syrjälä }
537917c2899SVille Syrjälä 
538917c2899SVille Syrjälä static void chv_post_disable_dp(struct intel_atomic_state *state,
539917c2899SVille Syrjälä 				struct intel_encoder *encoder,
540917c2899SVille Syrjälä 				const struct intel_crtc_state *old_crtc_state,
541917c2899SVille Syrjälä 				const struct drm_connector_state *old_conn_state)
542917c2899SVille Syrjälä {
543917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
544917c2899SVille Syrjälä 
545917c2899SVille Syrjälä 	intel_dp_link_down(encoder, old_crtc_state);
546917c2899SVille Syrjälä 
547917c2899SVille Syrjälä 	vlv_dpio_get(dev_priv);
548917c2899SVille Syrjälä 
549917c2899SVille Syrjälä 	/* Assert data lane reset */
550917c2899SVille Syrjälä 	chv_data_lane_soft_reset(encoder, old_crtc_state, true);
551917c2899SVille Syrjälä 
552917c2899SVille Syrjälä 	vlv_dpio_put(dev_priv);
553917c2899SVille Syrjälä }
554917c2899SVille Syrjälä 
555917c2899SVille Syrjälä static void
556917c2899SVille Syrjälä cpt_set_link_train(struct intel_dp *intel_dp,
557917c2899SVille Syrjälä 		   const struct intel_crtc_state *crtc_state,
558917c2899SVille Syrjälä 		   u8 dp_train_pat)
559917c2899SVille Syrjälä {
560917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
561917c2899SVille Syrjälä 
562cbf02c50SVille Syrjälä 	intel_dp->DP &= ~DP_LINK_TRAIN_MASK_CPT;
563917c2899SVille Syrjälä 
564917c2899SVille Syrjälä 	switch (intel_dp_training_pattern_symbol(dp_train_pat)) {
565917c2899SVille Syrjälä 	case DP_TRAINING_PATTERN_DISABLE:
566cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
567917c2899SVille Syrjälä 		break;
568917c2899SVille Syrjälä 	case DP_TRAINING_PATTERN_1:
569cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_PAT_1_CPT;
570917c2899SVille Syrjälä 		break;
571917c2899SVille Syrjälä 	case DP_TRAINING_PATTERN_2:
572cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_PAT_2_CPT;
573917c2899SVille Syrjälä 		break;
574917c2899SVille Syrjälä 	default:
575917c2899SVille Syrjälä 		MISSING_CASE(intel_dp_training_pattern_symbol(dp_train_pat));
576917c2899SVille Syrjälä 		return;
577917c2899SVille Syrjälä 	}
578917c2899SVille Syrjälä 
579917c2899SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
580917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
581917c2899SVille Syrjälä }
582917c2899SVille Syrjälä 
583917c2899SVille Syrjälä static void
584917c2899SVille Syrjälä g4x_set_link_train(struct intel_dp *intel_dp,
585917c2899SVille Syrjälä 		   const struct intel_crtc_state *crtc_state,
586917c2899SVille Syrjälä 		   u8 dp_train_pat)
587917c2899SVille Syrjälä {
588917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
589917c2899SVille Syrjälä 
590cbf02c50SVille Syrjälä 	intel_dp->DP &= ~DP_LINK_TRAIN_MASK;
591917c2899SVille Syrjälä 
592917c2899SVille Syrjälä 	switch (intel_dp_training_pattern_symbol(dp_train_pat)) {
593917c2899SVille Syrjälä 	case DP_TRAINING_PATTERN_DISABLE:
594cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_OFF;
595917c2899SVille Syrjälä 		break;
596917c2899SVille Syrjälä 	case DP_TRAINING_PATTERN_1:
597cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_PAT_1;
598917c2899SVille Syrjälä 		break;
599917c2899SVille Syrjälä 	case DP_TRAINING_PATTERN_2:
600cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_PAT_2;
601917c2899SVille Syrjälä 		break;
602917c2899SVille Syrjälä 	default:
603917c2899SVille Syrjälä 		MISSING_CASE(intel_dp_training_pattern_symbol(dp_train_pat));
604917c2899SVille Syrjälä 		return;
605917c2899SVille Syrjälä 	}
606917c2899SVille Syrjälä 
607917c2899SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
608917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
609917c2899SVille Syrjälä }
610917c2899SVille Syrjälä 
611917c2899SVille Syrjälä static void intel_dp_enable_port(struct intel_dp *intel_dp,
612917c2899SVille Syrjälä 				 const struct intel_crtc_state *crtc_state)
613917c2899SVille Syrjälä {
614917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
615917c2899SVille Syrjälä 
616917c2899SVille Syrjälä 	/* enable with pattern 1 (as per spec) */
617917c2899SVille Syrjälä 
618917c2899SVille Syrjälä 	intel_dp_program_link_training_pattern(intel_dp, crtc_state,
619be152504SVille Syrjälä 					       DP_PHY_DPRX, DP_TRAINING_PATTERN_1);
620917c2899SVille Syrjälä 
621917c2899SVille Syrjälä 	/*
622917c2899SVille Syrjälä 	 * Magic for VLV/CHV. We _must_ first set up the register
623917c2899SVille Syrjälä 	 * without actually enabling the port, and then do another
624917c2899SVille Syrjälä 	 * write to enable the port. Otherwise link training will
625917c2899SVille Syrjälä 	 * fail when the power sequencer is freshly used for this port.
626917c2899SVille Syrjälä 	 */
627917c2899SVille Syrjälä 	intel_dp->DP |= DP_PORT_EN;
628917c2899SVille Syrjälä 	if (crtc_state->has_audio)
629917c2899SVille Syrjälä 		intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
630917c2899SVille Syrjälä 
631917c2899SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
632917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
633917c2899SVille Syrjälä }
634917c2899SVille Syrjälä 
635917c2899SVille Syrjälä static void intel_enable_dp(struct intel_atomic_state *state,
636917c2899SVille Syrjälä 			    struct intel_encoder *encoder,
637917c2899SVille Syrjälä 			    const struct intel_crtc_state *pipe_config,
638917c2899SVille Syrjälä 			    const struct drm_connector_state *conn_state)
639917c2899SVille Syrjälä {
640917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
641917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
642917c2899SVille Syrjälä 	u32 dp_reg = intel_de_read(dev_priv, intel_dp->output_reg);
643917c2899SVille Syrjälä 	intel_wakeref_t wakeref;
644917c2899SVille Syrjälä 
645917c2899SVille Syrjälä 	if (drm_WARN_ON(&dev_priv->drm, dp_reg & DP_PORT_EN))
646917c2899SVille Syrjälä 		return;
647917c2899SVille Syrjälä 
648917c2899SVille Syrjälä 	with_intel_pps_lock(intel_dp, wakeref) {
649917c2899SVille Syrjälä 		if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
650917c2899SVille Syrjälä 			vlv_pps_init(encoder, pipe_config);
651917c2899SVille Syrjälä 
652917c2899SVille Syrjälä 		intel_dp_enable_port(intel_dp, pipe_config);
653917c2899SVille Syrjälä 
654917c2899SVille Syrjälä 		intel_pps_vdd_on_unlocked(intel_dp);
655917c2899SVille Syrjälä 		intel_pps_on_unlocked(intel_dp);
656917c2899SVille Syrjälä 		intel_pps_vdd_off_unlocked(intel_dp, true);
657917c2899SVille Syrjälä 	}
658917c2899SVille Syrjälä 
659917c2899SVille Syrjälä 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
660917c2899SVille Syrjälä 		unsigned int lane_mask = 0x0;
661917c2899SVille Syrjälä 
662917c2899SVille Syrjälä 		if (IS_CHERRYVIEW(dev_priv))
663917c2899SVille Syrjälä 			lane_mask = intel_dp_unused_lane_mask(pipe_config->lane_count);
664917c2899SVille Syrjälä 
665917c2899SVille Syrjälä 		vlv_wait_port_ready(dev_priv, dp_to_dig_port(intel_dp),
666917c2899SVille Syrjälä 				    lane_mask);
667917c2899SVille Syrjälä 	}
668917c2899SVille Syrjälä 
669917c2899SVille Syrjälä 	intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
670917c2899SVille Syrjälä 	intel_dp_configure_protocol_converter(intel_dp, pipe_config);
671917c2899SVille Syrjälä 	intel_dp_check_frl_training(intel_dp);
672917c2899SVille Syrjälä 	intel_dp_pcon_dsc_configure(intel_dp, pipe_config);
673917c2899SVille Syrjälä 	intel_dp_start_link_train(intel_dp, pipe_config);
674917c2899SVille Syrjälä 	intel_dp_stop_link_train(intel_dp, pipe_config);
675917c2899SVille Syrjälä }
676917c2899SVille Syrjälä 
677917c2899SVille Syrjälä static void g4x_enable_dp(struct intel_atomic_state *state,
678917c2899SVille Syrjälä 			  struct intel_encoder *encoder,
679917c2899SVille Syrjälä 			  const struct intel_crtc_state *pipe_config,
680917c2899SVille Syrjälä 			  const struct drm_connector_state *conn_state)
681917c2899SVille Syrjälä {
682917c2899SVille Syrjälä 	intel_enable_dp(state, encoder, pipe_config, conn_state);
683a467a243SVille Syrjälä 	intel_audio_codec_enable(encoder, pipe_config, conn_state);
684917c2899SVille Syrjälä 	intel_edp_backlight_on(pipe_config, conn_state);
685917c2899SVille Syrjälä }
686917c2899SVille Syrjälä 
687917c2899SVille Syrjälä static void vlv_enable_dp(struct intel_atomic_state *state,
688917c2899SVille Syrjälä 			  struct intel_encoder *encoder,
689917c2899SVille Syrjälä 			  const struct intel_crtc_state *pipe_config,
690917c2899SVille Syrjälä 			  const struct drm_connector_state *conn_state)
691917c2899SVille Syrjälä {
692a467a243SVille Syrjälä 	intel_audio_codec_enable(encoder, pipe_config, conn_state);
693917c2899SVille Syrjälä 	intel_edp_backlight_on(pipe_config, conn_state);
694917c2899SVille Syrjälä }
695917c2899SVille Syrjälä 
696917c2899SVille Syrjälä static void g4x_pre_enable_dp(struct intel_atomic_state *state,
697917c2899SVille Syrjälä 			      struct intel_encoder *encoder,
698917c2899SVille Syrjälä 			      const struct intel_crtc_state *pipe_config,
699917c2899SVille Syrjälä 			      const struct drm_connector_state *conn_state)
700917c2899SVille Syrjälä {
701917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
702917c2899SVille Syrjälä 	enum port port = encoder->port;
703917c2899SVille Syrjälä 
704917c2899SVille Syrjälä 	intel_dp_prepare(encoder, pipe_config);
705917c2899SVille Syrjälä 
706917c2899SVille Syrjälä 	/* Only ilk+ has port A */
707917c2899SVille Syrjälä 	if (port == PORT_A)
708917c2899SVille Syrjälä 		ilk_edp_pll_on(intel_dp, pipe_config);
709917c2899SVille Syrjälä }
710917c2899SVille Syrjälä 
711917c2899SVille Syrjälä static void vlv_pre_enable_dp(struct intel_atomic_state *state,
712917c2899SVille Syrjälä 			      struct intel_encoder *encoder,
713917c2899SVille Syrjälä 			      const struct intel_crtc_state *pipe_config,
714917c2899SVille Syrjälä 			      const struct drm_connector_state *conn_state)
715917c2899SVille Syrjälä {
716917c2899SVille Syrjälä 	vlv_phy_pre_encoder_enable(encoder, pipe_config);
717917c2899SVille Syrjälä 
718917c2899SVille Syrjälä 	intel_enable_dp(state, encoder, pipe_config, conn_state);
719917c2899SVille Syrjälä }
720917c2899SVille Syrjälä 
721917c2899SVille Syrjälä static void vlv_dp_pre_pll_enable(struct intel_atomic_state *state,
722917c2899SVille Syrjälä 				  struct intel_encoder *encoder,
723917c2899SVille Syrjälä 				  const struct intel_crtc_state *pipe_config,
724917c2899SVille Syrjälä 				  const struct drm_connector_state *conn_state)
725917c2899SVille Syrjälä {
726917c2899SVille Syrjälä 	intel_dp_prepare(encoder, pipe_config);
727917c2899SVille Syrjälä 
728917c2899SVille Syrjälä 	vlv_phy_pre_pll_enable(encoder, pipe_config);
729917c2899SVille Syrjälä }
730917c2899SVille Syrjälä 
731917c2899SVille Syrjälä static void chv_pre_enable_dp(struct intel_atomic_state *state,
732917c2899SVille Syrjälä 			      struct intel_encoder *encoder,
733917c2899SVille Syrjälä 			      const struct intel_crtc_state *pipe_config,
734917c2899SVille Syrjälä 			      const struct drm_connector_state *conn_state)
735917c2899SVille Syrjälä {
736917c2899SVille Syrjälä 	chv_phy_pre_encoder_enable(encoder, pipe_config);
737917c2899SVille Syrjälä 
738917c2899SVille Syrjälä 	intel_enable_dp(state, encoder, pipe_config, conn_state);
739917c2899SVille Syrjälä 
740917c2899SVille Syrjälä 	/* Second common lane will stay alive on its own now */
741917c2899SVille Syrjälä 	chv_phy_release_cl2_override(encoder);
742917c2899SVille Syrjälä }
743917c2899SVille Syrjälä 
744917c2899SVille Syrjälä static void chv_dp_pre_pll_enable(struct intel_atomic_state *state,
745917c2899SVille Syrjälä 				  struct intel_encoder *encoder,
746917c2899SVille Syrjälä 				  const struct intel_crtc_state *pipe_config,
747917c2899SVille Syrjälä 				  const struct drm_connector_state *conn_state)
748917c2899SVille Syrjälä {
749917c2899SVille Syrjälä 	intel_dp_prepare(encoder, pipe_config);
750917c2899SVille Syrjälä 
751917c2899SVille Syrjälä 	chv_phy_pre_pll_enable(encoder, pipe_config);
752917c2899SVille Syrjälä }
753917c2899SVille Syrjälä 
754917c2899SVille Syrjälä static void chv_dp_post_pll_disable(struct intel_atomic_state *state,
755917c2899SVille Syrjälä 				    struct intel_encoder *encoder,
756917c2899SVille Syrjälä 				    const struct intel_crtc_state *old_crtc_state,
757917c2899SVille Syrjälä 				    const struct drm_connector_state *old_conn_state)
758917c2899SVille Syrjälä {
759917c2899SVille Syrjälä 	chv_phy_post_pll_disable(encoder, old_crtc_state);
760917c2899SVille Syrjälä }
761917c2899SVille Syrjälä 
762917c2899SVille Syrjälä static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp,
763917c2899SVille Syrjälä 				 const struct intel_crtc_state *crtc_state)
764917c2899SVille Syrjälä {
765917c2899SVille Syrjälä 	return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
766917c2899SVille Syrjälä }
767917c2899SVille Syrjälä 
768917c2899SVille Syrjälä static u8 intel_dp_voltage_max_3(struct intel_dp *intel_dp,
769917c2899SVille Syrjälä 				 const struct intel_crtc_state *crtc_state)
770917c2899SVille Syrjälä {
771917c2899SVille Syrjälä 	return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
772917c2899SVille Syrjälä }
773917c2899SVille Syrjälä 
774917c2899SVille Syrjälä static u8 intel_dp_preemph_max_2(struct intel_dp *intel_dp)
775917c2899SVille Syrjälä {
776917c2899SVille Syrjälä 	return DP_TRAIN_PRE_EMPH_LEVEL_2;
777917c2899SVille Syrjälä }
778917c2899SVille Syrjälä 
779917c2899SVille Syrjälä static u8 intel_dp_preemph_max_3(struct intel_dp *intel_dp)
780917c2899SVille Syrjälä {
781917c2899SVille Syrjälä 	return DP_TRAIN_PRE_EMPH_LEVEL_3;
782917c2899SVille Syrjälä }
783917c2899SVille Syrjälä 
784e722ab8bSVille Syrjälä static void vlv_set_signal_levels(struct intel_encoder *encoder,
785917c2899SVille Syrjälä 				  const struct intel_crtc_state *crtc_state)
786917c2899SVille Syrjälä {
787e722ab8bSVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
788917c2899SVille Syrjälä 	unsigned long demph_reg_value, preemph_reg_value,
789917c2899SVille Syrjälä 		uniqtranscale_reg_value;
790917c2899SVille Syrjälä 	u8 train_set = intel_dp->train_set[0];
791917c2899SVille Syrjälä 
792917c2899SVille Syrjälä 	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
793917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_0:
794917c2899SVille Syrjälä 		preemph_reg_value = 0x0004000;
795917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
796917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
797917c2899SVille Syrjälä 			demph_reg_value = 0x2B405555;
798917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x552AB83A;
799917c2899SVille Syrjälä 			break;
800917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
801917c2899SVille Syrjälä 			demph_reg_value = 0x2B404040;
802917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x5548B83A;
803917c2899SVille Syrjälä 			break;
804917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
805917c2899SVille Syrjälä 			demph_reg_value = 0x2B245555;
806917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x5560B83A;
807917c2899SVille Syrjälä 			break;
808917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
809917c2899SVille Syrjälä 			demph_reg_value = 0x2B405555;
810917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x5598DA3A;
811917c2899SVille Syrjälä 			break;
812917c2899SVille Syrjälä 		default:
813917c2899SVille Syrjälä 			return;
814917c2899SVille Syrjälä 		}
815917c2899SVille Syrjälä 		break;
816917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_1:
817917c2899SVille Syrjälä 		preemph_reg_value = 0x0002000;
818917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
819917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
820917c2899SVille Syrjälä 			demph_reg_value = 0x2B404040;
821917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x5552B83A;
822917c2899SVille Syrjälä 			break;
823917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
824917c2899SVille Syrjälä 			demph_reg_value = 0x2B404848;
825917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x5580B83A;
826917c2899SVille Syrjälä 			break;
827917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
828917c2899SVille Syrjälä 			demph_reg_value = 0x2B404040;
829917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x55ADDA3A;
830917c2899SVille Syrjälä 			break;
831917c2899SVille Syrjälä 		default:
832917c2899SVille Syrjälä 			return;
833917c2899SVille Syrjälä 		}
834917c2899SVille Syrjälä 		break;
835917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_2:
836917c2899SVille Syrjälä 		preemph_reg_value = 0x0000000;
837917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
838917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
839917c2899SVille Syrjälä 			demph_reg_value = 0x2B305555;
840917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x5570B83A;
841917c2899SVille Syrjälä 			break;
842917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
843917c2899SVille Syrjälä 			demph_reg_value = 0x2B2B4040;
844917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x55ADDA3A;
845917c2899SVille Syrjälä 			break;
846917c2899SVille Syrjälä 		default:
847917c2899SVille Syrjälä 			return;
848917c2899SVille Syrjälä 		}
849917c2899SVille Syrjälä 		break;
850917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_3:
851917c2899SVille Syrjälä 		preemph_reg_value = 0x0006000;
852917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
853917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
854917c2899SVille Syrjälä 			demph_reg_value = 0x1B405555;
855917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x55ADDA3A;
856917c2899SVille Syrjälä 			break;
857917c2899SVille Syrjälä 		default:
858917c2899SVille Syrjälä 			return;
859917c2899SVille Syrjälä 		}
860917c2899SVille Syrjälä 		break;
861917c2899SVille Syrjälä 	default:
862917c2899SVille Syrjälä 		return;
863917c2899SVille Syrjälä 	}
864917c2899SVille Syrjälä 
865917c2899SVille Syrjälä 	vlv_set_phy_signal_level(encoder, crtc_state,
866917c2899SVille Syrjälä 				 demph_reg_value, preemph_reg_value,
867917c2899SVille Syrjälä 				 uniqtranscale_reg_value, 0);
868917c2899SVille Syrjälä }
869917c2899SVille Syrjälä 
870e722ab8bSVille Syrjälä static void chv_set_signal_levels(struct intel_encoder *encoder,
871917c2899SVille Syrjälä 				  const struct intel_crtc_state *crtc_state)
872917c2899SVille Syrjälä {
873e722ab8bSVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
874917c2899SVille Syrjälä 	u32 deemph_reg_value, margin_reg_value;
875917c2899SVille Syrjälä 	bool uniq_trans_scale = false;
876917c2899SVille Syrjälä 	u8 train_set = intel_dp->train_set[0];
877917c2899SVille Syrjälä 
878917c2899SVille Syrjälä 	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
879917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_0:
880917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
881917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
882917c2899SVille Syrjälä 			deemph_reg_value = 128;
883917c2899SVille Syrjälä 			margin_reg_value = 52;
884917c2899SVille Syrjälä 			break;
885917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
886917c2899SVille Syrjälä 			deemph_reg_value = 128;
887917c2899SVille Syrjälä 			margin_reg_value = 77;
888917c2899SVille Syrjälä 			break;
889917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
890917c2899SVille Syrjälä 			deemph_reg_value = 128;
891917c2899SVille Syrjälä 			margin_reg_value = 102;
892917c2899SVille Syrjälä 			break;
893917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
894917c2899SVille Syrjälä 			deemph_reg_value = 128;
895917c2899SVille Syrjälä 			margin_reg_value = 154;
896917c2899SVille Syrjälä 			uniq_trans_scale = true;
897917c2899SVille Syrjälä 			break;
898917c2899SVille Syrjälä 		default:
899917c2899SVille Syrjälä 			return;
900917c2899SVille Syrjälä 		}
901917c2899SVille Syrjälä 		break;
902917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_1:
903917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
904917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
905917c2899SVille Syrjälä 			deemph_reg_value = 85;
906917c2899SVille Syrjälä 			margin_reg_value = 78;
907917c2899SVille Syrjälä 			break;
908917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
909917c2899SVille Syrjälä 			deemph_reg_value = 85;
910917c2899SVille Syrjälä 			margin_reg_value = 116;
911917c2899SVille Syrjälä 			break;
912917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
913917c2899SVille Syrjälä 			deemph_reg_value = 85;
914917c2899SVille Syrjälä 			margin_reg_value = 154;
915917c2899SVille Syrjälä 			break;
916917c2899SVille Syrjälä 		default:
917917c2899SVille Syrjälä 			return;
918917c2899SVille Syrjälä 		}
919917c2899SVille Syrjälä 		break;
920917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_2:
921917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
922917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
923917c2899SVille Syrjälä 			deemph_reg_value = 64;
924917c2899SVille Syrjälä 			margin_reg_value = 104;
925917c2899SVille Syrjälä 			break;
926917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
927917c2899SVille Syrjälä 			deemph_reg_value = 64;
928917c2899SVille Syrjälä 			margin_reg_value = 154;
929917c2899SVille Syrjälä 			break;
930917c2899SVille Syrjälä 		default:
931917c2899SVille Syrjälä 			return;
932917c2899SVille Syrjälä 		}
933917c2899SVille Syrjälä 		break;
934917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_3:
935917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
936917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
937917c2899SVille Syrjälä 			deemph_reg_value = 43;
938917c2899SVille Syrjälä 			margin_reg_value = 154;
939917c2899SVille Syrjälä 			break;
940917c2899SVille Syrjälä 		default:
941917c2899SVille Syrjälä 			return;
942917c2899SVille Syrjälä 		}
943917c2899SVille Syrjälä 		break;
944917c2899SVille Syrjälä 	default:
945917c2899SVille Syrjälä 		return;
946917c2899SVille Syrjälä 	}
947917c2899SVille Syrjälä 
948917c2899SVille Syrjälä 	chv_set_phy_signal_level(encoder, crtc_state,
949917c2899SVille Syrjälä 				 deemph_reg_value, margin_reg_value,
950917c2899SVille Syrjälä 				 uniq_trans_scale);
951917c2899SVille Syrjälä }
952917c2899SVille Syrjälä 
953917c2899SVille Syrjälä static u32 g4x_signal_levels(u8 train_set)
954917c2899SVille Syrjälä {
955917c2899SVille Syrjälä 	u32 signal_levels = 0;
956917c2899SVille Syrjälä 
957917c2899SVille Syrjälä 	switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
958917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
959917c2899SVille Syrjälä 	default:
960917c2899SVille Syrjälä 		signal_levels |= DP_VOLTAGE_0_4;
961917c2899SVille Syrjälä 		break;
962917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
963917c2899SVille Syrjälä 		signal_levels |= DP_VOLTAGE_0_6;
964917c2899SVille Syrjälä 		break;
965917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
966917c2899SVille Syrjälä 		signal_levels |= DP_VOLTAGE_0_8;
967917c2899SVille Syrjälä 		break;
968917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
969917c2899SVille Syrjälä 		signal_levels |= DP_VOLTAGE_1_2;
970917c2899SVille Syrjälä 		break;
971917c2899SVille Syrjälä 	}
972917c2899SVille Syrjälä 	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
973917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_0:
974917c2899SVille Syrjälä 	default:
975917c2899SVille Syrjälä 		signal_levels |= DP_PRE_EMPHASIS_0;
976917c2899SVille Syrjälä 		break;
977917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_1:
978917c2899SVille Syrjälä 		signal_levels |= DP_PRE_EMPHASIS_3_5;
979917c2899SVille Syrjälä 		break;
980917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_2:
981917c2899SVille Syrjälä 		signal_levels |= DP_PRE_EMPHASIS_6;
982917c2899SVille Syrjälä 		break;
983917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_3:
984917c2899SVille Syrjälä 		signal_levels |= DP_PRE_EMPHASIS_9_5;
985917c2899SVille Syrjälä 		break;
986917c2899SVille Syrjälä 	}
987917c2899SVille Syrjälä 	return signal_levels;
988917c2899SVille Syrjälä }
989917c2899SVille Syrjälä 
990917c2899SVille Syrjälä static void
991e722ab8bSVille Syrjälä g4x_set_signal_levels(struct intel_encoder *encoder,
992917c2899SVille Syrjälä 		      const struct intel_crtc_state *crtc_state)
993917c2899SVille Syrjälä {
994e722ab8bSVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
995e722ab8bSVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
996917c2899SVille Syrjälä 	u8 train_set = intel_dp->train_set[0];
997917c2899SVille Syrjälä 	u32 signal_levels;
998917c2899SVille Syrjälä 
999917c2899SVille Syrjälä 	signal_levels = g4x_signal_levels(train_set);
1000917c2899SVille Syrjälä 
1001917c2899SVille Syrjälä 	drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n",
1002917c2899SVille Syrjälä 		    signal_levels);
1003917c2899SVille Syrjälä 
1004917c2899SVille Syrjälä 	intel_dp->DP &= ~(DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK);
1005917c2899SVille Syrjälä 	intel_dp->DP |= signal_levels;
1006917c2899SVille Syrjälä 
1007917c2899SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
1008917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
1009917c2899SVille Syrjälä }
1010917c2899SVille Syrjälä 
1011917c2899SVille Syrjälä /* SNB CPU eDP voltage swing and pre-emphasis control */
1012917c2899SVille Syrjälä static u32 snb_cpu_edp_signal_levels(u8 train_set)
1013917c2899SVille Syrjälä {
1014917c2899SVille Syrjälä 	u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
1015917c2899SVille Syrjälä 					DP_TRAIN_PRE_EMPHASIS_MASK);
1016917c2899SVille Syrjälä 
1017917c2899SVille Syrjälä 	switch (signal_levels) {
1018917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
1019917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
1020917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
1021917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
1022917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
1023917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
1024917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
1025917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_400_600MV_6DB_SNB_B;
1026917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
1027917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
1028917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
1029917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
1030917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
1031917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
1032917c2899SVille Syrjälä 	default:
1033917c2899SVille Syrjälä 		MISSING_CASE(signal_levels);
1034917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
1035917c2899SVille Syrjälä 	}
1036917c2899SVille Syrjälä }
1037917c2899SVille Syrjälä 
1038917c2899SVille Syrjälä static void
1039e722ab8bSVille Syrjälä snb_cpu_edp_set_signal_levels(struct intel_encoder *encoder,
1040917c2899SVille Syrjälä 			      const struct intel_crtc_state *crtc_state)
1041917c2899SVille Syrjälä {
1042e722ab8bSVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1043e722ab8bSVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1044917c2899SVille Syrjälä 	u8 train_set = intel_dp->train_set[0];
1045917c2899SVille Syrjälä 	u32 signal_levels;
1046917c2899SVille Syrjälä 
1047917c2899SVille Syrjälä 	signal_levels = snb_cpu_edp_signal_levels(train_set);
1048917c2899SVille Syrjälä 
1049917c2899SVille Syrjälä 	drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n",
1050917c2899SVille Syrjälä 		    signal_levels);
1051917c2899SVille Syrjälä 
1052917c2899SVille Syrjälä 	intel_dp->DP &= ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
1053917c2899SVille Syrjälä 	intel_dp->DP |= signal_levels;
1054917c2899SVille Syrjälä 
1055917c2899SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
1056917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
1057917c2899SVille Syrjälä }
1058917c2899SVille Syrjälä 
1059917c2899SVille Syrjälä /* IVB CPU eDP voltage swing and pre-emphasis control */
1060917c2899SVille Syrjälä static u32 ivb_cpu_edp_signal_levels(u8 train_set)
1061917c2899SVille Syrjälä {
1062917c2899SVille Syrjälä 	u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
1063917c2899SVille Syrjälä 					DP_TRAIN_PRE_EMPHASIS_MASK);
1064917c2899SVille Syrjälä 
1065917c2899SVille Syrjälä 	switch (signal_levels) {
1066917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
1067917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_400MV_0DB_IVB;
1068917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
1069917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_400MV_3_5DB_IVB;
1070917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
1071917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
1072917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_400MV_6DB_IVB;
1073917c2899SVille Syrjälä 
1074917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
1075917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_600MV_0DB_IVB;
1076917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
1077917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_600MV_3_5DB_IVB;
1078917c2899SVille Syrjälä 
1079917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
1080917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_800MV_0DB_IVB;
1081917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
1082917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_800MV_3_5DB_IVB;
1083917c2899SVille Syrjälä 
1084917c2899SVille Syrjälä 	default:
1085917c2899SVille Syrjälä 		MISSING_CASE(signal_levels);
1086917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_500MV_0DB_IVB;
1087917c2899SVille Syrjälä 	}
1088917c2899SVille Syrjälä }
1089917c2899SVille Syrjälä 
1090917c2899SVille Syrjälä static void
1091e722ab8bSVille Syrjälä ivb_cpu_edp_set_signal_levels(struct intel_encoder *encoder,
1092917c2899SVille Syrjälä 			      const struct intel_crtc_state *crtc_state)
1093917c2899SVille Syrjälä {
1094e722ab8bSVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1095e722ab8bSVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1096917c2899SVille Syrjälä 	u8 train_set = intel_dp->train_set[0];
1097917c2899SVille Syrjälä 	u32 signal_levels;
1098917c2899SVille Syrjälä 
1099917c2899SVille Syrjälä 	signal_levels = ivb_cpu_edp_signal_levels(train_set);
1100917c2899SVille Syrjälä 
1101917c2899SVille Syrjälä 	drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n",
1102917c2899SVille Syrjälä 		    signal_levels);
1103917c2899SVille Syrjälä 
1104917c2899SVille Syrjälä 	intel_dp->DP &= ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
1105917c2899SVille Syrjälä 	intel_dp->DP |= signal_levels;
1106917c2899SVille Syrjälä 
1107917c2899SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
1108917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
1109917c2899SVille Syrjälä }
1110917c2899SVille Syrjälä 
1111917c2899SVille Syrjälä /*
1112917c2899SVille Syrjälä  * If display is now connected check links status,
1113917c2899SVille Syrjälä  * there has been known issues of link loss triggering
1114917c2899SVille Syrjälä  * long pulse.
1115917c2899SVille Syrjälä  *
1116917c2899SVille Syrjälä  * Some sinks (eg. ASUS PB287Q) seem to perform some
1117917c2899SVille Syrjälä  * weird HPD ping pong during modesets. So we can apparently
1118917c2899SVille Syrjälä  * end up with HPD going low during a modeset, and then
1119917c2899SVille Syrjälä  * going back up soon after. And once that happens we must
1120917c2899SVille Syrjälä  * retrain the link to get a picture. That's in case no
1121917c2899SVille Syrjälä  * userspace component reacted to intermittent HPD dip.
1122917c2899SVille Syrjälä  */
1123917c2899SVille Syrjälä static enum intel_hotplug_state
1124917c2899SVille Syrjälä intel_dp_hotplug(struct intel_encoder *encoder,
1125917c2899SVille Syrjälä 		 struct intel_connector *connector)
1126917c2899SVille Syrjälä {
1127917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1128917c2899SVille Syrjälä 	struct drm_modeset_acquire_ctx ctx;
1129917c2899SVille Syrjälä 	enum intel_hotplug_state state;
1130917c2899SVille Syrjälä 	int ret;
1131917c2899SVille Syrjälä 
1132917c2899SVille Syrjälä 	if (intel_dp->compliance.test_active &&
1133917c2899SVille Syrjälä 	    intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) {
1134917c2899SVille Syrjälä 		intel_dp_phy_test(encoder);
1135917c2899SVille Syrjälä 		/* just do the PHY test and nothing else */
1136917c2899SVille Syrjälä 		return INTEL_HOTPLUG_UNCHANGED;
1137917c2899SVille Syrjälä 	}
1138917c2899SVille Syrjälä 
1139917c2899SVille Syrjälä 	state = intel_encoder_hotplug(encoder, connector);
1140917c2899SVille Syrjälä 
1141917c2899SVille Syrjälä 	drm_modeset_acquire_init(&ctx, 0);
1142917c2899SVille Syrjälä 
1143917c2899SVille Syrjälä 	for (;;) {
1144917c2899SVille Syrjälä 		ret = intel_dp_retrain_link(encoder, &ctx);
1145917c2899SVille Syrjälä 
1146917c2899SVille Syrjälä 		if (ret == -EDEADLK) {
1147917c2899SVille Syrjälä 			drm_modeset_backoff(&ctx);
1148917c2899SVille Syrjälä 			continue;
1149917c2899SVille Syrjälä 		}
1150917c2899SVille Syrjälä 
1151917c2899SVille Syrjälä 		break;
1152917c2899SVille Syrjälä 	}
1153917c2899SVille Syrjälä 
1154917c2899SVille Syrjälä 	drm_modeset_drop_locks(&ctx);
1155917c2899SVille Syrjälä 	drm_modeset_acquire_fini(&ctx);
1156917c2899SVille Syrjälä 	drm_WARN(encoder->base.dev, ret,
1157917c2899SVille Syrjälä 		 "Acquiring modeset locks failed with %i\n", ret);
1158917c2899SVille Syrjälä 
1159917c2899SVille Syrjälä 	/*
1160917c2899SVille Syrjälä 	 * Keeping it consistent with intel_ddi_hotplug() and
1161917c2899SVille Syrjälä 	 * intel_hdmi_hotplug().
1162917c2899SVille Syrjälä 	 */
1163917c2899SVille Syrjälä 	if (state == INTEL_HOTPLUG_UNCHANGED && !connector->hotplug_retries)
1164917c2899SVille Syrjälä 		state = INTEL_HOTPLUG_RETRY;
1165917c2899SVille Syrjälä 
1166917c2899SVille Syrjälä 	return state;
1167917c2899SVille Syrjälä }
1168917c2899SVille Syrjälä 
1169917c2899SVille Syrjälä static bool ibx_digital_port_connected(struct intel_encoder *encoder)
1170917c2899SVille Syrjälä {
1171917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
11725a4dd6f0SJani Nikula 	u32 bit = dev_priv->display.hotplug.pch_hpd[encoder->hpd_pin];
1173917c2899SVille Syrjälä 
1174917c2899SVille Syrjälä 	return intel_de_read(dev_priv, SDEISR) & bit;
1175917c2899SVille Syrjälä }
1176917c2899SVille Syrjälä 
1177917c2899SVille Syrjälä static bool g4x_digital_port_connected(struct intel_encoder *encoder)
1178917c2899SVille Syrjälä {
1179917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1180917c2899SVille Syrjälä 	u32 bit;
1181917c2899SVille Syrjälä 
1182917c2899SVille Syrjälä 	switch (encoder->hpd_pin) {
1183917c2899SVille Syrjälä 	case HPD_PORT_B:
1184917c2899SVille Syrjälä 		bit = PORTB_HOTPLUG_LIVE_STATUS_G4X;
1185917c2899SVille Syrjälä 		break;
1186917c2899SVille Syrjälä 	case HPD_PORT_C:
1187917c2899SVille Syrjälä 		bit = PORTC_HOTPLUG_LIVE_STATUS_G4X;
1188917c2899SVille Syrjälä 		break;
1189917c2899SVille Syrjälä 	case HPD_PORT_D:
1190917c2899SVille Syrjälä 		bit = PORTD_HOTPLUG_LIVE_STATUS_G4X;
1191917c2899SVille Syrjälä 		break;
1192917c2899SVille Syrjälä 	default:
1193917c2899SVille Syrjälä 		MISSING_CASE(encoder->hpd_pin);
1194917c2899SVille Syrjälä 		return false;
1195917c2899SVille Syrjälä 	}
1196917c2899SVille Syrjälä 
1197917c2899SVille Syrjälä 	return intel_de_read(dev_priv, PORT_HOTPLUG_STAT) & bit;
1198917c2899SVille Syrjälä }
1199917c2899SVille Syrjälä 
1200917c2899SVille Syrjälä static bool ilk_digital_port_connected(struct intel_encoder *encoder)
1201917c2899SVille Syrjälä {
1202917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
12035a4dd6f0SJani Nikula 	u32 bit = dev_priv->display.hotplug.hpd[encoder->hpd_pin];
1204917c2899SVille Syrjälä 
1205917c2899SVille Syrjälä 	return intel_de_read(dev_priv, DEISR) & bit;
1206917c2899SVille Syrjälä }
1207917c2899SVille Syrjälä 
1208917c2899SVille Syrjälä static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
1209917c2899SVille Syrjälä {
1210917c2899SVille Syrjälä 	intel_dp_encoder_flush_work(encoder);
1211917c2899SVille Syrjälä 
1212917c2899SVille Syrjälä 	drm_encoder_cleanup(encoder);
1213917c2899SVille Syrjälä 	kfree(enc_to_dig_port(to_intel_encoder(encoder)));
1214917c2899SVille Syrjälä }
1215917c2899SVille Syrjälä 
1216917c2899SVille Syrjälä enum pipe vlv_active_pipe(struct intel_dp *intel_dp)
1217917c2899SVille Syrjälä {
1218917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
1219917c2899SVille Syrjälä 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
1220917c2899SVille Syrjälä 	enum pipe pipe;
1221917c2899SVille Syrjälä 
1222053ffdd1SVille Syrjälä 	if (g4x_dp_port_enabled(dev_priv, intel_dp->output_reg,
1223917c2899SVille Syrjälä 				encoder->port, &pipe))
1224917c2899SVille Syrjälä 		return pipe;
1225917c2899SVille Syrjälä 
1226917c2899SVille Syrjälä 	return INVALID_PIPE;
1227917c2899SVille Syrjälä }
1228917c2899SVille Syrjälä 
1229917c2899SVille Syrjälä static void intel_dp_encoder_reset(struct drm_encoder *encoder)
1230917c2899SVille Syrjälä {
1231917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
1232917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(encoder));
1233917c2899SVille Syrjälä 
1234917c2899SVille Syrjälä 	intel_dp->DP = intel_de_read(dev_priv, intel_dp->output_reg);
1235917c2899SVille Syrjälä 
1236917c2899SVille Syrjälä 	intel_dp->reset_link_params = true;
1237917c2899SVille Syrjälä 
1238917c2899SVille Syrjälä 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
1239917c2899SVille Syrjälä 		intel_wakeref_t wakeref;
1240917c2899SVille Syrjälä 
1241917c2899SVille Syrjälä 		with_intel_pps_lock(intel_dp, wakeref)
1242917c2899SVille Syrjälä 			intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp);
1243917c2899SVille Syrjälä 	}
1244917c2899SVille Syrjälä 
1245917c2899SVille Syrjälä 	intel_pps_encoder_reset(intel_dp);
1246917c2899SVille Syrjälä }
1247917c2899SVille Syrjälä 
1248917c2899SVille Syrjälä static const struct drm_encoder_funcs intel_dp_enc_funcs = {
1249917c2899SVille Syrjälä 	.reset = intel_dp_encoder_reset,
1250917c2899SVille Syrjälä 	.destroy = intel_dp_encoder_destroy,
1251917c2899SVille Syrjälä };
1252917c2899SVille Syrjälä 
1253053ffdd1SVille Syrjälä bool g4x_dp_init(struct drm_i915_private *dev_priv,
1254053ffdd1SVille Syrjälä 		 i915_reg_t output_reg, enum port port)
1255917c2899SVille Syrjälä {
12561b108bc7SVille Syrjälä 	const struct intel_bios_encoder_data *devdata;
1257917c2899SVille Syrjälä 	struct intel_digital_port *dig_port;
1258917c2899SVille Syrjälä 	struct intel_encoder *intel_encoder;
1259917c2899SVille Syrjälä 	struct drm_encoder *encoder;
1260917c2899SVille Syrjälä 	struct intel_connector *intel_connector;
1261917c2899SVille Syrjälä 
1262679df6f1SVille Syrjälä 	if (!assert_port_valid(dev_priv, port))
1263679df6f1SVille Syrjälä 		return false;
1264679df6f1SVille Syrjälä 
12651b108bc7SVille Syrjälä 	devdata = intel_bios_encoder_data_lookup(dev_priv, port);
12661b108bc7SVille Syrjälä 
12671b108bc7SVille Syrjälä 	/* FIXME bail? */
12681b108bc7SVille Syrjälä 	if (!devdata)
12691b108bc7SVille Syrjälä 		drm_dbg_kms(&dev_priv->drm, "No VBT child device for DP-%c\n",
12701b108bc7SVille Syrjälä 			    port_name(port));
12711b108bc7SVille Syrjälä 
1272917c2899SVille Syrjälä 	dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL);
1273917c2899SVille Syrjälä 	if (!dig_port)
1274917c2899SVille Syrjälä 		return false;
1275917c2899SVille Syrjälä 
1276*4cca9676SVille Syrjälä 	dig_port->aux_ch = AUX_CH_NONE;
1277*4cca9676SVille Syrjälä 
1278917c2899SVille Syrjälä 	intel_connector = intel_connector_alloc();
1279917c2899SVille Syrjälä 	if (!intel_connector)
1280917c2899SVille Syrjälä 		goto err_connector_alloc;
1281917c2899SVille Syrjälä 
1282917c2899SVille Syrjälä 	intel_encoder = &dig_port->base;
1283917c2899SVille Syrjälä 	encoder = &intel_encoder->base;
1284917c2899SVille Syrjälä 
12851b108bc7SVille Syrjälä 	intel_encoder->devdata = devdata;
12861b108bc7SVille Syrjälä 
1287917c2899SVille Syrjälä 	mutex_init(&dig_port->hdcp_mutex);
1288917c2899SVille Syrjälä 
1289917c2899SVille Syrjälä 	if (drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
1290917c2899SVille Syrjälä 			     &intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS,
1291917c2899SVille Syrjälä 			     "DP %c", port_name(port)))
1292917c2899SVille Syrjälä 		goto err_encoder_init;
1293917c2899SVille Syrjälä 
1294917c2899SVille Syrjälä 	intel_encoder->hotplug = intel_dp_hotplug;
1295917c2899SVille Syrjälä 	intel_encoder->compute_config = intel_dp_compute_config;
1296917c2899SVille Syrjälä 	intel_encoder->get_hw_state = intel_dp_get_hw_state;
1297917c2899SVille Syrjälä 	intel_encoder->get_config = intel_dp_get_config;
1298917c2899SVille Syrjälä 	intel_encoder->sync_state = intel_dp_sync_state;
1299917c2899SVille Syrjälä 	intel_encoder->initial_fastset_check = intel_dp_initial_fastset_check;
1300c0a52f8bSJani Nikula 	intel_encoder->update_pipe = intel_backlight_update;
1301917c2899SVille Syrjälä 	intel_encoder->suspend = intel_dp_encoder_suspend;
1302917c2899SVille Syrjälä 	intel_encoder->shutdown = intel_dp_encoder_shutdown;
1303917c2899SVille Syrjälä 	if (IS_CHERRYVIEW(dev_priv)) {
1304917c2899SVille Syrjälä 		intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable;
1305917c2899SVille Syrjälä 		intel_encoder->pre_enable = chv_pre_enable_dp;
1306917c2899SVille Syrjälä 		intel_encoder->enable = vlv_enable_dp;
1307917c2899SVille Syrjälä 		intel_encoder->disable = vlv_disable_dp;
1308917c2899SVille Syrjälä 		intel_encoder->post_disable = chv_post_disable_dp;
1309917c2899SVille Syrjälä 		intel_encoder->post_pll_disable = chv_dp_post_pll_disable;
1310917c2899SVille Syrjälä 	} else if (IS_VALLEYVIEW(dev_priv)) {
1311917c2899SVille Syrjälä 		intel_encoder->pre_pll_enable = vlv_dp_pre_pll_enable;
1312917c2899SVille Syrjälä 		intel_encoder->pre_enable = vlv_pre_enable_dp;
1313917c2899SVille Syrjälä 		intel_encoder->enable = vlv_enable_dp;
1314917c2899SVille Syrjälä 		intel_encoder->disable = vlv_disable_dp;
1315917c2899SVille Syrjälä 		intel_encoder->post_disable = vlv_post_disable_dp;
1316917c2899SVille Syrjälä 	} else {
1317917c2899SVille Syrjälä 		intel_encoder->pre_enable = g4x_pre_enable_dp;
1318917c2899SVille Syrjälä 		intel_encoder->enable = g4x_enable_dp;
1319917c2899SVille Syrjälä 		intel_encoder->disable = g4x_disable_dp;
1320917c2899SVille Syrjälä 		intel_encoder->post_disable = g4x_post_disable_dp;
1321917c2899SVille Syrjälä 	}
1322917c2899SVille Syrjälä 
1323917c2899SVille Syrjälä 	if ((IS_IVYBRIDGE(dev_priv) && port == PORT_A) ||
1324917c2899SVille Syrjälä 	    (HAS_PCH_CPT(dev_priv) && port != PORT_A))
1325917c2899SVille Syrjälä 		dig_port->dp.set_link_train = cpt_set_link_train;
1326917c2899SVille Syrjälä 	else
1327917c2899SVille Syrjälä 		dig_port->dp.set_link_train = g4x_set_link_train;
1328917c2899SVille Syrjälä 
1329917c2899SVille Syrjälä 	if (IS_CHERRYVIEW(dev_priv))
1330e722ab8bSVille Syrjälä 		intel_encoder->set_signal_levels = chv_set_signal_levels;
1331917c2899SVille Syrjälä 	else if (IS_VALLEYVIEW(dev_priv))
1332e722ab8bSVille Syrjälä 		intel_encoder->set_signal_levels = vlv_set_signal_levels;
1333917c2899SVille Syrjälä 	else if (IS_IVYBRIDGE(dev_priv) && port == PORT_A)
1334e722ab8bSVille Syrjälä 		intel_encoder->set_signal_levels = ivb_cpu_edp_set_signal_levels;
1335d47d29a6SMatt Roper 	else if (IS_SANDYBRIDGE(dev_priv) && port == PORT_A)
1336e722ab8bSVille Syrjälä 		intel_encoder->set_signal_levels = snb_cpu_edp_set_signal_levels;
1337917c2899SVille Syrjälä 	else
1338e722ab8bSVille Syrjälä 		intel_encoder->set_signal_levels = g4x_set_signal_levels;
1339917c2899SVille Syrjälä 
1340917c2899SVille Syrjälä 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
1341917c2899SVille Syrjälä 	    (HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) {
1342917c2899SVille Syrjälä 		dig_port->dp.preemph_max = intel_dp_preemph_max_3;
1343917c2899SVille Syrjälä 		dig_port->dp.voltage_max = intel_dp_voltage_max_3;
1344917c2899SVille Syrjälä 	} else {
1345917c2899SVille Syrjälä 		dig_port->dp.preemph_max = intel_dp_preemph_max_2;
1346917c2899SVille Syrjälä 		dig_port->dp.voltage_max = intel_dp_voltage_max_2;
1347917c2899SVille Syrjälä 	}
1348917c2899SVille Syrjälä 
1349917c2899SVille Syrjälä 	dig_port->dp.output_reg = output_reg;
1350917c2899SVille Syrjälä 	dig_port->max_lanes = 4;
1351917c2899SVille Syrjälä 
1352917c2899SVille Syrjälä 	intel_encoder->type = INTEL_OUTPUT_DP;
1353979e1b32SImre Deak 	intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port);
1354917c2899SVille Syrjälä 	if (IS_CHERRYVIEW(dev_priv)) {
1355917c2899SVille Syrjälä 		if (port == PORT_D)
1356917c2899SVille Syrjälä 			intel_encoder->pipe_mask = BIT(PIPE_C);
1357917c2899SVille Syrjälä 		else
1358917c2899SVille Syrjälä 			intel_encoder->pipe_mask = BIT(PIPE_A) | BIT(PIPE_B);
1359917c2899SVille Syrjälä 	} else {
1360917c2899SVille Syrjälä 		intel_encoder->pipe_mask = ~0;
1361917c2899SVille Syrjälä 	}
1362917c2899SVille Syrjälä 	intel_encoder->cloneable = 0;
1363917c2899SVille Syrjälä 	intel_encoder->port = port;
1364917c2899SVille Syrjälä 	intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
1365917c2899SVille Syrjälä 
1366917c2899SVille Syrjälä 	dig_port->hpd_pulse = intel_dp_hpd_pulse;
1367917c2899SVille Syrjälä 
1368917c2899SVille Syrjälä 	if (HAS_GMCH(dev_priv)) {
1369917c2899SVille Syrjälä 		dig_port->connected = g4x_digital_port_connected;
1370917c2899SVille Syrjälä 	} else {
1371917c2899SVille Syrjälä 		if (port == PORT_A)
1372917c2899SVille Syrjälä 			dig_port->connected = ilk_digital_port_connected;
1373917c2899SVille Syrjälä 		else
1374917c2899SVille Syrjälä 			dig_port->connected = ibx_digital_port_connected;
1375917c2899SVille Syrjälä 	}
1376917c2899SVille Syrjälä 
1377917c2899SVille Syrjälä 	if (port != PORT_A)
1378917c2899SVille Syrjälä 		intel_infoframe_init(dig_port);
1379917c2899SVille Syrjälä 
1380bb45217fSVille Syrjälä 	dig_port->aux_ch = intel_dp_aux_ch(intel_encoder);
1381917c2899SVille Syrjälä 	if (!intel_dp_init_connector(dig_port, intel_connector))
1382917c2899SVille Syrjälä 		goto err_init_connector;
1383917c2899SVille Syrjälä 
1384917c2899SVille Syrjälä 	return true;
1385917c2899SVille Syrjälä 
1386917c2899SVille Syrjälä err_init_connector:
1387917c2899SVille Syrjälä 	drm_encoder_cleanup(encoder);
1388917c2899SVille Syrjälä err_encoder_init:
1389917c2899SVille Syrjälä 	kfree(intel_connector);
1390917c2899SVille Syrjälä err_connector_alloc:
1391917c2899SVille Syrjälä 	kfree(dig_port);
1392917c2899SVille Syrjälä 	return false;
1393917c2899SVille Syrjälä }
1394