dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Damien Lespiau <damien.lespiau@intel.com>
Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 05/12] drm/edid: Expose mandatory stereo modes for HDMI sinks
Date: Mon, 16 Sep 2013 21:29:31 +0300	[thread overview]
Message-ID: <20130916182931.GM4531@intel.com> (raw)
In-Reply-To: <1379353735-4472-6-git-send-email-damien.lespiau@intel.com>

On Mon, Sep 16, 2013 at 06:48:48PM +0100, Damien Lespiau wrote:
> For now, let's just look at the 3D_present flag of the CEA HDMI vendor
> block to detect if the sink supports a small list of then mandatory 3D
> formats.
> 
> See the HDMI 1.4a 3D extraction for detail:
>   http://www.hdmi.org/manufacturer/specification.aspx
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/drm_edid.c | 108 ++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 101 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index a207cc3..78009d1 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2550,13 +2550,93 @@ do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
>  	return modes;
>  }
>  
> +struct stereo_mandatory_mode {
> +	int width, height, freq;

Can we call it vrefresh like in drm_display_mode?

> +	unsigned int interlace_flag, layouts;

What's the benefit of separating the two?

> +};
> +
> +static const struct stereo_mandatory_mode stereo_mandatory_modes[] = {
> +	{ 1920, 1080, 24, 0,
> +	  DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING },
> +	{ 1920, 1080, 50, DRM_MODE_FLAG_INTERLACE,
> +	  DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF },
> +	{ 1920, 1080, 60, DRM_MODE_FLAG_INTERLACE,
> +	  DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF },
> +	{ 1280, 720,  50, 0,
> +	  DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING },
> +	{ 1280, 720,  60, 0,
> +	  DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING }
> +};
> +
> +static bool
> +stereo_match_mandatory(const struct drm_display_mode *mode,
> +		       const struct stereo_mandatory_mode *stereo_mode)
> +{
> +	unsigned int interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
> +
> +	return mode->hdisplay == stereo_mode->width &&
> +	       mode->vdisplay == stereo_mode->height &&
> +	       interlaced == stereo_mode->interlace_flag &&
> +	       drm_mode_vrefresh(mode) == stereo_mode->freq;
> +}
> +
> +static const struct stereo_mandatory_mode *
> +hdmi_find_stereo_mandatory_mode(struct drm_display_mode *mode)
                                   ^

Can be const.

> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++)
> +		if (stereo_match_mandatory(mode, &stereo_mandatory_modes[i]))
> +			return &stereo_mandatory_modes[i];
> +
> +	return NULL;
> +}
> +
> +static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector)
> +{
> +	struct drm_device *dev = connector->dev;
> +	struct drm_display_mode *mode, *new_mode;

'mode' can be const, 'new_mode' could be moved into tighter scope.

> +	struct list_head stereo_modes;
> +	int modes = 0;
> +
> +	INIT_LIST_HEAD(&stereo_modes);
> +
> +	list_for_each_entry(mode, &connector->probed_modes, head) {
> +		const struct stereo_mandatory_mode *mandatory;
> +		u32 stereo_layouts, layout;
> +
> +		mandatory = hdmi_find_stereo_mandatory_mode(mode);
> +		if (!mandatory)
> +			continue;
> +
> +		stereo_layouts = mandatory->layouts;
> +                do {
   ^^^^^^^^^^^^^^^^
> +                        layout = 1 << (ffs(stereo_layouts) - 1);
   ^^^^^^^^^^^^^^^^^^^^^^^^

-ENOTABS

> +			stereo_layouts &= ~layout;
> +
> +			new_mode = drm_mode_duplicate(dev, mode);
> +			if (!new_mode)
> +				continue;
> +
> +			new_mode->flags |= layout;
> +			list_add_tail(&new_mode->head, &stereo_modes);
> +			modes++;
> +		} while (stereo_layouts);
> +	}
> +
> +	list_splice_tail(&stereo_modes, &connector->probed_modes);
> +
> +	return modes;
> +}
> +
>  /*
>   * do_hdmi_vsdb_modes - Parse the HDMI Vendor Specific data block
>   * @connector: connector corresponding to the HDMI sink
>   * @db: start of the CEA vendor specific block
>   * @len: length of the CEA block payload, ie. one can access up to db[len]
>   *
> - * Parses the HDMI VSDB looking for modes to add to @connector.
> + * Parses the HDMI VSDB looking for modes to add to @connector. This function
> + * also adds the stereo 3d modes when applicable.
>   */
>  static int
>  do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len)
> @@ -2582,10 +2662,15 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len)
>  
>  	/* the declared length is not long enough for the 2 first bytes
>  	 * of additional video format capabilities */
> -	offset += 2;
> -	if (len < (8 + offset))
> +	if (len < (8 + offset + 2))
>  		goto out;
>  
> +	/* 3D_Present */
> +	offset++;
> +	if (db[8 + offset] & (1 << 7))
> +		modes += add_hdmi_mandatory_stereo_modes(connector);

