state = g4x_dp_port_enabled(display, dp_reg, port, &port_pipe);
INTEL_DISPLAY_STATE_WARN(display, state && port_pipe == pipe, "PCH DP %c enabled on transcoder %c, should be disabled\n",
port_name(port), pipe_name(pipe));
INTEL_DISPLAY_STATE_WARN(display,
HAS_PCH_IBX(display) && !state && port_pipe == PIPE_B, "IBX PCH DP %c still using transcoder B\n",
port_name(port));
}
state = intel_sdvo_port_enabled(display, hdmi_reg, &port_pipe);
INTEL_DISPLAY_STATE_WARN(display, state && port_pipe == pipe, "PCH HDMI %c enabled on transcoder %c, should be disabled\n",
port_name(port), pipe_name(pipe));
INTEL_DISPLAY_STATE_WARN(display,
HAS_PCH_IBX(display) && !state && port_pipe == PIPE_B, "IBX PCH HDMI %c still using transcoder B\n",
port_name(port));
}
val = intel_de_read(display, PCH_TRANSCONF(pipe));
enabled = !!(val & TRANS_ENABLE);
INTEL_DISPLAY_STATE_WARN(display, enabled, "transcoder assertion failed, should be off on pipe %c but is still active\n",
pipe_name(pipe));
}
staticvoid ibx_sanitize_pch_hdmi_port(struct intel_display *display, enum port port, i915_reg_t hdmi_reg)
{
u32 val = intel_de_read(display, hdmi_reg);
drm_dbg_kms(display->drm, "Sanitizing transcoder select for DP %c\n",
port_name(port));
val &= ~DP_PIPE_SEL_MASK;
val |= DP_PIPE_SEL(PIPE_A);
intel_de_write(display, dp_reg, val);
}
staticvoid ibx_sanitize_pch_ports(struct intel_display *display)
{ /* * The BIOS may select transcoder B on some of the PCH * ports even it doesn't enable the port. This would trip * assert_pch_dp_disabled() and assert_pch_hdmi_disabled(). * Sanitize the transcoder select bits to prevent that. We * assume that the BIOS never actually enabled the port, * because if it did we'd actually have to toggle the port * on and back off to make the transcoder A select stick * (see. intel_dp_link_down(), intel_disable_hdmi(), * intel_disable_sdvo()).
*/
ibx_sanitize_pch_dp_port(display, PORT_B, PCH_DP_B);
ibx_sanitize_pch_dp_port(display, PORT_C, PCH_DP_C);
ibx_sanitize_pch_dp_port(display, PORT_D, PCH_DP_D);
/* Make sure PCH DPLL is enabled */
assert_dpll_enabled(display, crtc_state->intel_dpll);
/* FDI must be feeding us bits for PCH ports */
assert_fdi_tx_enabled(display, pipe);
assert_fdi_rx_enabled(display, pipe);
if (HAS_PCH_CPT(display)) {
reg = TRANS_CHICKEN2(pipe);
val = intel_de_read(display, reg); /* * Workaround: Set the timing override bit * before enabling the pch transcoder.
*/
val |= TRANS_CHICKEN2_TIMING_OVERRIDE; /* Configure frame start delay to match the CPU */
val &= ~TRANS_CHICKEN2_FRAME_START_DELAY_MASK;
val |= TRANS_CHICKEN2_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
intel_de_write(display, reg, val);
}
if (HAS_PCH_IBX(display)) { /* Configure frame start delay to match the CPU */
val &= ~TRANS_FRAME_START_DELAY_MASK;
val |= TRANS_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
/* * Make the BPC in transcoder be consistent with * that in pipeconf reg. For HDMI we must use 8bpc * here for both 8bpc and 12bpc.
*/
val &= ~TRANSCONF_BPC_MASK; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
val |= TRANSCONF_BPC_8; else
val |= pipeconf_val & TRANSCONF_BPC_MASK;
}
val &= ~TRANS_INTERLACE_MASK; if ((pipeconf_val & TRANSCONF_INTERLACE_MASK_ILK) == TRANSCONF_INTERLACE_IF_ID_ILK) { if (HAS_PCH_IBX(display) &&
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO))
val |= TRANS_INTERLACE_LEGACY_VSYNC_IBX; else
val |= TRANS_INTERLACE_INTERLACED;
} else {
val |= TRANS_INTERLACE_PROGRESSIVE;
}
intel_de_write(display, reg, val | TRANS_ENABLE); if (intel_de_wait_for_set(display, reg, TRANS_STATE_ENABLE, 100))
drm_err(display->drm, "failed to enable transcoder %c\n",
pipe_name(pipe));
}
/* * Note: FDI PLL enabling _must_ be done before we enable the * cpu pipes, hence this is separate from all the other fdi/pch * enabling.
*/
ilk_fdi_pll_enable(crtc_state);
}
/* * XXX: pch pll's can be enabled any time before we enable the PCH * transcoder, and we actually should do this to not upset any PCH * transcoder that already use the clock when we share it. * * Note that dpll_enable tries to do the right thing, but * get_dpll unconditionally resets the pll - we need that * to have the right LVDS enable sequence.
*/
intel_dpll_enable(crtc_state);
/* set transcoder timing, panel must allow it */
assert_pps_unlocked(display, pipe); if (intel_crtc_has_dp_encoder(crtc_state)) {
intel_pch_transcoder_set_m1_n1(crtc, &crtc_state->dp_m_n);
intel_pch_transcoder_set_m2_n2(crtc, &crtc_state->dp_m2_n2);
}
ilk_pch_transcoder_set_timings(crtc_state, pipe);
temp = intel_de_read(display, reg);
temp &= ~(TRANS_DP_PORT_SEL_MASK |
TRANS_DP_VSYNC_ACTIVE_HIGH |
TRANS_DP_HSYNC_ACTIVE_HIGH |
TRANS_DP_BPC_MASK);
temp |= TRANS_DP_OUTPUT_ENABLE;
temp |= bpc << 9; /* same format but at 11:9 */
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
temp |= TRANS_DP_VSYNC_ACTIVE_HIGH;
port = intel_get_crtc_new_encoder(state, crtc_state)->port;
drm_WARN_ON(display->drm, port < PORT_B || port > PORT_D);
temp |= TRANS_DP_PORT_SEL(port);
/* read out port_clock from the DPLL */
i9xx_crtc_clock_get(crtc_state);
/* * In case there is an active pipe without active ports, * we may need some idea for the dotclock anyway. * Calculate one based on the FDI configuration.
*/
crtc_state->hw.adjusted_mode.crtc_clock =
intel_dotclock_calculate(intel_fdi_link_freq(display, crtc_state),
&crtc_state->fdi_m_n);
}
/* FDI must be feeding us bits for PCH ports */
assert_fdi_tx_enabled(display, (enum pipe)cpu_transcoder);
assert_fdi_rx_enabled(display, PIPE_A);
val = intel_de_read(display, TRANS_CHICKEN2(PIPE_A)); /* Workaround: set timing override bit. */
val |= TRANS_CHICKEN2_TIMING_OVERRIDE; /* Configure frame start delay to match the CPU */
val &= ~TRANS_CHICKEN2_FRAME_START_DELAY_MASK;
val |= TRANS_CHICKEN2_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
intel_de_write(display, TRANS_CHICKEN2(PIPE_A), val);
val = TRANS_ENABLE;
pipeconf_val = intel_de_read(display,
TRANSCONF(display, cpu_transcoder));
if ((pipeconf_val & TRANSCONF_INTERLACE_MASK_HSW) == TRANSCONF_INTERLACE_IF_ID_ILK)
val |= TRANS_INTERLACE_INTERLACED; else
val |= TRANS_INTERLACE_PROGRESSIVE;
intel_de_write(display, LPT_TRANSCONF, val); if (intel_de_wait_for_set(display, LPT_TRANSCONF,
TRANS_STATE_ENABLE, 100))
drm_err(display->drm, "Failed to enable PCH transcoder\n");
}
staticvoid lpt_disable_pch_transcoder(struct intel_display *display)
{
intel_de_rmw(display, LPT_TRANSCONF, TRANS_ENABLE, 0); /* wait for PCH transcoder off, transcoder state */ if (intel_de_wait_for_clear(display, LPT_TRANSCONF,
TRANS_STATE_ENABLE, 50))
drm_err(display->drm, "Failed to disable PCH transcoder\n");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.