793 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright © 2020 Intel Corporation4 *5 * HDMI support for G4x,ILK,SNB,IVB,VLV,CHV (HSW+ handled by the DDI code).6 */7 8#include "g4x_hdmi.h"9#include "i915_reg.h"10#include "intel_atomic.h"11#include "intel_audio.h"12#include "intel_connector.h"13#include "intel_crtc.h"14#include "intel_de.h"15#include "intel_display_power.h"16#include "intel_display_types.h"17#include "intel_dp_aux.h"18#include "intel_dpio_phy.h"19#include "intel_fdi.h"20#include "intel_fifo_underrun.h"21#include "intel_hdmi.h"22#include "intel_hotplug.h"23#include "intel_sdvo.h"24#include "vlv_sideband.h"25 26static void intel_hdmi_prepare(struct intel_encoder *encoder,27 const struct intel_crtc_state *crtc_state)28{29 struct drm_device *dev = encoder->base.dev;30 struct drm_i915_private *dev_priv = to_i915(dev);31 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);32 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);33 const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;34 u32 hdmi_val;35 36 intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);37 38 hdmi_val = SDVO_ENCODING_HDMI;39 if (!HAS_PCH_SPLIT(dev_priv) && crtc_state->limited_color_range)40 hdmi_val |= HDMI_COLOR_RANGE_16_235;41 if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)42 hdmi_val |= SDVO_VSYNC_ACTIVE_HIGH;43 if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)44 hdmi_val |= SDVO_HSYNC_ACTIVE_HIGH;45 46 if (crtc_state->pipe_bpp > 24)47 hdmi_val |= HDMI_COLOR_FORMAT_12bpc;48 else49 hdmi_val |= SDVO_COLOR_FORMAT_8bpc;50 51 if (crtc_state->has_hdmi_sink)52 hdmi_val |= HDMI_MODE_SELECT_HDMI;53 54 if (HAS_PCH_CPT(dev_priv))55 hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe);56 else if (IS_CHERRYVIEW(dev_priv))57 hdmi_val |= SDVO_PIPE_SEL_CHV(crtc->pipe);58 else59 hdmi_val |= SDVO_PIPE_SEL(crtc->pipe);60 61 intel_de_write(dev_priv, intel_hdmi->hdmi_reg, hdmi_val);62 intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);63}64 65static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,66 enum pipe *pipe)67{68 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);69 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);70 intel_wakeref_t wakeref;71 bool ret;72 73 wakeref = intel_display_power_get_if_enabled(dev_priv,74 encoder->power_domain);75 if (!wakeref)76 return false;77 78 ret = intel_sdvo_port_enabled(dev_priv, intel_hdmi->hdmi_reg, pipe);79 80 intel_display_power_put(dev_priv, encoder->power_domain, wakeref);81 82 return ret;83}84 85static bool connector_is_hdmi(struct drm_connector *connector)86{87 struct intel_encoder *encoder =88 intel_attached_encoder(to_intel_connector(connector));89 90 return encoder && encoder->type == INTEL_OUTPUT_HDMI;91}92 93static bool g4x_compute_has_hdmi_sink(struct intel_atomic_state *state,94 struct intel_crtc *this_crtc)95{96 const struct drm_connector_state *conn_state;97 struct drm_connector *connector;98 int i;99 100 /*101 * On g4x only one HDMI port can transmit infoframes/audio at102 * any given time. Select the first suitable port for this duty.103 *104 * See also g4x_hdmi_connector_atomic_check().105 */106 for_each_new_connector_in_state(&state->base, connector, conn_state, i) {107 struct intel_encoder *encoder = to_intel_encoder(conn_state->best_encoder);108 const struct intel_crtc_state *crtc_state;109 struct intel_crtc *crtc;110 111 if (!connector_is_hdmi(connector))112 continue;113 114 crtc = to_intel_crtc(conn_state->crtc);115 if (!crtc)116 continue;117 118 crtc_state = intel_atomic_get_new_crtc_state(state, crtc);119 120 if (!intel_hdmi_compute_has_hdmi_sink(encoder, crtc_state, conn_state))121 continue;122 123 return crtc == this_crtc;124 }125 126 return false;127}128 129static int g4x_hdmi_compute_config(struct intel_encoder *encoder,130 struct intel_crtc_state *crtc_state,131 struct drm_connector_state *conn_state)132{133 struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);134 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);135 struct drm_i915_private *i915 = to_i915(encoder->base.dev);136 137 if (HAS_PCH_SPLIT(i915)) {138 crtc_state->has_pch_encoder = true;139 if (!intel_fdi_compute_pipe_bpp(crtc_state))140 return -EINVAL;141 }142 143 if (IS_G4X(i915))144 crtc_state->has_hdmi_sink = g4x_compute_has_hdmi_sink(state, crtc);145 else146 crtc_state->has_hdmi_sink =147 intel_hdmi_compute_has_hdmi_sink(encoder, crtc_state, conn_state);148 149 return intel_hdmi_compute_config(encoder, crtc_state, conn_state);150}151 152static void intel_hdmi_get_config(struct intel_encoder *encoder,153 struct intel_crtc_state *pipe_config)154{155 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);156 struct drm_device *dev = encoder->base.dev;157 struct drm_i915_private *dev_priv = to_i915(dev);158 u32 tmp, flags = 0;159 int dotclock;160 161 pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI);162 163 tmp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);164 165 if (tmp & SDVO_HSYNC_ACTIVE_HIGH)166 flags |= DRM_MODE_FLAG_PHSYNC;167 else168 flags |= DRM_MODE_FLAG_NHSYNC;169 170 if (tmp & SDVO_VSYNC_ACTIVE_HIGH)171 flags |= DRM_MODE_FLAG_PVSYNC;172 else173 flags |= DRM_MODE_FLAG_NVSYNC;174 175 if (tmp & HDMI_MODE_SELECT_HDMI)176 pipe_config->has_hdmi_sink = true;177 178 pipe_config->infoframes.enable |=179 intel_hdmi_infoframes_enabled(encoder, pipe_config);180 181 if (pipe_config->infoframes.enable)182 pipe_config->has_infoframe = true;183 184 if (tmp & HDMI_AUDIO_ENABLE)185 pipe_config->has_audio = true;186 187 if (!HAS_PCH_SPLIT(dev_priv) &&188 tmp & HDMI_COLOR_RANGE_16_235)189 pipe_config->limited_color_range = true;190 191 pipe_config->hw.adjusted_mode.flags |= flags;192 193 if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc)194 dotclock = DIV_ROUND_CLOSEST(pipe_config->port_clock * 2, 3);195 else196 dotclock = pipe_config->port_clock;197 198 if (pipe_config->pixel_multiplier)199 dotclock /= pipe_config->pixel_multiplier;200 201 pipe_config->hw.adjusted_mode.crtc_clock = dotclock;202 203 pipe_config->lane_count = 4;204 205 intel_hdmi_read_gcp_infoframe(encoder, pipe_config);206 207 intel_read_infoframe(encoder, pipe_config,208 HDMI_INFOFRAME_TYPE_AVI,209 &pipe_config->infoframes.avi);210 intel_read_infoframe(encoder, pipe_config,211 HDMI_INFOFRAME_TYPE_SPD,212 &pipe_config->infoframes.spd);213 intel_read_infoframe(encoder, pipe_config,214 HDMI_INFOFRAME_TYPE_VENDOR,215 &pipe_config->infoframes.hdmi);216 217 intel_audio_codec_get_config(encoder, pipe_config);218}219 220static void g4x_hdmi_enable_port(struct intel_encoder *encoder,221 const struct intel_crtc_state *pipe_config)222{223 struct drm_device *dev = encoder->base.dev;224 struct drm_i915_private *dev_priv = to_i915(dev);225 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);226 u32 temp;227 228 temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);229 230 temp |= SDVO_ENABLE;231 232 intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);233 intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);234}235 236static void g4x_hdmi_audio_enable(struct intel_encoder *encoder,237 const struct intel_crtc_state *crtc_state,238 const struct drm_connector_state *conn_state)239{240 struct drm_i915_private *i915 = to_i915(encoder->base.dev);241 struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder);242 243 if (!crtc_state->has_audio)244 return;245 246 drm_WARN_ON(&i915->drm, !crtc_state->has_hdmi_sink);247 248 /* Enable audio presence detect */249 intel_de_rmw(i915, hdmi->hdmi_reg, 0, HDMI_AUDIO_ENABLE);250 251 intel_audio_codec_enable(encoder, crtc_state, conn_state);252}253 254static void g4x_hdmi_audio_disable(struct intel_encoder *encoder,255 const struct intel_crtc_state *old_crtc_state,256 const struct drm_connector_state *old_conn_state)257{258 struct drm_i915_private *i915 = to_i915(encoder->base.dev);259 struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder);260 261 if (!old_crtc_state->has_audio)262 return;263 264 intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);265 266 /* Disable audio presence detect */267 intel_de_rmw(i915, hdmi->hdmi_reg, HDMI_AUDIO_ENABLE, 0);268}269 270static void g4x_enable_hdmi(struct intel_atomic_state *state,271 struct intel_encoder *encoder,272 const struct intel_crtc_state *pipe_config,273 const struct drm_connector_state *conn_state)274{275 g4x_hdmi_enable_port(encoder, pipe_config);276}277 278static void ibx_enable_hdmi(struct intel_atomic_state *state,279 struct intel_encoder *encoder,280 const struct intel_crtc_state *pipe_config,281 const struct drm_connector_state *conn_state)282{283 struct drm_device *dev = encoder->base.dev;284 struct drm_i915_private *dev_priv = to_i915(dev);285 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);286 u32 temp;287 288 temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);289 290 temp |= SDVO_ENABLE;291 292 /*293 * HW workaround, need to write this twice for issue294 * that may result in first write getting masked.295 */296 intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);297 intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);298 intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);299 intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);300 301 /*302 * HW workaround, need to toggle enable bit off and on303 * for 12bpc with pixel repeat.304 *305 * FIXME: BSpec says this should be done at the end of306 * the modeset sequence, so not sure if this isn't too soon.307 */308 if (pipe_config->pipe_bpp > 24 &&309 pipe_config->pixel_multiplier > 1) {310 intel_de_write(dev_priv, intel_hdmi->hdmi_reg,311 temp & ~SDVO_ENABLE);312 intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);313 314 /*315 * HW workaround, need to write this twice for issue316 * that may result in first write getting masked.317 */318 intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);319 intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);320 intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);321 intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);322 }323}324 325static void cpt_enable_hdmi(struct intel_atomic_state *state,326 struct intel_encoder *encoder,327 const struct intel_crtc_state *pipe_config,328 const struct drm_connector_state *conn_state)329{330 struct drm_device *dev = encoder->base.dev;331 struct drm_i915_private *dev_priv = to_i915(dev);332 struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);333 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);334 enum pipe pipe = crtc->pipe;335 u32 temp;336 337 temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);338 339 temp |= SDVO_ENABLE;340 341 /*342 * WaEnableHDMI8bpcBefore12bpc:snb,ivb343 *344 * The procedure for 12bpc is as follows:345 * 1. disable HDMI clock gating346 * 2. enable HDMI with 8bpc347 * 3. enable HDMI with 12bpc348 * 4. enable HDMI clock gating349 */350 351 if (pipe_config->pipe_bpp > 24) {352 intel_de_rmw(dev_priv, TRANS_CHICKEN1(pipe),353 0, TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE);354 355 temp &= ~SDVO_COLOR_FORMAT_MASK;356 temp |= SDVO_COLOR_FORMAT_8bpc;357 }358 359 intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);360 intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);361 362 if (pipe_config->pipe_bpp > 24) {363 temp &= ~SDVO_COLOR_FORMAT_MASK;364 temp |= HDMI_COLOR_FORMAT_12bpc;365 366 intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);367 intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);368 369 intel_de_rmw(dev_priv, TRANS_CHICKEN1(pipe),370 TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE, 0);371 }372}373 374static void vlv_enable_hdmi(struct intel_atomic_state *state,375 struct intel_encoder *encoder,376 const struct intel_crtc_state *pipe_config,377 const struct drm_connector_state *conn_state)378{379}380 381static void intel_disable_hdmi(struct intel_atomic_state *state,382 struct intel_encoder *encoder,383 const struct intel_crtc_state *old_crtc_state,384 const struct drm_connector_state *old_conn_state)385{386 struct drm_device *dev = encoder->base.dev;387 struct drm_i915_private *dev_priv = to_i915(dev);388 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);389 struct intel_digital_port *dig_port =390 hdmi_to_dig_port(intel_hdmi);391 struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);392 u32 temp;393 394 temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);395 396 temp &= ~SDVO_ENABLE;397 intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);398 intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);399 400 /*401 * HW workaround for IBX, we need to move the port402 * to transcoder A after disabling it to allow the403 * matching DP port to be enabled on transcoder A.404 */405 if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B) {406 /*407 * We get CPU/PCH FIFO underruns on the other pipe when408 * doing the workaround. Sweep them under the rug.409 */410 intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false);411 intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);412 413 temp &= ~SDVO_PIPE_SEL_MASK;414 temp |= SDVO_ENABLE | SDVO_PIPE_SEL(PIPE_A);415 /*416 * HW workaround, need to write this twice for issue417 * that may result in first write getting masked.418 */419 intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);420 intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);421 intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);422 intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);423 424 temp &= ~SDVO_ENABLE;425 intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);426 intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);427 428 intel_wait_for_vblank_if_active(dev_priv, PIPE_A);429 intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true);430 intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);431 }432 433 dig_port->set_infoframes(encoder,434 false,435 old_crtc_state, old_conn_state);436 437 intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);438}439 440static void g4x_disable_hdmi(struct intel_atomic_state *state,441 struct intel_encoder *encoder,442 const struct intel_crtc_state *old_crtc_state,443 const struct drm_connector_state *old_conn_state)444{445 intel_disable_hdmi(state, encoder, old_crtc_state, old_conn_state);446}447 448static void pch_disable_hdmi(struct intel_atomic_state *state,449 struct intel_encoder *encoder,450 const struct intel_crtc_state *old_crtc_state,451 const struct drm_connector_state *old_conn_state)452{453}454 455static void pch_post_disable_hdmi(struct intel_atomic_state *state,456 struct intel_encoder *encoder,457 const struct intel_crtc_state *old_crtc_state,458 const struct drm_connector_state *old_conn_state)459{460 intel_disable_hdmi(state, encoder, old_crtc_state, old_conn_state);461}462 463static void intel_hdmi_pre_enable(struct intel_atomic_state *state,464 struct intel_encoder *encoder,465 const struct intel_crtc_state *pipe_config,466 const struct drm_connector_state *conn_state)467{468 struct intel_digital_port *dig_port =469 enc_to_dig_port(encoder);470 471 intel_hdmi_prepare(encoder, pipe_config);472 473 dig_port->set_infoframes(encoder,474 pipe_config->has_infoframe,475 pipe_config, conn_state);476}477 478static void vlv_hdmi_pre_enable(struct intel_atomic_state *state,479 struct intel_encoder *encoder,480 const struct intel_crtc_state *pipe_config,481 const struct drm_connector_state *conn_state)482{483 struct intel_digital_port *dig_port = enc_to_dig_port(encoder);484 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);485 486 vlv_phy_pre_encoder_enable(encoder, pipe_config);487 488 /* HDMI 1.0V-2dB */489 vlv_set_phy_signal_level(encoder, pipe_config,490 0x2b245f5f, 0x00002000,491 0x5578b83a, 0x2b247878);492 493 dig_port->set_infoframes(encoder,494 pipe_config->has_infoframe,495 pipe_config, conn_state);496 497 g4x_hdmi_enable_port(encoder, pipe_config);498 499 vlv_wait_port_ready(dev_priv, dig_port, 0x0);500}501 502static void vlv_hdmi_pre_pll_enable(struct intel_atomic_state *state,503 struct intel_encoder *encoder,504 const struct intel_crtc_state *pipe_config,505 const struct drm_connector_state *conn_state)506{507 intel_hdmi_prepare(encoder, pipe_config);508 509 vlv_phy_pre_pll_enable(encoder, pipe_config);510}511 512static void chv_hdmi_pre_pll_enable(struct intel_atomic_state *state,513 struct intel_encoder *encoder,514 const struct intel_crtc_state *pipe_config,515 const struct drm_connector_state *conn_state)516{517 intel_hdmi_prepare(encoder, pipe_config);518 519 chv_phy_pre_pll_enable(encoder, pipe_config);520}521 522static void chv_hdmi_post_pll_disable(struct intel_atomic_state *state,523 struct intel_encoder *encoder,524 const struct intel_crtc_state *old_crtc_state,525 const struct drm_connector_state *old_conn_state)526{527 chv_phy_post_pll_disable(encoder, old_crtc_state);528}529 530static void vlv_hdmi_post_disable(struct intel_atomic_state *state,531 struct intel_encoder *encoder,532 const struct intel_crtc_state *old_crtc_state,533 const struct drm_connector_state *old_conn_state)534{535 /* Reset lanes to avoid HDMI flicker (VLV w/a) */536 vlv_phy_reset_lanes(encoder, old_crtc_state);537}538 539static void chv_hdmi_post_disable(struct intel_atomic_state *state,540 struct intel_encoder *encoder,541 const struct intel_crtc_state *old_crtc_state,542 const struct drm_connector_state *old_conn_state)543{544 struct drm_device *dev = encoder->base.dev;545 struct drm_i915_private *dev_priv = to_i915(dev);546 547 vlv_dpio_get(dev_priv);548 549 /* Assert data lane reset */550 chv_data_lane_soft_reset(encoder, old_crtc_state, true);551 552 vlv_dpio_put(dev_priv);553}554 555static void chv_hdmi_pre_enable(struct intel_atomic_state *state,556 struct intel_encoder *encoder,557 const struct intel_crtc_state *pipe_config,558 const struct drm_connector_state *conn_state)559{560 struct intel_digital_port *dig_port = enc_to_dig_port(encoder);561 struct drm_device *dev = encoder->base.dev;562 struct drm_i915_private *dev_priv = to_i915(dev);563 564 chv_phy_pre_encoder_enable(encoder, pipe_config);565 566 /* FIXME: Program the support xxx V-dB */567 /* Use 800mV-0dB */568 chv_set_phy_signal_level(encoder, pipe_config, 128, 102, false);569 570 dig_port->set_infoframes(encoder,571 pipe_config->has_infoframe,572 pipe_config, conn_state);573 574 g4x_hdmi_enable_port(encoder, pipe_config);575 576 vlv_wait_port_ready(dev_priv, dig_port, 0x0);577 578 /* Second common lane will stay alive on its own now */579 chv_phy_release_cl2_override(encoder);580}581 582static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {583 .destroy = intel_encoder_destroy,584};585 586static enum intel_hotplug_state587intel_hdmi_hotplug(struct intel_encoder *encoder,588 struct intel_connector *connector)589{590 enum intel_hotplug_state state;591 592 state = intel_encoder_hotplug(encoder, connector);593 594 /*595 * On many platforms the HDMI live state signal is known to be596 * unreliable, so we can't use it to detect if a sink is connected or597 * not. Instead we detect if it's connected based on whether we can598 * read the EDID or not. That in turn has a problem during disconnect,599 * since the HPD interrupt may be raised before the DDC lines get600 * disconnected (due to how the required length of DDC vs. HPD601 * connector pins are specified) and so we'll still be able to get a602 * valid EDID. To solve this schedule another detection cycle if this603 * time around we didn't detect any change in the sink's connection604 * status.605 */606 if (state == INTEL_HOTPLUG_UNCHANGED && !connector->hotplug_retries)607 state = INTEL_HOTPLUG_RETRY;608 609 return state;610}611 612int g4x_hdmi_connector_atomic_check(struct drm_connector *connector,613 struct drm_atomic_state *state)614{615 struct drm_i915_private *i915 = to_i915(state->dev);616 struct drm_connector_list_iter conn_iter;617 struct drm_connector *conn;618 int ret;619 620 ret = intel_digital_connector_atomic_check(connector, state);621 if (ret)622 return ret;623 624 if (!IS_G4X(i915))625 return 0;626 627 if (!intel_connector_needs_modeset(to_intel_atomic_state(state), connector))628 return 0;629 630 /*631 * On g4x only one HDMI port can transmit infoframes/audio632 * at any given time. Make sure all enabled HDMI ports are633 * included in the state so that it's possible to select634 * one of them for this duty.635 *636 * See also g4x_compute_has_hdmi_sink().637 */638 drm_connector_list_iter_begin(&i915->drm, &conn_iter);639 drm_for_each_connector_iter(conn, &conn_iter) {640 struct drm_connector_state *conn_state;641 struct drm_crtc_state *crtc_state;642 struct drm_crtc *crtc;643 644 if (!connector_is_hdmi(conn))645 continue;646 647 drm_dbg_kms(&i915->drm, "Adding [CONNECTOR:%d:%s]\n",648 conn->base.id, conn->name);649 650 conn_state = drm_atomic_get_connector_state(state, conn);651 if (IS_ERR(conn_state)) {652 ret = PTR_ERR(conn_state);653 break;654 }655 656 crtc = conn_state->crtc;657 if (!crtc)658 continue;659 660 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);661 crtc_state->mode_changed = true;662 663 ret = drm_atomic_add_affected_planes(state, crtc);664 if (ret)665 break;666 }667 drm_connector_list_iter_end(&conn_iter);668 669 return ret;670}671 672static bool is_hdmi_port_valid(struct drm_i915_private *i915, enum port port)673{674 if (IS_G4X(i915) || IS_VALLEYVIEW(i915))675 return port == PORT_B || port == PORT_C;676 else677 return port == PORT_B || port == PORT_C || port == PORT_D;678}679 680static bool assert_hdmi_port_valid(struct drm_i915_private *i915, enum port port)681{682 return !drm_WARN(&i915->drm, !is_hdmi_port_valid(i915, port),683 "Platform does not support HDMI %c\n", port_name(port));684}685 686void g4x_hdmi_init(struct drm_i915_private *dev_priv,687 i915_reg_t hdmi_reg, enum port port)688{689 struct intel_display *display = &dev_priv->display;690 const struct intel_bios_encoder_data *devdata;691 struct intel_digital_port *dig_port;692 struct intel_encoder *intel_encoder;693 struct intel_connector *intel_connector;694 695 if (!assert_port_valid(dev_priv, port))696 return;697 698 if (!assert_hdmi_port_valid(dev_priv, port))699 return;700 701 devdata = intel_bios_encoder_data_lookup(display, port);702 703 /* FIXME bail? */704 if (!devdata)705 drm_dbg_kms(&dev_priv->drm, "No VBT child device for HDMI-%c\n",706 port_name(port));707 708 dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL);709 if (!dig_port)710 return;711 712 dig_port->aux_ch = AUX_CH_NONE;713 714 intel_connector = intel_connector_alloc();715 if (!intel_connector) {716 kfree(dig_port);717 return;718 }719 720 intel_encoder = &dig_port->base;721 722 intel_encoder->devdata = devdata;723 724 mutex_init(&dig_port->hdcp_mutex);725 726 drm_encoder_init(&dev_priv->drm, &intel_encoder->base,727 &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS,728 "HDMI %c", port_name(port));729 730 intel_encoder->hotplug = intel_hdmi_hotplug;731 intel_encoder->compute_config = g4x_hdmi_compute_config;732 if (HAS_PCH_SPLIT(dev_priv)) {733 intel_encoder->disable = pch_disable_hdmi;734 intel_encoder->post_disable = pch_post_disable_hdmi;735 } else {736 intel_encoder->disable = g4x_disable_hdmi;737 }738 intel_encoder->get_hw_state = intel_hdmi_get_hw_state;739 intel_encoder->get_config = intel_hdmi_get_config;740 if (IS_CHERRYVIEW(dev_priv)) {741 intel_encoder->pre_pll_enable = chv_hdmi_pre_pll_enable;742 intel_encoder->pre_enable = chv_hdmi_pre_enable;743 intel_encoder->enable = vlv_enable_hdmi;744 intel_encoder->post_disable = chv_hdmi_post_disable;745 intel_encoder->post_pll_disable = chv_hdmi_post_pll_disable;746 } else if (IS_VALLEYVIEW(dev_priv)) {747 intel_encoder->pre_pll_enable = vlv_hdmi_pre_pll_enable;748 intel_encoder->pre_enable = vlv_hdmi_pre_enable;749 intel_encoder->enable = vlv_enable_hdmi;750 intel_encoder->post_disable = vlv_hdmi_post_disable;751 } else {752 intel_encoder->pre_enable = intel_hdmi_pre_enable;753 if (HAS_PCH_CPT(dev_priv))754 intel_encoder->enable = cpt_enable_hdmi;755 else if (HAS_PCH_IBX(dev_priv))756 intel_encoder->enable = ibx_enable_hdmi;757 else758 intel_encoder->enable = g4x_enable_hdmi;759 }760 intel_encoder->audio_enable = g4x_hdmi_audio_enable;761 intel_encoder->audio_disable = g4x_hdmi_audio_disable;762 intel_encoder->shutdown = intel_hdmi_encoder_shutdown;763 764 intel_encoder->type = INTEL_OUTPUT_HDMI;765 intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port);766 intel_encoder->port = port;767 if (IS_CHERRYVIEW(dev_priv)) {768 if (port == PORT_D)769 intel_encoder->pipe_mask = BIT(PIPE_C);770 else771 intel_encoder->pipe_mask = BIT(PIPE_A) | BIT(PIPE_B);772 } else {773 intel_encoder->pipe_mask = ~0;774 }775 intel_encoder->cloneable = BIT(INTEL_OUTPUT_ANALOG);776 intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);777 /*778 * BSpec is unclear about HDMI+HDMI cloning on g4x, but it seems779 * to work on real hardware. And since g4x can send infoframes to780 * only one port anyway, nothing is lost by allowing it.781 */782 if (IS_G4X(dev_priv))783 intel_encoder->cloneable |= BIT(INTEL_OUTPUT_HDMI);784 785 dig_port->hdmi.hdmi_reg = hdmi_reg;786 dig_port->dp.output_reg = INVALID_MMIO_REG;787 dig_port->max_lanes = 4;788 789 intel_infoframe_init(dig_port);790 791 intel_hdmi_init_connector(dig_port, intel_connector);792}793