[Intel-gfx] [PATCH v2 7/7] drm/i915: YCBCR 420 support for LSPCON
Maarten Lankhorst
maarten.lankhorst at linux.intel.com
Wed Nov 1 09:32:44 UTC 2017
Op 09-08-17 om 08:46 schreef Shashank Sharma:
> LSPCON chips support YCBCR420 outputs. To be able to get
> YCBCR420 output from LSPCON chip, the source should:
> - Generate YCBCR444 HDMI output
> - Set AVI infoframes for a YCBCR420 output.
>
> Unlike Native HDMI 4:2:0 outputs, there is no need to
> reserve a scaler in pipe, LSPCON does the downsampling from
> YCBCR 4:4:4 to 4:2:0 on its own.
>
> LSPCON FW gets the information from AVI infoframes, and generates
> YCBCR420 output from a YCBCR444 input. This patch adds the necessary
> changes to drive YCBCR420 output from LSPCON based HDMI output.
>
> V2: Dont mess around with 8bpc and 12bpc clocks, its not reqd
> for DP links. (Ville)
>
> Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
> Cc: Imre Deak <imre.deak at intel.com>
> Signed-off-by: Shashank Sharma <shashank.sharma at intel.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 15 +++++++++++----
> drivers/gpu/drm/i915/intel_dp.c | 13 ++++++++++++-
> drivers/gpu/drm/i915/intel_drv.h | 10 +++++++++-
> drivers/gpu/drm/i915/intel_lspcon.c | 2 ++
> 4 files changed, 34 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 5a89db1..eb1d93b 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4487,7 +4487,8 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
> */
> need_scaling = src_w != dst_w || src_h != dst_h;
>
> - if (crtc_state->ycbcr420 && scaler_user == SKL_CRTC_INDEX)
> + if (crtc_state->ycbcr420 && scaler_user == SKL_CRTC_INDEX &&
> + !crtc_state->lspcon_active)
> need_scaling = true;
>
> /*
> @@ -7970,9 +7971,15 @@ static void haswell_set_pipemisc(struct drm_crtc *crtc)
> val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP;
>
> if (config->ycbcr420) {
> - val |= PIPEMISC_OUTPUT_COLORSPACE_YUV |
> - PIPEMISC_YUV420_ENABLE |
> - PIPEMISC_YUV420_MODE_FULL_BLEND;
> + val |= PIPEMISC_OUTPUT_COLORSPACE_YUV;
> + /*
> + * LSPCON doesn't need scaling/blending to be done in
> + * pipe. It just needs YCBCR444 input and proper AVI
> + * infoframes for 4:2:0 output enabling.
> + */
> + if (!config->lspcon_active)
> + val |= PIPEMISC_YUV420_ENABLE |
> + PIPEMISC_YUV420_MODE_FULL_BLEND;
> }
>
> I915_WRITE(PIPEMISC(intel_crtc->pipe), val);
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index d580243..b7774cc 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1614,7 +1614,9 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> - enum port port = dp_to_dig_port(intel_dp)->port;
> + struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base);
> + enum port port = dig_port->port;
> + struct intel_lspcon *lspcon = &dig_port->lspcon;
> struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
> struct intel_connector *intel_connector = intel_dp->attached_connector;
> struct intel_digital_connector_state *intel_conn_state =
> @@ -1635,6 +1637,15 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> common_len = intel_dp_common_len_rate_limit(intel_dp,
> intel_dp->max_link_rate);
>
> + /* LSPCON needs special handling to drive YCBCR420 outputs */
> + if (lspcon->active) {
> + struct drm_connector *connector = &intel_connector->base;
> +
> + pipe_config->lspcon_active = true;
> + pipe_config->ycbcr420 = lspcon_ycbcr420_config(connector,
> + pipe_config);
> + }
> +
> /* No common link rates between source and sink */
> WARN_ON(common_len <= 0);
>
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 99eaab6..b3cbe2d 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -783,6 +783,9 @@ struct intel_crtc_state {
>
> /* output format is YCBCR 4:2:0 */
> bool ycbcr420;
> +
> + /* LSPCON is active on port */
> + bool lspcon_active;
> };
>
> struct intel_crtc {
> @@ -1182,6 +1185,12 @@ static inline struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
> return &enc_to_dig_port(encoder)->dp;
> }
>
> +static inline struct intel_lspcon *
> +enc_to_intel_lspcon(struct drm_encoder *encoder)
> +{
> + return &enc_to_dig_port(encoder)->lspcon;
> +}
> +
> static inline struct intel_digital_port *
> dp_to_dig_port(struct intel_dp *intel_dp)
> {
> @@ -1662,7 +1671,6 @@ void intel_hdmi_handle_sink_scrambling(struct intel_encoder *intel_encoder,
> void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable);
> void intel_infoframe_init(struct intel_digital_port *intel_dig_port);
>
> -
> /* intel_lvds.c */
> void intel_lvds_init(struct drm_i915_private *dev_priv);
> struct intel_encoder *intel_get_lvds_encoder(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c
> index b4fcd30..8413a4c 100644
> --- a/drivers/gpu/drm/i915/intel_lspcon.c
> +++ b/drivers/gpu/drm/i915/intel_lspcon.c
> @@ -504,6 +504,7 @@ bool lspcon_init(struct intel_digital_port *intel_dig_port)
> struct intel_lspcon *lspcon = &intel_dig_port->lspcon;
> struct drm_device *dev = intel_dig_port->base.base.dev;
> struct drm_i915_private *dev_priv = to_i915(dev);
> + struct drm_connector *connector = &dp->attached_connector->base;
>
> if (!IS_GEN9(dev_priv)) {
> DRM_ERROR("LSPCON is supported on GEN9 only\n");
> @@ -528,6 +529,7 @@ bool lspcon_init(struct intel_digital_port *intel_dig_port)
> return false;
> }
>
> + connector->ycbcr_420_allowed = true;
> lspcon->active = true;
> DRM_DEBUG_KMS("Success: LSPCON init\n");
> return true;
Patch looks good, if the previous patch is fixed up. :)
I'll wait for the resubmit.
~Maarten
More information about the Intel-gfx
mailing list