[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