15ca02815Sjsg // SPDX-License-Identifier: MIT
25ca02815Sjsg /*
35ca02815Sjsg * Copyright © 2020 Intel Corporation
45ca02815Sjsg *
55ca02815Sjsg * HDMI support for G4x,ILK,SNB,IVB,VLV,CHV (HSW+ handled by the DDI code).
65ca02815Sjsg */
75ca02815Sjsg
85ca02815Sjsg #include "g4x_hdmi.h"
9*f005ef32Sjsg #include "i915_reg.h"
10*f005ef32Sjsg #include "intel_atomic.h"
115ca02815Sjsg #include "intel_audio.h"
125ca02815Sjsg #include "intel_connector.h"
131bb76ff1Sjsg #include "intel_crtc.h"
145ca02815Sjsg #include "intel_de.h"
151bb76ff1Sjsg #include "intel_display_power.h"
165ca02815Sjsg #include "intel_display_types.h"
17*f005ef32Sjsg #include "intel_dp_aux.h"
185ca02815Sjsg #include "intel_dpio_phy.h"
195ca02815Sjsg #include "intel_fifo_underrun.h"
205ca02815Sjsg #include "intel_hdmi.h"
215ca02815Sjsg #include "intel_hotplug.h"
225ca02815Sjsg #include "intel_sdvo.h"
231bb76ff1Sjsg #include "vlv_sideband.h"
245ca02815Sjsg
intel_hdmi_prepare(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)255ca02815Sjsg static void intel_hdmi_prepare(struct intel_encoder *encoder,
265ca02815Sjsg const struct intel_crtc_state *crtc_state)
275ca02815Sjsg {
285ca02815Sjsg struct drm_device *dev = encoder->base.dev;
295ca02815Sjsg struct drm_i915_private *dev_priv = to_i915(dev);
305ca02815Sjsg struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
315ca02815Sjsg struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
325ca02815Sjsg const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
335ca02815Sjsg u32 hdmi_val;
345ca02815Sjsg
355ca02815Sjsg intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
365ca02815Sjsg
375ca02815Sjsg hdmi_val = SDVO_ENCODING_HDMI;
385ca02815Sjsg if (!HAS_PCH_SPLIT(dev_priv) && crtc_state->limited_color_range)
395ca02815Sjsg hdmi_val |= HDMI_COLOR_RANGE_16_235;
405ca02815Sjsg if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
415ca02815Sjsg hdmi_val |= SDVO_VSYNC_ACTIVE_HIGH;
425ca02815Sjsg if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
435ca02815Sjsg hdmi_val |= SDVO_HSYNC_ACTIVE_HIGH;
445ca02815Sjsg
455ca02815Sjsg if (crtc_state->pipe_bpp > 24)
465ca02815Sjsg hdmi_val |= HDMI_COLOR_FORMAT_12bpc;
475ca02815Sjsg else
485ca02815Sjsg hdmi_val |= SDVO_COLOR_FORMAT_8bpc;
495ca02815Sjsg
505ca02815Sjsg if (crtc_state->has_hdmi_sink)
515ca02815Sjsg hdmi_val |= HDMI_MODE_SELECT_HDMI;
525ca02815Sjsg
535ca02815Sjsg if (HAS_PCH_CPT(dev_priv))
545ca02815Sjsg hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe);
555ca02815Sjsg else if (IS_CHERRYVIEW(dev_priv))
565ca02815Sjsg hdmi_val |= SDVO_PIPE_SEL_CHV(crtc->pipe);
575ca02815Sjsg else
585ca02815Sjsg hdmi_val |= SDVO_PIPE_SEL(crtc->pipe);
595ca02815Sjsg
605ca02815Sjsg intel_de_write(dev_priv, intel_hdmi->hdmi_reg, hdmi_val);
615ca02815Sjsg intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
625ca02815Sjsg }
635ca02815Sjsg
intel_hdmi_get_hw_state(struct intel_encoder * encoder,enum pipe * pipe)645ca02815Sjsg static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
655ca02815Sjsg enum pipe *pipe)
665ca02815Sjsg {
675ca02815Sjsg struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
685ca02815Sjsg struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
695ca02815Sjsg intel_wakeref_t wakeref;
705ca02815Sjsg bool ret;
715ca02815Sjsg
725ca02815Sjsg wakeref = intel_display_power_get_if_enabled(dev_priv,
735ca02815Sjsg encoder->power_domain);
745ca02815Sjsg if (!wakeref)
755ca02815Sjsg return false;
765ca02815Sjsg
775ca02815Sjsg ret = intel_sdvo_port_enabled(dev_priv, intel_hdmi->hdmi_reg, pipe);
785ca02815Sjsg
795ca02815Sjsg intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
805ca02815Sjsg
815ca02815Sjsg return ret;
825ca02815Sjsg }
835ca02815Sjsg
connector_is_hdmi(struct drm_connector * connector)84*f005ef32Sjsg static bool connector_is_hdmi(struct drm_connector *connector)
85*f005ef32Sjsg {
86*f005ef32Sjsg struct intel_encoder *encoder =
87*f005ef32Sjsg intel_attached_encoder(to_intel_connector(connector));
88*f005ef32Sjsg
89*f005ef32Sjsg return encoder && encoder->type == INTEL_OUTPUT_HDMI;
90*f005ef32Sjsg }
91*f005ef32Sjsg
g4x_compute_has_hdmi_sink(struct intel_atomic_state * state,struct intel_crtc * this_crtc)92*f005ef32Sjsg static bool g4x_compute_has_hdmi_sink(struct intel_atomic_state *state,
93*f005ef32Sjsg struct intel_crtc *this_crtc)
94*f005ef32Sjsg {
95*f005ef32Sjsg const struct drm_connector_state *conn_state;
96*f005ef32Sjsg struct drm_connector *connector;
97*f005ef32Sjsg int i;
98*f005ef32Sjsg
99*f005ef32Sjsg /*
100*f005ef32Sjsg * On g4x only one HDMI port can transmit infoframes/audio at
101*f005ef32Sjsg * any given time. Select the first suitable port for this duty.
102*f005ef32Sjsg *
103*f005ef32Sjsg * See also g4x_hdmi_connector_atomic_check().
104*f005ef32Sjsg */
105*f005ef32Sjsg for_each_new_connector_in_state(&state->base, connector, conn_state, i) {
106*f005ef32Sjsg struct intel_encoder *encoder = to_intel_encoder(conn_state->best_encoder);
107*f005ef32Sjsg const struct intel_crtc_state *crtc_state;
108*f005ef32Sjsg struct intel_crtc *crtc;
109*f005ef32Sjsg
110*f005ef32Sjsg if (!connector_is_hdmi(connector))
111*f005ef32Sjsg continue;
112*f005ef32Sjsg
113*f005ef32Sjsg crtc = to_intel_crtc(conn_state->crtc);
114*f005ef32Sjsg if (!crtc)
115*f005ef32Sjsg continue;
116*f005ef32Sjsg
117*f005ef32Sjsg crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
118*f005ef32Sjsg
119*f005ef32Sjsg if (!intel_hdmi_compute_has_hdmi_sink(encoder, crtc_state, conn_state))
120*f005ef32Sjsg continue;
121*f005ef32Sjsg
122*f005ef32Sjsg return crtc == this_crtc;
123*f005ef32Sjsg }
124*f005ef32Sjsg
125*f005ef32Sjsg return false;
126*f005ef32Sjsg }
127*f005ef32Sjsg
g4x_hdmi_compute_config(struct intel_encoder * encoder,struct intel_crtc_state * crtc_state,struct drm_connector_state * conn_state)128*f005ef32Sjsg static int g4x_hdmi_compute_config(struct intel_encoder *encoder,
129*f005ef32Sjsg struct intel_crtc_state *crtc_state,
130*f005ef32Sjsg struct drm_connector_state *conn_state)
131*f005ef32Sjsg {
132*f005ef32Sjsg struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
133*f005ef32Sjsg struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
134*f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
135*f005ef32Sjsg
136*f005ef32Sjsg if (HAS_PCH_SPLIT(i915))
137*f005ef32Sjsg crtc_state->has_pch_encoder = true;
138*f005ef32Sjsg
139*f005ef32Sjsg if (IS_G4X(i915))
140*f005ef32Sjsg crtc_state->has_hdmi_sink = g4x_compute_has_hdmi_sink(state, crtc);
141*f005ef32Sjsg else
142*f005ef32Sjsg crtc_state->has_hdmi_sink =
143*f005ef32Sjsg intel_hdmi_compute_has_hdmi_sink(encoder, crtc_state, conn_state);
144*f005ef32Sjsg
145*f005ef32Sjsg return intel_hdmi_compute_config(encoder, crtc_state, conn_state);
146*f005ef32Sjsg }
147*f005ef32Sjsg
intel_hdmi_get_config(struct intel_encoder * encoder,struct intel_crtc_state * pipe_config)1485ca02815Sjsg static void intel_hdmi_get_config(struct intel_encoder *encoder,
1495ca02815Sjsg struct intel_crtc_state *pipe_config)
1505ca02815Sjsg {
1515ca02815Sjsg struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
1525ca02815Sjsg struct drm_device *dev = encoder->base.dev;
1535ca02815Sjsg struct drm_i915_private *dev_priv = to_i915(dev);
1545ca02815Sjsg u32 tmp, flags = 0;
1555ca02815Sjsg int dotclock;
1565ca02815Sjsg
1575ca02815Sjsg pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI);
1585ca02815Sjsg
1595ca02815Sjsg tmp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
1605ca02815Sjsg
1615ca02815Sjsg if (tmp & SDVO_HSYNC_ACTIVE_HIGH)
1625ca02815Sjsg flags |= DRM_MODE_FLAG_PHSYNC;
1635ca02815Sjsg else
1645ca02815Sjsg flags |= DRM_MODE_FLAG_NHSYNC;
1655ca02815Sjsg
1665ca02815Sjsg if (tmp & SDVO_VSYNC_ACTIVE_HIGH)
1675ca02815Sjsg flags |= DRM_MODE_FLAG_PVSYNC;
1685ca02815Sjsg else
1695ca02815Sjsg flags |= DRM_MODE_FLAG_NVSYNC;
1705ca02815Sjsg
1715ca02815Sjsg if (tmp & HDMI_MODE_SELECT_HDMI)
1725ca02815Sjsg pipe_config->has_hdmi_sink = true;
1735ca02815Sjsg
1745ca02815Sjsg pipe_config->infoframes.enable |=
1755ca02815Sjsg intel_hdmi_infoframes_enabled(encoder, pipe_config);
1765ca02815Sjsg
1775ca02815Sjsg if (pipe_config->infoframes.enable)
1785ca02815Sjsg pipe_config->has_infoframe = true;
1795ca02815Sjsg
1805ca02815Sjsg if (tmp & HDMI_AUDIO_ENABLE)
1815ca02815Sjsg pipe_config->has_audio = true;
1825ca02815Sjsg
1835ca02815Sjsg if (!HAS_PCH_SPLIT(dev_priv) &&
1845ca02815Sjsg tmp & HDMI_COLOR_RANGE_16_235)
1855ca02815Sjsg pipe_config->limited_color_range = true;
1865ca02815Sjsg
1875ca02815Sjsg pipe_config->hw.adjusted_mode.flags |= flags;
1885ca02815Sjsg
1895ca02815Sjsg if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc)
1901bb76ff1Sjsg dotclock = DIV_ROUND_CLOSEST(pipe_config->port_clock * 2, 3);
1915ca02815Sjsg else
1925ca02815Sjsg dotclock = pipe_config->port_clock;
1935ca02815Sjsg
1945ca02815Sjsg if (pipe_config->pixel_multiplier)
1955ca02815Sjsg dotclock /= pipe_config->pixel_multiplier;
1965ca02815Sjsg
1975ca02815Sjsg pipe_config->hw.adjusted_mode.crtc_clock = dotclock;
1985ca02815Sjsg
1995ca02815Sjsg pipe_config->lane_count = 4;
2005ca02815Sjsg
2015ca02815Sjsg intel_hdmi_read_gcp_infoframe(encoder, pipe_config);
2025ca02815Sjsg
2035ca02815Sjsg intel_read_infoframe(encoder, pipe_config,
2045ca02815Sjsg HDMI_INFOFRAME_TYPE_AVI,
2055ca02815Sjsg &pipe_config->infoframes.avi);
2065ca02815Sjsg intel_read_infoframe(encoder, pipe_config,
2075ca02815Sjsg HDMI_INFOFRAME_TYPE_SPD,
2085ca02815Sjsg &pipe_config->infoframes.spd);
2095ca02815Sjsg intel_read_infoframe(encoder, pipe_config,
2105ca02815Sjsg HDMI_INFOFRAME_TYPE_VENDOR,
2115ca02815Sjsg &pipe_config->infoframes.hdmi);
212*f005ef32Sjsg
213*f005ef32Sjsg intel_audio_codec_get_config(encoder, pipe_config);
2145ca02815Sjsg }
2155ca02815Sjsg
g4x_hdmi_enable_port(struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config)216*f005ef32Sjsg static void g4x_hdmi_enable_port(struct intel_encoder *encoder,
217*f005ef32Sjsg const struct intel_crtc_state *pipe_config)
2185ca02815Sjsg {
2195ca02815Sjsg struct drm_device *dev = encoder->base.dev;
2205ca02815Sjsg struct drm_i915_private *dev_priv = to_i915(dev);
2215ca02815Sjsg struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2225ca02815Sjsg u32 temp;
2235ca02815Sjsg
2245ca02815Sjsg temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
2255ca02815Sjsg
2265ca02815Sjsg temp |= SDVO_ENABLE;
2275ca02815Sjsg if (pipe_config->has_audio)
2285ca02815Sjsg temp |= HDMI_AUDIO_ENABLE;
2295ca02815Sjsg
2305ca02815Sjsg intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
2315ca02815Sjsg intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
232*f005ef32Sjsg }
233*f005ef32Sjsg
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)234*f005ef32Sjsg static void g4x_enable_hdmi(struct intel_atomic_state *state,
235*f005ef32Sjsg struct intel_encoder *encoder,
236*f005ef32Sjsg const struct intel_crtc_state *pipe_config,
237*f005ef32Sjsg const struct drm_connector_state *conn_state)
238*f005ef32Sjsg {
239*f005ef32Sjsg struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
240*f005ef32Sjsg
241*f005ef32Sjsg g4x_hdmi_enable_port(encoder, pipe_config);
2425ca02815Sjsg
2431bb76ff1Sjsg drm_WARN_ON(&dev_priv->drm, pipe_config->has_audio &&
2441bb76ff1Sjsg !pipe_config->has_hdmi_sink);
2451bb76ff1Sjsg intel_audio_codec_enable(encoder, pipe_config, conn_state);
2465ca02815Sjsg }
2475ca02815Sjsg
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)2485ca02815Sjsg static void ibx_enable_hdmi(struct intel_atomic_state *state,
2495ca02815Sjsg struct intel_encoder *encoder,
2505ca02815Sjsg const struct intel_crtc_state *pipe_config,
2515ca02815Sjsg const struct drm_connector_state *conn_state)
2525ca02815Sjsg {
2535ca02815Sjsg struct drm_device *dev = encoder->base.dev;
2545ca02815Sjsg struct drm_i915_private *dev_priv = to_i915(dev);
2555ca02815Sjsg struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2565ca02815Sjsg u32 temp;
2575ca02815Sjsg
2585ca02815Sjsg temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
2595ca02815Sjsg
2605ca02815Sjsg temp |= SDVO_ENABLE;
2615ca02815Sjsg if (pipe_config->has_audio)
2625ca02815Sjsg temp |= HDMI_AUDIO_ENABLE;
2635ca02815Sjsg
2645ca02815Sjsg /*
2655ca02815Sjsg * HW workaround, need to write this twice for issue
2665ca02815Sjsg * that may result in first write getting masked.
2675ca02815Sjsg */
2685ca02815Sjsg intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
2695ca02815Sjsg intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
2705ca02815Sjsg intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
2715ca02815Sjsg intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
2725ca02815Sjsg
2735ca02815Sjsg /*
2745ca02815Sjsg * HW workaround, need to toggle enable bit off and on
2755ca02815Sjsg * for 12bpc with pixel repeat.
2765ca02815Sjsg *
2775ca02815Sjsg * FIXME: BSpec says this should be done at the end of
2785ca02815Sjsg * the modeset sequence, so not sure if this isn't too soon.
2795ca02815Sjsg */
2805ca02815Sjsg if (pipe_config->pipe_bpp > 24 &&
2815ca02815Sjsg pipe_config->pixel_multiplier > 1) {
2825ca02815Sjsg intel_de_write(dev_priv, intel_hdmi->hdmi_reg,
2835ca02815Sjsg temp & ~SDVO_ENABLE);
2845ca02815Sjsg intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
2855ca02815Sjsg
2865ca02815Sjsg /*
2875ca02815Sjsg * HW workaround, need to write this twice for issue
2885ca02815Sjsg * that may result in first write getting masked.
2895ca02815Sjsg */
2905ca02815Sjsg intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
2915ca02815Sjsg intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
2925ca02815Sjsg intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
2935ca02815Sjsg intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
2945ca02815Sjsg }
2955ca02815Sjsg
2961bb76ff1Sjsg drm_WARN_ON(&dev_priv->drm, pipe_config->has_audio &&
2971bb76ff1Sjsg !pipe_config->has_hdmi_sink);
2981bb76ff1Sjsg intel_audio_codec_enable(encoder, pipe_config, conn_state);
2995ca02815Sjsg }
3005ca02815Sjsg
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)3015ca02815Sjsg static void cpt_enable_hdmi(struct intel_atomic_state *state,
3025ca02815Sjsg struct intel_encoder *encoder,
3035ca02815Sjsg const struct intel_crtc_state *pipe_config,
3045ca02815Sjsg const struct drm_connector_state *conn_state)
3055ca02815Sjsg {
3065ca02815Sjsg struct drm_device *dev = encoder->base.dev;
3075ca02815Sjsg struct drm_i915_private *dev_priv = to_i915(dev);
3085ca02815Sjsg struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
3095ca02815Sjsg struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
3105ca02815Sjsg enum pipe pipe = crtc->pipe;
3115ca02815Sjsg u32 temp;
3125ca02815Sjsg
3135ca02815Sjsg temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
3145ca02815Sjsg
3155ca02815Sjsg temp |= SDVO_ENABLE;
3165ca02815Sjsg if (pipe_config->has_audio)
3175ca02815Sjsg temp |= HDMI_AUDIO_ENABLE;
3185ca02815Sjsg
3195ca02815Sjsg /*
3205ca02815Sjsg * WaEnableHDMI8bpcBefore12bpc:snb,ivb
3215ca02815Sjsg *
3225ca02815Sjsg * The procedure for 12bpc is as follows:
3235ca02815Sjsg * 1. disable HDMI clock gating
3245ca02815Sjsg * 2. enable HDMI with 8bpc
3255ca02815Sjsg * 3. enable HDMI with 12bpc
3265ca02815Sjsg * 4. enable HDMI clock gating
3275ca02815Sjsg */
3285ca02815Sjsg
3295ca02815Sjsg if (pipe_config->pipe_bpp > 24) {
330*f005ef32Sjsg intel_de_rmw(dev_priv, TRANS_CHICKEN1(pipe),
331*f005ef32Sjsg 0, TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE);
3325ca02815Sjsg
3335ca02815Sjsg temp &= ~SDVO_COLOR_FORMAT_MASK;
3345ca02815Sjsg temp |= SDVO_COLOR_FORMAT_8bpc;
3355ca02815Sjsg }
3365ca02815Sjsg
3375ca02815Sjsg intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
3385ca02815Sjsg intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
3395ca02815Sjsg
3405ca02815Sjsg if (pipe_config->pipe_bpp > 24) {
3415ca02815Sjsg temp &= ~SDVO_COLOR_FORMAT_MASK;
3425ca02815Sjsg temp |= HDMI_COLOR_FORMAT_12bpc;
3435ca02815Sjsg
3445ca02815Sjsg intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
3455ca02815Sjsg intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
3465ca02815Sjsg
347*f005ef32Sjsg intel_de_rmw(dev_priv, TRANS_CHICKEN1(pipe),
348*f005ef32Sjsg TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE, 0);
3495ca02815Sjsg }
3505ca02815Sjsg
3511bb76ff1Sjsg drm_WARN_ON(&dev_priv->drm, pipe_config->has_audio &&
3521bb76ff1Sjsg !pipe_config->has_hdmi_sink);
3531bb76ff1Sjsg intel_audio_codec_enable(encoder, pipe_config, conn_state);
3545ca02815Sjsg }
3555ca02815Sjsg
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)3565ca02815Sjsg static void vlv_enable_hdmi(struct intel_atomic_state *state,
3575ca02815Sjsg struct intel_encoder *encoder,
3585ca02815Sjsg const struct intel_crtc_state *pipe_config,
3595ca02815Sjsg const struct drm_connector_state *conn_state)
3605ca02815Sjsg {
361*f005ef32Sjsg struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
362*f005ef32Sjsg
363*f005ef32Sjsg drm_WARN_ON(&dev_priv->drm, pipe_config->has_audio &&
364*f005ef32Sjsg !pipe_config->has_hdmi_sink);
365*f005ef32Sjsg intel_audio_codec_enable(encoder, pipe_config, conn_state);
3665ca02815Sjsg }
3675ca02815Sjsg
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)3685ca02815Sjsg static void intel_disable_hdmi(struct intel_atomic_state *state,
3695ca02815Sjsg struct intel_encoder *encoder,
3705ca02815Sjsg const struct intel_crtc_state *old_crtc_state,
3715ca02815Sjsg const struct drm_connector_state *old_conn_state)
3725ca02815Sjsg {
3735ca02815Sjsg struct drm_device *dev = encoder->base.dev;
3745ca02815Sjsg struct drm_i915_private *dev_priv = to_i915(dev);
3755ca02815Sjsg struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
3765ca02815Sjsg struct intel_digital_port *dig_port =
3775ca02815Sjsg hdmi_to_dig_port(intel_hdmi);
3785ca02815Sjsg struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
3795ca02815Sjsg u32 temp;
3805ca02815Sjsg
3815ca02815Sjsg temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
3825ca02815Sjsg
3835ca02815Sjsg temp &= ~(SDVO_ENABLE | HDMI_AUDIO_ENABLE);
3845ca02815Sjsg intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
3855ca02815Sjsg intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
3865ca02815Sjsg
3875ca02815Sjsg /*
3885ca02815Sjsg * HW workaround for IBX, we need to move the port
3895ca02815Sjsg * to transcoder A after disabling it to allow the
3905ca02815Sjsg * matching DP port to be enabled on transcoder A.
3915ca02815Sjsg */
3925ca02815Sjsg if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B) {
3935ca02815Sjsg /*
3945ca02815Sjsg * We get CPU/PCH FIFO underruns on the other pipe when
3955ca02815Sjsg * doing the workaround. Sweep them under the rug.
3965ca02815Sjsg */
3975ca02815Sjsg intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false);
3985ca02815Sjsg intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
3995ca02815Sjsg
4005ca02815Sjsg temp &= ~SDVO_PIPE_SEL_MASK;
4015ca02815Sjsg temp |= SDVO_ENABLE | SDVO_PIPE_SEL(PIPE_A);
4025ca02815Sjsg /*
4035ca02815Sjsg * HW workaround, need to write this twice for issue
4045ca02815Sjsg * that may result in first write getting masked.
4055ca02815Sjsg */
4065ca02815Sjsg intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
4075ca02815Sjsg intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
4085ca02815Sjsg intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
4095ca02815Sjsg intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
4105ca02815Sjsg
4115ca02815Sjsg temp &= ~SDVO_ENABLE;
4125ca02815Sjsg intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
4135ca02815Sjsg intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
4145ca02815Sjsg
4155ca02815Sjsg intel_wait_for_vblank_if_active(dev_priv, PIPE_A);
4165ca02815Sjsg intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true);
4175ca02815Sjsg intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
4185ca02815Sjsg }
4195ca02815Sjsg
4205ca02815Sjsg dig_port->set_infoframes(encoder,
4215ca02815Sjsg false,
4225ca02815Sjsg old_crtc_state, old_conn_state);
4235ca02815Sjsg
4245ca02815Sjsg intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
4255ca02815Sjsg }
4265ca02815Sjsg
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)4275ca02815Sjsg static void g4x_disable_hdmi(struct intel_atomic_state *state,
4285ca02815Sjsg struct intel_encoder *encoder,
4295ca02815Sjsg const struct intel_crtc_state *old_crtc_state,
4305ca02815Sjsg const struct drm_connector_state *old_conn_state)
4315ca02815Sjsg {
4321bb76ff1Sjsg intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
4335ca02815Sjsg
4345ca02815Sjsg intel_disable_hdmi(state, encoder, old_crtc_state, old_conn_state);
4355ca02815Sjsg }
4365ca02815Sjsg
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)4375ca02815Sjsg static void pch_disable_hdmi(struct intel_atomic_state *state,
4385ca02815Sjsg struct intel_encoder *encoder,
4395ca02815Sjsg const struct intel_crtc_state *old_crtc_state,
4405ca02815Sjsg const struct drm_connector_state *old_conn_state)
4415ca02815Sjsg {
4421bb76ff1Sjsg intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
4435ca02815Sjsg }
4445ca02815Sjsg
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)4455ca02815Sjsg static void pch_post_disable_hdmi(struct intel_atomic_state *state,
4465ca02815Sjsg struct intel_encoder *encoder,
4475ca02815Sjsg const struct intel_crtc_state *old_crtc_state,
4485ca02815Sjsg const struct drm_connector_state *old_conn_state)
4495ca02815Sjsg {
4505ca02815Sjsg intel_disable_hdmi(state, encoder, old_crtc_state, old_conn_state);
4515ca02815Sjsg }
4525ca02815Sjsg
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)4535ca02815Sjsg static void intel_hdmi_pre_enable(struct intel_atomic_state *state,
4545ca02815Sjsg struct intel_encoder *encoder,
4555ca02815Sjsg const struct intel_crtc_state *pipe_config,
4565ca02815Sjsg const struct drm_connector_state *conn_state)
4575ca02815Sjsg {
4585ca02815Sjsg struct intel_digital_port *dig_port =
4595ca02815Sjsg enc_to_dig_port(encoder);
4605ca02815Sjsg
4615ca02815Sjsg intel_hdmi_prepare(encoder, pipe_config);
4625ca02815Sjsg
4635ca02815Sjsg dig_port->set_infoframes(encoder,
4645ca02815Sjsg pipe_config->has_infoframe,
4655ca02815Sjsg pipe_config, conn_state);
4665ca02815Sjsg }
4675ca02815Sjsg
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)4685ca02815Sjsg static void vlv_hdmi_pre_enable(struct intel_atomic_state *state,
4695ca02815Sjsg struct intel_encoder *encoder,
4705ca02815Sjsg const struct intel_crtc_state *pipe_config,
4715ca02815Sjsg const struct drm_connector_state *conn_state)
4725ca02815Sjsg {
4735ca02815Sjsg struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
4745ca02815Sjsg struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
4755ca02815Sjsg
4765ca02815Sjsg vlv_phy_pre_encoder_enable(encoder, pipe_config);
4775ca02815Sjsg
4785ca02815Sjsg /* HDMI 1.0V-2dB */
4795ca02815Sjsg vlv_set_phy_signal_level(encoder, pipe_config,
4805ca02815Sjsg 0x2b245f5f, 0x00002000,
4815ca02815Sjsg 0x5578b83a, 0x2b247878);
4825ca02815Sjsg
4835ca02815Sjsg dig_port->set_infoframes(encoder,
4845ca02815Sjsg pipe_config->has_infoframe,
4855ca02815Sjsg pipe_config, conn_state);
4865ca02815Sjsg
487*f005ef32Sjsg g4x_hdmi_enable_port(encoder, pipe_config);
4885ca02815Sjsg
4895ca02815Sjsg vlv_wait_port_ready(dev_priv, dig_port, 0x0);
4905ca02815Sjsg }
4915ca02815Sjsg
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)4925ca02815Sjsg static void vlv_hdmi_pre_pll_enable(struct intel_atomic_state *state,
4935ca02815Sjsg struct intel_encoder *encoder,
4945ca02815Sjsg const struct intel_crtc_state *pipe_config,
4955ca02815Sjsg const struct drm_connector_state *conn_state)
4965ca02815Sjsg {
4975ca02815Sjsg intel_hdmi_prepare(encoder, pipe_config);
4985ca02815Sjsg
4995ca02815Sjsg vlv_phy_pre_pll_enable(encoder, pipe_config);
5005ca02815Sjsg }
5015ca02815Sjsg
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)5025ca02815Sjsg static void chv_hdmi_pre_pll_enable(struct intel_atomic_state *state,
5035ca02815Sjsg struct intel_encoder *encoder,
5045ca02815Sjsg const struct intel_crtc_state *pipe_config,
5055ca02815Sjsg const struct drm_connector_state *conn_state)
5065ca02815Sjsg {
5075ca02815Sjsg intel_hdmi_prepare(encoder, pipe_config);
5085ca02815Sjsg
5095ca02815Sjsg chv_phy_pre_pll_enable(encoder, pipe_config);
5105ca02815Sjsg }
5115ca02815Sjsg
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)5125ca02815Sjsg static void chv_hdmi_post_pll_disable(struct intel_atomic_state *state,
5135ca02815Sjsg struct intel_encoder *encoder,
5145ca02815Sjsg const struct intel_crtc_state *old_crtc_state,
5155ca02815Sjsg const struct drm_connector_state *old_conn_state)
5165ca02815Sjsg {
5175ca02815Sjsg chv_phy_post_pll_disable(encoder, old_crtc_state);
5185ca02815Sjsg }
5195ca02815Sjsg
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)5205ca02815Sjsg static void vlv_hdmi_post_disable(struct intel_atomic_state *state,
5215ca02815Sjsg struct intel_encoder *encoder,
5225ca02815Sjsg const struct intel_crtc_state *old_crtc_state,
5235ca02815Sjsg const struct drm_connector_state *old_conn_state)
5245ca02815Sjsg {
5255ca02815Sjsg /* Reset lanes to avoid HDMI flicker (VLV w/a) */
5265ca02815Sjsg vlv_phy_reset_lanes(encoder, old_crtc_state);
5275ca02815Sjsg }
5285ca02815Sjsg
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)5295ca02815Sjsg static void chv_hdmi_post_disable(struct intel_atomic_state *state,
5305ca02815Sjsg struct intel_encoder *encoder,
5315ca02815Sjsg const struct intel_crtc_state *old_crtc_state,
5325ca02815Sjsg const struct drm_connector_state *old_conn_state)
5335ca02815Sjsg {
5345ca02815Sjsg struct drm_device *dev = encoder->base.dev;
5355ca02815Sjsg struct drm_i915_private *dev_priv = to_i915(dev);
5365ca02815Sjsg
5375ca02815Sjsg vlv_dpio_get(dev_priv);
5385ca02815Sjsg
5395ca02815Sjsg /* Assert data lane reset */
5405ca02815Sjsg chv_data_lane_soft_reset(encoder, old_crtc_state, true);
5415ca02815Sjsg
5425ca02815Sjsg vlv_dpio_put(dev_priv);
5435ca02815Sjsg }
5445ca02815Sjsg
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)5455ca02815Sjsg static void chv_hdmi_pre_enable(struct intel_atomic_state *state,
5465ca02815Sjsg struct intel_encoder *encoder,
5475ca02815Sjsg const struct intel_crtc_state *pipe_config,
5485ca02815Sjsg const struct drm_connector_state *conn_state)
5495ca02815Sjsg {
5505ca02815Sjsg struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
5515ca02815Sjsg struct drm_device *dev = encoder->base.dev;
5525ca02815Sjsg struct drm_i915_private *dev_priv = to_i915(dev);
5535ca02815Sjsg
5545ca02815Sjsg chv_phy_pre_encoder_enable(encoder, pipe_config);
5555ca02815Sjsg
5565ca02815Sjsg /* FIXME: Program the support xxx V-dB */
5575ca02815Sjsg /* Use 800mV-0dB */
5585ca02815Sjsg chv_set_phy_signal_level(encoder, pipe_config, 128, 102, false);
5595ca02815Sjsg
5605ca02815Sjsg dig_port->set_infoframes(encoder,
5615ca02815Sjsg pipe_config->has_infoframe,
5625ca02815Sjsg pipe_config, conn_state);
5635ca02815Sjsg
564*f005ef32Sjsg g4x_hdmi_enable_port(encoder, pipe_config);
5655ca02815Sjsg
5665ca02815Sjsg vlv_wait_port_ready(dev_priv, dig_port, 0x0);
5675ca02815Sjsg
5685ca02815Sjsg /* Second common lane will stay alive on its own now */
5695ca02815Sjsg chv_phy_release_cl2_override(encoder);
5705ca02815Sjsg }
5715ca02815Sjsg
5725ca02815Sjsg static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
5735ca02815Sjsg .destroy = intel_encoder_destroy,
5745ca02815Sjsg };
5755ca02815Sjsg
5765ca02815Sjsg static enum intel_hotplug_state
intel_hdmi_hotplug(struct intel_encoder * encoder,struct intel_connector * connector)5775ca02815Sjsg intel_hdmi_hotplug(struct intel_encoder *encoder,
5785ca02815Sjsg struct intel_connector *connector)
5795ca02815Sjsg {
5805ca02815Sjsg enum intel_hotplug_state state;
5815ca02815Sjsg
5825ca02815Sjsg state = intel_encoder_hotplug(encoder, connector);
5835ca02815Sjsg
5845ca02815Sjsg /*
5855ca02815Sjsg * On many platforms the HDMI live state signal is known to be
5865ca02815Sjsg * unreliable, so we can't use it to detect if a sink is connected or
5875ca02815Sjsg * not. Instead we detect if it's connected based on whether we can
5885ca02815Sjsg * read the EDID or not. That in turn has a problem during disconnect,
5895ca02815Sjsg * since the HPD interrupt may be raised before the DDC lines get
5905ca02815Sjsg * disconnected (due to how the required length of DDC vs. HPD
5915ca02815Sjsg * connector pins are specified) and so we'll still be able to get a
5925ca02815Sjsg * valid EDID. To solve this schedule another detection cycle if this
5935ca02815Sjsg * time around we didn't detect any change in the sink's connection
5945ca02815Sjsg * status.
5955ca02815Sjsg */
5965ca02815Sjsg if (state == INTEL_HOTPLUG_UNCHANGED && !connector->hotplug_retries)
5975ca02815Sjsg state = INTEL_HOTPLUG_RETRY;
5985ca02815Sjsg
5995ca02815Sjsg return state;
6005ca02815Sjsg }
6015ca02815Sjsg
g4x_hdmi_connector_atomic_check(struct drm_connector * connector,struct drm_atomic_state * state)602*f005ef32Sjsg int g4x_hdmi_connector_atomic_check(struct drm_connector *connector,
603*f005ef32Sjsg struct drm_atomic_state *state)
604*f005ef32Sjsg {
605*f005ef32Sjsg struct drm_i915_private *i915 = to_i915(state->dev);
606*f005ef32Sjsg struct drm_connector_list_iter conn_iter;
607*f005ef32Sjsg struct drm_connector *conn;
608*f005ef32Sjsg int ret;
609*f005ef32Sjsg
610*f005ef32Sjsg ret = intel_digital_connector_atomic_check(connector, state);
611*f005ef32Sjsg if (ret)
612*f005ef32Sjsg return ret;
613*f005ef32Sjsg
614*f005ef32Sjsg if (!IS_G4X(i915))
615*f005ef32Sjsg return 0;
616*f005ef32Sjsg
617*f005ef32Sjsg if (!intel_connector_needs_modeset(to_intel_atomic_state(state), connector))
618*f005ef32Sjsg return 0;
619*f005ef32Sjsg
620*f005ef32Sjsg /*
621*f005ef32Sjsg * On g4x only one HDMI port can transmit infoframes/audio
622*f005ef32Sjsg * at any given time. Make sure all enabled HDMI ports are
623*f005ef32Sjsg * included in the state so that it's possible to select
624*f005ef32Sjsg * one of them for this duty.
625*f005ef32Sjsg *
626*f005ef32Sjsg * See also g4x_compute_has_hdmi_sink().
627*f005ef32Sjsg */
628*f005ef32Sjsg drm_connector_list_iter_begin(&i915->drm, &conn_iter);
629*f005ef32Sjsg drm_for_each_connector_iter(conn, &conn_iter) {
630*f005ef32Sjsg struct drm_connector_state *conn_state;
631*f005ef32Sjsg struct drm_crtc_state *crtc_state;
632*f005ef32Sjsg struct drm_crtc *crtc;
633*f005ef32Sjsg
634*f005ef32Sjsg if (!connector_is_hdmi(conn))
635*f005ef32Sjsg continue;
636*f005ef32Sjsg
637*f005ef32Sjsg drm_dbg_kms(&i915->drm, "Adding [CONNECTOR:%d:%s]\n",
638*f005ef32Sjsg conn->base.id, conn->name);
639*f005ef32Sjsg
640*f005ef32Sjsg conn_state = drm_atomic_get_connector_state(state, conn);
641*f005ef32Sjsg if (IS_ERR(conn_state)) {
642*f005ef32Sjsg ret = PTR_ERR(conn_state);
643*f005ef32Sjsg break;
644*f005ef32Sjsg }
645*f005ef32Sjsg
646*f005ef32Sjsg crtc = conn_state->crtc;
647*f005ef32Sjsg if (!crtc)
648*f005ef32Sjsg continue;
649*f005ef32Sjsg
650*f005ef32Sjsg crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
651*f005ef32Sjsg crtc_state->mode_changed = true;
652*f005ef32Sjsg
653*f005ef32Sjsg ret = drm_atomic_add_affected_planes(state, crtc);
654*f005ef32Sjsg if (ret)
655*f005ef32Sjsg break;
656*f005ef32Sjsg }
657*f005ef32Sjsg drm_connector_list_iter_end(&conn_iter);
658*f005ef32Sjsg
659*f005ef32Sjsg return ret;
660*f005ef32Sjsg }
661*f005ef32Sjsg
is_hdmi_port_valid(struct drm_i915_private * i915,enum port port)662*f005ef32Sjsg static bool is_hdmi_port_valid(struct drm_i915_private *i915, enum port port)
663*f005ef32Sjsg {
664*f005ef32Sjsg if (IS_G4X(i915) || IS_VALLEYVIEW(i915))
665*f005ef32Sjsg return port == PORT_B || port == PORT_C;
666*f005ef32Sjsg else
667*f005ef32Sjsg return port == PORT_B || port == PORT_C || port == PORT_D;
668*f005ef32Sjsg }
669*f005ef32Sjsg
assert_hdmi_port_valid(struct drm_i915_private * i915,enum port port)670*f005ef32Sjsg static bool assert_hdmi_port_valid(struct drm_i915_private *i915, enum port port)
671*f005ef32Sjsg {
672*f005ef32Sjsg return !drm_WARN(&i915->drm, !is_hdmi_port_valid(i915, port),
673*f005ef32Sjsg "Platform does not support HDMI %c\n", port_name(port));
674*f005ef32Sjsg }
675*f005ef32Sjsg
g4x_hdmi_init(struct drm_i915_private * dev_priv,i915_reg_t hdmi_reg,enum port port)6765ca02815Sjsg void g4x_hdmi_init(struct drm_i915_private *dev_priv,
6775ca02815Sjsg i915_reg_t hdmi_reg, enum port port)
6785ca02815Sjsg {
679*f005ef32Sjsg const struct intel_bios_encoder_data *devdata;
6805ca02815Sjsg struct intel_digital_port *dig_port;
6815ca02815Sjsg struct intel_encoder *intel_encoder;
6825ca02815Sjsg struct intel_connector *intel_connector;
6835ca02815Sjsg
684*f005ef32Sjsg if (!assert_port_valid(dev_priv, port))
685*f005ef32Sjsg return;
686*f005ef32Sjsg
687*f005ef32Sjsg if (!assert_hdmi_port_valid(dev_priv, port))
688*f005ef32Sjsg return;
689*f005ef32Sjsg
690*f005ef32Sjsg devdata = intel_bios_encoder_data_lookup(dev_priv, port);
691*f005ef32Sjsg
692*f005ef32Sjsg /* FIXME bail? */
693*f005ef32Sjsg if (!devdata)
694*f005ef32Sjsg drm_dbg_kms(&dev_priv->drm, "No VBT child device for HDMI-%c\n",
695*f005ef32Sjsg port_name(port));
696*f005ef32Sjsg
6975ca02815Sjsg dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL);
6985ca02815Sjsg if (!dig_port)
6995ca02815Sjsg return;
7005ca02815Sjsg
701*f005ef32Sjsg dig_port->aux_ch = AUX_CH_NONE;
702*f005ef32Sjsg
7035ca02815Sjsg intel_connector = intel_connector_alloc();
7045ca02815Sjsg if (!intel_connector) {
7055ca02815Sjsg kfree(dig_port);
7065ca02815Sjsg return;
7075ca02815Sjsg }
7085ca02815Sjsg
7095ca02815Sjsg intel_encoder = &dig_port->base;
7105ca02815Sjsg
711*f005ef32Sjsg intel_encoder->devdata = devdata;
712*f005ef32Sjsg
7135ca02815Sjsg rw_init(&dig_port->hdcp_mutex, "hhdcp");
7145ca02815Sjsg
7155ca02815Sjsg drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
7165ca02815Sjsg &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS,
7175ca02815Sjsg "HDMI %c", port_name(port));
7185ca02815Sjsg
7195ca02815Sjsg intel_encoder->hotplug = intel_hdmi_hotplug;
720*f005ef32Sjsg intel_encoder->compute_config = g4x_hdmi_compute_config;
7215ca02815Sjsg if (HAS_PCH_SPLIT(dev_priv)) {
7225ca02815Sjsg intel_encoder->disable = pch_disable_hdmi;
7235ca02815Sjsg intel_encoder->post_disable = pch_post_disable_hdmi;
7245ca02815Sjsg } else {
7255ca02815Sjsg intel_encoder->disable = g4x_disable_hdmi;
7265ca02815Sjsg }
7275ca02815Sjsg intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
7285ca02815Sjsg intel_encoder->get_config = intel_hdmi_get_config;
7295ca02815Sjsg if (IS_CHERRYVIEW(dev_priv)) {
7305ca02815Sjsg intel_encoder->pre_pll_enable = chv_hdmi_pre_pll_enable;
7315ca02815Sjsg intel_encoder->pre_enable = chv_hdmi_pre_enable;
7325ca02815Sjsg intel_encoder->enable = vlv_enable_hdmi;
7335ca02815Sjsg intel_encoder->post_disable = chv_hdmi_post_disable;
7345ca02815Sjsg intel_encoder->post_pll_disable = chv_hdmi_post_pll_disable;
7355ca02815Sjsg } else if (IS_VALLEYVIEW(dev_priv)) {
7365ca02815Sjsg intel_encoder->pre_pll_enable = vlv_hdmi_pre_pll_enable;
7375ca02815Sjsg intel_encoder->pre_enable = vlv_hdmi_pre_enable;
7385ca02815Sjsg intel_encoder->enable = vlv_enable_hdmi;
7395ca02815Sjsg intel_encoder->post_disable = vlv_hdmi_post_disable;
7405ca02815Sjsg } else {
7415ca02815Sjsg intel_encoder->pre_enable = intel_hdmi_pre_enable;
7425ca02815Sjsg if (HAS_PCH_CPT(dev_priv))
7435ca02815Sjsg intel_encoder->enable = cpt_enable_hdmi;
7445ca02815Sjsg else if (HAS_PCH_IBX(dev_priv))
7455ca02815Sjsg intel_encoder->enable = ibx_enable_hdmi;
7465ca02815Sjsg else
7475ca02815Sjsg intel_encoder->enable = g4x_enable_hdmi;
7485ca02815Sjsg }
7495ca02815Sjsg intel_encoder->shutdown = intel_hdmi_encoder_shutdown;
7505ca02815Sjsg
7515ca02815Sjsg intel_encoder->type = INTEL_OUTPUT_HDMI;
7521bb76ff1Sjsg intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port);
7535ca02815Sjsg intel_encoder->port = port;
7545ca02815Sjsg if (IS_CHERRYVIEW(dev_priv)) {
7555ca02815Sjsg if (port == PORT_D)
7565ca02815Sjsg intel_encoder->pipe_mask = BIT(PIPE_C);
7575ca02815Sjsg else
7585ca02815Sjsg intel_encoder->pipe_mask = BIT(PIPE_A) | BIT(PIPE_B);
7595ca02815Sjsg } else {
7605ca02815Sjsg intel_encoder->pipe_mask = ~0;
7615ca02815Sjsg }
762*f005ef32Sjsg intel_encoder->cloneable = BIT(INTEL_OUTPUT_ANALOG);
7635ca02815Sjsg intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
7645ca02815Sjsg /*
7655ca02815Sjsg * BSpec is unclear about HDMI+HDMI cloning on g4x, but it seems
7665ca02815Sjsg * to work on real hardware. And since g4x can send infoframes to
7675ca02815Sjsg * only one port anyway, nothing is lost by allowing it.
7685ca02815Sjsg */
7695ca02815Sjsg if (IS_G4X(dev_priv))
770*f005ef32Sjsg intel_encoder->cloneable |= BIT(INTEL_OUTPUT_HDMI);
7715ca02815Sjsg
7725ca02815Sjsg dig_port->hdmi.hdmi_reg = hdmi_reg;
7735ca02815Sjsg dig_port->dp.output_reg = INVALID_MMIO_REG;
7745ca02815Sjsg dig_port->max_lanes = 4;
7755ca02815Sjsg
7765ca02815Sjsg intel_infoframe_init(dig_port);
7775ca02815Sjsg
7785ca02815Sjsg intel_hdmi_init_connector(dig_port, intel_connector);
7795ca02815Sjsg }
780