xref: /openbmc/linux/drivers/gpu/drm/i915/display/g4x_dp.c (revision e4c16db9)
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ä 
vlv_get_dpll(struct drm_i915_private * i915)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ä 
g4x_dp_set_clock(struct intel_encoder * encoder,struct intel_crtc_state * pipe_config)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ä 
intel_dp_prepare(struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config)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,
144*e4c16db9SVille Syrjälä 			     pipe_config->enhanced_framing ?
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ä 
156*e4c16db9SVille Syrjälä 		if (pipe_config->enhanced_framing)
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ä 
assert_dp_port(struct intel_dp * intel_dp,bool state)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ä 
assert_edp_pll(struct drm_i915_private * dev_priv,bool state)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ä 
ilk_edp_pll_on(struct intel_dp * intel_dp,const struct intel_crtc_state * pipe_config)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ä 
ilk_edp_pll_off(struct intel_dp * intel_dp,const struct intel_crtc_state * old_crtc_state)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ä 
cpt_dp_port_selected(struct drm_i915_private * dev_priv,enum port port,enum pipe * pipe)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ä 
g4x_dp_port_enabled(struct drm_i915_private * dev_priv,i915_reg_t dp_reg,enum port port,enum pipe * pipe)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ä 
intel_dp_get_hw_state(struct intel_encoder * encoder,enum pipe * pipe)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ä 
g4x_dp_get_m_n(struct intel_crtc_state * crtc_state)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ä 
intel_dp_get_config(struct intel_encoder * encoder,struct intel_crtc_state * pipe_config)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ä 
354*e4c16db9SVille Syrjälä 		if (trans_dp & TRANS_DP_ENH_FRAMING)
355*e4c16db9SVille Syrjälä 			pipe_config->enhanced_framing = true;
356*e4c16db9SVille Syrjälä 
357917c2899SVille Syrjälä 		if (trans_dp & TRANS_DP_HSYNC_ACTIVE_HIGH)
358917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_PHSYNC;
359917c2899SVille Syrjälä 		else
360917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_NHSYNC;
361917c2899SVille Syrjälä 
362917c2899SVille Syrjälä 		if (trans_dp & TRANS_DP_VSYNC_ACTIVE_HIGH)
363917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_PVSYNC;
364917c2899SVille Syrjälä 		else
365917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_NVSYNC;
366917c2899SVille Syrjälä 	} else {
367*e4c16db9SVille Syrjälä 		if (tmp & DP_ENHANCED_FRAMING)
368*e4c16db9SVille Syrjälä 			pipe_config->enhanced_framing = true;
369*e4c16db9SVille Syrjälä 
370917c2899SVille Syrjälä 		if (tmp & DP_SYNC_HS_HIGH)
371917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_PHSYNC;
372917c2899SVille Syrjälä 		else
373917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_NHSYNC;
374917c2899SVille Syrjälä 
375917c2899SVille Syrjälä 		if (tmp & DP_SYNC_VS_HIGH)
376917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_PVSYNC;
377917c2899SVille Syrjälä 		else
378917c2899SVille Syrjälä 			flags |= DRM_MODE_FLAG_NVSYNC;
379917c2899SVille Syrjälä 	}
380917c2899SVille Syrjälä 
381917c2899SVille Syrjälä 	pipe_config->hw.adjusted_mode.flags |= flags;
382917c2899SVille Syrjälä 
383917c2899SVille Syrjälä 	if (IS_G4X(dev_priv) && tmp & DP_COLOR_RANGE_16_235)
384917c2899SVille Syrjälä 		pipe_config->limited_color_range = true;
385917c2899SVille Syrjälä 
386917c2899SVille Syrjälä 	pipe_config->lane_count =
387917c2899SVille Syrjälä 		((tmp & DP_PORT_WIDTH_MASK) >> DP_PORT_WIDTH_SHIFT) + 1;
388917c2899SVille Syrjälä 
3896149cb68SVille Syrjälä 	g4x_dp_get_m_n(pipe_config);
390917c2899SVille Syrjälä 
391917c2899SVille Syrjälä 	if (port == PORT_A) {
392917c2899SVille Syrjälä 		if ((intel_de_read(dev_priv, DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_162MHZ)
393917c2899SVille Syrjälä 			pipe_config->port_clock = 162000;
394917c2899SVille Syrjälä 		else
395917c2899SVille Syrjälä 			pipe_config->port_clock = 270000;
396917c2899SVille Syrjälä 	}
397917c2899SVille Syrjälä 
398917c2899SVille Syrjälä 	pipe_config->hw.adjusted_mode.crtc_clock =
399917c2899SVille Syrjälä 		intel_dotclock_calculate(pipe_config->port_clock,
400917c2899SVille Syrjälä 					 &pipe_config->dp_m_n);
401917c2899SVille Syrjälä 
402822e5ae7SVille Syrjälä 	if (intel_dp_is_edp(intel_dp))
403822e5ae7SVille Syrjälä 		intel_edp_fixup_vbt_bpp(encoder, pipe_config->pipe_bpp);
40461a60df6SVille Syrjälä 
40561a60df6SVille Syrjälä 	intel_audio_codec_get_config(encoder, pipe_config);
406917c2899SVille Syrjälä }
407917c2899SVille Syrjälä 
408917c2899SVille Syrjälä static void
intel_dp_link_down(struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state)409917c2899SVille Syrjälä intel_dp_link_down(struct intel_encoder *encoder,
410917c2899SVille Syrjälä 		   const struct intel_crtc_state *old_crtc_state)
411917c2899SVille Syrjälä {
412917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
413917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
414917c2899SVille Syrjälä 	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
415917c2899SVille Syrjälä 	enum port port = encoder->port;
416917c2899SVille Syrjälä 
417917c2899SVille Syrjälä 	if (drm_WARN_ON(&dev_priv->drm,
418917c2899SVille Syrjälä 			(intel_de_read(dev_priv, intel_dp->output_reg) &
419917c2899SVille Syrjälä 			 DP_PORT_EN) == 0))
420917c2899SVille Syrjälä 		return;
421917c2899SVille Syrjälä 
422917c2899SVille Syrjälä 	drm_dbg_kms(&dev_priv->drm, "\n");
423917c2899SVille Syrjälä 
424917c2899SVille Syrjälä 	if ((IS_IVYBRIDGE(dev_priv) && port == PORT_A) ||
425917c2899SVille Syrjälä 	    (HAS_PCH_CPT(dev_priv) && port != PORT_A)) {
426cbf02c50SVille Syrjälä 		intel_dp->DP &= ~DP_LINK_TRAIN_MASK_CPT;
427cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE_CPT;
428917c2899SVille Syrjälä 	} else {
429cbf02c50SVille Syrjälä 		intel_dp->DP &= ~DP_LINK_TRAIN_MASK;
430cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE;
431917c2899SVille Syrjälä 	}
432cbf02c50SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
433917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
434917c2899SVille Syrjälä 
435cbf02c50SVille Syrjälä 	intel_dp->DP &= ~(DP_PORT_EN | DP_AUDIO_OUTPUT_ENABLE);
436cbf02c50SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
437917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
438917c2899SVille Syrjälä 
439917c2899SVille Syrjälä 	/*
440917c2899SVille Syrjälä 	 * HW workaround for IBX, we need to move the port
441917c2899SVille Syrjälä 	 * to transcoder A after disabling it to allow the
442917c2899SVille Syrjälä 	 * matching HDMI port to be enabled on transcoder A.
443917c2899SVille Syrjälä 	 */
444917c2899SVille Syrjälä 	if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B && port != PORT_A) {
445917c2899SVille Syrjälä 		/*
446917c2899SVille Syrjälä 		 * We get CPU/PCH FIFO underruns on the other pipe when
447917c2899SVille Syrjälä 		 * doing the workaround. Sweep them under the rug.
448917c2899SVille Syrjälä 		 */
449917c2899SVille Syrjälä 		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false);
450917c2899SVille Syrjälä 		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
451917c2899SVille Syrjälä 
452917c2899SVille Syrjälä 		/* always enable with pattern 1 (as per spec) */
453cbf02c50SVille Syrjälä 		intel_dp->DP &= ~(DP_PIPE_SEL_MASK | DP_LINK_TRAIN_MASK);
454cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_PORT_EN | DP_PIPE_SEL(PIPE_A) |
455917c2899SVille Syrjälä 			DP_LINK_TRAIN_PAT_1;
456cbf02c50SVille Syrjälä 		intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
457917c2899SVille Syrjälä 		intel_de_posting_read(dev_priv, intel_dp->output_reg);
458917c2899SVille Syrjälä 
459cbf02c50SVille Syrjälä 		intel_dp->DP &= ~DP_PORT_EN;
460cbf02c50SVille Syrjälä 		intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
461917c2899SVille Syrjälä 		intel_de_posting_read(dev_priv, intel_dp->output_reg);
462917c2899SVille Syrjälä 
463917c2899SVille Syrjälä 		intel_wait_for_vblank_if_active(dev_priv, PIPE_A);
464917c2899SVille Syrjälä 		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true);
465917c2899SVille Syrjälä 		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
466917c2899SVille Syrjälä 	}
467917c2899SVille Syrjälä 
468917c2899SVille Syrjälä 	msleep(intel_dp->pps.panel_power_down_delay);
469917c2899SVille Syrjälä 
470917c2899SVille Syrjälä 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
471917c2899SVille Syrjälä 		intel_wakeref_t wakeref;
472917c2899SVille Syrjälä 
473917c2899SVille Syrjälä 		with_intel_pps_lock(intel_dp, wakeref)
474917c2899SVille Syrjälä 			intel_dp->pps.active_pipe = INVALID_PIPE;
475917c2899SVille Syrjälä 	}
476917c2899SVille Syrjälä }
477917c2899SVille Syrjälä 
intel_disable_dp(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)478917c2899SVille Syrjälä static void intel_disable_dp(struct intel_atomic_state *state,
479917c2899SVille Syrjälä 			     struct intel_encoder *encoder,
480917c2899SVille Syrjälä 			     const struct intel_crtc_state *old_crtc_state,
481917c2899SVille Syrjälä 			     const struct drm_connector_state *old_conn_state)
482917c2899SVille Syrjälä {
483917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
484917c2899SVille Syrjälä 
485917c2899SVille Syrjälä 	intel_dp->link_trained = false;
486917c2899SVille Syrjälä 
487179db7c1SJani Nikula 	intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
488917c2899SVille Syrjälä 
489917c2899SVille Syrjälä 	/*
490917c2899SVille Syrjälä 	 * Make sure the panel is off before trying to change the mode.
491917c2899SVille Syrjälä 	 * But also ensure that we have vdd while we switch off the panel.
492917c2899SVille Syrjälä 	 */
493917c2899SVille Syrjälä 	intel_pps_vdd_on(intel_dp);
494917c2899SVille Syrjälä 	intel_edp_backlight_off(old_conn_state);
495917c2899SVille Syrjälä 	intel_dp_set_power(intel_dp, DP_SET_POWER_D3);
496917c2899SVille Syrjälä 	intel_pps_off(intel_dp);
497917c2899SVille Syrjälä }
498917c2899SVille Syrjälä 
g4x_disable_dp(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)499917c2899SVille Syrjälä static void g4x_disable_dp(struct intel_atomic_state *state,
500917c2899SVille Syrjälä 			   struct intel_encoder *encoder,
501917c2899SVille Syrjälä 			   const struct intel_crtc_state *old_crtc_state,
502917c2899SVille Syrjälä 			   const struct drm_connector_state *old_conn_state)
503917c2899SVille Syrjälä {
504917c2899SVille Syrjälä 	intel_disable_dp(state, encoder, old_crtc_state, old_conn_state);
505917c2899SVille Syrjälä }
506917c2899SVille Syrjälä 
vlv_disable_dp(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)507917c2899SVille Syrjälä static void vlv_disable_dp(struct intel_atomic_state *state,
508917c2899SVille Syrjälä 			   struct intel_encoder *encoder,
509917c2899SVille Syrjälä 			   const struct intel_crtc_state *old_crtc_state,
510917c2899SVille Syrjälä 			   const struct drm_connector_state *old_conn_state)
511917c2899SVille Syrjälä {
512917c2899SVille Syrjälä 	intel_disable_dp(state, encoder, old_crtc_state, old_conn_state);
513917c2899SVille Syrjälä }
514917c2899SVille Syrjälä 
g4x_post_disable_dp(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)515917c2899SVille Syrjälä static void g4x_post_disable_dp(struct intel_atomic_state *state,
516917c2899SVille Syrjälä 				struct intel_encoder *encoder,
517917c2899SVille Syrjälä 				const struct intel_crtc_state *old_crtc_state,
518917c2899SVille Syrjälä 				const struct drm_connector_state *old_conn_state)
519917c2899SVille Syrjälä {
520917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
521917c2899SVille Syrjälä 	enum port port = encoder->port;
522917c2899SVille Syrjälä 
523917c2899SVille Syrjälä 	/*
524917c2899SVille Syrjälä 	 * Bspec does not list a specific disable sequence for g4x DP.
525917c2899SVille Syrjälä 	 * Follow the ilk+ sequence (disable pipe before the port) for
526917c2899SVille Syrjälä 	 * g4x DP as it does not suffer from underruns like the normal
527917c2899SVille Syrjälä 	 * g4x modeset sequence (disable pipe after the port).
528917c2899SVille Syrjälä 	 */
529917c2899SVille Syrjälä 	intel_dp_link_down(encoder, old_crtc_state);
530917c2899SVille Syrjälä 
531917c2899SVille Syrjälä 	/* Only ilk+ has port A */
532917c2899SVille Syrjälä 	if (port == PORT_A)
533917c2899SVille Syrjälä 		ilk_edp_pll_off(intel_dp, old_crtc_state);
534917c2899SVille Syrjälä }
535917c2899SVille Syrjälä 
vlv_post_disable_dp(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)536917c2899SVille Syrjälä static void vlv_post_disable_dp(struct intel_atomic_state *state,
537917c2899SVille Syrjälä 				struct intel_encoder *encoder,
538917c2899SVille Syrjälä 				const struct intel_crtc_state *old_crtc_state,
539917c2899SVille Syrjälä 				const struct drm_connector_state *old_conn_state)
540917c2899SVille Syrjälä {
541917c2899SVille Syrjälä 	intel_dp_link_down(encoder, old_crtc_state);
542917c2899SVille Syrjälä }
543917c2899SVille Syrjälä 
chv_post_disable_dp(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)544917c2899SVille Syrjälä static void chv_post_disable_dp(struct intel_atomic_state *state,
545917c2899SVille Syrjälä 				struct intel_encoder *encoder,
546917c2899SVille Syrjälä 				const struct intel_crtc_state *old_crtc_state,
547917c2899SVille Syrjälä 				const struct drm_connector_state *old_conn_state)
548917c2899SVille Syrjälä {
549917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
550917c2899SVille Syrjälä 
551917c2899SVille Syrjälä 	intel_dp_link_down(encoder, old_crtc_state);
552917c2899SVille Syrjälä 
553917c2899SVille Syrjälä 	vlv_dpio_get(dev_priv);
554917c2899SVille Syrjälä 
555917c2899SVille Syrjälä 	/* Assert data lane reset */
556917c2899SVille Syrjälä 	chv_data_lane_soft_reset(encoder, old_crtc_state, true);
557917c2899SVille Syrjälä 
558917c2899SVille Syrjälä 	vlv_dpio_put(dev_priv);
559917c2899SVille Syrjälä }
560917c2899SVille Syrjälä 
561917c2899SVille Syrjälä static void
cpt_set_link_train(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state,u8 dp_train_pat)562917c2899SVille Syrjälä cpt_set_link_train(struct intel_dp *intel_dp,
563917c2899SVille Syrjälä 		   const struct intel_crtc_state *crtc_state,
564917c2899SVille Syrjälä 		   u8 dp_train_pat)
565917c2899SVille Syrjälä {
566917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
567917c2899SVille Syrjälä 
568cbf02c50SVille Syrjälä 	intel_dp->DP &= ~DP_LINK_TRAIN_MASK_CPT;
569917c2899SVille Syrjälä 
570917c2899SVille Syrjälä 	switch (intel_dp_training_pattern_symbol(dp_train_pat)) {
571917c2899SVille Syrjälä 	case DP_TRAINING_PATTERN_DISABLE:
572cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
573917c2899SVille Syrjälä 		break;
574917c2899SVille Syrjälä 	case DP_TRAINING_PATTERN_1:
575cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_PAT_1_CPT;
576917c2899SVille Syrjälä 		break;
577917c2899SVille Syrjälä 	case DP_TRAINING_PATTERN_2:
578cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_PAT_2_CPT;
579917c2899SVille Syrjälä 		break;
580917c2899SVille Syrjälä 	default:
581917c2899SVille Syrjälä 		MISSING_CASE(intel_dp_training_pattern_symbol(dp_train_pat));
582917c2899SVille Syrjälä 		return;
583917c2899SVille Syrjälä 	}
584917c2899SVille Syrjälä 
585917c2899SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
586917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
587917c2899SVille Syrjälä }
588917c2899SVille Syrjälä 
589917c2899SVille Syrjälä static void
g4x_set_link_train(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state,u8 dp_train_pat)590917c2899SVille Syrjälä g4x_set_link_train(struct intel_dp *intel_dp,
591917c2899SVille Syrjälä 		   const struct intel_crtc_state *crtc_state,
592917c2899SVille Syrjälä 		   u8 dp_train_pat)
593917c2899SVille Syrjälä {
594917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
595917c2899SVille Syrjälä 
596cbf02c50SVille Syrjälä 	intel_dp->DP &= ~DP_LINK_TRAIN_MASK;
597917c2899SVille Syrjälä 
598917c2899SVille Syrjälä 	switch (intel_dp_training_pattern_symbol(dp_train_pat)) {
599917c2899SVille Syrjälä 	case DP_TRAINING_PATTERN_DISABLE:
600cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_OFF;
601917c2899SVille Syrjälä 		break;
602917c2899SVille Syrjälä 	case DP_TRAINING_PATTERN_1:
603cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_PAT_1;
604917c2899SVille Syrjälä 		break;
605917c2899SVille Syrjälä 	case DP_TRAINING_PATTERN_2:
606cbf02c50SVille Syrjälä 		intel_dp->DP |= DP_LINK_TRAIN_PAT_2;
607917c2899SVille Syrjälä 		break;
608917c2899SVille Syrjälä 	default:
609917c2899SVille Syrjälä 		MISSING_CASE(intel_dp_training_pattern_symbol(dp_train_pat));
610917c2899SVille Syrjälä 		return;
611917c2899SVille Syrjälä 	}
612917c2899SVille Syrjälä 
613917c2899SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
614917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
615917c2899SVille Syrjälä }
616917c2899SVille Syrjälä 
intel_dp_enable_port(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state)617917c2899SVille Syrjälä static void intel_dp_enable_port(struct intel_dp *intel_dp,
618917c2899SVille Syrjälä 				 const struct intel_crtc_state *crtc_state)
619917c2899SVille Syrjälä {
620917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
621917c2899SVille Syrjälä 
622917c2899SVille Syrjälä 	/* enable with pattern 1 (as per spec) */
623917c2899SVille Syrjälä 
624917c2899SVille Syrjälä 	intel_dp_program_link_training_pattern(intel_dp, crtc_state,
625be152504SVille Syrjälä 					       DP_PHY_DPRX, DP_TRAINING_PATTERN_1);
626917c2899SVille Syrjälä 
627917c2899SVille Syrjälä 	/*
628917c2899SVille Syrjälä 	 * Magic for VLV/CHV. We _must_ first set up the register
629917c2899SVille Syrjälä 	 * without actually enabling the port, and then do another
630917c2899SVille Syrjälä 	 * write to enable the port. Otherwise link training will
631917c2899SVille Syrjälä 	 * fail when the power sequencer is freshly used for this port.
632917c2899SVille Syrjälä 	 */
633917c2899SVille Syrjälä 	intel_dp->DP |= DP_PORT_EN;
634917c2899SVille Syrjälä 	if (crtc_state->has_audio)
635917c2899SVille Syrjälä 		intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
636917c2899SVille Syrjälä 
637917c2899SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
638917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
639917c2899SVille Syrjälä }
640917c2899SVille Syrjälä 
intel_enable_dp(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)641917c2899SVille Syrjälä static void intel_enable_dp(struct intel_atomic_state *state,
642917c2899SVille Syrjälä 			    struct intel_encoder *encoder,
643917c2899SVille Syrjälä 			    const struct intel_crtc_state *pipe_config,
644917c2899SVille Syrjälä 			    const struct drm_connector_state *conn_state)
645917c2899SVille Syrjälä {
646917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
647917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
648917c2899SVille Syrjälä 	u32 dp_reg = intel_de_read(dev_priv, intel_dp->output_reg);
649917c2899SVille Syrjälä 	intel_wakeref_t wakeref;
650917c2899SVille Syrjälä 
651917c2899SVille Syrjälä 	if (drm_WARN_ON(&dev_priv->drm, dp_reg & DP_PORT_EN))
652917c2899SVille Syrjälä 		return;
653917c2899SVille Syrjälä 
654917c2899SVille Syrjälä 	with_intel_pps_lock(intel_dp, wakeref) {
655917c2899SVille Syrjälä 		if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
656917c2899SVille Syrjälä 			vlv_pps_init(encoder, pipe_config);
657917c2899SVille Syrjälä 
658917c2899SVille Syrjälä 		intel_dp_enable_port(intel_dp, pipe_config);
659917c2899SVille Syrjälä 
660917c2899SVille Syrjälä 		intel_pps_vdd_on_unlocked(intel_dp);
661917c2899SVille Syrjälä 		intel_pps_on_unlocked(intel_dp);
662917c2899SVille Syrjälä 		intel_pps_vdd_off_unlocked(intel_dp, true);
663917c2899SVille Syrjälä 	}
664917c2899SVille Syrjälä 
665917c2899SVille Syrjälä 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
666917c2899SVille Syrjälä 		unsigned int lane_mask = 0x0;
667917c2899SVille Syrjälä 
668917c2899SVille Syrjälä 		if (IS_CHERRYVIEW(dev_priv))
669917c2899SVille Syrjälä 			lane_mask = intel_dp_unused_lane_mask(pipe_config->lane_count);
670917c2899SVille Syrjälä 
671917c2899SVille Syrjälä 		vlv_wait_port_ready(dev_priv, dp_to_dig_port(intel_dp),
672917c2899SVille Syrjälä 				    lane_mask);
673917c2899SVille Syrjälä 	}
674917c2899SVille Syrjälä 
675917c2899SVille Syrjälä 	intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
676917c2899SVille Syrjälä 	intel_dp_configure_protocol_converter(intel_dp, pipe_config);
677917c2899SVille Syrjälä 	intel_dp_check_frl_training(intel_dp);
678917c2899SVille Syrjälä 	intel_dp_pcon_dsc_configure(intel_dp, pipe_config);
679917c2899SVille Syrjälä 	intel_dp_start_link_train(intel_dp, pipe_config);
680917c2899SVille Syrjälä 	intel_dp_stop_link_train(intel_dp, pipe_config);
681917c2899SVille Syrjälä }
682917c2899SVille Syrjälä 
g4x_enable_dp(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)683917c2899SVille Syrjälä static void g4x_enable_dp(struct intel_atomic_state *state,
684917c2899SVille Syrjälä 			  struct intel_encoder *encoder,
685917c2899SVille Syrjälä 			  const struct intel_crtc_state *pipe_config,
686917c2899SVille Syrjälä 			  const struct drm_connector_state *conn_state)
687917c2899SVille Syrjälä {
688917c2899SVille Syrjälä 	intel_enable_dp(state, encoder, pipe_config, conn_state);
689a467a243SVille Syrjälä 	intel_audio_codec_enable(encoder, pipe_config, conn_state);
690917c2899SVille Syrjälä 	intel_edp_backlight_on(pipe_config, conn_state);
691917c2899SVille Syrjälä }
692917c2899SVille Syrjälä 
vlv_enable_dp(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)693917c2899SVille Syrjälä static void vlv_enable_dp(struct intel_atomic_state *state,
694917c2899SVille Syrjälä 			  struct intel_encoder *encoder,
695917c2899SVille Syrjälä 			  const struct intel_crtc_state *pipe_config,
696917c2899SVille Syrjälä 			  const struct drm_connector_state *conn_state)
697917c2899SVille Syrjälä {
698a467a243SVille Syrjälä 	intel_audio_codec_enable(encoder, pipe_config, conn_state);
699917c2899SVille Syrjälä 	intel_edp_backlight_on(pipe_config, conn_state);
700917c2899SVille Syrjälä }
701917c2899SVille Syrjälä 
g4x_pre_enable_dp(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)702917c2899SVille Syrjälä static void g4x_pre_enable_dp(struct intel_atomic_state *state,
703917c2899SVille Syrjälä 			      struct intel_encoder *encoder,
704917c2899SVille Syrjälä 			      const struct intel_crtc_state *pipe_config,
705917c2899SVille Syrjälä 			      const struct drm_connector_state *conn_state)
706917c2899SVille Syrjälä {
707917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
708917c2899SVille Syrjälä 	enum port port = encoder->port;
709917c2899SVille Syrjälä 
710917c2899SVille Syrjälä 	intel_dp_prepare(encoder, pipe_config);
711917c2899SVille Syrjälä 
712917c2899SVille Syrjälä 	/* Only ilk+ has port A */
713917c2899SVille Syrjälä 	if (port == PORT_A)
714917c2899SVille Syrjälä 		ilk_edp_pll_on(intel_dp, pipe_config);
715917c2899SVille Syrjälä }
716917c2899SVille Syrjälä 
vlv_pre_enable_dp(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)717917c2899SVille Syrjälä static void vlv_pre_enable_dp(struct intel_atomic_state *state,
718917c2899SVille Syrjälä 			      struct intel_encoder *encoder,
719917c2899SVille Syrjälä 			      const struct intel_crtc_state *pipe_config,
720917c2899SVille Syrjälä 			      const struct drm_connector_state *conn_state)
721917c2899SVille Syrjälä {
722917c2899SVille Syrjälä 	vlv_phy_pre_encoder_enable(encoder, pipe_config);
723917c2899SVille Syrjälä 
724917c2899SVille Syrjälä 	intel_enable_dp(state, encoder, pipe_config, conn_state);
725917c2899SVille Syrjälä }
726917c2899SVille Syrjälä 
vlv_dp_pre_pll_enable(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)727917c2899SVille Syrjälä static void vlv_dp_pre_pll_enable(struct intel_atomic_state *state,
728917c2899SVille Syrjälä 				  struct intel_encoder *encoder,
729917c2899SVille Syrjälä 				  const struct intel_crtc_state *pipe_config,
730917c2899SVille Syrjälä 				  const struct drm_connector_state *conn_state)
731917c2899SVille Syrjälä {
732917c2899SVille Syrjälä 	intel_dp_prepare(encoder, pipe_config);
733917c2899SVille Syrjälä 
734917c2899SVille Syrjälä 	vlv_phy_pre_pll_enable(encoder, pipe_config);
735917c2899SVille Syrjälä }
736917c2899SVille Syrjälä 
chv_pre_enable_dp(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)737917c2899SVille Syrjälä static void chv_pre_enable_dp(struct intel_atomic_state *state,
738917c2899SVille Syrjälä 			      struct intel_encoder *encoder,
739917c2899SVille Syrjälä 			      const struct intel_crtc_state *pipe_config,
740917c2899SVille Syrjälä 			      const struct drm_connector_state *conn_state)
741917c2899SVille Syrjälä {
742917c2899SVille Syrjälä 	chv_phy_pre_encoder_enable(encoder, pipe_config);
743917c2899SVille Syrjälä 
744917c2899SVille Syrjälä 	intel_enable_dp(state, encoder, pipe_config, conn_state);
745917c2899SVille Syrjälä 
746917c2899SVille Syrjälä 	/* Second common lane will stay alive on its own now */
747917c2899SVille Syrjälä 	chv_phy_release_cl2_override(encoder);
748917c2899SVille Syrjälä }
749917c2899SVille Syrjälä 
chv_dp_pre_pll_enable(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)750917c2899SVille Syrjälä static void chv_dp_pre_pll_enable(struct intel_atomic_state *state,
751917c2899SVille Syrjälä 				  struct intel_encoder *encoder,
752917c2899SVille Syrjälä 				  const struct intel_crtc_state *pipe_config,
753917c2899SVille Syrjälä 				  const struct drm_connector_state *conn_state)
754917c2899SVille Syrjälä {
755917c2899SVille Syrjälä 	intel_dp_prepare(encoder, pipe_config);
756917c2899SVille Syrjälä 
757917c2899SVille Syrjälä 	chv_phy_pre_pll_enable(encoder, pipe_config);
758917c2899SVille Syrjälä }
759917c2899SVille Syrjälä 
chv_dp_post_pll_disable(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)760917c2899SVille Syrjälä static void chv_dp_post_pll_disable(struct intel_atomic_state *state,
761917c2899SVille Syrjälä 				    struct intel_encoder *encoder,
762917c2899SVille Syrjälä 				    const struct intel_crtc_state *old_crtc_state,
763917c2899SVille Syrjälä 				    const struct drm_connector_state *old_conn_state)
764917c2899SVille Syrjälä {
765917c2899SVille Syrjälä 	chv_phy_post_pll_disable(encoder, old_crtc_state);
766917c2899SVille Syrjälä }
767917c2899SVille Syrjälä 
intel_dp_voltage_max_2(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state)768917c2899SVille Syrjälä static u8 intel_dp_voltage_max_2(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_2;
772917c2899SVille Syrjälä }
773917c2899SVille Syrjälä 
intel_dp_voltage_max_3(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state)774917c2899SVille Syrjälä static u8 intel_dp_voltage_max_3(struct intel_dp *intel_dp,
775917c2899SVille Syrjälä 				 const struct intel_crtc_state *crtc_state)
776917c2899SVille Syrjälä {
777917c2899SVille Syrjälä 	return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
778917c2899SVille Syrjälä }
779917c2899SVille Syrjälä 
intel_dp_preemph_max_2(struct intel_dp * intel_dp)780917c2899SVille Syrjälä static u8 intel_dp_preemph_max_2(struct intel_dp *intel_dp)
781917c2899SVille Syrjälä {
782917c2899SVille Syrjälä 	return DP_TRAIN_PRE_EMPH_LEVEL_2;
783917c2899SVille Syrjälä }
784917c2899SVille Syrjälä 
intel_dp_preemph_max_3(struct intel_dp * intel_dp)785917c2899SVille Syrjälä static u8 intel_dp_preemph_max_3(struct intel_dp *intel_dp)
786917c2899SVille Syrjälä {
787917c2899SVille Syrjälä 	return DP_TRAIN_PRE_EMPH_LEVEL_3;
788917c2899SVille Syrjälä }
789917c2899SVille Syrjälä 
vlv_set_signal_levels(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)790e722ab8bSVille Syrjälä static void vlv_set_signal_levels(struct intel_encoder *encoder,
791917c2899SVille Syrjälä 				  const struct intel_crtc_state *crtc_state)
792917c2899SVille Syrjälä {
793e722ab8bSVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
794917c2899SVille Syrjälä 	unsigned long demph_reg_value, preemph_reg_value,
795917c2899SVille Syrjälä 		uniqtranscale_reg_value;
796917c2899SVille Syrjälä 	u8 train_set = intel_dp->train_set[0];
797917c2899SVille Syrjälä 
798917c2899SVille Syrjälä 	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
799917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_0:
800917c2899SVille Syrjälä 		preemph_reg_value = 0x0004000;
801917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
802917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
803917c2899SVille Syrjälä 			demph_reg_value = 0x2B405555;
804917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x552AB83A;
805917c2899SVille Syrjälä 			break;
806917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
807917c2899SVille Syrjälä 			demph_reg_value = 0x2B404040;
808917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x5548B83A;
809917c2899SVille Syrjälä 			break;
810917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
811917c2899SVille Syrjälä 			demph_reg_value = 0x2B245555;
812917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x5560B83A;
813917c2899SVille Syrjälä 			break;
814917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
815917c2899SVille Syrjälä 			demph_reg_value = 0x2B405555;
816917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x5598DA3A;
817917c2899SVille Syrjälä 			break;
818917c2899SVille Syrjälä 		default:
819917c2899SVille Syrjälä 			return;
820917c2899SVille Syrjälä 		}
821917c2899SVille Syrjälä 		break;
822917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_1:
823917c2899SVille Syrjälä 		preemph_reg_value = 0x0002000;
824917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
825917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
826917c2899SVille Syrjälä 			demph_reg_value = 0x2B404040;
827917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x5552B83A;
828917c2899SVille Syrjälä 			break;
829917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
830917c2899SVille Syrjälä 			demph_reg_value = 0x2B404848;
831917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x5580B83A;
832917c2899SVille Syrjälä 			break;
833917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
834917c2899SVille Syrjälä 			demph_reg_value = 0x2B404040;
835917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x55ADDA3A;
836917c2899SVille Syrjälä 			break;
837917c2899SVille Syrjälä 		default:
838917c2899SVille Syrjälä 			return;
839917c2899SVille Syrjälä 		}
840917c2899SVille Syrjälä 		break;
841917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_2:
842917c2899SVille Syrjälä 		preemph_reg_value = 0x0000000;
843917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
844917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
845917c2899SVille Syrjälä 			demph_reg_value = 0x2B305555;
846917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x5570B83A;
847917c2899SVille Syrjälä 			break;
848917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
849917c2899SVille Syrjälä 			demph_reg_value = 0x2B2B4040;
850917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x55ADDA3A;
851917c2899SVille Syrjälä 			break;
852917c2899SVille Syrjälä 		default:
853917c2899SVille Syrjälä 			return;
854917c2899SVille Syrjälä 		}
855917c2899SVille Syrjälä 		break;
856917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_3:
857917c2899SVille Syrjälä 		preemph_reg_value = 0x0006000;
858917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
859917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
860917c2899SVille Syrjälä 			demph_reg_value = 0x1B405555;
861917c2899SVille Syrjälä 			uniqtranscale_reg_value = 0x55ADDA3A;
862917c2899SVille Syrjälä 			break;
863917c2899SVille Syrjälä 		default:
864917c2899SVille Syrjälä 			return;
865917c2899SVille Syrjälä 		}
866917c2899SVille Syrjälä 		break;
867917c2899SVille Syrjälä 	default:
868917c2899SVille Syrjälä 		return;
869917c2899SVille Syrjälä 	}
870917c2899SVille Syrjälä 
871917c2899SVille Syrjälä 	vlv_set_phy_signal_level(encoder, crtc_state,
872917c2899SVille Syrjälä 				 demph_reg_value, preemph_reg_value,
873917c2899SVille Syrjälä 				 uniqtranscale_reg_value, 0);
874917c2899SVille Syrjälä }
875917c2899SVille Syrjälä 
chv_set_signal_levels(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)876e722ab8bSVille Syrjälä static void chv_set_signal_levels(struct intel_encoder *encoder,
877917c2899SVille Syrjälä 				  const struct intel_crtc_state *crtc_state)
878917c2899SVille Syrjälä {
879e722ab8bSVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
880917c2899SVille Syrjälä 	u32 deemph_reg_value, margin_reg_value;
881917c2899SVille Syrjälä 	bool uniq_trans_scale = false;
882917c2899SVille Syrjälä 	u8 train_set = intel_dp->train_set[0];
883917c2899SVille Syrjälä 
884917c2899SVille Syrjälä 	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
885917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_0:
886917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
887917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
888917c2899SVille Syrjälä 			deemph_reg_value = 128;
889917c2899SVille Syrjälä 			margin_reg_value = 52;
890917c2899SVille Syrjälä 			break;
891917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
892917c2899SVille Syrjälä 			deemph_reg_value = 128;
893917c2899SVille Syrjälä 			margin_reg_value = 77;
894917c2899SVille Syrjälä 			break;
895917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
896917c2899SVille Syrjälä 			deemph_reg_value = 128;
897917c2899SVille Syrjälä 			margin_reg_value = 102;
898917c2899SVille Syrjälä 			break;
899917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
900917c2899SVille Syrjälä 			deemph_reg_value = 128;
901917c2899SVille Syrjälä 			margin_reg_value = 154;
902917c2899SVille Syrjälä 			uniq_trans_scale = true;
903917c2899SVille Syrjälä 			break;
904917c2899SVille Syrjälä 		default:
905917c2899SVille Syrjälä 			return;
906917c2899SVille Syrjälä 		}
907917c2899SVille Syrjälä 		break;
908917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_1:
909917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
910917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
911917c2899SVille Syrjälä 			deemph_reg_value = 85;
912917c2899SVille Syrjälä 			margin_reg_value = 78;
913917c2899SVille Syrjälä 			break;
914917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
915917c2899SVille Syrjälä 			deemph_reg_value = 85;
916917c2899SVille Syrjälä 			margin_reg_value = 116;
917917c2899SVille Syrjälä 			break;
918917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
919917c2899SVille Syrjälä 			deemph_reg_value = 85;
920917c2899SVille Syrjälä 			margin_reg_value = 154;
921917c2899SVille Syrjälä 			break;
922917c2899SVille Syrjälä 		default:
923917c2899SVille Syrjälä 			return;
924917c2899SVille Syrjälä 		}
925917c2899SVille Syrjälä 		break;
926917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_2:
927917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
928917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
929917c2899SVille Syrjälä 			deemph_reg_value = 64;
930917c2899SVille Syrjälä 			margin_reg_value = 104;
931917c2899SVille Syrjälä 			break;
932917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
933917c2899SVille Syrjälä 			deemph_reg_value = 64;
934917c2899SVille Syrjälä 			margin_reg_value = 154;
935917c2899SVille Syrjälä 			break;
936917c2899SVille Syrjälä 		default:
937917c2899SVille Syrjälä 			return;
938917c2899SVille Syrjälä 		}
939917c2899SVille Syrjälä 		break;
940917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_3:
941917c2899SVille Syrjälä 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
942917c2899SVille Syrjälä 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
943917c2899SVille Syrjälä 			deemph_reg_value = 43;
944917c2899SVille Syrjälä 			margin_reg_value = 154;
945917c2899SVille Syrjälä 			break;
946917c2899SVille Syrjälä 		default:
947917c2899SVille Syrjälä 			return;
948917c2899SVille Syrjälä 		}
949917c2899SVille Syrjälä 		break;
950917c2899SVille Syrjälä 	default:
951917c2899SVille Syrjälä 		return;
952917c2899SVille Syrjälä 	}
953917c2899SVille Syrjälä 
954917c2899SVille Syrjälä 	chv_set_phy_signal_level(encoder, crtc_state,
955917c2899SVille Syrjälä 				 deemph_reg_value, margin_reg_value,
956917c2899SVille Syrjälä 				 uniq_trans_scale);
957917c2899SVille Syrjälä }
958917c2899SVille Syrjälä 
g4x_signal_levels(u8 train_set)959917c2899SVille Syrjälä static u32 g4x_signal_levels(u8 train_set)
960917c2899SVille Syrjälä {
961917c2899SVille Syrjälä 	u32 signal_levels = 0;
962917c2899SVille Syrjälä 
963917c2899SVille Syrjälä 	switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
964917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
965917c2899SVille Syrjälä 	default:
966917c2899SVille Syrjälä 		signal_levels |= DP_VOLTAGE_0_4;
967917c2899SVille Syrjälä 		break;
968917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
969917c2899SVille Syrjälä 		signal_levels |= DP_VOLTAGE_0_6;
970917c2899SVille Syrjälä 		break;
971917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
972917c2899SVille Syrjälä 		signal_levels |= DP_VOLTAGE_0_8;
973917c2899SVille Syrjälä 		break;
974917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
975917c2899SVille Syrjälä 		signal_levels |= DP_VOLTAGE_1_2;
976917c2899SVille Syrjälä 		break;
977917c2899SVille Syrjälä 	}
978917c2899SVille Syrjälä 	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
979917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_0:
980917c2899SVille Syrjälä 	default:
981917c2899SVille Syrjälä 		signal_levels |= DP_PRE_EMPHASIS_0;
982917c2899SVille Syrjälä 		break;
983917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_1:
984917c2899SVille Syrjälä 		signal_levels |= DP_PRE_EMPHASIS_3_5;
985917c2899SVille Syrjälä 		break;
986917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_2:
987917c2899SVille Syrjälä 		signal_levels |= DP_PRE_EMPHASIS_6;
988917c2899SVille Syrjälä 		break;
989917c2899SVille Syrjälä 	case DP_TRAIN_PRE_EMPH_LEVEL_3:
990917c2899SVille Syrjälä 		signal_levels |= DP_PRE_EMPHASIS_9_5;
991917c2899SVille Syrjälä 		break;
992917c2899SVille Syrjälä 	}
993917c2899SVille Syrjälä 	return signal_levels;
994917c2899SVille Syrjälä }
995917c2899SVille Syrjälä 
996917c2899SVille Syrjälä static void
g4x_set_signal_levels(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)997e722ab8bSVille Syrjälä g4x_set_signal_levels(struct intel_encoder *encoder,
998917c2899SVille Syrjälä 		      const struct intel_crtc_state *crtc_state)
999917c2899SVille Syrjälä {
1000e722ab8bSVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1001e722ab8bSVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1002917c2899SVille Syrjälä 	u8 train_set = intel_dp->train_set[0];
1003917c2899SVille Syrjälä 	u32 signal_levels;
1004917c2899SVille Syrjälä 
1005917c2899SVille Syrjälä 	signal_levels = g4x_signal_levels(train_set);
1006917c2899SVille Syrjälä 
1007917c2899SVille Syrjälä 	drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n",
1008917c2899SVille Syrjälä 		    signal_levels);
1009917c2899SVille Syrjälä 
1010917c2899SVille Syrjälä 	intel_dp->DP &= ~(DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK);
1011917c2899SVille Syrjälä 	intel_dp->DP |= signal_levels;
1012917c2899SVille Syrjälä 
1013917c2899SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
1014917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
1015917c2899SVille Syrjälä }
1016917c2899SVille Syrjälä 
1017917c2899SVille Syrjälä /* SNB CPU eDP voltage swing and pre-emphasis control */
snb_cpu_edp_signal_levels(u8 train_set)1018917c2899SVille Syrjälä static u32 snb_cpu_edp_signal_levels(u8 train_set)
1019917c2899SVille Syrjälä {
1020917c2899SVille Syrjälä 	u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
1021917c2899SVille Syrjälä 					DP_TRAIN_PRE_EMPHASIS_MASK);
1022917c2899SVille Syrjälä 
1023917c2899SVille Syrjälä 	switch (signal_levels) {
1024917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
1025917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
1026917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
1027917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
1028917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
1029917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
1030917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
1031917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_400_600MV_6DB_SNB_B;
1032917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
1033917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
1034917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
1035917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
1036917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
1037917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
1038917c2899SVille Syrjälä 	default:
1039917c2899SVille Syrjälä 		MISSING_CASE(signal_levels);
1040917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
1041917c2899SVille Syrjälä 	}
1042917c2899SVille Syrjälä }
1043917c2899SVille Syrjälä 
1044917c2899SVille Syrjälä static void
snb_cpu_edp_set_signal_levels(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)1045e722ab8bSVille Syrjälä snb_cpu_edp_set_signal_levels(struct intel_encoder *encoder,
1046917c2899SVille Syrjälä 			      const struct intel_crtc_state *crtc_state)
1047917c2899SVille Syrjälä {
1048e722ab8bSVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1049e722ab8bSVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1050917c2899SVille Syrjälä 	u8 train_set = intel_dp->train_set[0];
1051917c2899SVille Syrjälä 	u32 signal_levels;
1052917c2899SVille Syrjälä 
1053917c2899SVille Syrjälä 	signal_levels = snb_cpu_edp_signal_levels(train_set);
1054917c2899SVille Syrjälä 
1055917c2899SVille Syrjälä 	drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n",
1056917c2899SVille Syrjälä 		    signal_levels);
1057917c2899SVille Syrjälä 
1058917c2899SVille Syrjälä 	intel_dp->DP &= ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
1059917c2899SVille Syrjälä 	intel_dp->DP |= signal_levels;
1060917c2899SVille Syrjälä 
1061917c2899SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
1062917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
1063917c2899SVille Syrjälä }
1064917c2899SVille Syrjälä 
1065917c2899SVille Syrjälä /* IVB CPU eDP voltage swing and pre-emphasis control */
ivb_cpu_edp_signal_levels(u8 train_set)1066917c2899SVille Syrjälä static u32 ivb_cpu_edp_signal_levels(u8 train_set)
1067917c2899SVille Syrjälä {
1068917c2899SVille Syrjälä 	u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
1069917c2899SVille Syrjälä 					DP_TRAIN_PRE_EMPHASIS_MASK);
1070917c2899SVille Syrjälä 
1071917c2899SVille Syrjälä 	switch (signal_levels) {
1072917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
1073917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_400MV_0DB_IVB;
1074917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
1075917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_400MV_3_5DB_IVB;
1076917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
1077917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
1078917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_400MV_6DB_IVB;
1079917c2899SVille Syrjälä 
1080917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
1081917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_600MV_0DB_IVB;
1082917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
1083917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_600MV_3_5DB_IVB;
1084917c2899SVille Syrjälä 
1085917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
1086917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_800MV_0DB_IVB;
1087917c2899SVille Syrjälä 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
1088917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_800MV_3_5DB_IVB;
1089917c2899SVille Syrjälä 
1090917c2899SVille Syrjälä 	default:
1091917c2899SVille Syrjälä 		MISSING_CASE(signal_levels);
1092917c2899SVille Syrjälä 		return EDP_LINK_TRAIN_500MV_0DB_IVB;
1093917c2899SVille Syrjälä 	}
1094917c2899SVille Syrjälä }
1095917c2899SVille Syrjälä 
1096917c2899SVille Syrjälä static void
ivb_cpu_edp_set_signal_levels(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)1097e722ab8bSVille Syrjälä ivb_cpu_edp_set_signal_levels(struct intel_encoder *encoder,
1098917c2899SVille Syrjälä 			      const struct intel_crtc_state *crtc_state)
1099917c2899SVille Syrjälä {
1100e722ab8bSVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1101e722ab8bSVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1102917c2899SVille Syrjälä 	u8 train_set = intel_dp->train_set[0];
1103917c2899SVille Syrjälä 	u32 signal_levels;
1104917c2899SVille Syrjälä 
1105917c2899SVille Syrjälä 	signal_levels = ivb_cpu_edp_signal_levels(train_set);
1106917c2899SVille Syrjälä 
1107917c2899SVille Syrjälä 	drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n",
1108917c2899SVille Syrjälä 		    signal_levels);
1109917c2899SVille Syrjälä 
1110917c2899SVille Syrjälä 	intel_dp->DP &= ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
1111917c2899SVille Syrjälä 	intel_dp->DP |= signal_levels;
1112917c2899SVille Syrjälä 
1113917c2899SVille Syrjälä 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
1114917c2899SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
1115917c2899SVille Syrjälä }
1116917c2899SVille Syrjälä 
1117917c2899SVille Syrjälä /*
1118917c2899SVille Syrjälä  * If display is now connected check links status,
1119917c2899SVille Syrjälä  * there has been known issues of link loss triggering
1120917c2899SVille Syrjälä  * long pulse.
1121917c2899SVille Syrjälä  *
1122917c2899SVille Syrjälä  * Some sinks (eg. ASUS PB287Q) seem to perform some
1123917c2899SVille Syrjälä  * weird HPD ping pong during modesets. So we can apparently
1124917c2899SVille Syrjälä  * end up with HPD going low during a modeset, and then
1125917c2899SVille Syrjälä  * going back up soon after. And once that happens we must
1126917c2899SVille Syrjälä  * retrain the link to get a picture. That's in case no
1127917c2899SVille Syrjälä  * userspace component reacted to intermittent HPD dip.
1128917c2899SVille Syrjälä  */
1129917c2899SVille Syrjälä static enum intel_hotplug_state
intel_dp_hotplug(struct intel_encoder * encoder,struct intel_connector * connector)1130917c2899SVille Syrjälä intel_dp_hotplug(struct intel_encoder *encoder,
1131917c2899SVille Syrjälä 		 struct intel_connector *connector)
1132917c2899SVille Syrjälä {
1133917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1134917c2899SVille Syrjälä 	struct drm_modeset_acquire_ctx ctx;
1135917c2899SVille Syrjälä 	enum intel_hotplug_state state;
1136917c2899SVille Syrjälä 	int ret;
1137917c2899SVille Syrjälä 
1138917c2899SVille Syrjälä 	if (intel_dp->compliance.test_active &&
1139917c2899SVille Syrjälä 	    intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) {
1140917c2899SVille Syrjälä 		intel_dp_phy_test(encoder);
1141917c2899SVille Syrjälä 		/* just do the PHY test and nothing else */
1142917c2899SVille Syrjälä 		return INTEL_HOTPLUG_UNCHANGED;
1143917c2899SVille Syrjälä 	}
1144917c2899SVille Syrjälä 
1145917c2899SVille Syrjälä 	state = intel_encoder_hotplug(encoder, connector);
1146917c2899SVille Syrjälä 
1147917c2899SVille Syrjälä 	drm_modeset_acquire_init(&ctx, 0);
1148917c2899SVille Syrjälä 
1149917c2899SVille Syrjälä 	for (;;) {
1150917c2899SVille Syrjälä 		ret = intel_dp_retrain_link(encoder, &ctx);
1151917c2899SVille Syrjälä 
1152917c2899SVille Syrjälä 		if (ret == -EDEADLK) {
1153917c2899SVille Syrjälä 			drm_modeset_backoff(&ctx);
1154917c2899SVille Syrjälä 			continue;
1155917c2899SVille Syrjälä 		}
1156917c2899SVille Syrjälä 
1157917c2899SVille Syrjälä 		break;
1158917c2899SVille Syrjälä 	}
1159917c2899SVille Syrjälä 
1160917c2899SVille Syrjälä 	drm_modeset_drop_locks(&ctx);
1161917c2899SVille Syrjälä 	drm_modeset_acquire_fini(&ctx);
1162917c2899SVille Syrjälä 	drm_WARN(encoder->base.dev, ret,
1163917c2899SVille Syrjälä 		 "Acquiring modeset locks failed with %i\n", ret);
1164917c2899SVille Syrjälä 
1165917c2899SVille Syrjälä 	/*
1166917c2899SVille Syrjälä 	 * Keeping it consistent with intel_ddi_hotplug() and
1167917c2899SVille Syrjälä 	 * intel_hdmi_hotplug().
1168917c2899SVille Syrjälä 	 */
1169917c2899SVille Syrjälä 	if (state == INTEL_HOTPLUG_UNCHANGED && !connector->hotplug_retries)
1170917c2899SVille Syrjälä 		state = INTEL_HOTPLUG_RETRY;
1171917c2899SVille Syrjälä 
1172917c2899SVille Syrjälä 	return state;
1173917c2899SVille Syrjälä }
1174917c2899SVille Syrjälä 
ibx_digital_port_connected(struct intel_encoder * encoder)1175917c2899SVille Syrjälä static bool ibx_digital_port_connected(struct intel_encoder *encoder)
1176917c2899SVille Syrjälä {
1177917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
11785a4dd6f0SJani Nikula 	u32 bit = dev_priv->display.hotplug.pch_hpd[encoder->hpd_pin];
1179917c2899SVille Syrjälä 
1180917c2899SVille Syrjälä 	return intel_de_read(dev_priv, SDEISR) & bit;
1181917c2899SVille Syrjälä }
1182917c2899SVille Syrjälä 
g4x_digital_port_connected(struct intel_encoder * encoder)1183917c2899SVille Syrjälä static bool g4x_digital_port_connected(struct intel_encoder *encoder)
1184917c2899SVille Syrjälä {
1185917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1186917c2899SVille Syrjälä 	u32 bit;
1187917c2899SVille Syrjälä 
1188917c2899SVille Syrjälä 	switch (encoder->hpd_pin) {
1189917c2899SVille Syrjälä 	case HPD_PORT_B:
1190917c2899SVille Syrjälä 		bit = PORTB_HOTPLUG_LIVE_STATUS_G4X;
1191917c2899SVille Syrjälä 		break;
1192917c2899SVille Syrjälä 	case HPD_PORT_C:
1193917c2899SVille Syrjälä 		bit = PORTC_HOTPLUG_LIVE_STATUS_G4X;
1194917c2899SVille Syrjälä 		break;
1195917c2899SVille Syrjälä 	case HPD_PORT_D:
1196917c2899SVille Syrjälä 		bit = PORTD_HOTPLUG_LIVE_STATUS_G4X;
1197917c2899SVille Syrjälä 		break;
1198917c2899SVille Syrjälä 	default:
1199917c2899SVille Syrjälä 		MISSING_CASE(encoder->hpd_pin);
1200917c2899SVille Syrjälä 		return false;
1201917c2899SVille Syrjälä 	}
1202917c2899SVille Syrjälä 
1203917c2899SVille Syrjälä 	return intel_de_read(dev_priv, PORT_HOTPLUG_STAT) & bit;
1204917c2899SVille Syrjälä }
1205917c2899SVille Syrjälä 
ilk_digital_port_connected(struct intel_encoder * encoder)1206917c2899SVille Syrjälä static bool ilk_digital_port_connected(struct intel_encoder *encoder)
1207917c2899SVille Syrjälä {
1208917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
12095a4dd6f0SJani Nikula 	u32 bit = dev_priv->display.hotplug.hpd[encoder->hpd_pin];
1210917c2899SVille Syrjälä 
1211917c2899SVille Syrjälä 	return intel_de_read(dev_priv, DEISR) & bit;
1212917c2899SVille Syrjälä }
1213917c2899SVille Syrjälä 
intel_dp_encoder_destroy(struct drm_encoder * encoder)1214917c2899SVille Syrjälä static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
1215917c2899SVille Syrjälä {
1216917c2899SVille Syrjälä 	intel_dp_encoder_flush_work(encoder);
1217917c2899SVille Syrjälä 
1218917c2899SVille Syrjälä 	drm_encoder_cleanup(encoder);
1219917c2899SVille Syrjälä 	kfree(enc_to_dig_port(to_intel_encoder(encoder)));
1220917c2899SVille Syrjälä }
1221917c2899SVille Syrjälä 
vlv_active_pipe(struct intel_dp * intel_dp)1222917c2899SVille Syrjälä enum pipe vlv_active_pipe(struct intel_dp *intel_dp)
1223917c2899SVille Syrjälä {
1224917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
1225917c2899SVille Syrjälä 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
1226917c2899SVille Syrjälä 	enum pipe pipe;
1227917c2899SVille Syrjälä 
1228053ffdd1SVille Syrjälä 	if (g4x_dp_port_enabled(dev_priv, intel_dp->output_reg,
1229917c2899SVille Syrjälä 				encoder->port, &pipe))
1230917c2899SVille Syrjälä 		return pipe;
1231917c2899SVille Syrjälä 
1232917c2899SVille Syrjälä 	return INVALID_PIPE;
1233917c2899SVille Syrjälä }
1234917c2899SVille Syrjälä 
intel_dp_encoder_reset(struct drm_encoder * encoder)1235917c2899SVille Syrjälä static void intel_dp_encoder_reset(struct drm_encoder *encoder)
1236917c2899SVille Syrjälä {
1237917c2899SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
1238917c2899SVille Syrjälä 	struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(encoder));
1239917c2899SVille Syrjälä 
1240917c2899SVille Syrjälä 	intel_dp->DP = intel_de_read(dev_priv, intel_dp->output_reg);
1241917c2899SVille Syrjälä 
1242917c2899SVille Syrjälä 	intel_dp->reset_link_params = true;
1243917c2899SVille Syrjälä 
1244917c2899SVille Syrjälä 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
1245917c2899SVille Syrjälä 		intel_wakeref_t wakeref;
1246917c2899SVille Syrjälä 
1247917c2899SVille Syrjälä 		with_intel_pps_lock(intel_dp, wakeref)
1248917c2899SVille Syrjälä 			intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp);
1249917c2899SVille Syrjälä 	}
1250917c2899SVille Syrjälä 
1251917c2899SVille Syrjälä 	intel_pps_encoder_reset(intel_dp);
1252917c2899SVille Syrjälä }
1253917c2899SVille Syrjälä 
1254917c2899SVille Syrjälä static const struct drm_encoder_funcs intel_dp_enc_funcs = {
1255917c2899SVille Syrjälä 	.reset = intel_dp_encoder_reset,
1256917c2899SVille Syrjälä 	.destroy = intel_dp_encoder_destroy,
1257917c2899SVille Syrjälä };
1258917c2899SVille Syrjälä 
g4x_dp_init(struct drm_i915_private * dev_priv,i915_reg_t output_reg,enum port port)1259053ffdd1SVille Syrjälä bool g4x_dp_init(struct drm_i915_private *dev_priv,
1260053ffdd1SVille Syrjälä 		 i915_reg_t output_reg, enum port port)
1261917c2899SVille Syrjälä {
12621b108bc7SVille Syrjälä 	const struct intel_bios_encoder_data *devdata;
1263917c2899SVille Syrjälä 	struct intel_digital_port *dig_port;
1264917c2899SVille Syrjälä 	struct intel_encoder *intel_encoder;
1265917c2899SVille Syrjälä 	struct drm_encoder *encoder;
1266917c2899SVille Syrjälä 	struct intel_connector *intel_connector;
1267917c2899SVille Syrjälä 
1268679df6f1SVille Syrjälä 	if (!assert_port_valid(dev_priv, port))
1269679df6f1SVille Syrjälä 		return false;
1270679df6f1SVille Syrjälä 
12711b108bc7SVille Syrjälä 	devdata = intel_bios_encoder_data_lookup(dev_priv, port);
12721b108bc7SVille Syrjälä 
12731b108bc7SVille Syrjälä 	/* FIXME bail? */
12741b108bc7SVille Syrjälä 	if (!devdata)
12751b108bc7SVille Syrjälä 		drm_dbg_kms(&dev_priv->drm, "No VBT child device for DP-%c\n",
12761b108bc7SVille Syrjälä 			    port_name(port));
12771b108bc7SVille Syrjälä 
1278917c2899SVille Syrjälä 	dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL);
1279917c2899SVille Syrjälä 	if (!dig_port)
1280917c2899SVille Syrjälä 		return false;
1281917c2899SVille Syrjälä 
12824cca9676SVille Syrjälä 	dig_port->aux_ch = AUX_CH_NONE;
12834cca9676SVille Syrjälä 
1284917c2899SVille Syrjälä 	intel_connector = intel_connector_alloc();
1285917c2899SVille Syrjälä 	if (!intel_connector)
1286917c2899SVille Syrjälä 		goto err_connector_alloc;
1287917c2899SVille Syrjälä 
1288917c2899SVille Syrjälä 	intel_encoder = &dig_port->base;
1289917c2899SVille Syrjälä 	encoder = &intel_encoder->base;
1290917c2899SVille Syrjälä 
12911b108bc7SVille Syrjälä 	intel_encoder->devdata = devdata;
12921b108bc7SVille Syrjälä 
1293917c2899SVille Syrjälä 	mutex_init(&dig_port->hdcp_mutex);
1294917c2899SVille Syrjälä 
1295917c2899SVille Syrjälä 	if (drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
1296917c2899SVille Syrjälä 			     &intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS,
1297917c2899SVille Syrjälä 			     "DP %c", port_name(port)))
1298917c2899SVille Syrjälä 		goto err_encoder_init;
1299917c2899SVille Syrjälä 
1300917c2899SVille Syrjälä 	intel_encoder->hotplug = intel_dp_hotplug;
1301917c2899SVille Syrjälä 	intel_encoder->compute_config = intel_dp_compute_config;
1302917c2899SVille Syrjälä 	intel_encoder->get_hw_state = intel_dp_get_hw_state;
1303917c2899SVille Syrjälä 	intel_encoder->get_config = intel_dp_get_config;
1304917c2899SVille Syrjälä 	intel_encoder->sync_state = intel_dp_sync_state;
1305917c2899SVille Syrjälä 	intel_encoder->initial_fastset_check = intel_dp_initial_fastset_check;
1306c0a52f8bSJani Nikula 	intel_encoder->update_pipe = intel_backlight_update;
1307917c2899SVille Syrjälä 	intel_encoder->suspend = intel_dp_encoder_suspend;
1308917c2899SVille Syrjälä 	intel_encoder->shutdown = intel_dp_encoder_shutdown;
1309917c2899SVille Syrjälä 	if (IS_CHERRYVIEW(dev_priv)) {
1310917c2899SVille Syrjälä 		intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable;
1311917c2899SVille Syrjälä 		intel_encoder->pre_enable = chv_pre_enable_dp;
1312917c2899SVille Syrjälä 		intel_encoder->enable = vlv_enable_dp;
1313917c2899SVille Syrjälä 		intel_encoder->disable = vlv_disable_dp;
1314917c2899SVille Syrjälä 		intel_encoder->post_disable = chv_post_disable_dp;
1315917c2899SVille Syrjälä 		intel_encoder->post_pll_disable = chv_dp_post_pll_disable;
1316917c2899SVille Syrjälä 	} else if (IS_VALLEYVIEW(dev_priv)) {
1317917c2899SVille Syrjälä 		intel_encoder->pre_pll_enable = vlv_dp_pre_pll_enable;
1318917c2899SVille Syrjälä 		intel_encoder->pre_enable = vlv_pre_enable_dp;
1319917c2899SVille Syrjälä 		intel_encoder->enable = vlv_enable_dp;
1320917c2899SVille Syrjälä 		intel_encoder->disable = vlv_disable_dp;
1321917c2899SVille Syrjälä 		intel_encoder->post_disable = vlv_post_disable_dp;
1322917c2899SVille Syrjälä 	} else {
1323917c2899SVille Syrjälä 		intel_encoder->pre_enable = g4x_pre_enable_dp;
1324917c2899SVille Syrjälä 		intel_encoder->enable = g4x_enable_dp;
1325917c2899SVille Syrjälä 		intel_encoder->disable = g4x_disable_dp;
1326917c2899SVille Syrjälä 		intel_encoder->post_disable = g4x_post_disable_dp;
1327917c2899SVille Syrjälä 	}
1328917c2899SVille Syrjälä 
1329917c2899SVille Syrjälä 	if ((IS_IVYBRIDGE(dev_priv) && port == PORT_A) ||
1330917c2899SVille Syrjälä 	    (HAS_PCH_CPT(dev_priv) && port != PORT_A))
1331917c2899SVille Syrjälä 		dig_port->dp.set_link_train = cpt_set_link_train;
1332917c2899SVille Syrjälä 	else
1333917c2899SVille Syrjälä 		dig_port->dp.set_link_train = g4x_set_link_train;
1334917c2899SVille Syrjälä 
1335917c2899SVille Syrjälä 	if (IS_CHERRYVIEW(dev_priv))
1336e722ab8bSVille Syrjälä 		intel_encoder->set_signal_levels = chv_set_signal_levels;
1337917c2899SVille Syrjälä 	else if (IS_VALLEYVIEW(dev_priv))
1338e722ab8bSVille Syrjälä 		intel_encoder->set_signal_levels = vlv_set_signal_levels;
1339917c2899SVille Syrjälä 	else if (IS_IVYBRIDGE(dev_priv) && port == PORT_A)
1340e722ab8bSVille Syrjälä 		intel_encoder->set_signal_levels = ivb_cpu_edp_set_signal_levels;
1341d47d29a6SMatt Roper 	else if (IS_SANDYBRIDGE(dev_priv) && port == PORT_A)
1342e722ab8bSVille Syrjälä 		intel_encoder->set_signal_levels = snb_cpu_edp_set_signal_levels;
1343917c2899SVille Syrjälä 	else
1344e722ab8bSVille Syrjälä 		intel_encoder->set_signal_levels = g4x_set_signal_levels;
1345917c2899SVille Syrjälä 
1346917c2899SVille Syrjälä 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
1347917c2899SVille Syrjälä 	    (HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) {
1348917c2899SVille Syrjälä 		dig_port->dp.preemph_max = intel_dp_preemph_max_3;
1349917c2899SVille Syrjälä 		dig_port->dp.voltage_max = intel_dp_voltage_max_3;
1350917c2899SVille Syrjälä 	} else {
1351917c2899SVille Syrjälä 		dig_port->dp.preemph_max = intel_dp_preemph_max_2;
1352917c2899SVille Syrjälä 		dig_port->dp.voltage_max = intel_dp_voltage_max_2;
1353917c2899SVille Syrjälä 	}
1354917c2899SVille Syrjälä 
1355917c2899SVille Syrjälä 	dig_port->dp.output_reg = output_reg;
1356917c2899SVille Syrjälä 	dig_port->max_lanes = 4;
1357917c2899SVille Syrjälä 
1358917c2899SVille Syrjälä 	intel_encoder->type = INTEL_OUTPUT_DP;
1359979e1b32SImre Deak 	intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port);
1360917c2899SVille Syrjälä 	if (IS_CHERRYVIEW(dev_priv)) {
1361917c2899SVille Syrjälä 		if (port == PORT_D)
1362917c2899SVille Syrjälä 			intel_encoder->pipe_mask = BIT(PIPE_C);
1363917c2899SVille Syrjälä 		else
1364917c2899SVille Syrjälä 			intel_encoder->pipe_mask = BIT(PIPE_A) | BIT(PIPE_B);
1365917c2899SVille Syrjälä 	} else {
1366917c2899SVille Syrjälä 		intel_encoder->pipe_mask = ~0;
1367917c2899SVille Syrjälä 	}
1368917c2899SVille Syrjälä 	intel_encoder->cloneable = 0;
1369917c2899SVille Syrjälä 	intel_encoder->port = port;
1370917c2899SVille Syrjälä 	intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
1371917c2899SVille Syrjälä 
1372917c2899SVille Syrjälä 	dig_port->hpd_pulse = intel_dp_hpd_pulse;
1373917c2899SVille Syrjälä 
1374917c2899SVille Syrjälä 	if (HAS_GMCH(dev_priv)) {
1375917c2899SVille Syrjälä 		dig_port->connected = g4x_digital_port_connected;
1376917c2899SVille Syrjälä 	} else {
1377917c2899SVille Syrjälä 		if (port == PORT_A)
1378917c2899SVille Syrjälä 			dig_port->connected = ilk_digital_port_connected;
1379917c2899SVille Syrjälä 		else
1380917c2899SVille Syrjälä 			dig_port->connected = ibx_digital_port_connected;
1381917c2899SVille Syrjälä 	}
1382917c2899SVille Syrjälä 
1383917c2899SVille Syrjälä 	if (port != PORT_A)
1384917c2899SVille Syrjälä 		intel_infoframe_init(dig_port);
1385917c2899SVille Syrjälä 
1386bb45217fSVille Syrjälä 	dig_port->aux_ch = intel_dp_aux_ch(intel_encoder);
1387b8a13e87SVille Syrjälä 	if (dig_port->aux_ch == AUX_CH_NONE)
1388b8a13e87SVille Syrjälä 		goto err_init_connector;
1389b8a13e87SVille Syrjälä 
1390917c2899SVille Syrjälä 	if (!intel_dp_init_connector(dig_port, intel_connector))
1391917c2899SVille Syrjälä 		goto err_init_connector;
1392917c2899SVille Syrjälä 
1393917c2899SVille Syrjälä 	return true;
1394917c2899SVille Syrjälä 
1395917c2899SVille Syrjälä err_init_connector:
1396917c2899SVille Syrjälä 	drm_encoder_cleanup(encoder);
1397917c2899SVille Syrjälä err_encoder_init:
1398917c2899SVille Syrjälä 	kfree(intel_connector);
1399917c2899SVille Syrjälä err_connector_alloc:
1400917c2899SVille Syrjälä 	kfree(dig_port);
1401917c2899SVille Syrjälä 	return false;
1402917c2899SVille Syrjälä }
1403