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