[Intel-gfx] [PATCH 2/3] drm/i915: Reinitialize sink scrambling/TMDS clock ratio on HPD
Sharma, Shashank
shashank.sharma at intel.com
Thu Dec 28 15:02:05 UTC 2017
On 12/22/2017 11:58 PM, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
>
> The LG 4k TV I have doesn't deassert HPD when I turn the TV off, but
> when I turn it back on it will pulse the HPD line. By that time it has
> forgotten everything we told it about scrambling and the clock ratio.
> Hence if we want to get a picture out if it again we have to tell it
> whether we're currently sending scrambled data or not. Implement
> that via the encoder->post_hotplug() hook.
I am not sure if I understood the problem statement correctly. Even if
the TV triggers HPD line while turning it back, I would expect:
- EDID read for TV's detection, which will refresh SCDC and scrambling
capabilities
- A new modeset will be triggered, which will program the scrambling and
high tmds clock ratio again
- Once HDMI controller is programmed, it will generate scrambled signals
till next modeset / disable.
So why do we need to do this ? I might be missing something, but lets
discus about it.
- Shashank
> Cc: Shashank Sharma <shashank.sharma at intel.com>
> Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> ---
> drivers/gpu/drm/i915/intel_ddi.c | 75 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 75 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index f51645a08dca..12da7024f01a 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2720,6 +2720,79 @@ intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
> return connector;
> }
>
> +static int intel_ddi_hdmi_reset_scrambling(struct intel_encoder *encoder,
> + struct drm_modeset_acquire_ctx *ctx)
> +{
> + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> + struct intel_hdmi *hdmi = enc_to_intel_hdmi(&encoder->base);
> + struct intel_connector *connector = hdmi->attached_connector;
> + struct drm_connector_state *conn_state;
> + struct intel_crtc_state *crtc_state;
> + struct intel_crtc *crtc;
> + int ret;
> +
> + if (!connector || connector->base.status != connector_status_connected)
> + return 0;
> +
> + ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, ctx);
> + if (ret)
> + return ret;
> +
> + conn_state = connector->base.state;
> +
> + crtc = to_intel_crtc(conn_state->crtc);
> + if (!crtc)
> + return 0;
> +
> + ret = drm_modeset_lock(&crtc->base.mutex, ctx);
> + if (ret)
> + return ret;
> +
> + crtc_state = to_intel_crtc_state(crtc->base.state);
> +
> + WARN_ON(!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI));
> +
> + if (!crtc_state->base.active)
> + return 0;
> +
> + if (!crtc_state->hdmi_high_tmds_clock_ratio &&
> + !crtc_state->hdmi_scrambling)
> + return 0;
> +
> + if (conn_state->commit &&
> + !try_wait_for_completion(&conn_state->commit->hw_done))
> + return 0;
> +
> + intel_hdmi_handle_sink_scrambling(encoder, &connector->base,
> + crtc_state->hdmi_high_tmds_clock_ratio,
> + crtc_state->hdmi_scrambling);
> +
> + return 0;
> +}
> +
> +static void intel_ddi_post_hotplug(struct intel_encoder *encoder)
> +{
> + struct drm_modeset_acquire_ctx ctx;
> + int ret;
> +
> + drm_modeset_acquire_init(&ctx, 0);
> +
> + for (;;) {
> + ret = intel_ddi_hdmi_reset_scrambling(encoder, &ctx);
> +
> + if (ret == -EDEADLK) {
> + drm_modeset_backoff(&ctx);
> + continue;
> + }
> +
> + break;
> + }
> +
> + drm_modeset_drop_locks(&ctx);
> + drm_modeset_acquire_fini(&ctx);
> + WARN(ret, "Acquiring modeset locks failed with %i\n", ret);
> +}
> +
> static struct intel_connector *
> intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
> {
> @@ -2830,6 +2903,8 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
> drm_encoder_init(&dev_priv->drm, encoder, &intel_ddi_funcs,
> DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port));
>
> + if (init_hdmi)
> + intel_encoder->post_hotplug = intel_ddi_post_hotplug;
> intel_encoder->compute_output_type = intel_ddi_compute_output_type;
> intel_encoder->compute_config = intel_ddi_compute_config;
> intel_encoder->enable = intel_enable_ddi;
More information about the Intel-gfx
mailing list