xref: /openbmc/linux/drivers/gpu/drm/i915/display/g4x_hdmi.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
133e9e541SVille Syrjälä // SPDX-License-Identifier: MIT
233e9e541SVille Syrjälä /*
333e9e541SVille Syrjälä  * Copyright © 2020 Intel Corporation
433e9e541SVille Syrjälä  *
533e9e541SVille Syrjälä  * HDMI support for G4x,ILK,SNB,IVB,VLV,CHV (HSW+ handled by the DDI code).
633e9e541SVille Syrjälä  */
733e9e541SVille Syrjälä 
833e9e541SVille Syrjälä #include "g4x_hdmi.h"
9801543b2SJani Nikula #include "i915_reg.h"
10dafa65d1SVille Syrjälä #include "intel_atomic.h"
1133e9e541SVille Syrjälä #include "intel_audio.h"
1233e9e541SVille Syrjälä #include "intel_connector.h"
13fd2b94a5SJani Nikula #include "intel_crtc.h"
147785ae0bSVille Syrjälä #include "intel_de.h"
15979e1b32SImre Deak #include "intel_display_power.h"
1633e9e541SVille Syrjälä #include "intel_display_types.h"
17bb45217fSVille Syrjälä #include "intel_dp_aux.h"
1833e9e541SVille Syrjälä #include "intel_dpio_phy.h"
1933e9e541SVille Syrjälä #include "intel_fifo_underrun.h"
2033e9e541SVille Syrjälä #include "intel_hdmi.h"
2133e9e541SVille Syrjälä #include "intel_hotplug.h"
2233e9e541SVille Syrjälä #include "intel_sdvo.h"
231eecf31eSJani Nikula #include "vlv_sideband.h"
2433e9e541SVille Syrjälä 
intel_hdmi_prepare(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)2533e9e541SVille Syrjälä static void intel_hdmi_prepare(struct intel_encoder *encoder,
2633e9e541SVille Syrjälä 			       const struct intel_crtc_state *crtc_state)
2733e9e541SVille Syrjälä {
2833e9e541SVille Syrjälä 	struct drm_device *dev = encoder->base.dev;
2933e9e541SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(dev);
3033e9e541SVille Syrjälä 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3133e9e541SVille Syrjälä 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
3233e9e541SVille Syrjälä 	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
3333e9e541SVille Syrjälä 	u32 hdmi_val;
3433e9e541SVille Syrjälä 
3533e9e541SVille Syrjälä 	intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
3633e9e541SVille Syrjälä 
3733e9e541SVille Syrjälä 	hdmi_val = SDVO_ENCODING_HDMI;
3833e9e541SVille Syrjälä 	if (!HAS_PCH_SPLIT(dev_priv) && crtc_state->limited_color_range)
3933e9e541SVille Syrjälä 		hdmi_val |= HDMI_COLOR_RANGE_16_235;
4033e9e541SVille Syrjälä 	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
4133e9e541SVille Syrjälä 		hdmi_val |= SDVO_VSYNC_ACTIVE_HIGH;
4233e9e541SVille Syrjälä 	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
4333e9e541SVille Syrjälä 		hdmi_val |= SDVO_HSYNC_ACTIVE_HIGH;
4433e9e541SVille Syrjälä 
4533e9e541SVille Syrjälä 	if (crtc_state->pipe_bpp > 24)
4633e9e541SVille Syrjälä 		hdmi_val |= HDMI_COLOR_FORMAT_12bpc;
4733e9e541SVille Syrjälä 	else
4833e9e541SVille Syrjälä 		hdmi_val |= SDVO_COLOR_FORMAT_8bpc;
4933e9e541SVille Syrjälä 
5033e9e541SVille Syrjälä 	if (crtc_state->has_hdmi_sink)
5133e9e541SVille Syrjälä 		hdmi_val |= HDMI_MODE_SELECT_HDMI;
5233e9e541SVille Syrjälä 
5333e9e541SVille Syrjälä 	if (HAS_PCH_CPT(dev_priv))
5433e9e541SVille Syrjälä 		hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe);
5533e9e541SVille Syrjälä 	else if (IS_CHERRYVIEW(dev_priv))
5633e9e541SVille Syrjälä 		hdmi_val |= SDVO_PIPE_SEL_CHV(crtc->pipe);
5733e9e541SVille Syrjälä 	else
5833e9e541SVille Syrjälä 		hdmi_val |= SDVO_PIPE_SEL(crtc->pipe);
5933e9e541SVille Syrjälä 
6033e9e541SVille Syrjälä 	intel_de_write(dev_priv, intel_hdmi->hdmi_reg, hdmi_val);
6133e9e541SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
6233e9e541SVille Syrjälä }
6333e9e541SVille Syrjälä 
intel_hdmi_get_hw_state(struct intel_encoder * encoder,enum pipe * pipe)6433e9e541SVille Syrjälä static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
6533e9e541SVille Syrjälä 				    enum pipe *pipe)
6633e9e541SVille Syrjälä {
6733e9e541SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
6833e9e541SVille Syrjälä 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
6933e9e541SVille Syrjälä 	intel_wakeref_t wakeref;
7033e9e541SVille Syrjälä 	bool ret;
7133e9e541SVille Syrjälä 
7233e9e541SVille Syrjälä 	wakeref = intel_display_power_get_if_enabled(dev_priv,
7333e9e541SVille Syrjälä 						     encoder->power_domain);
7433e9e541SVille Syrjälä 	if (!wakeref)
7533e9e541SVille Syrjälä 		return false;
7633e9e541SVille Syrjälä 
7733e9e541SVille Syrjälä 	ret = intel_sdvo_port_enabled(dev_priv, intel_hdmi->hdmi_reg, pipe);
7833e9e541SVille Syrjälä 
7933e9e541SVille Syrjälä 	intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
8033e9e541SVille Syrjälä 
8133e9e541SVille Syrjälä 	return ret;
8233e9e541SVille Syrjälä }
8333e9e541SVille Syrjälä 
connector_is_hdmi(struct drm_connector * connector)84dafa65d1SVille Syrjälä static bool connector_is_hdmi(struct drm_connector *connector)
85dafa65d1SVille Syrjälä {
86dafa65d1SVille Syrjälä 	struct intel_encoder *encoder =
87dafa65d1SVille Syrjälä 		intel_attached_encoder(to_intel_connector(connector));
88dafa65d1SVille Syrjälä 
89dafa65d1SVille Syrjälä 	return encoder && encoder->type == INTEL_OUTPUT_HDMI;
90dafa65d1SVille Syrjälä }
91dafa65d1SVille Syrjälä 
g4x_compute_has_hdmi_sink(struct intel_atomic_state * state,struct intel_crtc * this_crtc)92dafa65d1SVille Syrjälä static bool g4x_compute_has_hdmi_sink(struct intel_atomic_state *state,
93dafa65d1SVille Syrjälä 				      struct intel_crtc *this_crtc)
94dafa65d1SVille Syrjälä {
95dafa65d1SVille Syrjälä 	const struct drm_connector_state *conn_state;
96dafa65d1SVille Syrjälä 	struct drm_connector *connector;
97dafa65d1SVille Syrjälä 	int i;
98dafa65d1SVille Syrjälä 
99dafa65d1SVille Syrjälä 	/*
100dafa65d1SVille Syrjälä 	 * On g4x only one HDMI port can transmit infoframes/audio at
101dafa65d1SVille Syrjälä 	 * any given time. Select the first suitable port for this duty.
102dafa65d1SVille Syrjälä 	 *
103dafa65d1SVille Syrjälä 	 * See also g4x_hdmi_connector_atomic_check().
104dafa65d1SVille Syrjälä 	 */
105dafa65d1SVille Syrjälä 	for_each_new_connector_in_state(&state->base, connector, conn_state, i) {
106dafa65d1SVille Syrjälä 		struct intel_encoder *encoder = to_intel_encoder(conn_state->best_encoder);
107dafa65d1SVille Syrjälä 		const struct intel_crtc_state *crtc_state;
108dafa65d1SVille Syrjälä 		struct intel_crtc *crtc;
109dafa65d1SVille Syrjälä 
110dafa65d1SVille Syrjälä 		if (!connector_is_hdmi(connector))
111dafa65d1SVille Syrjälä 			continue;
112dafa65d1SVille Syrjälä 
113dafa65d1SVille Syrjälä 		crtc = to_intel_crtc(conn_state->crtc);
114dafa65d1SVille Syrjälä 		if (!crtc)
115dafa65d1SVille Syrjälä 			continue;
116dafa65d1SVille Syrjälä 
117dafa65d1SVille Syrjälä 		crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
118dafa65d1SVille Syrjälä 
119dafa65d1SVille Syrjälä 		if (!intel_hdmi_compute_has_hdmi_sink(encoder, crtc_state, conn_state))
120dafa65d1SVille Syrjälä 			continue;
121dafa65d1SVille Syrjälä 
122dafa65d1SVille Syrjälä 		return crtc == this_crtc;
123dafa65d1SVille Syrjälä 	}
124dafa65d1SVille Syrjälä 
125dafa65d1SVille Syrjälä 	return false;
126dafa65d1SVille Syrjälä }
127dafa65d1SVille Syrjälä 
g4x_hdmi_compute_config(struct intel_encoder * encoder,struct intel_crtc_state * crtc_state,struct drm_connector_state * conn_state)12895067dc6SVille Syrjälä static int g4x_hdmi_compute_config(struct intel_encoder *encoder,
12995067dc6SVille Syrjälä 				   struct intel_crtc_state *crtc_state,
13095067dc6SVille Syrjälä 				   struct drm_connector_state *conn_state)
13195067dc6SVille Syrjälä {
132dafa65d1SVille Syrjälä 	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
133dafa65d1SVille Syrjälä 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
13495067dc6SVille Syrjälä 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
13595067dc6SVille Syrjälä 
13695067dc6SVille Syrjälä 	if (HAS_PCH_SPLIT(i915))
13795067dc6SVille Syrjälä 		crtc_state->has_pch_encoder = true;
13895067dc6SVille Syrjälä 
139dafa65d1SVille Syrjälä 	if (IS_G4X(i915))
140dafa65d1SVille Syrjälä 		crtc_state->has_hdmi_sink = g4x_compute_has_hdmi_sink(state, crtc);
141dafa65d1SVille Syrjälä 	else
14234682d60SVille Syrjälä 		crtc_state->has_hdmi_sink =
14334682d60SVille Syrjälä 			intel_hdmi_compute_has_hdmi_sink(encoder, crtc_state, conn_state);
14434682d60SVille Syrjälä 
14595067dc6SVille Syrjälä 	return intel_hdmi_compute_config(encoder, crtc_state, conn_state);
14695067dc6SVille Syrjälä }
14795067dc6SVille Syrjälä 
intel_hdmi_get_config(struct intel_encoder * encoder,struct intel_crtc_state * pipe_config)14833e9e541SVille Syrjälä static void intel_hdmi_get_config(struct intel_encoder *encoder,
14933e9e541SVille Syrjälä 				  struct intel_crtc_state *pipe_config)
15033e9e541SVille Syrjälä {
15133e9e541SVille Syrjälä 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
15233e9e541SVille Syrjälä 	struct drm_device *dev = encoder->base.dev;
15333e9e541SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(dev);
15433e9e541SVille Syrjälä 	u32 tmp, flags = 0;
15533e9e541SVille Syrjälä 	int dotclock;
15633e9e541SVille Syrjälä 
15733e9e541SVille Syrjälä 	pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI);
15833e9e541SVille Syrjälä 
15933e9e541SVille Syrjälä 	tmp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
16033e9e541SVille Syrjälä 
16133e9e541SVille Syrjälä 	if (tmp & SDVO_HSYNC_ACTIVE_HIGH)
16233e9e541SVille Syrjälä 		flags |= DRM_MODE_FLAG_PHSYNC;
16333e9e541SVille Syrjälä 	else
16433e9e541SVille Syrjälä 		flags |= DRM_MODE_FLAG_NHSYNC;
16533e9e541SVille Syrjälä 
16633e9e541SVille Syrjälä 	if (tmp & SDVO_VSYNC_ACTIVE_HIGH)
16733e9e541SVille Syrjälä 		flags |= DRM_MODE_FLAG_PVSYNC;
16833e9e541SVille Syrjälä 	else
16933e9e541SVille Syrjälä 		flags |= DRM_MODE_FLAG_NVSYNC;
17033e9e541SVille Syrjälä 
17133e9e541SVille Syrjälä 	if (tmp & HDMI_MODE_SELECT_HDMI)
17233e9e541SVille Syrjälä 		pipe_config->has_hdmi_sink = true;
17333e9e541SVille Syrjälä 
17433e9e541SVille Syrjälä 	pipe_config->infoframes.enable |=
17533e9e541SVille Syrjälä 		intel_hdmi_infoframes_enabled(encoder, pipe_config);
17633e9e541SVille Syrjälä 
17733e9e541SVille Syrjälä 	if (pipe_config->infoframes.enable)
17833e9e541SVille Syrjälä 		pipe_config->has_infoframe = true;
17933e9e541SVille Syrjälä 
18033e9e541SVille Syrjälä 	if (tmp & HDMI_AUDIO_ENABLE)
18133e9e541SVille Syrjälä 		pipe_config->has_audio = true;
18233e9e541SVille Syrjälä 
18333e9e541SVille Syrjälä 	if (!HAS_PCH_SPLIT(dev_priv) &&
18433e9e541SVille Syrjälä 	    tmp & HDMI_COLOR_RANGE_16_235)
18533e9e541SVille Syrjälä 		pipe_config->limited_color_range = true;
18633e9e541SVille Syrjälä 
18733e9e541SVille Syrjälä 	pipe_config->hw.adjusted_mode.flags |= flags;
18833e9e541SVille Syrjälä 
18933e9e541SVille Syrjälä 	if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc)
19086b972efSVille Syrjälä 		dotclock = DIV_ROUND_CLOSEST(pipe_config->port_clock * 2, 3);
19133e9e541SVille Syrjälä 	else
19233e9e541SVille Syrjälä 		dotclock = pipe_config->port_clock;
19333e9e541SVille Syrjälä 
19433e9e541SVille Syrjälä 	if (pipe_config->pixel_multiplier)
19533e9e541SVille Syrjälä 		dotclock /= pipe_config->pixel_multiplier;
19633e9e541SVille Syrjälä 
19733e9e541SVille Syrjälä 	pipe_config->hw.adjusted_mode.crtc_clock = dotclock;
19833e9e541SVille Syrjälä 
19933e9e541SVille Syrjälä 	pipe_config->lane_count = 4;
20033e9e541SVille Syrjälä 
20133e9e541SVille Syrjälä 	intel_hdmi_read_gcp_infoframe(encoder, pipe_config);
20233e9e541SVille Syrjälä 
20333e9e541SVille Syrjälä 	intel_read_infoframe(encoder, pipe_config,
20433e9e541SVille Syrjälä 			     HDMI_INFOFRAME_TYPE_AVI,
20533e9e541SVille Syrjälä 			     &pipe_config->infoframes.avi);
20633e9e541SVille Syrjälä 	intel_read_infoframe(encoder, pipe_config,
20733e9e541SVille Syrjälä 			     HDMI_INFOFRAME_TYPE_SPD,
20833e9e541SVille Syrjälä 			     &pipe_config->infoframes.spd);
20933e9e541SVille Syrjälä 	intel_read_infoframe(encoder, pipe_config,
21033e9e541SVille Syrjälä 			     HDMI_INFOFRAME_TYPE_VENDOR,
21133e9e541SVille Syrjälä 			     &pipe_config->infoframes.hdmi);
21261a60df6SVille Syrjälä 
21361a60df6SVille Syrjälä 	intel_audio_codec_get_config(encoder, pipe_config);
21433e9e541SVille Syrjälä }
21533e9e541SVille Syrjälä 
g4x_hdmi_enable_port(struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config)216a467a243SVille Syrjälä static void g4x_hdmi_enable_port(struct intel_encoder *encoder,
217a467a243SVille Syrjälä 				 const struct intel_crtc_state *pipe_config)
21833e9e541SVille Syrjälä {
21933e9e541SVille Syrjälä 	struct drm_device *dev = encoder->base.dev;
22033e9e541SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(dev);
22133e9e541SVille Syrjälä 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
22233e9e541SVille Syrjälä 	u32 temp;
22333e9e541SVille Syrjälä 
22433e9e541SVille Syrjälä 	temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
22533e9e541SVille Syrjälä 
22633e9e541SVille Syrjälä 	temp |= SDVO_ENABLE;
22733e9e541SVille Syrjälä 	if (pipe_config->has_audio)
22833e9e541SVille Syrjälä 		temp |= HDMI_AUDIO_ENABLE;
22933e9e541SVille Syrjälä 
23033e9e541SVille Syrjälä 	intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
23133e9e541SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
232a467a243SVille Syrjälä }
233a467a243SVille Syrjälä 
g4x_enable_hdmi(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)234a467a243SVille Syrjälä static void g4x_enable_hdmi(struct intel_atomic_state *state,
235a467a243SVille Syrjälä 			    struct intel_encoder *encoder,
236a467a243SVille Syrjälä 			    const struct intel_crtc_state *pipe_config,
237a467a243SVille Syrjälä 			    const struct drm_connector_state *conn_state)
238a467a243SVille Syrjälä {
239a467a243SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
240a467a243SVille Syrjälä 
241a467a243SVille Syrjälä 	g4x_hdmi_enable_port(encoder, pipe_config);
24233e9e541SVille Syrjälä 
243179db7c1SJani Nikula 	drm_WARN_ON(&dev_priv->drm, pipe_config->has_audio &&
244179db7c1SJani Nikula 		    !pipe_config->has_hdmi_sink);
245179db7c1SJani Nikula 	intel_audio_codec_enable(encoder, pipe_config, conn_state);
24633e9e541SVille Syrjälä }
24733e9e541SVille Syrjälä 
ibx_enable_hdmi(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)24833e9e541SVille Syrjälä static void ibx_enable_hdmi(struct intel_atomic_state *state,
24933e9e541SVille Syrjälä 			    struct intel_encoder *encoder,
25033e9e541SVille Syrjälä 			    const struct intel_crtc_state *pipe_config,
25133e9e541SVille Syrjälä 			    const struct drm_connector_state *conn_state)
25233e9e541SVille Syrjälä {
25333e9e541SVille Syrjälä 	struct drm_device *dev = encoder->base.dev;
25433e9e541SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(dev);
25533e9e541SVille Syrjälä 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
25633e9e541SVille Syrjälä 	u32 temp;
25733e9e541SVille Syrjälä 
25833e9e541SVille Syrjälä 	temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
25933e9e541SVille Syrjälä 
26033e9e541SVille Syrjälä 	temp |= SDVO_ENABLE;
26133e9e541SVille Syrjälä 	if (pipe_config->has_audio)
26233e9e541SVille Syrjälä 		temp |= HDMI_AUDIO_ENABLE;
26333e9e541SVille Syrjälä 
26433e9e541SVille Syrjälä 	/*
26533e9e541SVille Syrjälä 	 * HW workaround, need to write this twice for issue
26633e9e541SVille Syrjälä 	 * that may result in first write getting masked.
26733e9e541SVille Syrjälä 	 */
26833e9e541SVille Syrjälä 	intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
26933e9e541SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
27033e9e541SVille Syrjälä 	intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
27133e9e541SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
27233e9e541SVille Syrjälä 
27333e9e541SVille Syrjälä 	/*
27433e9e541SVille Syrjälä 	 * HW workaround, need to toggle enable bit off and on
27533e9e541SVille Syrjälä 	 * for 12bpc with pixel repeat.
27633e9e541SVille Syrjälä 	 *
27733e9e541SVille Syrjälä 	 * FIXME: BSpec says this should be done at the end of
27833e9e541SVille Syrjälä 	 * the modeset sequence, so not sure if this isn't too soon.
27933e9e541SVille Syrjälä 	 */
28033e9e541SVille Syrjälä 	if (pipe_config->pipe_bpp > 24 &&
28133e9e541SVille Syrjälä 	    pipe_config->pixel_multiplier > 1) {
28233e9e541SVille Syrjälä 		intel_de_write(dev_priv, intel_hdmi->hdmi_reg,
28333e9e541SVille Syrjälä 			       temp & ~SDVO_ENABLE);
28433e9e541SVille Syrjälä 		intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
28533e9e541SVille Syrjälä 
28633e9e541SVille Syrjälä 		/*
28733e9e541SVille Syrjälä 		 * HW workaround, need to write this twice for issue
28833e9e541SVille Syrjälä 		 * that may result in first write getting masked.
28933e9e541SVille Syrjälä 		 */
29033e9e541SVille Syrjälä 		intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
29133e9e541SVille Syrjälä 		intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
29233e9e541SVille Syrjälä 		intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
29333e9e541SVille Syrjälä 		intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
29433e9e541SVille Syrjälä 	}
29533e9e541SVille Syrjälä 
296179db7c1SJani Nikula 	drm_WARN_ON(&dev_priv->drm, pipe_config->has_audio &&
297179db7c1SJani Nikula 		    !pipe_config->has_hdmi_sink);
298179db7c1SJani Nikula 	intel_audio_codec_enable(encoder, pipe_config, conn_state);
29933e9e541SVille Syrjälä }
30033e9e541SVille Syrjälä 
cpt_enable_hdmi(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)30133e9e541SVille Syrjälä static void cpt_enable_hdmi(struct intel_atomic_state *state,
30233e9e541SVille Syrjälä 			    struct intel_encoder *encoder,
30333e9e541SVille Syrjälä 			    const struct intel_crtc_state *pipe_config,
30433e9e541SVille Syrjälä 			    const struct drm_connector_state *conn_state)
30533e9e541SVille Syrjälä {
30633e9e541SVille Syrjälä 	struct drm_device *dev = encoder->base.dev;
30733e9e541SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(dev);
30833e9e541SVille Syrjälä 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
30933e9e541SVille Syrjälä 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
31033e9e541SVille Syrjälä 	enum pipe pipe = crtc->pipe;
31133e9e541SVille Syrjälä 	u32 temp;
31233e9e541SVille Syrjälä 
31333e9e541SVille Syrjälä 	temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
31433e9e541SVille Syrjälä 
31533e9e541SVille Syrjälä 	temp |= SDVO_ENABLE;
31633e9e541SVille Syrjälä 	if (pipe_config->has_audio)
31733e9e541SVille Syrjälä 		temp |= HDMI_AUDIO_ENABLE;
31833e9e541SVille Syrjälä 
31933e9e541SVille Syrjälä 	/*
32033e9e541SVille Syrjälä 	 * WaEnableHDMI8bpcBefore12bpc:snb,ivb
32133e9e541SVille Syrjälä 	 *
32233e9e541SVille Syrjälä 	 * The procedure for 12bpc is as follows:
32333e9e541SVille Syrjälä 	 * 1. disable HDMI clock gating
32433e9e541SVille Syrjälä 	 * 2. enable HDMI with 8bpc
32533e9e541SVille Syrjälä 	 * 3. enable HDMI with 12bpc
32633e9e541SVille Syrjälä 	 * 4. enable HDMI clock gating
32733e9e541SVille Syrjälä 	 */
32833e9e541SVille Syrjälä 
32933e9e541SVille Syrjälä 	if (pipe_config->pipe_bpp > 24) {
330cd5103eeSAndrzej Hajda 		intel_de_rmw(dev_priv, TRANS_CHICKEN1(pipe),
331cd5103eeSAndrzej Hajda 			     0, TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE);
33233e9e541SVille Syrjälä 
33333e9e541SVille Syrjälä 		temp &= ~SDVO_COLOR_FORMAT_MASK;
33433e9e541SVille Syrjälä 		temp |= SDVO_COLOR_FORMAT_8bpc;
33533e9e541SVille Syrjälä 	}
33633e9e541SVille Syrjälä 
33733e9e541SVille Syrjälä 	intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
33833e9e541SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
33933e9e541SVille Syrjälä 
34033e9e541SVille Syrjälä 	if (pipe_config->pipe_bpp > 24) {
34133e9e541SVille Syrjälä 		temp &= ~SDVO_COLOR_FORMAT_MASK;
34233e9e541SVille Syrjälä 		temp |= HDMI_COLOR_FORMAT_12bpc;
34333e9e541SVille Syrjälä 
34433e9e541SVille Syrjälä 		intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
34533e9e541SVille Syrjälä 		intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
34633e9e541SVille Syrjälä 
347cd5103eeSAndrzej Hajda 		intel_de_rmw(dev_priv, TRANS_CHICKEN1(pipe),
348cd5103eeSAndrzej Hajda 			     TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE, 0);
34933e9e541SVille Syrjälä 	}
35033e9e541SVille Syrjälä 
351179db7c1SJani Nikula 	drm_WARN_ON(&dev_priv->drm, pipe_config->has_audio &&
352179db7c1SJani Nikula 		    !pipe_config->has_hdmi_sink);
353179db7c1SJani Nikula 	intel_audio_codec_enable(encoder, pipe_config, conn_state);
35433e9e541SVille Syrjälä }
35533e9e541SVille Syrjälä 
vlv_enable_hdmi(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)35633e9e541SVille Syrjälä static void vlv_enable_hdmi(struct intel_atomic_state *state,
35733e9e541SVille Syrjälä 			    struct intel_encoder *encoder,
35833e9e541SVille Syrjälä 			    const struct intel_crtc_state *pipe_config,
35933e9e541SVille Syrjälä 			    const struct drm_connector_state *conn_state)
36033e9e541SVille Syrjälä {
361a467a243SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
362a467a243SVille Syrjälä 
363a467a243SVille Syrjälä 	drm_WARN_ON(&dev_priv->drm, pipe_config->has_audio &&
364a467a243SVille Syrjälä 		    !pipe_config->has_hdmi_sink);
365a467a243SVille Syrjälä 	intel_audio_codec_enable(encoder, pipe_config, conn_state);
36633e9e541SVille Syrjälä }
36733e9e541SVille Syrjälä 
intel_disable_hdmi(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)36833e9e541SVille Syrjälä static void intel_disable_hdmi(struct intel_atomic_state *state,
36933e9e541SVille Syrjälä 			       struct intel_encoder *encoder,
37033e9e541SVille Syrjälä 			       const struct intel_crtc_state *old_crtc_state,
37133e9e541SVille Syrjälä 			       const struct drm_connector_state *old_conn_state)
37233e9e541SVille Syrjälä {
37333e9e541SVille Syrjälä 	struct drm_device *dev = encoder->base.dev;
37433e9e541SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(dev);
37533e9e541SVille Syrjälä 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
37633e9e541SVille Syrjälä 	struct intel_digital_port *dig_port =
37733e9e541SVille Syrjälä 		hdmi_to_dig_port(intel_hdmi);
37833e9e541SVille Syrjälä 	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
37933e9e541SVille Syrjälä 	u32 temp;
38033e9e541SVille Syrjälä 
38133e9e541SVille Syrjälä 	temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
38233e9e541SVille Syrjälä 
38333e9e541SVille Syrjälä 	temp &= ~(SDVO_ENABLE | HDMI_AUDIO_ENABLE);
38433e9e541SVille Syrjälä 	intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
38533e9e541SVille Syrjälä 	intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
38633e9e541SVille Syrjälä 
38733e9e541SVille Syrjälä 	/*
38833e9e541SVille Syrjälä 	 * HW workaround for IBX, we need to move the port
38933e9e541SVille Syrjälä 	 * to transcoder A after disabling it to allow the
39033e9e541SVille Syrjälä 	 * matching DP port to be enabled on transcoder A.
39133e9e541SVille Syrjälä 	 */
39233e9e541SVille Syrjälä 	if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B) {
39333e9e541SVille Syrjälä 		/*
39433e9e541SVille Syrjälä 		 * We get CPU/PCH FIFO underruns on the other pipe when
39533e9e541SVille Syrjälä 		 * doing the workaround. Sweep them under the rug.
39633e9e541SVille Syrjälä 		 */
39733e9e541SVille Syrjälä 		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false);
39833e9e541SVille Syrjälä 		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
39933e9e541SVille Syrjälä 
40033e9e541SVille Syrjälä 		temp &= ~SDVO_PIPE_SEL_MASK;
40133e9e541SVille Syrjälä 		temp |= SDVO_ENABLE | SDVO_PIPE_SEL(PIPE_A);
40233e9e541SVille Syrjälä 		/*
40333e9e541SVille Syrjälä 		 * HW workaround, need to write this twice for issue
40433e9e541SVille Syrjälä 		 * that may result in first write getting masked.
40533e9e541SVille Syrjälä 		 */
40633e9e541SVille Syrjälä 		intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
40733e9e541SVille Syrjälä 		intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
40833e9e541SVille Syrjälä 		intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
40933e9e541SVille Syrjälä 		intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
41033e9e541SVille Syrjälä 
41133e9e541SVille Syrjälä 		temp &= ~SDVO_ENABLE;
41233e9e541SVille Syrjälä 		intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
41333e9e541SVille Syrjälä 		intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
41433e9e541SVille Syrjälä 
41533e9e541SVille Syrjälä 		intel_wait_for_vblank_if_active(dev_priv, PIPE_A);
41633e9e541SVille Syrjälä 		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true);
41733e9e541SVille Syrjälä 		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
41833e9e541SVille Syrjälä 	}
41933e9e541SVille Syrjälä 
42033e9e541SVille Syrjälä 	dig_port->set_infoframes(encoder,
42133e9e541SVille Syrjälä 				       false,
42233e9e541SVille Syrjälä 				       old_crtc_state, old_conn_state);
42333e9e541SVille Syrjälä 
42433e9e541SVille Syrjälä 	intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
42533e9e541SVille Syrjälä }
42633e9e541SVille Syrjälä 
g4x_disable_hdmi(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)42733e9e541SVille Syrjälä static void g4x_disable_hdmi(struct intel_atomic_state *state,
42833e9e541SVille Syrjälä 			     struct intel_encoder *encoder,
42933e9e541SVille Syrjälä 			     const struct intel_crtc_state *old_crtc_state,
43033e9e541SVille Syrjälä 			     const struct drm_connector_state *old_conn_state)
43133e9e541SVille Syrjälä {
432179db7c1SJani Nikula 	intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
43333e9e541SVille Syrjälä 
43433e9e541SVille Syrjälä 	intel_disable_hdmi(state, encoder, old_crtc_state, old_conn_state);
43533e9e541SVille Syrjälä }
43633e9e541SVille Syrjälä 
pch_disable_hdmi(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)43733e9e541SVille Syrjälä static void pch_disable_hdmi(struct intel_atomic_state *state,
43833e9e541SVille Syrjälä 			     struct intel_encoder *encoder,
43933e9e541SVille Syrjälä 			     const struct intel_crtc_state *old_crtc_state,
44033e9e541SVille Syrjälä 			     const struct drm_connector_state *old_conn_state)
44133e9e541SVille Syrjälä {
442179db7c1SJani Nikula 	intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
44333e9e541SVille Syrjälä }
44433e9e541SVille Syrjälä 
pch_post_disable_hdmi(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)44533e9e541SVille Syrjälä static void pch_post_disable_hdmi(struct intel_atomic_state *state,
44633e9e541SVille Syrjälä 				  struct intel_encoder *encoder,
44733e9e541SVille Syrjälä 				  const struct intel_crtc_state *old_crtc_state,
44833e9e541SVille Syrjälä 				  const struct drm_connector_state *old_conn_state)
44933e9e541SVille Syrjälä {
45033e9e541SVille Syrjälä 	intel_disable_hdmi(state, encoder, old_crtc_state, old_conn_state);
45133e9e541SVille Syrjälä }
45233e9e541SVille Syrjälä 
intel_hdmi_pre_enable(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)45333e9e541SVille Syrjälä static void intel_hdmi_pre_enable(struct intel_atomic_state *state,
45433e9e541SVille Syrjälä 				  struct intel_encoder *encoder,
45533e9e541SVille Syrjälä 				  const struct intel_crtc_state *pipe_config,
45633e9e541SVille Syrjälä 				  const struct drm_connector_state *conn_state)
45733e9e541SVille Syrjälä {
45833e9e541SVille Syrjälä 	struct intel_digital_port *dig_port =
45933e9e541SVille Syrjälä 		enc_to_dig_port(encoder);
46033e9e541SVille Syrjälä 
46133e9e541SVille Syrjälä 	intel_hdmi_prepare(encoder, pipe_config);
46233e9e541SVille Syrjälä 
46333e9e541SVille Syrjälä 	dig_port->set_infoframes(encoder,
46433e9e541SVille Syrjälä 				       pipe_config->has_infoframe,
46533e9e541SVille Syrjälä 				       pipe_config, conn_state);
46633e9e541SVille Syrjälä }
46733e9e541SVille Syrjälä 
vlv_hdmi_pre_enable(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)46833e9e541SVille Syrjälä static void vlv_hdmi_pre_enable(struct intel_atomic_state *state,
46933e9e541SVille Syrjälä 				struct intel_encoder *encoder,
47033e9e541SVille Syrjälä 				const struct intel_crtc_state *pipe_config,
47133e9e541SVille Syrjälä 				const struct drm_connector_state *conn_state)
47233e9e541SVille Syrjälä {
47333e9e541SVille Syrjälä 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
47433e9e541SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
47533e9e541SVille Syrjälä 
47633e9e541SVille Syrjälä 	vlv_phy_pre_encoder_enable(encoder, pipe_config);
47733e9e541SVille Syrjälä 
47833e9e541SVille Syrjälä 	/* HDMI 1.0V-2dB */
47933e9e541SVille Syrjälä 	vlv_set_phy_signal_level(encoder, pipe_config,
48033e9e541SVille Syrjälä 				 0x2b245f5f, 0x00002000,
48133e9e541SVille Syrjälä 				 0x5578b83a, 0x2b247878);
48233e9e541SVille Syrjälä 
48333e9e541SVille Syrjälä 	dig_port->set_infoframes(encoder,
48433e9e541SVille Syrjälä 			      pipe_config->has_infoframe,
48533e9e541SVille Syrjälä 			      pipe_config, conn_state);
48633e9e541SVille Syrjälä 
487a467a243SVille Syrjälä 	g4x_hdmi_enable_port(encoder, pipe_config);
48833e9e541SVille Syrjälä 
48933e9e541SVille Syrjälä 	vlv_wait_port_ready(dev_priv, dig_port, 0x0);
49033e9e541SVille Syrjälä }
49133e9e541SVille Syrjälä 
vlv_hdmi_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)49233e9e541SVille Syrjälä static void vlv_hdmi_pre_pll_enable(struct intel_atomic_state *state,
49333e9e541SVille Syrjälä 				    struct intel_encoder *encoder,
49433e9e541SVille Syrjälä 				    const struct intel_crtc_state *pipe_config,
49533e9e541SVille Syrjälä 				    const struct drm_connector_state *conn_state)
49633e9e541SVille Syrjälä {
49733e9e541SVille Syrjälä 	intel_hdmi_prepare(encoder, pipe_config);
49833e9e541SVille Syrjälä 
49933e9e541SVille Syrjälä 	vlv_phy_pre_pll_enable(encoder, pipe_config);
50033e9e541SVille Syrjälä }
50133e9e541SVille Syrjälä 
chv_hdmi_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)50233e9e541SVille Syrjälä static void chv_hdmi_pre_pll_enable(struct intel_atomic_state *state,
50333e9e541SVille Syrjälä 				    struct intel_encoder *encoder,
50433e9e541SVille Syrjälä 				    const struct intel_crtc_state *pipe_config,
50533e9e541SVille Syrjälä 				    const struct drm_connector_state *conn_state)
50633e9e541SVille Syrjälä {
50733e9e541SVille Syrjälä 	intel_hdmi_prepare(encoder, pipe_config);
50833e9e541SVille Syrjälä 
50933e9e541SVille Syrjälä 	chv_phy_pre_pll_enable(encoder, pipe_config);
51033e9e541SVille Syrjälä }
51133e9e541SVille Syrjälä 
chv_hdmi_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)51233e9e541SVille Syrjälä static void chv_hdmi_post_pll_disable(struct intel_atomic_state *state,
51333e9e541SVille Syrjälä 				      struct intel_encoder *encoder,
51433e9e541SVille Syrjälä 				      const struct intel_crtc_state *old_crtc_state,
51533e9e541SVille Syrjälä 				      const struct drm_connector_state *old_conn_state)
51633e9e541SVille Syrjälä {
51733e9e541SVille Syrjälä 	chv_phy_post_pll_disable(encoder, old_crtc_state);
51833e9e541SVille Syrjälä }
51933e9e541SVille Syrjälä 
vlv_hdmi_post_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)52033e9e541SVille Syrjälä static void vlv_hdmi_post_disable(struct intel_atomic_state *state,
52133e9e541SVille Syrjälä 				  struct intel_encoder *encoder,
52233e9e541SVille Syrjälä 				  const struct intel_crtc_state *old_crtc_state,
52333e9e541SVille Syrjälä 				  const struct drm_connector_state *old_conn_state)
52433e9e541SVille Syrjälä {
52533e9e541SVille Syrjälä 	/* Reset lanes to avoid HDMI flicker (VLV w/a) */
52633e9e541SVille Syrjälä 	vlv_phy_reset_lanes(encoder, old_crtc_state);
52733e9e541SVille Syrjälä }
52833e9e541SVille Syrjälä 
chv_hdmi_post_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)52933e9e541SVille Syrjälä static void chv_hdmi_post_disable(struct intel_atomic_state *state,
53033e9e541SVille Syrjälä 				  struct intel_encoder *encoder,
53133e9e541SVille Syrjälä 				  const struct intel_crtc_state *old_crtc_state,
53233e9e541SVille Syrjälä 				  const struct drm_connector_state *old_conn_state)
53333e9e541SVille Syrjälä {
53433e9e541SVille Syrjälä 	struct drm_device *dev = encoder->base.dev;
53533e9e541SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(dev);
53633e9e541SVille Syrjälä 
53733e9e541SVille Syrjälä 	vlv_dpio_get(dev_priv);
53833e9e541SVille Syrjälä 
53933e9e541SVille Syrjälä 	/* Assert data lane reset */
54033e9e541SVille Syrjälä 	chv_data_lane_soft_reset(encoder, old_crtc_state, true);
54133e9e541SVille Syrjälä 
54233e9e541SVille Syrjälä 	vlv_dpio_put(dev_priv);
54333e9e541SVille Syrjälä }
54433e9e541SVille Syrjälä 
chv_hdmi_pre_enable(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)54533e9e541SVille Syrjälä static void chv_hdmi_pre_enable(struct intel_atomic_state *state,
54633e9e541SVille Syrjälä 				struct intel_encoder *encoder,
54733e9e541SVille Syrjälä 				const struct intel_crtc_state *pipe_config,
54833e9e541SVille Syrjälä 				const struct drm_connector_state *conn_state)
54933e9e541SVille Syrjälä {
55033e9e541SVille Syrjälä 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
55133e9e541SVille Syrjälä 	struct drm_device *dev = encoder->base.dev;
55233e9e541SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(dev);
55333e9e541SVille Syrjälä 
55433e9e541SVille Syrjälä 	chv_phy_pre_encoder_enable(encoder, pipe_config);
55533e9e541SVille Syrjälä 
55633e9e541SVille Syrjälä 	/* FIXME: Program the support xxx V-dB */
55733e9e541SVille Syrjälä 	/* Use 800mV-0dB */
55833e9e541SVille Syrjälä 	chv_set_phy_signal_level(encoder, pipe_config, 128, 102, false);
55933e9e541SVille Syrjälä 
56033e9e541SVille Syrjälä 	dig_port->set_infoframes(encoder,
56133e9e541SVille Syrjälä 			      pipe_config->has_infoframe,
56233e9e541SVille Syrjälä 			      pipe_config, conn_state);
56333e9e541SVille Syrjälä 
564a467a243SVille Syrjälä 	g4x_hdmi_enable_port(encoder, pipe_config);
56533e9e541SVille Syrjälä 
56633e9e541SVille Syrjälä 	vlv_wait_port_ready(dev_priv, dig_port, 0x0);
56733e9e541SVille Syrjälä 
56833e9e541SVille Syrjälä 	/* Second common lane will stay alive on its own now */
56933e9e541SVille Syrjälä 	chv_phy_release_cl2_override(encoder);
57033e9e541SVille Syrjälä }
57133e9e541SVille Syrjälä 
57233e9e541SVille Syrjälä static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
57333e9e541SVille Syrjälä 	.destroy = intel_encoder_destroy,
57433e9e541SVille Syrjälä };
57533e9e541SVille Syrjälä 
57633e9e541SVille Syrjälä static enum intel_hotplug_state
intel_hdmi_hotplug(struct intel_encoder * encoder,struct intel_connector * connector)57733e9e541SVille Syrjälä intel_hdmi_hotplug(struct intel_encoder *encoder,
57833e9e541SVille Syrjälä 		   struct intel_connector *connector)
57933e9e541SVille Syrjälä {
58033e9e541SVille Syrjälä 	enum intel_hotplug_state state;
58133e9e541SVille Syrjälä 
58233e9e541SVille Syrjälä 	state = intel_encoder_hotplug(encoder, connector);
58333e9e541SVille Syrjälä 
58433e9e541SVille Syrjälä 	/*
58533e9e541SVille Syrjälä 	 * On many platforms the HDMI live state signal is known to be
58633e9e541SVille Syrjälä 	 * unreliable, so we can't use it to detect if a sink is connected or
58733e9e541SVille Syrjälä 	 * not. Instead we detect if it's connected based on whether we can
58833e9e541SVille Syrjälä 	 * read the EDID or not. That in turn has a problem during disconnect,
58933e9e541SVille Syrjälä 	 * since the HPD interrupt may be raised before the DDC lines get
59033e9e541SVille Syrjälä 	 * disconnected (due to how the required length of DDC vs. HPD
59133e9e541SVille Syrjälä 	 * connector pins are specified) and so we'll still be able to get a
59233e9e541SVille Syrjälä 	 * valid EDID. To solve this schedule another detection cycle if this
59333e9e541SVille Syrjälä 	 * time around we didn't detect any change in the sink's connection
59433e9e541SVille Syrjälä 	 * status.
59533e9e541SVille Syrjälä 	 */
59633e9e541SVille Syrjälä 	if (state == INTEL_HOTPLUG_UNCHANGED && !connector->hotplug_retries)
59733e9e541SVille Syrjälä 		state = INTEL_HOTPLUG_RETRY;
59833e9e541SVille Syrjälä 
59933e9e541SVille Syrjälä 	return state;
60033e9e541SVille Syrjälä }
60133e9e541SVille Syrjälä 
g4x_hdmi_connector_atomic_check(struct drm_connector * connector,struct drm_atomic_state * state)602dafa65d1SVille Syrjälä int g4x_hdmi_connector_atomic_check(struct drm_connector *connector,
603dafa65d1SVille Syrjälä 				    struct drm_atomic_state *state)
604dafa65d1SVille Syrjälä {
605dafa65d1SVille Syrjälä 	struct drm_i915_private *i915 = to_i915(state->dev);
606dafa65d1SVille Syrjälä 	struct drm_connector_list_iter conn_iter;
607dafa65d1SVille Syrjälä 	struct drm_connector *conn;
608dafa65d1SVille Syrjälä 	int ret;
609dafa65d1SVille Syrjälä 
610dafa65d1SVille Syrjälä 	ret = intel_digital_connector_atomic_check(connector, state);
611dafa65d1SVille Syrjälä 	if (ret)
612dafa65d1SVille Syrjälä 		return ret;
613dafa65d1SVille Syrjälä 
614dafa65d1SVille Syrjälä 	if (!IS_G4X(i915))
615dafa65d1SVille Syrjälä 		return 0;
616dafa65d1SVille Syrjälä 
617dafa65d1SVille Syrjälä 	if (!intel_connector_needs_modeset(to_intel_atomic_state(state), connector))
618dafa65d1SVille Syrjälä 		return 0;
619dafa65d1SVille Syrjälä 
620dafa65d1SVille Syrjälä 	/*
621dafa65d1SVille Syrjälä 	 * On g4x only one HDMI port can transmit infoframes/audio
622dafa65d1SVille Syrjälä 	 * at any given time. Make sure all enabled HDMI ports are
623dafa65d1SVille Syrjälä 	 * included in the state so that it's possible to select
624dafa65d1SVille Syrjälä 	 * one of them for this duty.
625dafa65d1SVille Syrjälä 	 *
626dafa65d1SVille Syrjälä 	 * See also g4x_compute_has_hdmi_sink().
627dafa65d1SVille Syrjälä 	 */
628dafa65d1SVille Syrjälä 	drm_connector_list_iter_begin(&i915->drm, &conn_iter);
629dafa65d1SVille Syrjälä 	drm_for_each_connector_iter(conn, &conn_iter) {
630dafa65d1SVille Syrjälä 		struct drm_connector_state *conn_state;
631dafa65d1SVille Syrjälä 		struct drm_crtc_state *crtc_state;
632dafa65d1SVille Syrjälä 		struct drm_crtc *crtc;
633dafa65d1SVille Syrjälä 
634dafa65d1SVille Syrjälä 		if (!connector_is_hdmi(conn))
635dafa65d1SVille Syrjälä 			continue;
636dafa65d1SVille Syrjälä 
637dafa65d1SVille Syrjälä 		drm_dbg_kms(&i915->drm, "Adding [CONNECTOR:%d:%s]\n",
638dafa65d1SVille Syrjälä 			    conn->base.id, conn->name);
639dafa65d1SVille Syrjälä 
640dafa65d1SVille Syrjälä 		conn_state = drm_atomic_get_connector_state(state, conn);
641dafa65d1SVille Syrjälä 		if (IS_ERR(conn_state)) {
642dafa65d1SVille Syrjälä 			ret = PTR_ERR(conn_state);
643dafa65d1SVille Syrjälä 			break;
644dafa65d1SVille Syrjälä 		}
645dafa65d1SVille Syrjälä 
646dafa65d1SVille Syrjälä 		crtc = conn_state->crtc;
647dafa65d1SVille Syrjälä 		if (!crtc)
648dafa65d1SVille Syrjälä 			continue;
649dafa65d1SVille Syrjälä 
650dafa65d1SVille Syrjälä 		crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
651dafa65d1SVille Syrjälä 		crtc_state->mode_changed = true;
652dafa65d1SVille Syrjälä 
653dafa65d1SVille Syrjälä 		ret = drm_atomic_add_affected_planes(state, crtc);
654dafa65d1SVille Syrjälä 		if (ret)
655dafa65d1SVille Syrjälä 			break;
656dafa65d1SVille Syrjälä 	}
657dafa65d1SVille Syrjälä 	drm_connector_list_iter_end(&conn_iter);
658dafa65d1SVille Syrjälä 
659dafa65d1SVille Syrjälä 	return ret;
660dafa65d1SVille Syrjälä }
661dafa65d1SVille Syrjälä 
is_hdmi_port_valid(struct drm_i915_private * i915,enum port port)66239432640SVille Syrjälä static bool is_hdmi_port_valid(struct drm_i915_private *i915, enum port port)
66339432640SVille Syrjälä {
66439432640SVille Syrjälä 	if (IS_G4X(i915) || IS_VALLEYVIEW(i915))
66539432640SVille Syrjälä 		return port == PORT_B || port == PORT_C;
66639432640SVille Syrjälä 	else
66739432640SVille Syrjälä 		return port == PORT_B || port == PORT_C || port == PORT_D;
66839432640SVille Syrjälä }
66939432640SVille Syrjälä 
assert_hdmi_port_valid(struct drm_i915_private * i915,enum port port)67039432640SVille Syrjälä static bool assert_hdmi_port_valid(struct drm_i915_private *i915, enum port port)
67139432640SVille Syrjälä {
67239432640SVille Syrjälä 	return !drm_WARN(&i915->drm, !is_hdmi_port_valid(i915, port),
67339432640SVille Syrjälä 			 "Platform does not support HDMI %c\n", port_name(port));
67439432640SVille Syrjälä }
67539432640SVille Syrjälä 
g4x_hdmi_init(struct drm_i915_private * dev_priv,i915_reg_t hdmi_reg,enum port port)676053ffdd1SVille Syrjälä void g4x_hdmi_init(struct drm_i915_private *dev_priv,
67733e9e541SVille Syrjälä 		   i915_reg_t hdmi_reg, enum port port)
67833e9e541SVille Syrjälä {
6791b108bc7SVille Syrjälä 	const struct intel_bios_encoder_data *devdata;
68033e9e541SVille Syrjälä 	struct intel_digital_port *dig_port;
68133e9e541SVille Syrjälä 	struct intel_encoder *intel_encoder;
68233e9e541SVille Syrjälä 	struct intel_connector *intel_connector;
68333e9e541SVille Syrjälä 
684679df6f1SVille Syrjälä 	if (!assert_port_valid(dev_priv, port))
685679df6f1SVille Syrjälä 		return;
686679df6f1SVille Syrjälä 
68739432640SVille Syrjälä 	if (!assert_hdmi_port_valid(dev_priv, port))
68839432640SVille Syrjälä 		return;
68939432640SVille Syrjälä 
6901b108bc7SVille Syrjälä 	devdata = intel_bios_encoder_data_lookup(dev_priv, port);
6911b108bc7SVille Syrjälä 
6921b108bc7SVille Syrjälä 	/* FIXME bail? */
6931b108bc7SVille Syrjälä 	if (!devdata)
6941b108bc7SVille Syrjälä 		drm_dbg_kms(&dev_priv->drm, "No VBT child device for HDMI-%c\n",
6951b108bc7SVille Syrjälä 			    port_name(port));
6961b108bc7SVille Syrjälä 
69733e9e541SVille Syrjälä 	dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL);
69833e9e541SVille Syrjälä 	if (!dig_port)
69933e9e541SVille Syrjälä 		return;
70033e9e541SVille Syrjälä 
701*4cca9676SVille Syrjälä 	dig_port->aux_ch = AUX_CH_NONE;
702*4cca9676SVille Syrjälä 
70333e9e541SVille Syrjälä 	intel_connector = intel_connector_alloc();
70433e9e541SVille Syrjälä 	if (!intel_connector) {
70533e9e541SVille Syrjälä 		kfree(dig_port);
70633e9e541SVille Syrjälä 		return;
70733e9e541SVille Syrjälä 	}
70833e9e541SVille Syrjälä 
70933e9e541SVille Syrjälä 	intel_encoder = &dig_port->base;
71033e9e541SVille Syrjälä 
7111b108bc7SVille Syrjälä 	intel_encoder->devdata = devdata;
7121b108bc7SVille Syrjälä 
71333e9e541SVille Syrjälä 	mutex_init(&dig_port->hdcp_mutex);
71433e9e541SVille Syrjälä 
71533e9e541SVille Syrjälä 	drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
71633e9e541SVille Syrjälä 			 &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS,
71733e9e541SVille Syrjälä 			 "HDMI %c", port_name(port));
71833e9e541SVille Syrjälä 
71933e9e541SVille Syrjälä 	intel_encoder->hotplug = intel_hdmi_hotplug;
72095067dc6SVille Syrjälä 	intel_encoder->compute_config = g4x_hdmi_compute_config;
72133e9e541SVille Syrjälä 	if (HAS_PCH_SPLIT(dev_priv)) {
72233e9e541SVille Syrjälä 		intel_encoder->disable = pch_disable_hdmi;
72333e9e541SVille Syrjälä 		intel_encoder->post_disable = pch_post_disable_hdmi;
72433e9e541SVille Syrjälä 	} else {
72533e9e541SVille Syrjälä 		intel_encoder->disable = g4x_disable_hdmi;
72633e9e541SVille Syrjälä 	}
72733e9e541SVille Syrjälä 	intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
72833e9e541SVille Syrjälä 	intel_encoder->get_config = intel_hdmi_get_config;
72933e9e541SVille Syrjälä 	if (IS_CHERRYVIEW(dev_priv)) {
73033e9e541SVille Syrjälä 		intel_encoder->pre_pll_enable = chv_hdmi_pre_pll_enable;
73133e9e541SVille Syrjälä 		intel_encoder->pre_enable = chv_hdmi_pre_enable;
73233e9e541SVille Syrjälä 		intel_encoder->enable = vlv_enable_hdmi;
73333e9e541SVille Syrjälä 		intel_encoder->post_disable = chv_hdmi_post_disable;
73433e9e541SVille Syrjälä 		intel_encoder->post_pll_disable = chv_hdmi_post_pll_disable;
73533e9e541SVille Syrjälä 	} else if (IS_VALLEYVIEW(dev_priv)) {
73633e9e541SVille Syrjälä 		intel_encoder->pre_pll_enable = vlv_hdmi_pre_pll_enable;
73733e9e541SVille Syrjälä 		intel_encoder->pre_enable = vlv_hdmi_pre_enable;
73833e9e541SVille Syrjälä 		intel_encoder->enable = vlv_enable_hdmi;
73933e9e541SVille Syrjälä 		intel_encoder->post_disable = vlv_hdmi_post_disable;
74033e9e541SVille Syrjälä 	} else {
74133e9e541SVille Syrjälä 		intel_encoder->pre_enable = intel_hdmi_pre_enable;
74233e9e541SVille Syrjälä 		if (HAS_PCH_CPT(dev_priv))
74333e9e541SVille Syrjälä 			intel_encoder->enable = cpt_enable_hdmi;
74433e9e541SVille Syrjälä 		else if (HAS_PCH_IBX(dev_priv))
74533e9e541SVille Syrjälä 			intel_encoder->enable = ibx_enable_hdmi;
74633e9e541SVille Syrjälä 		else
74733e9e541SVille Syrjälä 			intel_encoder->enable = g4x_enable_hdmi;
74833e9e541SVille Syrjälä 	}
74949c55f7bSVille Syrjälä 	intel_encoder->shutdown = intel_hdmi_encoder_shutdown;
75033e9e541SVille Syrjälä 
75133e9e541SVille Syrjälä 	intel_encoder->type = INTEL_OUTPUT_HDMI;
752979e1b32SImre Deak 	intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port);
75333e9e541SVille Syrjälä 	intel_encoder->port = port;
75433e9e541SVille Syrjälä 	if (IS_CHERRYVIEW(dev_priv)) {
75533e9e541SVille Syrjälä 		if (port == PORT_D)
75633e9e541SVille Syrjälä 			intel_encoder->pipe_mask = BIT(PIPE_C);
75733e9e541SVille Syrjälä 		else
75833e9e541SVille Syrjälä 			intel_encoder->pipe_mask = BIT(PIPE_A) | BIT(PIPE_B);
75933e9e541SVille Syrjälä 	} else {
76033e9e541SVille Syrjälä 		intel_encoder->pipe_mask = ~0;
76133e9e541SVille Syrjälä 	}
76249fd5403SVille Syrjälä 	intel_encoder->cloneable = BIT(INTEL_OUTPUT_ANALOG);
76333e9e541SVille Syrjälä 	intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
76433e9e541SVille Syrjälä 	/*
76533e9e541SVille Syrjälä 	 * BSpec is unclear about HDMI+HDMI cloning on g4x, but it seems
76633e9e541SVille Syrjälä 	 * to work on real hardware. And since g4x can send infoframes to
76733e9e541SVille Syrjälä 	 * only one port anyway, nothing is lost by allowing it.
76833e9e541SVille Syrjälä 	 */
76933e9e541SVille Syrjälä 	if (IS_G4X(dev_priv))
77049fd5403SVille Syrjälä 		intel_encoder->cloneable |= BIT(INTEL_OUTPUT_HDMI);
77133e9e541SVille Syrjälä 
77233e9e541SVille Syrjälä 	dig_port->hdmi.hdmi_reg = hdmi_reg;
77333e9e541SVille Syrjälä 	dig_port->dp.output_reg = INVALID_MMIO_REG;
77433e9e541SVille Syrjälä 	dig_port->max_lanes = 4;
77533e9e541SVille Syrjälä 
77633e9e541SVille Syrjälä 	intel_infoframe_init(dig_port);
77733e9e541SVille Syrjälä 
77833e9e541SVille Syrjälä 	intel_hdmi_init_connector(dig_port, intel_connector);
77933e9e541SVille Syrjälä }
780