All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.