Hmm. I was thinking this is a bit soon since we haven't added the 4k
modes, nor the alternate clock modes yet. But I guess the 4k modes
aren't relevant here, and the alternate modes vs. 3D modes steps can
be done in either order. Or did I miss something here?

> +
> +	offset++;
>  	vic_len = db[8 + offset] >> 5;
>  
>  	for (i = 0; i < vic_len && len >= (9 + offset + i); i++) {
> @@ -2665,8 +2750,8 @@ static int
>  add_cea_modes(struct drm_connector *connector, struct edid *edid)
>  {
>  	const u8 *cea = drm_find_cea_extension(edid);
> -	const u8 *db;
> -	u8 dbl;
> +	const u8 *db, *hdmi = NULL;
> +	u8 dbl, hdmi_len;
>  	int modes = 0;
>  
>  	if (cea && cea_revision(cea) >= 3) {
> @@ -2681,11 +2766,20 @@ add_cea_modes(struct drm_connector *connector, struct edid *edid)
>  
>  			if (cea_db_tag(db) == VIDEO_BLOCK)
>  				modes += do_cea_modes(connector, db + 1, dbl);
> -			else if (cea_db_is_hdmi_vsdb(db))
> -				modes += do_hdmi_vsdb_modes(connector, db, dbl);
> +			else if (cea_db_is_hdmi_vsdb(db)) {
> +				hdmi = db;
> +				hdmi_len = dbl;
> +			}
>  		}
>  	}
>  
> +	/*
> +	 * We parse the HDMI VSDB after having added the cea modes as we will
> +	 * be patching their flags when the sink supports stereo 3D.
> +	 */
> +	if (hdmi)
> +		modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len);
> +
>  	return modes;
>  }
>  
> -- 
> 1.8.3.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Ville Syrjälä
Intel OTC

  reply	other threads:[~2013-09-16 18:29 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-16 17:48 HDMI stereo support v4 Damien Lespiau
2013-09-16 17:48 ` [PATCH 01/12] drm: Move the GET_CAP macros next to the corresponding ioctl structure Damien Lespiau
2013-09-16 17:48 ` [PATCH 02/12] drm: Add a SET_CLIENT_CAP ioctl Damien Lespiau
2013-09-16 17:48 ` [PATCH 03/12] drm: Add HDMI stereo 3D flags to struct drm_mode_modeinfo Damien Lespiau
2013-09-16 17:48 ` [PATCH 04/12] drm: Add a STEREO_3D capability to the SET_CLIENT_CAP ioctl Damien Lespiau
2013-09-16 17:48 ` [PATCH 05/12] drm/edid: Expose mandatory stereo modes for HDMI sinks Damien Lespiau
2013-09-16 18:29   ` Ville Syrjälä [this message]
2013-09-16 21:28     ` Damien Lespiau
2013-09-17 13:48     ` Damien Lespiau
2013-09-16 17:48 ` [PATCH 06/12] drm: Extract add_hdmi_mode() out of do_hdmi_vsdb_modes() Damien Lespiau
2013-09-16 17:48 ` [PATCH 07/12] drm: Reject modes with more than 1 stereo flags set Damien Lespiau
2013-09-16 17:48 ` [PATCH 08/12] drm: Set the relevant infoframe field when scanning out a 3D mode Damien Lespiau
2013-09-16 18:59   ` Ville Syrjälä
2013-09-16 17:48 ` [PATCH 09/12] drm: Track the number of buffers that compose a framebuffer Damien Lespiau
2013-09-16 17:48 ` [PATCH 10/12] drm: Don't allow multiple buffers fb with stereo modes Damien Lespiau
2013-09-17  8:20   ` [Intel-gfx] " Ville Syrjälä
2013-09-17  9:03     ` Damien Lespiau
2013-09-17  9:54       ` Ville Syrjälä
2013-09-17 10:37         ` [Intel-gfx] " Daniel Vetter
2013-09-17 11:02           ` Ville Syrjälä
2013-09-17 13:34             ` [Intel-gfx] " Daniel Vetter
2013-09-17 13:20           ` Damien Lespiau
2013-09-17 13:32             ` Ville Syrjälä
2013-09-17 13:33             ` [Intel-gfx] " Daniel Vetter
2013-09-16 17:48 ` [PATCH 11/12] drm: Make drm_match_cea_mode() return the underlying 2D VIC for 3d modes Damien Lespiau
2013-09-17  8:22   ` Ville Syrjälä
2013-09-17  8:52     ` [Intel-gfx] " Damien Lespiau
2013-09-16 17:48 ` [PATCH 12/12] drm: Carry over the stereo flags when adding the alternate mode Damien Lespiau
2013-09-17  9:17 ` HDMI stereo support v4 Damien Lespiau

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130916182931.GM4531@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=damien.lespiau@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).