On Mon, Jul 03, 2017 at 10:19:38PM +0300, ville.syrj...@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrj...@linux.intel.com>
> 
> Appedix F of HDMI 2.0 says that some HDMI sink may fail to switch from
> 3D to 2D mode in a timely fashion if the source simply stops sending the
> HDMI infoframe. The suggested workaround is to keep sending the
> infoframe even when strictly not necessary (ie. no VIC and no S3D).
> HDMI 1.4 does allow for this behaviour, stating that sending the
> infoframe is optional in this case.
> 
> The infoframe was first specified in HDMI 1.4, so in theory sinks
> predating that may not appreciate us sending an uknown infoframe
> their way. To avoid regressions let's try to determine if the sink
> supports the infoframe or not. Unfortunately there's no direct way
> to do that, so instead we'll just check if we managed to parse any
> HDMI 1.4 4k or stereo modes from the EDID, and if so we assume the
> sink will accept the infoframe. Also if the EDID contains the HDMI
> 2.0 HDMI Forum VSDB we can assume the sink is prepared to receive
> the infoframe.
> 
> Cc: Archit Taneja <arch...@codeaurora.org>
> Cc: Andrzej Hajda <a.ha...@samsung.com>
> Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
> Cc: Inki Dae <inki....@samsung.com>
> Cc: Joonyoung Shim <jy0922.s...@samsung.com>
> Cc: Seung-Woo Kim <sw0312....@samsung.com>
> Cc: Kyungmin Park <kyungmin.p...@samsung.com>
> Cc: CK Hu <ck...@mediatek.com>
> Cc: Philipp Zabel <p.za...@pengutronix.de>
> Cc: Ben Skeggs <bske...@redhat.com>
> Cc: Mark Yao <mark....@rock-chips.com>
> Cc: Benjamin Gaignard <benjamin.gaign...@linaro.org>
> Cc: Vincent Abriou <vincent.abr...@st.com>
> Cc: Shawn Guo <shawn...@kernel.org>
> Cc: Shashank Sharma <shashank.sha...@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
> ---
>  drivers/gpu/drm/bridge/sil-sii8620.c      |  3 ++-
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c |  4 +++-
>  drivers/gpu/drm/drm_edid.c                | 32 
> +++++++++++++++++++++++++------
>  drivers/gpu/drm/exynos/exynos_hdmi.c      |  2 +-
>  drivers/gpu/drm/i915/intel_hdmi.c         | 14 ++++++++------
>  drivers/gpu/drm/mediatek/mtk_hdmi.c       |  3 ++-
>  drivers/gpu/drm/nouveau/nv50_display.c    |  3 ++-
>  drivers/gpu/drm/rockchip/inno_hdmi.c      |  1 +
>  drivers/gpu/drm/sti/sti_hdmi.c            |  4 +++-
>  drivers/gpu/drm/zte/zx_hdmi.c             |  1 +
>  include/drm/drm_connector.h               |  5 +++++
>  include/drm/drm_edid.h                    |  1 +
>  12 files changed, 55 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c 
> b/drivers/gpu/drm/bridge/sil-sii8620.c
> index 2d51a2269fc6..758b5a4546f1 100644
> --- a/drivers/gpu/drm/bridge/sil-sii8620.c
> +++ b/drivers/gpu/drm/bridge/sil-sii8620.c
> @@ -2136,8 +2136,9 @@ static bool sii8620_mode_fixup(struct drm_bridge 
> *bridge,
>                       union hdmi_infoframe frm;
>                       u8 mhl_vic[] = { 0, 95, 94, 93, 98 };
>  
> +                     /* FIXME: We need the connector here */
>                       drm_hdmi_vendor_infoframe_from_display_mode(
> -                             &frm.vendor.hdmi, adjusted_mode);
> +                             &frm.vendor.hdmi, NULL, adjusted_mode);
>                       vic = frm.vendor.hdmi.vic;
>                       if (vic >= ARRAY_SIZE(mhl_vic))
>                               vic = 0;
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index ead11242c4b9..c43389774691 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -1426,7 +1426,9 @@ static void 
> hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi,
>       u8 buffer[10];
>       ssize_t err;
>  
> -     err = drm_hdmi_vendor_infoframe_from_display_mode(&frame, mode);
> +     err = drm_hdmi_vendor_infoframe_from_display_mode(&frame,
> +                                                       &hdmi->connector,
> +                                                       mode);
>       if (err < 0)
>               /*
>                * Going into that statement does not means vendor infoframe
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 2e55599816aa..c061dd5d25c0 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -3081,6 +3081,7 @@ static int
>  do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len,
>                  const u8 *video_db, u8 video_len)
>  {
> +     struct drm_display_info *info = &connector->display_info;
>       int modes = 0, offset = 0, i, multi_present = 0, multi_len;
>       u8 vic_len, hdmi_3d_len = 0;
>       u16 mask;
> @@ -3208,6 +3209,8 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, 
> const u8 *db, u8 len,
>       }
>  
>  out:
> +     if (modes > 0)
> +             info->has_hdmi_infoframe = true;

Oh, and I forgot to mention that this depends on Shashank's patch to
reorder things such that drm_add_display_info() gets called prior to
parsing the modes. With the current order we'd end up clearing this
almost immediately afterwards.

>       return modes;
>  }
>  
> @@ -3829,6 +3832,8 @@ static void drm_parse_hdmi_forum_vsdb(struct 
> drm_connector *connector,
>       struct drm_display_info *display = &connector->display_info;
>       struct drm_hdmi_info *hdmi = &display->hdmi;
>  
> +     display->has_hdmi_infoframe = true;
> +
>       if (hf_vsdb[6] & 0x80) {
>               hdmi->scdc.supported = true;
>               if (hf_vsdb[6] & 0x40)
> @@ -3998,6 +4003,7 @@ static void drm_add_display_info(struct drm_connector 
> *connector,
>       info->cea_rev = 0;
>       info->max_tmds_clock = 0;
>       info->dvi_dual = false;
> +     info->has_hdmi_infoframe = false;
>  
>       if (edid->revision < 3)
>               return;

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to