xref: /openbsd-src/sys/dev/pci/drm/i915/display/g4x_dp.c (revision f005ef32267c16bdb134f0e9fa4477dbe07c263a)
15ca02815Sjsg // SPDX-License-Identifier: MIT
25ca02815Sjsg /*
35ca02815Sjsg  * Copyright © 2020 Intel Corporation
45ca02815Sjsg  *
55ca02815Sjsg  * DisplayPort support for G4x,ILK,SNB,IVB,VLV,CHV (HSW+ handled by the DDI code).
65ca02815Sjsg  */
75ca02815Sjsg 
81bb76ff1Sjsg #include <linux/string_helpers.h>
91bb76ff1Sjsg 
105ca02815Sjsg #include "g4x_dp.h"
11*f005ef32Sjsg #include "i915_reg.h"
125ca02815Sjsg #include "intel_audio.h"
13b35a56d4Sjsg #include "intel_backlight.h"
145ca02815Sjsg #include "intel_connector.h"
151bb76ff1Sjsg #include "intel_crtc.h"
165ca02815Sjsg #include "intel_de.h"
171bb76ff1Sjsg #include "intel_display_power.h"
185ca02815Sjsg #include "intel_display_types.h"
195ca02815Sjsg #include "intel_dp.h"
20*f005ef32Sjsg #include "intel_dp_aux.h"
215ca02815Sjsg #include "intel_dp_link_training.h"
225ca02815Sjsg #include "intel_dpio_phy.h"
235ca02815Sjsg #include "intel_fifo_underrun.h"
245ca02815Sjsg #include "intel_hdmi.h"
255ca02815Sjsg #include "intel_hotplug.h"
261bb76ff1Sjsg #include "intel_pch_display.h"
275ca02815Sjsg #include "intel_pps.h"
281bb76ff1Sjsg #include "vlv_sideband.h"
295ca02815Sjsg 
301bb76ff1Sjsg static const struct dpll g4x_dpll[] = {
311bb76ff1Sjsg 	{ .dot = 162000, .p1 = 2, .p2 = 10, .n = 2, .m1 = 23, .m2 = 8, },
321bb76ff1Sjsg 	{ .dot = 270000, .p1 = 1, .p2 = 10, .n = 1, .m1 = 14, .m2 = 2, },
335ca02815Sjsg };
345ca02815Sjsg 
351bb76ff1Sjsg static const struct dpll pch_dpll[] = {
361bb76ff1Sjsg 	{ .dot = 162000, .p1 = 2, .p2 = 10, .n = 1, .m1 = 12, .m2 = 9, },
371bb76ff1Sjsg 	{ .dot = 270000, .p1 = 1, .p2 = 10, .n = 2, .m1 = 14, .m2 = 8, },
385ca02815Sjsg };
395ca02815Sjsg 
401bb76ff1Sjsg static const struct dpll vlv_dpll[] = {
411bb76ff1Sjsg 	{ .dot = 162000, .p1 = 3, .p2 = 2, .n = 5, .m1 = 3, .m2 = 81, },
421bb76ff1Sjsg 	{ .dot = 270000, .p1 = 2, .p2 = 2, .n = 1, .m1 = 2, .m2 = 27, },
435ca02815Sjsg };
445ca02815Sjsg 
451bb76ff1Sjsg static const struct dpll chv_dpll[] = {
461bb76ff1Sjsg 	/* m2 is .22 binary fixed point  */
471bb76ff1Sjsg 	{ .dot = 162000, .p1 = 4, .p2 = 2, .n = 1, .m1 = 2, .m2 = 0x819999a /* 32.4 */ },
481bb76ff1Sjsg 	{ .dot = 270000, .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 /* 27.0 */ },
495ca02815Sjsg };
505ca02815Sjsg 
vlv_get_dpll(struct drm_i915_private * i915)515ca02815Sjsg const struct dpll *vlv_get_dpll(struct drm_i915_private *i915)
525ca02815Sjsg {
531bb76ff1Sjsg 	return IS_CHERRYVIEW(i915) ? &chv_dpll[0] : &vlv_dpll[0];
545ca02815Sjsg }
555ca02815Sjsg 
g4x_dp_set_clock(struct intel_encoder * encoder,struct intel_crtc_state * pipe_config)565ca02815Sjsg void g4x_dp_set_clock(struct intel_encoder *encoder,
575ca02815Sjsg 		      struct intel_crtc_state *pipe_config)
585ca02815Sjsg {
595ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
601bb76ff1Sjsg 	const struct dpll *divisor = NULL;
615ca02815Sjsg 	int i, count = 0;
625ca02815Sjsg 
635ca02815Sjsg 	if (IS_G4X(dev_priv)) {
645ca02815Sjsg 		divisor = g4x_dpll;
655ca02815Sjsg 		count = ARRAY_SIZE(g4x_dpll);
665ca02815Sjsg 	} else if (HAS_PCH_SPLIT(dev_priv)) {
675ca02815Sjsg 		divisor = pch_dpll;
685ca02815Sjsg 		count = ARRAY_SIZE(pch_dpll);
695ca02815Sjsg 	} else if (IS_CHERRYVIEW(dev_priv)) {
705ca02815Sjsg 		divisor = chv_dpll;
715ca02815Sjsg 		count = ARRAY_SIZE(chv_dpll);
725ca02815Sjsg 	} else if (IS_VALLEYVIEW(dev_priv)) {
735ca02815Sjsg 		divisor = vlv_dpll;
745ca02815Sjsg 		count = ARRAY_SIZE(vlv_dpll);
755ca02815Sjsg 	}
765ca02815Sjsg 
775ca02815Sjsg 	if (divisor && count) {
785ca02815Sjsg 		for (i = 0; i < count; i++) {
791bb76ff1Sjsg 			if (pipe_config->port_clock == divisor[i].dot) {
801bb76ff1Sjsg 				pipe_config->dpll = divisor[i];
815ca02815Sjsg 				pipe_config->clock_set = true;
825ca02815Sjsg 				break;
835ca02815Sjsg 			}
845ca02815Sjsg 		}
855ca02815Sjsg 	}
865ca02815Sjsg }
875ca02815Sjsg 
intel_dp_prepare(struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config)885ca02815Sjsg static void intel_dp_prepare(struct intel_encoder *encoder,
895ca02815Sjsg 			     const struct intel_crtc_state *pipe_config)
905ca02815Sjsg {
915ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
925ca02815Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
935ca02815Sjsg 	enum port port = encoder->port;
945ca02815Sjsg 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
955ca02815Sjsg 	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
965ca02815Sjsg 
975ca02815Sjsg 	intel_dp_set_link_params(intel_dp,
985ca02815Sjsg 				 pipe_config->port_clock,
995ca02815Sjsg 				 pipe_config->lane_count);
1005ca02815Sjsg 
1015ca02815Sjsg 	/*
1025ca02815Sjsg 	 * There are four kinds of DP registers:
1035ca02815Sjsg 	 * IBX PCH
1045ca02815Sjsg 	 * SNB CPU
1055ca02815Sjsg 	 * IVB CPU
1065ca02815Sjsg 	 * CPT PCH
1075ca02815Sjsg 	 *
1085ca02815Sjsg 	 * IBX PCH and CPU are the same for almost everything,
1095ca02815Sjsg 	 * except that the CPU DP PLL is configured in this
1105ca02815Sjsg 	 * register
1115ca02815Sjsg 	 *
1125ca02815Sjsg 	 * CPT PCH is quite different, having many bits moved
1135ca02815Sjsg 	 * to the TRANS_DP_CTL register instead. That
1145ca02815Sjsg 	 * configuration happens (oddly) in ilk_pch_enable
1155ca02815Sjsg 	 */
1165ca02815Sjsg 
1175ca02815Sjsg 	/* Preserve the BIOS-computed detected bit. This is
1185ca02815Sjsg 	 * supposed to be read-only.
1195ca02815Sjsg 	 */
1205ca02815Sjsg 	intel_dp->DP = intel_de_read(dev_priv, intel_dp->output_reg) & DP_DETECTED;
1215ca02815Sjsg 
1225ca02815Sjsg 	/* Handle DP bits in common between all three register formats */
1235ca02815Sjsg 	intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
1245ca02815Sjsg 	intel_dp->DP |= DP_PORT_WIDTH(pipe_config->lane_count);
1255ca02815Sjsg 
1265ca02815Sjsg 	/* Split out the IBX/CPU vs CPT settings */
1275ca02815Sjsg 
1285ca02815Sjsg 	if (IS_IVYBRIDGE(dev_priv) && port == PORT_A) {
1295ca02815Sjsg 		if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
1305ca02815Sjsg 			intel_dp->DP |= DP_SYNC_HS_HIGH;
1315ca02815Sjsg 		if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
1325ca02815Sjsg 			intel_dp->DP |= DP_SYNC_VS_HIGH;
1335ca02815Sjsg 		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
1345ca02815Sjsg 
1355ca02815Sjsg 		if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
1365ca02815Sjsg 			intel_dp->DP |= DP_ENHANCED_FRAMING;
1375ca02815Sjsg 
1385ca02815Sjsg 		intel_dp->DP |= DP_PIPE_SEL_IVB(crtc->pipe);
1395ca02815Sjsg 	} else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) {
1405ca02815Sjsg 		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
1415ca02815Sjsg 
142*f005ef32Sjsg 		intel_de_rmw(dev_priv, TRANS_DP_CTL(crtc->pipe),
143*f005ef32Sjsg 			     TRANS_DP_ENH_FRAMING,
144*f005ef32Sjsg 			     pipe_config->enhanced_framing ?
145*f005ef32Sjsg 			     TRANS_DP_ENH_FRAMING : 0);
1465ca02815Sjsg 	} else {
1475ca02815Sjsg 		if (IS_G4X(dev_priv) && pipe_config->limited_color_range)
1485ca02815Sjsg 			intel_dp->DP |= DP_COLOR_RANGE_16_235;
1495ca02815Sjsg 
1505ca02815Sjsg 		if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
1515ca02815Sjsg 			intel_dp->DP |= DP_SYNC_HS_HIGH;
1525ca02815Sjsg 		if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
1535ca02815Sjsg 			intel_dp->DP |= DP_SYNC_VS_HIGH;
1545ca02815Sjsg 		intel_dp->DP |= DP_LINK_TRAIN_OFF;
1555ca02815Sjsg 
156*f005ef32Sjsg 		if (pipe_config->enhanced_framing)
1575ca02815Sjsg 			intel_dp->DP |= DP_ENHANCED_FRAMING;
1585ca02815Sjsg 
1595ca02815Sjsg 		if (IS_CHERRYVIEW(dev_priv))
1605ca02815Sjsg 			intel_dp->DP |= DP_PIPE_SEL_CHV(crtc->pipe);
1615ca02815Sjsg 		else
1625ca02815Sjsg 			intel_dp->DP |= DP_PIPE_SEL(crtc->pipe);
1635ca02815Sjsg 	}
1645ca02815Sjsg }
1655ca02815Sjsg 
assert_dp_port(struct intel_dp * intel_dp,bool state)1665ca02815Sjsg static void assert_dp_port(struct intel_dp *intel_dp, bool state)
1675ca02815Sjsg {
1685ca02815Sjsg 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
1695ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
1705ca02815Sjsg 	bool cur_state = intel_de_read(dev_priv, intel_dp->output_reg) & DP_PORT_EN;
1715ca02815Sjsg 
172*f005ef32Sjsg 	I915_STATE_WARN(dev_priv, cur_state != state,
1735ca02815Sjsg 			"[ENCODER:%d:%s] state assertion failure (expected %s, current %s)\n",
1745ca02815Sjsg 			dig_port->base.base.base.id, dig_port->base.base.name,
1751bb76ff1Sjsg 			str_on_off(state), str_on_off(cur_state));
1765ca02815Sjsg }
1775ca02815Sjsg #define assert_dp_port_disabled(d) assert_dp_port((d), false)
1785ca02815Sjsg 
assert_edp_pll(struct drm_i915_private * dev_priv,bool state)1795ca02815Sjsg static void assert_edp_pll(struct drm_i915_private *dev_priv, bool state)
1805ca02815Sjsg {
1815ca02815Sjsg 	bool cur_state = intel_de_read(dev_priv, DP_A) & DP_PLL_ENABLE;
1825ca02815Sjsg 
183*f005ef32Sjsg 	I915_STATE_WARN(dev_priv, cur_state != state,
1845ca02815Sjsg 			"eDP PLL state assertion failure (expected %s, current %s)\n",
1851bb76ff1Sjsg 			str_on_off(state), str_on_off(cur_state));
1865ca02815Sjsg }
1875ca02815Sjsg #define assert_edp_pll_enabled(d) assert_edp_pll((d), true)
1885ca02815Sjsg #define assert_edp_pll_disabled(d) assert_edp_pll((d), false)
1895ca02815Sjsg 
ilk_edp_pll_on(struct intel_dp * intel_dp,const struct intel_crtc_state * pipe_config)1905ca02815Sjsg static void ilk_edp_pll_on(struct intel_dp *intel_dp,
1915ca02815Sjsg 			   const struct intel_crtc_state *pipe_config)
1925ca02815Sjsg {
1935ca02815Sjsg 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
1945ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1955ca02815Sjsg 
1961bb76ff1Sjsg 	assert_transcoder_disabled(dev_priv, pipe_config->cpu_transcoder);
1975ca02815Sjsg 	assert_dp_port_disabled(intel_dp);
1985ca02815Sjsg 	assert_edp_pll_disabled(dev_priv);
1995ca02815Sjsg 
2005ca02815Sjsg 	drm_dbg_kms(&dev_priv->drm, "enabling eDP PLL for clock %d\n",
2015ca02815Sjsg 		    pipe_config->port_clock);
2025ca02815Sjsg 
2035ca02815Sjsg 	intel_dp->DP &= ~DP_PLL_FREQ_MASK;
2045ca02815Sjsg 
2055ca02815Sjsg 	if (pipe_config->port_clock == 162000)
2065ca02815Sjsg 		intel_dp->DP |= DP_PLL_FREQ_162MHZ;
2075ca02815Sjsg 	else
2085ca02815Sjsg 		intel_dp->DP |= DP_PLL_FREQ_270MHZ;
2095ca02815Sjsg 
2105ca02815Sjsg 	intel_de_write(dev_priv, DP_A, intel_dp->DP);
2115ca02815Sjsg 	intel_de_posting_read(dev_priv, DP_A);
2125ca02815Sjsg 	udelay(500);
2135ca02815Sjsg 
2145ca02815Sjsg 	/*
2155ca02815Sjsg 	 * [DevILK] Work around required when enabling DP PLL
2165ca02815Sjsg 	 * while a pipe is enabled going to FDI:
2175ca02815Sjsg 	 * 1. Wait for the start of vertical blank on the enabled pipe going to FDI
2185ca02815Sjsg 	 * 2. Program DP PLL enable
2195ca02815Sjsg 	 */
2205ca02815Sjsg 	if (IS_IRONLAKE(dev_priv))
2215ca02815Sjsg 		intel_wait_for_vblank_if_active(dev_priv, !crtc->pipe);
2225ca02815Sjsg 
2235ca02815Sjsg 	intel_dp->DP |= DP_PLL_ENABLE;
2245ca02815Sjsg 
2255ca02815Sjsg 	intel_de_write(dev_priv, DP_A, intel_dp->DP);
2265ca02815Sjsg 	intel_de_posting_read(dev_priv, DP_A);
2275ca02815Sjsg 	udelay(200);
2285ca02815Sjsg }
2295ca02815Sjsg 
ilk_edp_pll_off(struct intel_dp * intel_dp,const struct intel_crtc_state * old_crtc_state)2305ca02815Sjsg static void ilk_edp_pll_off(struct intel_dp *intel_dp,
2315ca02815Sjsg 			    const struct intel_crtc_state *old_crtc_state)
2325ca02815Sjsg {
2335ca02815Sjsg 	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
2345ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
2355ca02815Sjsg 
2361bb76ff1Sjsg 	assert_transcoder_disabled(dev_priv, old_crtc_state->cpu_transcoder);
2375ca02815Sjsg 	assert_dp_port_disabled(intel_dp);
2385ca02815Sjsg 	assert_edp_pll_enabled(dev_priv);
2395ca02815Sjsg 
2405ca02815Sjsg 	drm_dbg_kms(&dev_priv->drm, "disabling eDP PLL\n");
2415ca02815Sjsg 
2425ca02815Sjsg 	intel_dp->DP &= ~DP_PLL_ENABLE;
2435ca02815Sjsg 
2445ca02815Sjsg 	intel_de_write(dev_priv, DP_A, intel_dp->DP);
2455ca02815Sjsg 	intel_de_posting_read(dev_priv, DP_A);
2465ca02815Sjsg 	udelay(200);
2475ca02815Sjsg }
2485ca02815Sjsg 
cpt_dp_port_selected(struct drm_i915_private * dev_priv,enum port port,enum pipe * pipe)2495ca02815Sjsg static bool cpt_dp_port_selected(struct drm_i915_private *dev_priv,
2505ca02815Sjsg 				 enum port port, enum pipe *pipe)
2515ca02815Sjsg {
2525ca02815Sjsg 	enum pipe p;
2535ca02815Sjsg 
2545ca02815Sjsg 	for_each_pipe(dev_priv, p) {
2555ca02815Sjsg 		u32 val = intel_de_read(dev_priv, TRANS_DP_CTL(p));
2565ca02815Sjsg 
2575ca02815Sjsg 		if ((val & TRANS_DP_PORT_SEL_MASK) == TRANS_DP_PORT_SEL(port)) {
2585ca02815Sjsg 			*pipe = p;
2595ca02815Sjsg 			return true;
2605ca02815Sjsg 		}
2615ca02815Sjsg 	}
2625ca02815Sjsg 
2635ca02815Sjsg 	drm_dbg_kms(&dev_priv->drm, "No pipe for DP port %c found\n",
2645ca02815Sjsg 		    port_name(port));
2655ca02815Sjsg 
2665ca02815Sjsg 	/* must initialize pipe to something for the asserts */
2675ca02815Sjsg 	*pipe = PIPE_A;
2685ca02815Sjsg 
2695ca02815Sjsg 	return false;
2705ca02815Sjsg }
2715ca02815Sjsg 
g4x_dp_port_enabled(struct drm_i915_private * dev_priv,i915_reg_t dp_reg,enum port port,enum pipe * pipe)2725ca02815Sjsg bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv,
2735ca02815Sjsg 			 i915_reg_t dp_reg, enum port port,
2745ca02815Sjsg 			 enum pipe *pipe)
2755ca02815Sjsg {
2765ca02815Sjsg 	bool ret;
2775ca02815Sjsg 	u32 val;
2785ca02815Sjsg 
2795ca02815Sjsg 	val = intel_de_read(dev_priv, dp_reg);
2805ca02815Sjsg 
2815ca02815Sjsg 	ret = val & DP_PORT_EN;
2825ca02815Sjsg 
2835ca02815Sjsg 	/* asserts want to know the pipe even if the port is disabled */
2845ca02815Sjsg 	if (IS_IVYBRIDGE(dev_priv) && port == PORT_A)
2855ca02815Sjsg 		*pipe = (val & DP_PIPE_SEL_MASK_IVB) >> DP_PIPE_SEL_SHIFT_IVB;
2865ca02815Sjsg 	else if (HAS_PCH_CPT(dev_priv) && port != PORT_A)
2875ca02815Sjsg 		ret &= cpt_dp_port_selected(dev_priv, port, pipe);
2885ca02815Sjsg 	else if (IS_CHERRYVIEW(dev_priv))
2895ca02815Sjsg 		*pipe = (val & DP_PIPE_SEL_MASK_CHV) >> DP_PIPE_SEL_SHIFT_CHV;
2905ca02815Sjsg 	else
2915ca02815Sjsg 		*pipe = (val & DP_PIPE_SEL_MASK) >> DP_PIPE_SEL_SHIFT;
2925ca02815Sjsg 
2935ca02815Sjsg 	return ret;
2945ca02815Sjsg }
2955ca02815Sjsg 
intel_dp_get_hw_state(struct intel_encoder * encoder,enum pipe * pipe)2965ca02815Sjsg static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
2975ca02815Sjsg 				  enum pipe *pipe)
2985ca02815Sjsg {
2995ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3005ca02815Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
3015ca02815Sjsg 	intel_wakeref_t wakeref;
3025ca02815Sjsg 	bool ret;
3035ca02815Sjsg 
3045ca02815Sjsg 	wakeref = intel_display_power_get_if_enabled(dev_priv,
3055ca02815Sjsg 						     encoder->power_domain);
3065ca02815Sjsg 	if (!wakeref)
3075ca02815Sjsg 		return false;
3085ca02815Sjsg 
3095ca02815Sjsg 	ret = g4x_dp_port_enabled(dev_priv, intel_dp->output_reg,
3105ca02815Sjsg 				  encoder->port, pipe);
3115ca02815Sjsg 
3125ca02815Sjsg 	intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
3135ca02815Sjsg 
3145ca02815Sjsg 	return ret;
3155ca02815Sjsg }
3165ca02815Sjsg 
g4x_dp_get_m_n(struct intel_crtc_state * crtc_state)3171bb76ff1Sjsg static void g4x_dp_get_m_n(struct intel_crtc_state *crtc_state)
3181bb76ff1Sjsg {
3191bb76ff1Sjsg 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3201bb76ff1Sjsg 
3211bb76ff1Sjsg 	if (crtc_state->has_pch_encoder) {
3221bb76ff1Sjsg 		intel_pch_transcoder_get_m1_n1(crtc, &crtc_state->dp_m_n);
3231bb76ff1Sjsg 		intel_pch_transcoder_get_m2_n2(crtc, &crtc_state->dp_m2_n2);
3241bb76ff1Sjsg 	} else {
3251bb76ff1Sjsg 		intel_cpu_transcoder_get_m1_n1(crtc, crtc_state->cpu_transcoder,
3261bb76ff1Sjsg 					       &crtc_state->dp_m_n);
3271bb76ff1Sjsg 		intel_cpu_transcoder_get_m2_n2(crtc, crtc_state->cpu_transcoder,
3281bb76ff1Sjsg 					       &crtc_state->dp_m2_n2);
3291bb76ff1Sjsg 	}
3301bb76ff1Sjsg }
3311bb76ff1Sjsg 
intel_dp_get_config(struct intel_encoder * encoder,struct intel_crtc_state * pipe_config)3325ca02815Sjsg static void intel_dp_get_config(struct intel_encoder *encoder,
3335ca02815Sjsg 				struct intel_crtc_state *pipe_config)
3345ca02815Sjsg {
3355ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3365ca02815Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
3375ca02815Sjsg 	u32 tmp, flags = 0;
3385ca02815Sjsg 	enum port port = encoder->port;
3395ca02815Sjsg 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
3405ca02815Sjsg 
3415ca02815Sjsg 	if (encoder->type == INTEL_OUTPUT_EDP)
3425ca02815Sjsg 		pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP);
3435ca02815Sjsg 	else
3445ca02815Sjsg 		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP);
3455ca02815Sjsg 
3465ca02815Sjsg 	tmp = intel_de_read(dev_priv, intel_dp->output_reg);
3475ca02815Sjsg 
3485ca02815Sjsg 	pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A;
3495ca02815Sjsg 
3505ca02815Sjsg 	if (HAS_PCH_CPT(dev_priv) && port != PORT_A) {
3515ca02815Sjsg 		u32 trans_dp = intel_de_read(dev_priv,
3525ca02815Sjsg 					     TRANS_DP_CTL(crtc->pipe));
3535ca02815Sjsg 
354*f005ef32Sjsg 		if (trans_dp & TRANS_DP_ENH_FRAMING)
355*f005ef32Sjsg 			pipe_config->enhanced_framing = true;
356*f005ef32Sjsg 
3575ca02815Sjsg 		if (trans_dp & TRANS_DP_HSYNC_ACTIVE_HIGH)
3585ca02815Sjsg 			flags |= DRM_MODE_FLAG_PHSYNC;
3595ca02815Sjsg 		else
3605ca02815Sjsg 			flags |= DRM_MODE_FLAG_NHSYNC;
3615ca02815Sjsg 
3625ca02815Sjsg 		if (trans_dp & TRANS_DP_VSYNC_ACTIVE_HIGH)
3635ca02815Sjsg 			flags |= DRM_MODE_FLAG_PVSYNC;
3645ca02815Sjsg 		else
3655ca02815Sjsg 			flags |= DRM_MODE_FLAG_NVSYNC;
3665ca02815Sjsg 	} else {
367*f005ef32Sjsg 		if (tmp & DP_ENHANCED_FRAMING)
368*f005ef32Sjsg 			pipe_config->enhanced_framing = true;
369*f005ef32Sjsg 
3705ca02815Sjsg 		if (tmp & DP_SYNC_HS_HIGH)
3715ca02815Sjsg 			flags |= DRM_MODE_FLAG_PHSYNC;
3725ca02815Sjsg 		else
3735ca02815Sjsg 			flags |= DRM_MODE_FLAG_NHSYNC;
3745ca02815Sjsg 
3755ca02815Sjsg 		if (tmp & DP_SYNC_VS_HIGH)
3765ca02815Sjsg 			flags |= DRM_MODE_FLAG_PVSYNC;
3775ca02815Sjsg 		else
3785ca02815Sjsg 			flags |= DRM_MODE_FLAG_NVSYNC;
3795ca02815Sjsg 	}
3805ca02815Sjsg 
3815ca02815Sjsg 	pipe_config->hw.adjusted_mode.flags |= flags;
3825ca02815Sjsg 
3835ca02815Sjsg 	if (IS_G4X(dev_priv) && tmp & DP_COLOR_RANGE_16_235)
3845ca02815Sjsg 		pipe_config->limited_color_range = true;
3855ca02815Sjsg 
3865ca02815Sjsg 	pipe_config->lane_count =
3875ca02815Sjsg 		((tmp & DP_PORT_WIDTH_MASK) >> DP_PORT_WIDTH_SHIFT) + 1;
3885ca02815Sjsg 
3891bb76ff1Sjsg 	g4x_dp_get_m_n(pipe_config);
3905ca02815Sjsg 
3915ca02815Sjsg 	if (port == PORT_A) {
3925ca02815Sjsg 		if ((intel_de_read(dev_priv, DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_162MHZ)
3935ca02815Sjsg 			pipe_config->port_clock = 162000;
3945ca02815Sjsg 		else
3955ca02815Sjsg 			pipe_config->port_clock = 270000;
3965ca02815Sjsg 	}
3975ca02815Sjsg 
3985ca02815Sjsg 	pipe_config->hw.adjusted_mode.crtc_clock =
3995ca02815Sjsg 		intel_dotclock_calculate(pipe_config->port_clock,
4005ca02815Sjsg 					 &pipe_config->dp_m_n);
4015ca02815Sjsg 
4021bb76ff1Sjsg 	if (intel_dp_is_edp(intel_dp))
4031bb76ff1Sjsg 		intel_edp_fixup_vbt_bpp(encoder, pipe_config->pipe_bpp);
404*f005ef32Sjsg 
405*f005ef32Sjsg 	intel_audio_codec_get_config(encoder, pipe_config);
4065ca02815Sjsg }
4075ca02815Sjsg 
4085ca02815Sjsg static void
intel_dp_link_down(struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state)4095ca02815Sjsg intel_dp_link_down(struct intel_encoder *encoder,
4105ca02815Sjsg 		   const struct intel_crtc_state *old_crtc_state)
4115ca02815Sjsg {
4125ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
4135ca02815Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
4145ca02815Sjsg 	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
4155ca02815Sjsg 	enum port port = encoder->port;
4165ca02815Sjsg 
4175ca02815Sjsg 	if (drm_WARN_ON(&dev_priv->drm,
4185ca02815Sjsg 			(intel_de_read(dev_priv, intel_dp->output_reg) &
4195ca02815Sjsg 			 DP_PORT_EN) == 0))
4205ca02815Sjsg 		return;
4215ca02815Sjsg 
4225ca02815Sjsg 	drm_dbg_kms(&dev_priv->drm, "\n");
4235ca02815Sjsg 
4245ca02815Sjsg 	if ((IS_IVYBRIDGE(dev_priv) && port == PORT_A) ||
4255ca02815Sjsg 	    (HAS_PCH_CPT(dev_priv) && port != PORT_A)) {
4261bb76ff1Sjsg 		intel_dp->DP &= ~DP_LINK_TRAIN_MASK_CPT;
4271bb76ff1Sjsg 		intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE_CPT;
4285ca02815Sjsg 	} else {
4291bb76ff1Sjsg 		intel_dp->DP &= ~DP_LINK_TRAIN_MASK;
4301bb76ff1Sjsg 		intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE;
4315ca02815Sjsg 	}
4321bb76ff1Sjsg 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
4335ca02815Sjsg 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
4345ca02815Sjsg 
4351bb76ff1Sjsg 	intel_dp->DP &= ~(DP_PORT_EN | DP_AUDIO_OUTPUT_ENABLE);
4361bb76ff1Sjsg 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
4375ca02815Sjsg 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
4385ca02815Sjsg 
4395ca02815Sjsg 	/*
4405ca02815Sjsg 	 * HW workaround for IBX, we need to move the port
4415ca02815Sjsg 	 * to transcoder A after disabling it to allow the
4425ca02815Sjsg 	 * matching HDMI port to be enabled on transcoder A.
4435ca02815Sjsg 	 */
4445ca02815Sjsg 	if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B && port != PORT_A) {
4455ca02815Sjsg 		/*
4465ca02815Sjsg 		 * We get CPU/PCH FIFO underruns on the other pipe when
4475ca02815Sjsg 		 * doing the workaround. Sweep them under the rug.
4485ca02815Sjsg 		 */
4495ca02815Sjsg 		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false);
4505ca02815Sjsg 		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
4515ca02815Sjsg 
4525ca02815Sjsg 		/* always enable with pattern 1 (as per spec) */
4531bb76ff1Sjsg 		intel_dp->DP &= ~(DP_PIPE_SEL_MASK | DP_LINK_TRAIN_MASK);
4541bb76ff1Sjsg 		intel_dp->DP |= DP_PORT_EN | DP_PIPE_SEL(PIPE_A) |
4555ca02815Sjsg 			DP_LINK_TRAIN_PAT_1;
4561bb76ff1Sjsg 		intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
4575ca02815Sjsg 		intel_de_posting_read(dev_priv, intel_dp->output_reg);
4585ca02815Sjsg 
4591bb76ff1Sjsg 		intel_dp->DP &= ~DP_PORT_EN;
4601bb76ff1Sjsg 		intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
4615ca02815Sjsg 		intel_de_posting_read(dev_priv, intel_dp->output_reg);
4625ca02815Sjsg 
4635ca02815Sjsg 		intel_wait_for_vblank_if_active(dev_priv, PIPE_A);
4645ca02815Sjsg 		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true);
4655ca02815Sjsg 		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
4665ca02815Sjsg 	}
4675ca02815Sjsg 
4685ca02815Sjsg 	drm_msleep(intel_dp->pps.panel_power_down_delay);
4695ca02815Sjsg 
4705ca02815Sjsg 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
4715ca02815Sjsg 		intel_wakeref_t wakeref;
4725ca02815Sjsg 
4735ca02815Sjsg 		with_intel_pps_lock(intel_dp, wakeref)
4745ca02815Sjsg 			intel_dp->pps.active_pipe = INVALID_PIPE;
4755ca02815Sjsg 	}
4765ca02815Sjsg }
4775ca02815Sjsg 
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)4785ca02815Sjsg static void intel_disable_dp(struct intel_atomic_state *state,
4795ca02815Sjsg 			     struct intel_encoder *encoder,
4805ca02815Sjsg 			     const struct intel_crtc_state *old_crtc_state,
4815ca02815Sjsg 			     const struct drm_connector_state *old_conn_state)
4825ca02815Sjsg {
4835ca02815Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
4845ca02815Sjsg 
4855ca02815Sjsg 	intel_dp->link_trained = false;
4865ca02815Sjsg 
4871bb76ff1Sjsg 	intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
4885ca02815Sjsg 
4895ca02815Sjsg 	/*
4905ca02815Sjsg 	 * Make sure the panel is off before trying to change the mode.
4915ca02815Sjsg 	 * But also ensure that we have vdd while we switch off the panel.
4925ca02815Sjsg 	 */
4935ca02815Sjsg 	intel_pps_vdd_on(intel_dp);
4945ca02815Sjsg 	intel_edp_backlight_off(old_conn_state);
4955ca02815Sjsg 	intel_dp_set_power(intel_dp, DP_SET_POWER_D3);
4965ca02815Sjsg 	intel_pps_off(intel_dp);
4975ca02815Sjsg }
4985ca02815Sjsg 
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)4995ca02815Sjsg static void g4x_disable_dp(struct intel_atomic_state *state,
5005ca02815Sjsg 			   struct intel_encoder *encoder,
5015ca02815Sjsg 			   const struct intel_crtc_state *old_crtc_state,
5025ca02815Sjsg 			   const struct drm_connector_state *old_conn_state)
5035ca02815Sjsg {
5045ca02815Sjsg 	intel_disable_dp(state, encoder, old_crtc_state, old_conn_state);
5055ca02815Sjsg }
5065ca02815Sjsg 
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)5075ca02815Sjsg static void vlv_disable_dp(struct intel_atomic_state *state,
5085ca02815Sjsg 			   struct intel_encoder *encoder,
5095ca02815Sjsg 			   const struct intel_crtc_state *old_crtc_state,
5105ca02815Sjsg 			   const struct drm_connector_state *old_conn_state)
5115ca02815Sjsg {
5125ca02815Sjsg 	intel_disable_dp(state, encoder, old_crtc_state, old_conn_state);
5135ca02815Sjsg }
5145ca02815Sjsg 
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)5155ca02815Sjsg static void g4x_post_disable_dp(struct intel_atomic_state *state,
5165ca02815Sjsg 				struct intel_encoder *encoder,
5175ca02815Sjsg 				const struct intel_crtc_state *old_crtc_state,
5185ca02815Sjsg 				const struct drm_connector_state *old_conn_state)
5195ca02815Sjsg {
5205ca02815Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
5215ca02815Sjsg 	enum port port = encoder->port;
5225ca02815Sjsg 
5235ca02815Sjsg 	/*
5245ca02815Sjsg 	 * Bspec does not list a specific disable sequence for g4x DP.
5255ca02815Sjsg 	 * Follow the ilk+ sequence (disable pipe before the port) for
5265ca02815Sjsg 	 * g4x DP as it does not suffer from underruns like the normal
5275ca02815Sjsg 	 * g4x modeset sequence (disable pipe after the port).
5285ca02815Sjsg 	 */
5295ca02815Sjsg 	intel_dp_link_down(encoder, old_crtc_state);
5305ca02815Sjsg 
5315ca02815Sjsg 	/* Only ilk+ has port A */
5325ca02815Sjsg 	if (port == PORT_A)
5335ca02815Sjsg 		ilk_edp_pll_off(intel_dp, old_crtc_state);
5345ca02815Sjsg }
5355ca02815Sjsg 
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)5365ca02815Sjsg static void vlv_post_disable_dp(struct intel_atomic_state *state,
5375ca02815Sjsg 				struct intel_encoder *encoder,
5385ca02815Sjsg 				const struct intel_crtc_state *old_crtc_state,
5395ca02815Sjsg 				const struct drm_connector_state *old_conn_state)
5405ca02815Sjsg {
5415ca02815Sjsg 	intel_dp_link_down(encoder, old_crtc_state);
5425ca02815Sjsg }
5435ca02815Sjsg 
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)5445ca02815Sjsg static void chv_post_disable_dp(struct intel_atomic_state *state,
5455ca02815Sjsg 				struct intel_encoder *encoder,
5465ca02815Sjsg 				const struct intel_crtc_state *old_crtc_state,
5475ca02815Sjsg 				const struct drm_connector_state *old_conn_state)
5485ca02815Sjsg {
5495ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
5505ca02815Sjsg 
5515ca02815Sjsg 	intel_dp_link_down(encoder, old_crtc_state);
5525ca02815Sjsg 
5535ca02815Sjsg 	vlv_dpio_get(dev_priv);
5545ca02815Sjsg 
5555ca02815Sjsg 	/* Assert data lane reset */
5565ca02815Sjsg 	chv_data_lane_soft_reset(encoder, old_crtc_state, true);
5575ca02815Sjsg 
5585ca02815Sjsg 	vlv_dpio_put(dev_priv);
5595ca02815Sjsg }
5605ca02815Sjsg 
5615ca02815Sjsg static void
cpt_set_link_train(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state,u8 dp_train_pat)5625ca02815Sjsg cpt_set_link_train(struct intel_dp *intel_dp,
5635ca02815Sjsg 		   const struct intel_crtc_state *crtc_state,
5645ca02815Sjsg 		   u8 dp_train_pat)
5655ca02815Sjsg {
5665ca02815Sjsg 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
5675ca02815Sjsg 
5681bb76ff1Sjsg 	intel_dp->DP &= ~DP_LINK_TRAIN_MASK_CPT;
5695ca02815Sjsg 
5705ca02815Sjsg 	switch (intel_dp_training_pattern_symbol(dp_train_pat)) {
5715ca02815Sjsg 	case DP_TRAINING_PATTERN_DISABLE:
5721bb76ff1Sjsg 		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
5735ca02815Sjsg 		break;
5745ca02815Sjsg 	case DP_TRAINING_PATTERN_1:
5751bb76ff1Sjsg 		intel_dp->DP |= DP_LINK_TRAIN_PAT_1_CPT;
5765ca02815Sjsg 		break;
5775ca02815Sjsg 	case DP_TRAINING_PATTERN_2:
5781bb76ff1Sjsg 		intel_dp->DP |= DP_LINK_TRAIN_PAT_2_CPT;
5795ca02815Sjsg 		break;
5805ca02815Sjsg 	default:
5815ca02815Sjsg 		MISSING_CASE(intel_dp_training_pattern_symbol(dp_train_pat));
5825ca02815Sjsg 		return;
5835ca02815Sjsg 	}
5845ca02815Sjsg 
5855ca02815Sjsg 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
5865ca02815Sjsg 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
5875ca02815Sjsg }
5885ca02815Sjsg 
5895ca02815Sjsg static void
g4x_set_link_train(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state,u8 dp_train_pat)5905ca02815Sjsg g4x_set_link_train(struct intel_dp *intel_dp,
5915ca02815Sjsg 		   const struct intel_crtc_state *crtc_state,
5925ca02815Sjsg 		   u8 dp_train_pat)
5935ca02815Sjsg {
5945ca02815Sjsg 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
5955ca02815Sjsg 
5961bb76ff1Sjsg 	intel_dp->DP &= ~DP_LINK_TRAIN_MASK;
5975ca02815Sjsg 
5985ca02815Sjsg 	switch (intel_dp_training_pattern_symbol(dp_train_pat)) {
5995ca02815Sjsg 	case DP_TRAINING_PATTERN_DISABLE:
6001bb76ff1Sjsg 		intel_dp->DP |= DP_LINK_TRAIN_OFF;
6015ca02815Sjsg 		break;
6025ca02815Sjsg 	case DP_TRAINING_PATTERN_1:
6031bb76ff1Sjsg 		intel_dp->DP |= DP_LINK_TRAIN_PAT_1;
6045ca02815Sjsg 		break;
6055ca02815Sjsg 	case DP_TRAINING_PATTERN_2:
6061bb76ff1Sjsg 		intel_dp->DP |= DP_LINK_TRAIN_PAT_2;
6075ca02815Sjsg 		break;
6085ca02815Sjsg 	default:
6095ca02815Sjsg 		MISSING_CASE(intel_dp_training_pattern_symbol(dp_train_pat));
6105ca02815Sjsg 		return;
6115ca02815Sjsg 	}
6125ca02815Sjsg 
6135ca02815Sjsg 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
6145ca02815Sjsg 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
6155ca02815Sjsg }
6165ca02815Sjsg 
intel_dp_enable_port(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state)6175ca02815Sjsg static void intel_dp_enable_port(struct intel_dp *intel_dp,
6185ca02815Sjsg 				 const struct intel_crtc_state *crtc_state)
6195ca02815Sjsg {
6205ca02815Sjsg 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
6215ca02815Sjsg 
6225ca02815Sjsg 	/* enable with pattern 1 (as per spec) */
6235ca02815Sjsg 
6245ca02815Sjsg 	intel_dp_program_link_training_pattern(intel_dp, crtc_state,
6251bb76ff1Sjsg 					       DP_PHY_DPRX, DP_TRAINING_PATTERN_1);
6265ca02815Sjsg 
6275ca02815Sjsg 	/*
6285ca02815Sjsg 	 * Magic for VLV/CHV. We _must_ first set up the register
6295ca02815Sjsg 	 * without actually enabling the port, and then do another
6305ca02815Sjsg 	 * write to enable the port. Otherwise link training will
6315ca02815Sjsg 	 * fail when the power sequencer is freshly used for this port.
6325ca02815Sjsg 	 */
6335ca02815Sjsg 	intel_dp->DP |= DP_PORT_EN;
6345ca02815Sjsg 	if (crtc_state->has_audio)
6355ca02815Sjsg 		intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
6365ca02815Sjsg 
6375ca02815Sjsg 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
6385ca02815Sjsg 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
6395ca02815Sjsg }
6405ca02815Sjsg 
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)6415ca02815Sjsg static void intel_enable_dp(struct intel_atomic_state *state,
6425ca02815Sjsg 			    struct intel_encoder *encoder,
6435ca02815Sjsg 			    const struct intel_crtc_state *pipe_config,
6445ca02815Sjsg 			    const struct drm_connector_state *conn_state)
6455ca02815Sjsg {
6465ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
6475ca02815Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
6485ca02815Sjsg 	u32 dp_reg = intel_de_read(dev_priv, intel_dp->output_reg);
6495ca02815Sjsg 	intel_wakeref_t wakeref;
6505ca02815Sjsg 
6515ca02815Sjsg 	if (drm_WARN_ON(&dev_priv->drm, dp_reg & DP_PORT_EN))
6525ca02815Sjsg 		return;
6535ca02815Sjsg 
6545ca02815Sjsg 	with_intel_pps_lock(intel_dp, wakeref) {
6555ca02815Sjsg 		if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
6565ca02815Sjsg 			vlv_pps_init(encoder, pipe_config);
6575ca02815Sjsg 
6585ca02815Sjsg 		intel_dp_enable_port(intel_dp, pipe_config);
6595ca02815Sjsg 
6605ca02815Sjsg 		intel_pps_vdd_on_unlocked(intel_dp);
6615ca02815Sjsg 		intel_pps_on_unlocked(intel_dp);
6625ca02815Sjsg 		intel_pps_vdd_off_unlocked(intel_dp, true);
6635ca02815Sjsg 	}
6645ca02815Sjsg 
6655ca02815Sjsg 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
6665ca02815Sjsg 		unsigned int lane_mask = 0x0;
6675ca02815Sjsg 
6685ca02815Sjsg 		if (IS_CHERRYVIEW(dev_priv))
6695ca02815Sjsg 			lane_mask = intel_dp_unused_lane_mask(pipe_config->lane_count);
6705ca02815Sjsg 
6715ca02815Sjsg 		vlv_wait_port_ready(dev_priv, dp_to_dig_port(intel_dp),
6725ca02815Sjsg 				    lane_mask);
6735ca02815Sjsg 	}
6745ca02815Sjsg 
6755ca02815Sjsg 	intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
6765ca02815Sjsg 	intel_dp_configure_protocol_converter(intel_dp, pipe_config);
6775ca02815Sjsg 	intel_dp_check_frl_training(intel_dp);
6785ca02815Sjsg 	intel_dp_pcon_dsc_configure(intel_dp, pipe_config);
6795ca02815Sjsg 	intel_dp_start_link_train(intel_dp, pipe_config);
6805ca02815Sjsg 	intel_dp_stop_link_train(intel_dp, pipe_config);
6815ca02815Sjsg }
6825ca02815Sjsg 
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)6835ca02815Sjsg static void g4x_enable_dp(struct intel_atomic_state *state,
6845ca02815Sjsg 			  struct intel_encoder *encoder,
6855ca02815Sjsg 			  const struct intel_crtc_state *pipe_config,
6865ca02815Sjsg 			  const struct drm_connector_state *conn_state)
6875ca02815Sjsg {
6885ca02815Sjsg 	intel_enable_dp(state, encoder, pipe_config, conn_state);
689*f005ef32Sjsg 	intel_audio_codec_enable(encoder, pipe_config, conn_state);
6905ca02815Sjsg 	intel_edp_backlight_on(pipe_config, conn_state);
6915ca02815Sjsg }
6925ca02815Sjsg 
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)6935ca02815Sjsg static void vlv_enable_dp(struct intel_atomic_state *state,
6945ca02815Sjsg 			  struct intel_encoder *encoder,
6955ca02815Sjsg 			  const struct intel_crtc_state *pipe_config,
6965ca02815Sjsg 			  const struct drm_connector_state *conn_state)
6975ca02815Sjsg {
698*f005ef32Sjsg 	intel_audio_codec_enable(encoder, pipe_config, conn_state);
6995ca02815Sjsg 	intel_edp_backlight_on(pipe_config, conn_state);
7005ca02815Sjsg }
7015ca02815Sjsg 
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)7025ca02815Sjsg static void g4x_pre_enable_dp(struct intel_atomic_state *state,
7035ca02815Sjsg 			      struct intel_encoder *encoder,
7045ca02815Sjsg 			      const struct intel_crtc_state *pipe_config,
7055ca02815Sjsg 			      const struct drm_connector_state *conn_state)
7065ca02815Sjsg {
7075ca02815Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
7085ca02815Sjsg 	enum port port = encoder->port;
7095ca02815Sjsg 
7105ca02815Sjsg 	intel_dp_prepare(encoder, pipe_config);
7115ca02815Sjsg 
7125ca02815Sjsg 	/* Only ilk+ has port A */
7135ca02815Sjsg 	if (port == PORT_A)
7145ca02815Sjsg 		ilk_edp_pll_on(intel_dp, pipe_config);
7155ca02815Sjsg }
7165ca02815Sjsg 
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)7175ca02815Sjsg static void vlv_pre_enable_dp(struct intel_atomic_state *state,
7185ca02815Sjsg 			      struct intel_encoder *encoder,
7195ca02815Sjsg 			      const struct intel_crtc_state *pipe_config,
7205ca02815Sjsg 			      const struct drm_connector_state *conn_state)
7215ca02815Sjsg {
7225ca02815Sjsg 	vlv_phy_pre_encoder_enable(encoder, pipe_config);
7235ca02815Sjsg 
7245ca02815Sjsg 	intel_enable_dp(state, encoder, pipe_config, conn_state);
7255ca02815Sjsg }
7265ca02815Sjsg 
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)7275ca02815Sjsg static void vlv_dp_pre_pll_enable(struct intel_atomic_state *state,
7285ca02815Sjsg 				  struct intel_encoder *encoder,
7295ca02815Sjsg 				  const struct intel_crtc_state *pipe_config,
7305ca02815Sjsg 				  const struct drm_connector_state *conn_state)
7315ca02815Sjsg {
7325ca02815Sjsg 	intel_dp_prepare(encoder, pipe_config);
7335ca02815Sjsg 
7345ca02815Sjsg 	vlv_phy_pre_pll_enable(encoder, pipe_config);
7355ca02815Sjsg }
7365ca02815Sjsg 
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)7375ca02815Sjsg static void chv_pre_enable_dp(struct intel_atomic_state *state,
7385ca02815Sjsg 			      struct intel_encoder *encoder,
7395ca02815Sjsg 			      const struct intel_crtc_state *pipe_config,
7405ca02815Sjsg 			      const struct drm_connector_state *conn_state)
7415ca02815Sjsg {
7425ca02815Sjsg 	chv_phy_pre_encoder_enable(encoder, pipe_config);
7435ca02815Sjsg 
7445ca02815Sjsg 	intel_enable_dp(state, encoder, pipe_config, conn_state);
7455ca02815Sjsg 
7465ca02815Sjsg 	/* Second common lane will stay alive on its own now */
7475ca02815Sjsg 	chv_phy_release_cl2_override(encoder);
7485ca02815Sjsg }
7495ca02815Sjsg 
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)7505ca02815Sjsg static void chv_dp_pre_pll_enable(struct intel_atomic_state *state,
7515ca02815Sjsg 				  struct intel_encoder *encoder,
7525ca02815Sjsg 				  const struct intel_crtc_state *pipe_config,
7535ca02815Sjsg 				  const struct drm_connector_state *conn_state)
7545ca02815Sjsg {
7555ca02815Sjsg 	intel_dp_prepare(encoder, pipe_config);
7565ca02815Sjsg 
7575ca02815Sjsg 	chv_phy_pre_pll_enable(encoder, pipe_config);
7585ca02815Sjsg }
7595ca02815Sjsg 
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)7605ca02815Sjsg static void chv_dp_post_pll_disable(struct intel_atomic_state *state,
7615ca02815Sjsg 				    struct intel_encoder *encoder,
7625ca02815Sjsg 				    const struct intel_crtc_state *old_crtc_state,
7635ca02815Sjsg 				    const struct drm_connector_state *old_conn_state)
7645ca02815Sjsg {
7655ca02815Sjsg 	chv_phy_post_pll_disable(encoder, old_crtc_state);
7665ca02815Sjsg }
7675ca02815Sjsg 
intel_dp_voltage_max_2(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state)7685ca02815Sjsg static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp,
7695ca02815Sjsg 				 const struct intel_crtc_state *crtc_state)
7705ca02815Sjsg {
7715ca02815Sjsg 	return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
7725ca02815Sjsg }
7735ca02815Sjsg 
intel_dp_voltage_max_3(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state)7745ca02815Sjsg static u8 intel_dp_voltage_max_3(struct intel_dp *intel_dp,
7755ca02815Sjsg 				 const struct intel_crtc_state *crtc_state)
7765ca02815Sjsg {
7775ca02815Sjsg 	return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
7785ca02815Sjsg }
7795ca02815Sjsg 
intel_dp_preemph_max_2(struct intel_dp * intel_dp)7805ca02815Sjsg static u8 intel_dp_preemph_max_2(struct intel_dp *intel_dp)
7815ca02815Sjsg {
7825ca02815Sjsg 	return DP_TRAIN_PRE_EMPH_LEVEL_2;
7835ca02815Sjsg }
7845ca02815Sjsg 
intel_dp_preemph_max_3(struct intel_dp * intel_dp)7855ca02815Sjsg static u8 intel_dp_preemph_max_3(struct intel_dp *intel_dp)
7865ca02815Sjsg {
7875ca02815Sjsg 	return DP_TRAIN_PRE_EMPH_LEVEL_3;
7885ca02815Sjsg }
7895ca02815Sjsg 
vlv_set_signal_levels(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)7901bb76ff1Sjsg static void vlv_set_signal_levels(struct intel_encoder *encoder,
7915ca02815Sjsg 				  const struct intel_crtc_state *crtc_state)
7925ca02815Sjsg {
7931bb76ff1Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
7945ca02815Sjsg 	unsigned long demph_reg_value, preemph_reg_value,
7955ca02815Sjsg 		uniqtranscale_reg_value;
7965ca02815Sjsg 	u8 train_set = intel_dp->train_set[0];
7975ca02815Sjsg 
7985ca02815Sjsg 	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
7995ca02815Sjsg 	case DP_TRAIN_PRE_EMPH_LEVEL_0:
8005ca02815Sjsg 		preemph_reg_value = 0x0004000;
8015ca02815Sjsg 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
8025ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
8035ca02815Sjsg 			demph_reg_value = 0x2B405555;
8045ca02815Sjsg 			uniqtranscale_reg_value = 0x552AB83A;
8055ca02815Sjsg 			break;
8065ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
8075ca02815Sjsg 			demph_reg_value = 0x2B404040;
8085ca02815Sjsg 			uniqtranscale_reg_value = 0x5548B83A;
8095ca02815Sjsg 			break;
8105ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
8115ca02815Sjsg 			demph_reg_value = 0x2B245555;
8125ca02815Sjsg 			uniqtranscale_reg_value = 0x5560B83A;
8135ca02815Sjsg 			break;
8145ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
8155ca02815Sjsg 			demph_reg_value = 0x2B405555;
8165ca02815Sjsg 			uniqtranscale_reg_value = 0x5598DA3A;
8175ca02815Sjsg 			break;
8185ca02815Sjsg 		default:
8195ca02815Sjsg 			return;
8205ca02815Sjsg 		}
8215ca02815Sjsg 		break;
8225ca02815Sjsg 	case DP_TRAIN_PRE_EMPH_LEVEL_1:
8235ca02815Sjsg 		preemph_reg_value = 0x0002000;
8245ca02815Sjsg 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
8255ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
8265ca02815Sjsg 			demph_reg_value = 0x2B404040;
8275ca02815Sjsg 			uniqtranscale_reg_value = 0x5552B83A;
8285ca02815Sjsg 			break;
8295ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
8305ca02815Sjsg 			demph_reg_value = 0x2B404848;
8315ca02815Sjsg 			uniqtranscale_reg_value = 0x5580B83A;
8325ca02815Sjsg 			break;
8335ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
8345ca02815Sjsg 			demph_reg_value = 0x2B404040;
8355ca02815Sjsg 			uniqtranscale_reg_value = 0x55ADDA3A;
8365ca02815Sjsg 			break;
8375ca02815Sjsg 		default:
8385ca02815Sjsg 			return;
8395ca02815Sjsg 		}
8405ca02815Sjsg 		break;
8415ca02815Sjsg 	case DP_TRAIN_PRE_EMPH_LEVEL_2:
8425ca02815Sjsg 		preemph_reg_value = 0x0000000;
8435ca02815Sjsg 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
8445ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
8455ca02815Sjsg 			demph_reg_value = 0x2B305555;
8465ca02815Sjsg 			uniqtranscale_reg_value = 0x5570B83A;
8475ca02815Sjsg 			break;
8485ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
8495ca02815Sjsg 			demph_reg_value = 0x2B2B4040;
8505ca02815Sjsg 			uniqtranscale_reg_value = 0x55ADDA3A;
8515ca02815Sjsg 			break;
8525ca02815Sjsg 		default:
8535ca02815Sjsg 			return;
8545ca02815Sjsg 		}
8555ca02815Sjsg 		break;
8565ca02815Sjsg 	case DP_TRAIN_PRE_EMPH_LEVEL_3:
8575ca02815Sjsg 		preemph_reg_value = 0x0006000;
8585ca02815Sjsg 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
8595ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
8605ca02815Sjsg 			demph_reg_value = 0x1B405555;
8615ca02815Sjsg 			uniqtranscale_reg_value = 0x55ADDA3A;
8625ca02815Sjsg 			break;
8635ca02815Sjsg 		default:
8645ca02815Sjsg 			return;
8655ca02815Sjsg 		}
8665ca02815Sjsg 		break;
8675ca02815Sjsg 	default:
8685ca02815Sjsg 		return;
8695ca02815Sjsg 	}
8705ca02815Sjsg 
8715ca02815Sjsg 	vlv_set_phy_signal_level(encoder, crtc_state,
8725ca02815Sjsg 				 demph_reg_value, preemph_reg_value,
8735ca02815Sjsg 				 uniqtranscale_reg_value, 0);
8745ca02815Sjsg }
8755ca02815Sjsg 
chv_set_signal_levels(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)8761bb76ff1Sjsg static void chv_set_signal_levels(struct intel_encoder *encoder,
8775ca02815Sjsg 				  const struct intel_crtc_state *crtc_state)
8785ca02815Sjsg {
8791bb76ff1Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
8805ca02815Sjsg 	u32 deemph_reg_value, margin_reg_value;
8815ca02815Sjsg 	bool uniq_trans_scale = false;
8825ca02815Sjsg 	u8 train_set = intel_dp->train_set[0];
8835ca02815Sjsg 
8845ca02815Sjsg 	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
8855ca02815Sjsg 	case DP_TRAIN_PRE_EMPH_LEVEL_0:
8865ca02815Sjsg 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
8875ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
8885ca02815Sjsg 			deemph_reg_value = 128;
8895ca02815Sjsg 			margin_reg_value = 52;
8905ca02815Sjsg 			break;
8915ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
8925ca02815Sjsg 			deemph_reg_value = 128;
8935ca02815Sjsg 			margin_reg_value = 77;
8945ca02815Sjsg 			break;
8955ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
8965ca02815Sjsg 			deemph_reg_value = 128;
8975ca02815Sjsg 			margin_reg_value = 102;
8985ca02815Sjsg 			break;
8995ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
9005ca02815Sjsg 			deemph_reg_value = 128;
9015ca02815Sjsg 			margin_reg_value = 154;
9025ca02815Sjsg 			uniq_trans_scale = true;
9035ca02815Sjsg 			break;
9045ca02815Sjsg 		default:
9055ca02815Sjsg 			return;
9065ca02815Sjsg 		}
9075ca02815Sjsg 		break;
9085ca02815Sjsg 	case DP_TRAIN_PRE_EMPH_LEVEL_1:
9095ca02815Sjsg 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
9105ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
9115ca02815Sjsg 			deemph_reg_value = 85;
9125ca02815Sjsg 			margin_reg_value = 78;
9135ca02815Sjsg 			break;
9145ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
9155ca02815Sjsg 			deemph_reg_value = 85;
9165ca02815Sjsg 			margin_reg_value = 116;
9175ca02815Sjsg 			break;
9185ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
9195ca02815Sjsg 			deemph_reg_value = 85;
9205ca02815Sjsg 			margin_reg_value = 154;
9215ca02815Sjsg 			break;
9225ca02815Sjsg 		default:
9235ca02815Sjsg 			return;
9245ca02815Sjsg 		}
9255ca02815Sjsg 		break;
9265ca02815Sjsg 	case DP_TRAIN_PRE_EMPH_LEVEL_2:
9275ca02815Sjsg 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
9285ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
9295ca02815Sjsg 			deemph_reg_value = 64;
9305ca02815Sjsg 			margin_reg_value = 104;
9315ca02815Sjsg 			break;
9325ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
9335ca02815Sjsg 			deemph_reg_value = 64;
9345ca02815Sjsg 			margin_reg_value = 154;
9355ca02815Sjsg 			break;
9365ca02815Sjsg 		default:
9375ca02815Sjsg 			return;
9385ca02815Sjsg 		}
9395ca02815Sjsg 		break;
9405ca02815Sjsg 	case DP_TRAIN_PRE_EMPH_LEVEL_3:
9415ca02815Sjsg 		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
9425ca02815Sjsg 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
9435ca02815Sjsg 			deemph_reg_value = 43;
9445ca02815Sjsg 			margin_reg_value = 154;
9455ca02815Sjsg 			break;
9465ca02815Sjsg 		default:
9475ca02815Sjsg 			return;
9485ca02815Sjsg 		}
9495ca02815Sjsg 		break;
9505ca02815Sjsg 	default:
9515ca02815Sjsg 		return;
9525ca02815Sjsg 	}
9535ca02815Sjsg 
9545ca02815Sjsg 	chv_set_phy_signal_level(encoder, crtc_state,
9555ca02815Sjsg 				 deemph_reg_value, margin_reg_value,
9565ca02815Sjsg 				 uniq_trans_scale);
9575ca02815Sjsg }
9585ca02815Sjsg 
g4x_signal_levels(u8 train_set)9595ca02815Sjsg static u32 g4x_signal_levels(u8 train_set)
9605ca02815Sjsg {
9615ca02815Sjsg 	u32 signal_levels = 0;
9625ca02815Sjsg 
9635ca02815Sjsg 	switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
9645ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
9655ca02815Sjsg 	default:
9665ca02815Sjsg 		signal_levels |= DP_VOLTAGE_0_4;
9675ca02815Sjsg 		break;
9685ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
9695ca02815Sjsg 		signal_levels |= DP_VOLTAGE_0_6;
9705ca02815Sjsg 		break;
9715ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
9725ca02815Sjsg 		signal_levels |= DP_VOLTAGE_0_8;
9735ca02815Sjsg 		break;
9745ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
9755ca02815Sjsg 		signal_levels |= DP_VOLTAGE_1_2;
9765ca02815Sjsg 		break;
9775ca02815Sjsg 	}
9785ca02815Sjsg 	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
9795ca02815Sjsg 	case DP_TRAIN_PRE_EMPH_LEVEL_0:
9805ca02815Sjsg 	default:
9815ca02815Sjsg 		signal_levels |= DP_PRE_EMPHASIS_0;
9825ca02815Sjsg 		break;
9835ca02815Sjsg 	case DP_TRAIN_PRE_EMPH_LEVEL_1:
9845ca02815Sjsg 		signal_levels |= DP_PRE_EMPHASIS_3_5;
9855ca02815Sjsg 		break;
9865ca02815Sjsg 	case DP_TRAIN_PRE_EMPH_LEVEL_2:
9875ca02815Sjsg 		signal_levels |= DP_PRE_EMPHASIS_6;
9885ca02815Sjsg 		break;
9895ca02815Sjsg 	case DP_TRAIN_PRE_EMPH_LEVEL_3:
9905ca02815Sjsg 		signal_levels |= DP_PRE_EMPHASIS_9_5;
9915ca02815Sjsg 		break;
9925ca02815Sjsg 	}
9935ca02815Sjsg 	return signal_levels;
9945ca02815Sjsg }
9955ca02815Sjsg 
9965ca02815Sjsg static void
g4x_set_signal_levels(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)9971bb76ff1Sjsg g4x_set_signal_levels(struct intel_encoder *encoder,
9985ca02815Sjsg 		      const struct intel_crtc_state *crtc_state)
9995ca02815Sjsg {
10001bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
10011bb76ff1Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
10025ca02815Sjsg 	u8 train_set = intel_dp->train_set[0];
10035ca02815Sjsg 	u32 signal_levels;
10045ca02815Sjsg 
10055ca02815Sjsg 	signal_levels = g4x_signal_levels(train_set);
10065ca02815Sjsg 
10075ca02815Sjsg 	drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n",
10085ca02815Sjsg 		    signal_levels);
10095ca02815Sjsg 
10105ca02815Sjsg 	intel_dp->DP &= ~(DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK);
10115ca02815Sjsg 	intel_dp->DP |= signal_levels;
10125ca02815Sjsg 
10135ca02815Sjsg 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
10145ca02815Sjsg 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
10155ca02815Sjsg }
10165ca02815Sjsg 
10175ca02815Sjsg /* SNB CPU eDP voltage swing and pre-emphasis control */
snb_cpu_edp_signal_levels(u8 train_set)10185ca02815Sjsg static u32 snb_cpu_edp_signal_levels(u8 train_set)
10195ca02815Sjsg {
10205ca02815Sjsg 	u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
10215ca02815Sjsg 					DP_TRAIN_PRE_EMPHASIS_MASK);
10225ca02815Sjsg 
10235ca02815Sjsg 	switch (signal_levels) {
10245ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
10255ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
10265ca02815Sjsg 		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
10275ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
10285ca02815Sjsg 		return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
10295ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
10305ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
10315ca02815Sjsg 		return EDP_LINK_TRAIN_400_600MV_6DB_SNB_B;
10325ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
10335ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
10345ca02815Sjsg 		return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
10355ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
10365ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
10375ca02815Sjsg 		return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
10385ca02815Sjsg 	default:
10395ca02815Sjsg 		MISSING_CASE(signal_levels);
10405ca02815Sjsg 		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
10415ca02815Sjsg 	}
10425ca02815Sjsg }
10435ca02815Sjsg 
10445ca02815Sjsg static void
snb_cpu_edp_set_signal_levels(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)10451bb76ff1Sjsg snb_cpu_edp_set_signal_levels(struct intel_encoder *encoder,
10465ca02815Sjsg 			      const struct intel_crtc_state *crtc_state)
10475ca02815Sjsg {
10481bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
10491bb76ff1Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
10505ca02815Sjsg 	u8 train_set = intel_dp->train_set[0];
10515ca02815Sjsg 	u32 signal_levels;
10525ca02815Sjsg 
10535ca02815Sjsg 	signal_levels = snb_cpu_edp_signal_levels(train_set);
10545ca02815Sjsg 
10555ca02815Sjsg 	drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n",
10565ca02815Sjsg 		    signal_levels);
10575ca02815Sjsg 
10585ca02815Sjsg 	intel_dp->DP &= ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
10595ca02815Sjsg 	intel_dp->DP |= signal_levels;
10605ca02815Sjsg 
10615ca02815Sjsg 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
10625ca02815Sjsg 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
10635ca02815Sjsg }
10645ca02815Sjsg 
10655ca02815Sjsg /* IVB CPU eDP voltage swing and pre-emphasis control */
ivb_cpu_edp_signal_levels(u8 train_set)10665ca02815Sjsg static u32 ivb_cpu_edp_signal_levels(u8 train_set)
10675ca02815Sjsg {
10685ca02815Sjsg 	u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
10695ca02815Sjsg 					DP_TRAIN_PRE_EMPHASIS_MASK);
10705ca02815Sjsg 
10715ca02815Sjsg 	switch (signal_levels) {
10725ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
10735ca02815Sjsg 		return EDP_LINK_TRAIN_400MV_0DB_IVB;
10745ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
10755ca02815Sjsg 		return EDP_LINK_TRAIN_400MV_3_5DB_IVB;
10765ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
10775ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
10785ca02815Sjsg 		return EDP_LINK_TRAIN_400MV_6DB_IVB;
10795ca02815Sjsg 
10805ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
10815ca02815Sjsg 		return EDP_LINK_TRAIN_600MV_0DB_IVB;
10825ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
10835ca02815Sjsg 		return EDP_LINK_TRAIN_600MV_3_5DB_IVB;
10845ca02815Sjsg 
10855ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
10865ca02815Sjsg 		return EDP_LINK_TRAIN_800MV_0DB_IVB;
10875ca02815Sjsg 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
10885ca02815Sjsg 		return EDP_LINK_TRAIN_800MV_3_5DB_IVB;
10895ca02815Sjsg 
10905ca02815Sjsg 	default:
10915ca02815Sjsg 		MISSING_CASE(signal_levels);
10925ca02815Sjsg 		return EDP_LINK_TRAIN_500MV_0DB_IVB;
10935ca02815Sjsg 	}
10945ca02815Sjsg }
10955ca02815Sjsg 
10965ca02815Sjsg static void
ivb_cpu_edp_set_signal_levels(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)10971bb76ff1Sjsg ivb_cpu_edp_set_signal_levels(struct intel_encoder *encoder,
10985ca02815Sjsg 			      const struct intel_crtc_state *crtc_state)
10995ca02815Sjsg {
11001bb76ff1Sjsg 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
11011bb76ff1Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
11025ca02815Sjsg 	u8 train_set = intel_dp->train_set[0];
11035ca02815Sjsg 	u32 signal_levels;
11045ca02815Sjsg 
11055ca02815Sjsg 	signal_levels = ivb_cpu_edp_signal_levels(train_set);
11065ca02815Sjsg 
11075ca02815Sjsg 	drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n",
11085ca02815Sjsg 		    signal_levels);
11095ca02815Sjsg 
11105ca02815Sjsg 	intel_dp->DP &= ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
11115ca02815Sjsg 	intel_dp->DP |= signal_levels;
11125ca02815Sjsg 
11135ca02815Sjsg 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
11145ca02815Sjsg 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
11155ca02815Sjsg }
11165ca02815Sjsg 
11175ca02815Sjsg /*
11185ca02815Sjsg  * If display is now connected check links status,
11195ca02815Sjsg  * there has been known issues of link loss triggering
11205ca02815Sjsg  * long pulse.
11215ca02815Sjsg  *
11225ca02815Sjsg  * Some sinks (eg. ASUS PB287Q) seem to perform some
11235ca02815Sjsg  * weird HPD ping pong during modesets. So we can apparently
11245ca02815Sjsg  * end up with HPD going low during a modeset, and then
11255ca02815Sjsg  * going back up soon after. And once that happens we must
11265ca02815Sjsg  * retrain the link to get a picture. That's in case no
11275ca02815Sjsg  * userspace component reacted to intermittent HPD dip.
11285ca02815Sjsg  */
11295ca02815Sjsg static enum intel_hotplug_state
intel_dp_hotplug(struct intel_encoder * encoder,struct intel_connector * connector)11305ca02815Sjsg intel_dp_hotplug(struct intel_encoder *encoder,
11315ca02815Sjsg 		 struct intel_connector *connector)
11325ca02815Sjsg {
11335ca02815Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
11345ca02815Sjsg 	struct drm_modeset_acquire_ctx ctx;
11355ca02815Sjsg 	enum intel_hotplug_state state;
11365ca02815Sjsg 	int ret;
11375ca02815Sjsg 
11385ca02815Sjsg 	if (intel_dp->compliance.test_active &&
11395ca02815Sjsg 	    intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) {
11405ca02815Sjsg 		intel_dp_phy_test(encoder);
11415ca02815Sjsg 		/* just do the PHY test and nothing else */
11425ca02815Sjsg 		return INTEL_HOTPLUG_UNCHANGED;
11435ca02815Sjsg 	}
11445ca02815Sjsg 
11455ca02815Sjsg 	state = intel_encoder_hotplug(encoder, connector);
11465ca02815Sjsg 
11475ca02815Sjsg 	drm_modeset_acquire_init(&ctx, 0);
11485ca02815Sjsg 
11495ca02815Sjsg 	for (;;) {
11505ca02815Sjsg 		ret = intel_dp_retrain_link(encoder, &ctx);
11515ca02815Sjsg 
11525ca02815Sjsg 		if (ret == -EDEADLK) {
11535ca02815Sjsg 			drm_modeset_backoff(&ctx);
11545ca02815Sjsg 			continue;
11555ca02815Sjsg 		}
11565ca02815Sjsg 
11575ca02815Sjsg 		break;
11585ca02815Sjsg 	}
11595ca02815Sjsg 
11605ca02815Sjsg 	drm_modeset_drop_locks(&ctx);
11615ca02815Sjsg 	drm_modeset_acquire_fini(&ctx);
11625ca02815Sjsg 	drm_WARN(encoder->base.dev, ret,
11635ca02815Sjsg 		 "Acquiring modeset locks failed with %i\n", ret);
11645ca02815Sjsg 
11655ca02815Sjsg 	/*
11665ca02815Sjsg 	 * Keeping it consistent with intel_ddi_hotplug() and
11675ca02815Sjsg 	 * intel_hdmi_hotplug().
11685ca02815Sjsg 	 */
11695ca02815Sjsg 	if (state == INTEL_HOTPLUG_UNCHANGED && !connector->hotplug_retries)
11705ca02815Sjsg 		state = INTEL_HOTPLUG_RETRY;
11715ca02815Sjsg 
11725ca02815Sjsg 	return state;
11735ca02815Sjsg }
11745ca02815Sjsg 
ibx_digital_port_connected(struct intel_encoder * encoder)11755ca02815Sjsg static bool ibx_digital_port_connected(struct intel_encoder *encoder)
11765ca02815Sjsg {
11775ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
11781bb76ff1Sjsg 	u32 bit = dev_priv->display.hotplug.pch_hpd[encoder->hpd_pin];
11795ca02815Sjsg 
11805ca02815Sjsg 	return intel_de_read(dev_priv, SDEISR) & bit;
11815ca02815Sjsg }
11825ca02815Sjsg 
g4x_digital_port_connected(struct intel_encoder * encoder)11835ca02815Sjsg static bool g4x_digital_port_connected(struct intel_encoder *encoder)
11845ca02815Sjsg {
11855ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
11865ca02815Sjsg 	u32 bit;
11875ca02815Sjsg 
11885ca02815Sjsg 	switch (encoder->hpd_pin) {
11895ca02815Sjsg 	case HPD_PORT_B:
11905ca02815Sjsg 		bit = PORTB_HOTPLUG_LIVE_STATUS_G4X;
11915ca02815Sjsg 		break;
11925ca02815Sjsg 	case HPD_PORT_C:
11935ca02815Sjsg 		bit = PORTC_HOTPLUG_LIVE_STATUS_G4X;
11945ca02815Sjsg 		break;
11955ca02815Sjsg 	case HPD_PORT_D:
11965ca02815Sjsg 		bit = PORTD_HOTPLUG_LIVE_STATUS_G4X;
11975ca02815Sjsg 		break;
11985ca02815Sjsg 	default:
11995ca02815Sjsg 		MISSING_CASE(encoder->hpd_pin);
12005ca02815Sjsg 		return false;
12015ca02815Sjsg 	}
12025ca02815Sjsg 
12035ca02815Sjsg 	return intel_de_read(dev_priv, PORT_HOTPLUG_STAT) & bit;
12045ca02815Sjsg }
12055ca02815Sjsg 
ilk_digital_port_connected(struct intel_encoder * encoder)12065ca02815Sjsg static bool ilk_digital_port_connected(struct intel_encoder *encoder)
12075ca02815Sjsg {
12085ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
12091bb76ff1Sjsg 	u32 bit = dev_priv->display.hotplug.hpd[encoder->hpd_pin];
12105ca02815Sjsg 
12115ca02815Sjsg 	return intel_de_read(dev_priv, DEISR) & bit;
12125ca02815Sjsg }
12135ca02815Sjsg 
intel_dp_encoder_destroy(struct drm_encoder * encoder)12145ca02815Sjsg static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
12155ca02815Sjsg {
12165ca02815Sjsg 	intel_dp_encoder_flush_work(encoder);
12175ca02815Sjsg 
12185ca02815Sjsg 	drm_encoder_cleanup(encoder);
12195ca02815Sjsg 	kfree(enc_to_dig_port(to_intel_encoder(encoder)));
12205ca02815Sjsg }
12215ca02815Sjsg 
vlv_active_pipe(struct intel_dp * intel_dp)12225ca02815Sjsg enum pipe vlv_active_pipe(struct intel_dp *intel_dp)
12235ca02815Sjsg {
12245ca02815Sjsg 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
12255ca02815Sjsg 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
12265ca02815Sjsg 	enum pipe pipe;
12275ca02815Sjsg 
12285ca02815Sjsg 	if (g4x_dp_port_enabled(dev_priv, intel_dp->output_reg,
12295ca02815Sjsg 				encoder->port, &pipe))
12305ca02815Sjsg 		return pipe;
12315ca02815Sjsg 
12325ca02815Sjsg 	return INVALID_PIPE;
12335ca02815Sjsg }
12345ca02815Sjsg 
intel_dp_encoder_reset(struct drm_encoder * encoder)12355ca02815Sjsg static void intel_dp_encoder_reset(struct drm_encoder *encoder)
12365ca02815Sjsg {
12375ca02815Sjsg 	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
12385ca02815Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(encoder));
12395ca02815Sjsg 
12405ca02815Sjsg 	intel_dp->DP = intel_de_read(dev_priv, intel_dp->output_reg);
12415ca02815Sjsg 
12425ca02815Sjsg 	intel_dp->reset_link_params = true;
12435ca02815Sjsg 
12445ca02815Sjsg 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
12455ca02815Sjsg 		intel_wakeref_t wakeref;
12465ca02815Sjsg 
12475ca02815Sjsg 		with_intel_pps_lock(intel_dp, wakeref)
12485ca02815Sjsg 			intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp);
12495ca02815Sjsg 	}
12505ca02815Sjsg 
12515ca02815Sjsg 	intel_pps_encoder_reset(intel_dp);
12525ca02815Sjsg }
12535ca02815Sjsg 
12545ca02815Sjsg static const struct drm_encoder_funcs intel_dp_enc_funcs = {
12555ca02815Sjsg 	.reset = intel_dp_encoder_reset,
12565ca02815Sjsg 	.destroy = intel_dp_encoder_destroy,
12575ca02815Sjsg };
12585ca02815Sjsg 
g4x_dp_init(struct drm_i915_private * dev_priv,i915_reg_t output_reg,enum port port)12595ca02815Sjsg bool g4x_dp_init(struct drm_i915_private *dev_priv,
12605ca02815Sjsg 		 i915_reg_t output_reg, enum port port)
12615ca02815Sjsg {
1262*f005ef32Sjsg 	const struct intel_bios_encoder_data *devdata;
12635ca02815Sjsg 	struct intel_digital_port *dig_port;
12645ca02815Sjsg 	struct intel_encoder *intel_encoder;
12655ca02815Sjsg 	struct drm_encoder *encoder;
12665ca02815Sjsg 	struct intel_connector *intel_connector;
12675ca02815Sjsg 
1268*f005ef32Sjsg 	if (!assert_port_valid(dev_priv, port))
1269*f005ef32Sjsg 		return false;
1270*f005ef32Sjsg 
1271*f005ef32Sjsg 	devdata = intel_bios_encoder_data_lookup(dev_priv, port);
1272*f005ef32Sjsg 
1273*f005ef32Sjsg 	/* FIXME bail? */
1274*f005ef32Sjsg 	if (!devdata)
1275*f005ef32Sjsg 		drm_dbg_kms(&dev_priv->drm, "No VBT child device for DP-%c\n",
1276*f005ef32Sjsg 			    port_name(port));
1277*f005ef32Sjsg 
12785ca02815Sjsg 	dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL);
12795ca02815Sjsg 	if (!dig_port)
12805ca02815Sjsg 		return false;
12815ca02815Sjsg 
1282*f005ef32Sjsg 	dig_port->aux_ch = AUX_CH_NONE;
1283*f005ef32Sjsg 
12845ca02815Sjsg 	intel_connector = intel_connector_alloc();
12855ca02815Sjsg 	if (!intel_connector)
12865ca02815Sjsg 		goto err_connector_alloc;
12875ca02815Sjsg 
12885ca02815Sjsg 	intel_encoder = &dig_port->base;
12895ca02815Sjsg 	encoder = &intel_encoder->base;
12905ca02815Sjsg 
1291*f005ef32Sjsg 	intel_encoder->devdata = devdata;
1292*f005ef32Sjsg 
12935ca02815Sjsg 	rw_init(&dig_port->hdcp_mutex, "dhdcp");
12945ca02815Sjsg 
12955ca02815Sjsg 	if (drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
12965ca02815Sjsg 			     &intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS,
12975ca02815Sjsg 			     "DP %c", port_name(port)))
12985ca02815Sjsg 		goto err_encoder_init;
12995ca02815Sjsg 
13005ca02815Sjsg 	intel_encoder->hotplug = intel_dp_hotplug;
13015ca02815Sjsg 	intel_encoder->compute_config = intel_dp_compute_config;
13025ca02815Sjsg 	intel_encoder->get_hw_state = intel_dp_get_hw_state;
13035ca02815Sjsg 	intel_encoder->get_config = intel_dp_get_config;
13045ca02815Sjsg 	intel_encoder->sync_state = intel_dp_sync_state;
13055ca02815Sjsg 	intel_encoder->initial_fastset_check = intel_dp_initial_fastset_check;
13061bb76ff1Sjsg 	intel_encoder->update_pipe = intel_backlight_update;
13075ca02815Sjsg 	intel_encoder->suspend = intel_dp_encoder_suspend;
13085ca02815Sjsg 	intel_encoder->shutdown = intel_dp_encoder_shutdown;
13095ca02815Sjsg 	if (IS_CHERRYVIEW(dev_priv)) {
13105ca02815Sjsg 		intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable;
13115ca02815Sjsg 		intel_encoder->pre_enable = chv_pre_enable_dp;
13125ca02815Sjsg 		intel_encoder->enable = vlv_enable_dp;
13135ca02815Sjsg 		intel_encoder->disable = vlv_disable_dp;
13145ca02815Sjsg 		intel_encoder->post_disable = chv_post_disable_dp;
13155ca02815Sjsg 		intel_encoder->post_pll_disable = chv_dp_post_pll_disable;
13165ca02815Sjsg 	} else if (IS_VALLEYVIEW(dev_priv)) {
13175ca02815Sjsg 		intel_encoder->pre_pll_enable = vlv_dp_pre_pll_enable;
13185ca02815Sjsg 		intel_encoder->pre_enable = vlv_pre_enable_dp;
13195ca02815Sjsg 		intel_encoder->enable = vlv_enable_dp;
13205ca02815Sjsg 		intel_encoder->disable = vlv_disable_dp;
13215ca02815Sjsg 		intel_encoder->post_disable = vlv_post_disable_dp;
13225ca02815Sjsg 	} else {
13235ca02815Sjsg 		intel_encoder->pre_enable = g4x_pre_enable_dp;
13245ca02815Sjsg 		intel_encoder->enable = g4x_enable_dp;
13255ca02815Sjsg 		intel_encoder->disable = g4x_disable_dp;
13265ca02815Sjsg 		intel_encoder->post_disable = g4x_post_disable_dp;
13275ca02815Sjsg 	}
13285ca02815Sjsg 
13295ca02815Sjsg 	if ((IS_IVYBRIDGE(dev_priv) && port == PORT_A) ||
13305ca02815Sjsg 	    (HAS_PCH_CPT(dev_priv) && port != PORT_A))
13315ca02815Sjsg 		dig_port->dp.set_link_train = cpt_set_link_train;
13325ca02815Sjsg 	else
13335ca02815Sjsg 		dig_port->dp.set_link_train = g4x_set_link_train;
13345ca02815Sjsg 
13355ca02815Sjsg 	if (IS_CHERRYVIEW(dev_priv))
13361bb76ff1Sjsg 		intel_encoder->set_signal_levels = chv_set_signal_levels;
13375ca02815Sjsg 	else if (IS_VALLEYVIEW(dev_priv))
13381bb76ff1Sjsg 		intel_encoder->set_signal_levels = vlv_set_signal_levels;
13395ca02815Sjsg 	else if (IS_IVYBRIDGE(dev_priv) && port == PORT_A)
13401bb76ff1Sjsg 		intel_encoder->set_signal_levels = ivb_cpu_edp_set_signal_levels;
13415ca02815Sjsg 	else if (IS_SANDYBRIDGE(dev_priv) && port == PORT_A)
13421bb76ff1Sjsg 		intel_encoder->set_signal_levels = snb_cpu_edp_set_signal_levels;
13435ca02815Sjsg 	else
13441bb76ff1Sjsg 		intel_encoder->set_signal_levels = g4x_set_signal_levels;
13455ca02815Sjsg 
13465ca02815Sjsg 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
13475ca02815Sjsg 	    (HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) {
13485ca02815Sjsg 		dig_port->dp.preemph_max = intel_dp_preemph_max_3;
13495ca02815Sjsg 		dig_port->dp.voltage_max = intel_dp_voltage_max_3;
13505ca02815Sjsg 	} else {
13515ca02815Sjsg 		dig_port->dp.preemph_max = intel_dp_preemph_max_2;
13525ca02815Sjsg 		dig_port->dp.voltage_max = intel_dp_voltage_max_2;
13535ca02815Sjsg 	}
13545ca02815Sjsg 
13555ca02815Sjsg 	dig_port->dp.output_reg = output_reg;
13565ca02815Sjsg 	dig_port->max_lanes = 4;
13575ca02815Sjsg 
13585ca02815Sjsg 	intel_encoder->type = INTEL_OUTPUT_DP;
13591bb76ff1Sjsg 	intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port);
13605ca02815Sjsg 	if (IS_CHERRYVIEW(dev_priv)) {
13615ca02815Sjsg 		if (port == PORT_D)
13625ca02815Sjsg 			intel_encoder->pipe_mask = BIT(PIPE_C);
13635ca02815Sjsg 		else
13645ca02815Sjsg 			intel_encoder->pipe_mask = BIT(PIPE_A) | BIT(PIPE_B);
13655ca02815Sjsg 	} else {
13665ca02815Sjsg 		intel_encoder->pipe_mask = ~0;
13675ca02815Sjsg 	}
13685ca02815Sjsg 	intel_encoder->cloneable = 0;
13695ca02815Sjsg 	intel_encoder->port = port;
13705ca02815Sjsg 	intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
13715ca02815Sjsg 
13725ca02815Sjsg 	dig_port->hpd_pulse = intel_dp_hpd_pulse;
13735ca02815Sjsg 
13745ca02815Sjsg 	if (HAS_GMCH(dev_priv)) {
13755ca02815Sjsg 		dig_port->connected = g4x_digital_port_connected;
13765ca02815Sjsg 	} else {
13775ca02815Sjsg 		if (port == PORT_A)
13785ca02815Sjsg 			dig_port->connected = ilk_digital_port_connected;
13795ca02815Sjsg 		else
13805ca02815Sjsg 			dig_port->connected = ibx_digital_port_connected;
13815ca02815Sjsg 	}
13825ca02815Sjsg 
13835ca02815Sjsg 	if (port != PORT_A)
13845ca02815Sjsg 		intel_infoframe_init(dig_port);
13855ca02815Sjsg 
1386*f005ef32Sjsg 	dig_port->aux_ch = intel_dp_aux_ch(intel_encoder);
1387*f005ef32Sjsg 	if (dig_port->aux_ch == AUX_CH_NONE)
1388*f005ef32Sjsg 		goto err_init_connector;
1389*f005ef32Sjsg 
13905ca02815Sjsg 	if (!intel_dp_init_connector(dig_port, intel_connector))
13915ca02815Sjsg 		goto err_init_connector;
13925ca02815Sjsg 
13935ca02815Sjsg 	return true;
13945ca02815Sjsg 
13955ca02815Sjsg err_init_connector:
13965ca02815Sjsg 	drm_encoder_cleanup(encoder);
13975ca02815Sjsg err_encoder_init:
13985ca02815Sjsg 	kfree(intel_connector);
13995ca02815Sjsg err_connector_alloc:
14005ca02815Sjsg 	kfree(dig_port);
14015ca02815Sjsg 	return false;
14025ca02815Sjsg }
1403