All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jani Nikula <jani.nikula@intel.com>
To: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 3/5] drm/edid: parse the DisplayID v2.0 VESA vendor block for MSO
Date: Tue, 31 Aug 2021 11:10:53 +0300	[thread overview]
Message-ID: <87wno2avaq.fsf@intel.com> (raw)
In-Reply-To: <YSz1AhsVUc7m3Ng7@intel.com>

On Mon, 30 Aug 2021, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Mon, Aug 30, 2021 at 01:29:01PM +0300, Jani Nikula wrote:
>> The VESA Organization Vendor-Specific Data Block, defined in VESA
>> DisplayID Standard v2.0, specifies the eDP Multi-SST Operation (MSO)
>> stream count and segment pixel overlap.
>> 
>> DisplayID v1.3 has Appendix B: DisplayID as an EDID Extension,
>> describing how DisplayID sections may be embedded in EDID extension
>> blocks. DisplayID v2.0 does not have such a section, perhaps implying
>> that DisplayID v2.0 data should not be included in EDID extensions, but
>> rather in a "pure" DisplayID structure at its own DDC address pair
>> A4h/A5h, as described in VESA E-DDC Standard v1.3 chapter 3.
>> 
>> However, in practice, displays out in the field have embedded DisplayID
>> v2.0 data blocks in EDID extensions, including, in particular, some eDP
>> MSO displays, where a pure DisplayID structure is not available at all.
>> 
>> Parse the MSO data from the DisplayID data block. Do it as part of
>> drm_add_display_info(), extending it to parse also DisplayID data to
>> avoid requiring extra calls to update the information.
>> 
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>>  drivers/gpu/drm/drm_edid.c  | 63 +++++++++++++++++++++++++++++++++++++
>>  include/drm/drm_connector.h | 12 +++++++
>>  include/drm/drm_displayid.h | 11 +++++++
>>  3 files changed, 86 insertions(+)
>> 
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> index 6325877c5fd6..7e8083068f3f 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -28,6 +28,7 @@
>>   * DEALINGS IN THE SOFTWARE.
>>   */
>>  
>> +#include <linux/bitfield.h>
>>  #include <linux/hdmi.h>
>>  #include <linux/i2c.h>
>>  #include <linux/kernel.h>
>> @@ -5148,6 +5149,62 @@ void drm_get_monitor_range(struct drm_connector *connector,
>>  		      info->monitor_range.max_vfreq);
>>  }
>>  
>> +static void drm_parse_vesa_mso_data(struct drm_connector *connector,
>> +				    const struct displayid_block *block)
>> +{
>> +	struct displayid_vesa_vendor_specific_block *vesa =
>> +		(struct displayid_vesa_vendor_specific_block *)block;
>> +	struct drm_display_info *info = &connector->display_info;
>> +
>> +	if (sizeof(*vesa) != sizeof(*block) + block->num_bytes) {
>> +		drm_dbg_kms(connector->dev, "Unexpected VESA vendor block size\n");
>> +		return;
>> +	}
>> +
>> +	switch (FIELD_GET(DISPLAYID_VESA_MSO_MODE, vesa->mso)) {
>> +	default:
>> +		drm_dbg_kms(connector->dev, "Reserved MSO mode value\n");
>> +		fallthrough;
>> +	case 0:
>> +		info->mso_stream_count = 0;
>> +		break;
>> +	case 1:
>> +		info->mso_stream_count = 2; /* 2 or 4 links */
>> +		break;
>> +	case 2:
>> +		info->mso_stream_count = 4; /* 4 links */
>> +		break;
>> +	}
>> +
>> +	if (!info->mso_stream_count) {
>> +		info->mso_pixel_overlap = 0;
>> +		return;
>> +	}
>> +
>> +	info->mso_pixel_overlap = FIELD_GET(DISPLAYID_VESA_MSO_OVERLAP, vesa->mso);
>> +	if (info->mso_pixel_overlap > 8) {
>> +		drm_dbg_kms(connector->dev, "Reserved MSO pixel overlap value %u\n",
>> +			    info->mso_pixel_overlap);
>> +		info->mso_pixel_overlap = 8;
>> +	}
>> +
>> +	drm_dbg_kms(connector->dev, "MSO stream count %u, pixel overlap %u\n",
>> +		    info->mso_stream_count, info->mso_pixel_overlap);
>> +}
>> +
>> +static void drm_update_mso(struct drm_connector *connector, const struct edid *edid)
>> +{
>> +	const struct displayid_block *block;
>> +	struct displayid_iter iter;
>> +
>> +	displayid_iter_edid_begin(edid, &iter);
>> +	displayid_iter_for_each(block, &iter) {
>> +		if (block->tag == DATA_BLOCK_2_VENDOR_SPECIFIC)
>
> Don't we need to check the OUI to make sure the block is the right
> type? I don't have the v2 spec at hand atm, but I presume a vendor
> specific block could contain all kinds of different things?

You're right.

BR,
Jani.

>
>> +			drm_parse_vesa_mso_data(connector, block);
>> +	}
>> +	displayid_iter_end(&iter);
>> +}
>> +
>>  /* A connector has no EDID information, so we've got no EDID to compute quirks from. Reset
>>   * all of the values which would have been set from EDID
>>   */
>> @@ -5171,6 +5228,9 @@ drm_reset_display_info(struct drm_connector *connector)
>>  
>>  	info->non_desktop = 0;
>>  	memset(&info->monitor_range, 0, sizeof(info->monitor_range));
>> +
>> +	info->mso_stream_count = 0;
>> +	info->mso_pixel_overlap = 0;
>>  }
>>  
>>  u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid)
>> @@ -5249,6 +5309,9 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi
>>  		info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
>>  	if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422)
>>  		info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
>> +
>> +	drm_update_mso(connector, edid);
>> +
>>  	return quirks;
>>  }
>>  
>> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
>> index 79fa34e5ccdb..379746d3266f 100644
>> --- a/include/drm/drm_connector.h
>> +++ b/include/drm/drm_connector.h
>> @@ -590,6 +590,18 @@ struct drm_display_info {
>>  	 * @monitor_range: Frequency range supported by monitor range descriptor
>>  	 */
>>  	struct drm_monitor_range_info monitor_range;
>> +
>> +	/**
>> +	 * @mso_stream_count: eDP Multi-SST Operation (MSO) stream count from
>> +	 * the DisplayID VESA vendor block. 0 for conventional Single-Stream
>> +	 * Transport (SST), or 2 or 4 MSO streams.
>> +	 */
>> +	u8 mso_stream_count;
>> +
>> +	/**
>> +	 * @mso_pixel_overlap: eDP MSO segment pixel overlap, 0-8 pixels.
>> +	 */
>> +	u8 mso_pixel_overlap;
>>  };
>>  
>>  int drm_display_info_set_bus_formats(struct drm_display_info *info,
>> diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h
>> index 79771091771a..b18611e016a2 100644
>> --- a/include/drm/drm_displayid.h
>> +++ b/include/drm/drm_displayid.h
>> @@ -23,6 +23,7 @@
>>  #define DRM_DISPLAYID_H
>>  
>>  #include <linux/types.h>
>> +#include <linux/bits.h>
>>  
>>  struct edid;
>>  
>> @@ -126,6 +127,16 @@ struct displayid_detailed_timing_block {
>>  	struct displayid_detailed_timings_1 timings[];
>>  };
>>  
>> +#define DISPLAYID_VESA_MSO_OVERLAP	GENMASK(3, 0)
>> +#define DISPLAYID_VESA_MSO_MODE		GENMASK(6, 5)
>> +
>> +struct displayid_vesa_vendor_specific_block {
>> +	struct displayid_block base;
>> +	u8 oui[3];
>> +	u8 data_structure_type;
>> +	u8 mso;
>> +} __packed;
>> +
>>  /* DisplayID iteration */
>>  struct displayid_iter {
>>  	const struct edid *edid;
>> -- 
>> 2.20.1

-- 
Jani Nikula, Intel Open Source Graphics Center

WARNING: multiple messages have this Message-ID (diff)
From: Jani Nikula <jani.nikula@intel.com>
To: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 3/5] drm/edid: parse the DisplayID v2.0 VESA vendor block for MSO
Date: Tue, 31 Aug 2021 11:10:53 +0300	[thread overview]
Message-ID: <87wno2avaq.fsf@intel.com> (raw)
In-Reply-To: <YSz1AhsVUc7m3Ng7@intel.com>

On Mon, 30 Aug 2021, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Mon, Aug 30, 2021 at 01:29:01PM +0300, Jani Nikula wrote:
>> The VESA Organization Vendor-Specific Data Block, defined in VESA
>> DisplayID Standard v2.0, specifies the eDP Multi-SST Operation (MSO)
>> stream count and segment pixel overlap.
>> 
>> DisplayID v1.3 has Appendix B: DisplayID as an EDID Extension,
>> describing how DisplayID sections may be embedded in EDID extension
>> blocks. DisplayID v2.0 does not have such a section, perhaps implying
>> that DisplayID v2.0 data should not be included in EDID extensions, but
>> rather in a "pure" DisplayID structure at its own DDC address pair
>> A4h/A5h, as described in VESA E-DDC Standard v1.3 chapter 3.
>> 
>> However, in practice, displays out in the field have embedded DisplayID
>> v2.0 data blocks in EDID extensions, including, in particular, some eDP
>> MSO displays, where a pure DisplayID structure is not available at all.
>> 
>> Parse the MSO data from the DisplayID data block. Do it as part of
>> drm_add_display_info(), extending it to parse also DisplayID data to
>> avoid requiring extra calls to update the information.
>> 
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>>  drivers/gpu/drm/drm_edid.c  | 63 +++++++++++++++++++++++++++++++++++++
>>  include/drm/drm_connector.h | 12 +++++++
>>  include/drm/drm_displayid.h | 11 +++++++
>>  3 files changed, 86 insertions(+)
>> 
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> index 6325877c5fd6..7e8083068f3f 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -28,6 +28,7 @@
>>   * DEALINGS IN THE SOFTWARE.
>>   */
>>  
>> +#include <linux/bitfield.h>
>>  #include <linux/hdmi.h>
>>  #include <linux/i2c.h>
>>  #include <linux/kernel.h>
>> @@ -5148,6 +5149,62 @@ void drm_get_monitor_range(struct drm_connector *connector,
>>  		      info->monitor_range.max_vfreq);
>>  }
>>  
>> +static void drm_parse_vesa_mso_data(struct drm_connector *connector,
>> +				    const struct displayid_block *block)
>> +{
>> +	struct displayid_vesa_vendor_specific_block *vesa =
>> +		(struct displayid_vesa_vendor_specific_block *)block;
>> +	struct drm_display_info *info = &connector->display_info;
>> +
>> +	if (sizeof(*vesa) != sizeof(*block) + block->num_bytes) {
>> +		drm_dbg_kms(connector->dev, "Unexpected VESA vendor block size\n");
>> +		return;
>> +	}
>> +
>> +	switch (FIELD_GET(DISPLAYID_VESA_MSO_MODE, vesa->mso)) {
>> +	default:
>> +		drm_dbg_kms(connector->dev, "Reserved MSO mode value\n");
>> +		fallthrough;
>> +	case 0:
>> +		info->mso_stream_count = 0;
>> +		break;
>> +	case 1:
>> +		info->mso_stream_count = 2; /* 2 or 4 links */
>> +		break;
>> +	case 2:
>> +		info->mso_stream_count = 4; /* 4 links */
>> +		break;
>> +	}
>> +
>> +	if (!info->mso_stream_count) {
>> +		info->mso_pixel_overlap = 0;
>> +		return;
>> +	}
>> +
>> +	info->mso_pixel_overlap = FIELD_GET(DISPLAYID_VESA_MSO_OVERLAP, vesa->mso);
>> +	if (info->mso_pixel_overlap > 8) {
>> +		drm_dbg_kms(connector->dev, "Reserved MSO pixel overlap value %u\n",
>> +			    info->mso_pixel_overlap);
>> +		info->mso_pixel_overlap = 8;
>> +	}
>> +
>> +	drm_dbg_kms(connector->dev, "MSO stream count %u, pixel overlap %u\n",
>> +		    info->mso_stream_count, info->mso_pixel_overlap);
>> +}
>> +
>> +static void drm_update_mso(struct drm_connector *connector, const struct edid *edid)
>> +{
>> +	const struct displayid_block *block;
>> +	struct displayid_iter iter;
>> +
>> +	displayid_iter_edid_begin(edid, &iter);
>> +	displayid_iter_for_each(block, &iter) {
>> +		if (block->tag == DATA_BLOCK_2_VENDOR_SPECIFIC)
>
> Don't we need to check the OUI to make sure the block is the right
> type? I don't have the v2 spec at hand atm, but I presume a vendor
> specific block could contain all kinds of different things?

You're right.

BR,
Jani.

>
>> +			drm_parse_vesa_mso_data(connector, block);
>> +	}
>> +	displayid_iter_end(&iter);
>> +}
>> +
>>  /* A connector has no EDID information, so we've got no EDID to compute quirks from. Reset
>>   * all of the values which would have been set from EDID
>>   */
>> @@ -5171,6 +5228,9 @@ drm_reset_display_info(struct drm_connector *connector)
>>  
>>  	info->non_desktop = 0;
>>  	memset(&info->monitor_range, 0, sizeof(info->monitor_range));
>> +
>> +	info->mso_stream_count = 0;
>> +	info->mso_pixel_overlap = 0;
>>  }
>>  
>>  u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid)
>> @@ -5249,6 +5309,9 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi
>>  		info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
>>  	if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422)
>>  		info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
>> +
>> +	drm_update_mso(connector, edid);
>> +
>>  	return quirks;
>>  }
>>  
>> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
>> index 79fa34e5ccdb..379746d3266f 100644
>> --- a/include/drm/drm_connector.h
>> +++ b/include/drm/drm_connector.h
>> @@ -590,6 +590,18 @@ struct drm_display_info {
>>  	 * @monitor_range: Frequency range supported by monitor range descriptor
>>  	 */
>>  	struct drm_monitor_range_info monitor_range;
>> +
>> +	/**
>> +	 * @mso_stream_count: eDP Multi-SST Operation (MSO) stream count from
>> +	 * the DisplayID VESA vendor block. 0 for conventional Single-Stream
>> +	 * Transport (SST), or 2 or 4 MSO streams.
>> +	 */
>> +	u8 mso_stream_count;
>> +
>> +	/**
>> +	 * @mso_pixel_overlap: eDP MSO segment pixel overlap, 0-8 pixels.
>> +	 */
>> +	u8 mso_pixel_overlap;
>>  };
>>  
>>  int drm_display_info_set_bus_formats(struct drm_display_info *info,
>> diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h
>> index 79771091771a..b18611e016a2 100644
>> --- a/include/drm/drm_displayid.h
>> +++ b/include/drm/drm_displayid.h
>> @@ -23,6 +23,7 @@
>>  #define DRM_DISPLAYID_H
>>  
>>  #include <linux/types.h>
>> +#include <linux/bits.h>
>>  
>>  struct edid;
>>  
>> @@ -126,6 +127,16 @@ struct displayid_detailed_timing_block {
>>  	struct displayid_detailed_timings_1 timings[];
>>  };
>>  
>> +#define DISPLAYID_VESA_MSO_OVERLAP	GENMASK(3, 0)
>> +#define DISPLAYID_VESA_MSO_MODE		GENMASK(6, 5)
>> +
>> +struct displayid_vesa_vendor_specific_block {
>> +	struct displayid_block base;
>> +	u8 oui[3];
>> +	u8 data_structure_type;
>> +	u8 mso;
>> +} __packed;
>> +
>>  /* DisplayID iteration */
>>  struct displayid_iter {
>>  	const struct edid *edid;
>> -- 
>> 2.20.1

-- 
Jani Nikula, Intel Open Source Graphics Center

  reply	other threads:[~2021-08-31  8:11 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-30 10:28 [Intel-gfx] [PATCH 0/5] drm/displayid: VESA vendor block and drm/i915 MSO use of it Jani Nikula
2021-08-30 10:28 ` Jani Nikula
2021-08-30 10:28 ` [Intel-gfx] [PATCH 1/5] drm/displayid: re-align data block macros Jani Nikula
2021-08-30 10:28   ` Jani Nikula
2021-08-30 10:29 ` [Intel-gfx] [PATCH 2/5] drm/displayid: add DisplayID v2.0 data blocks and primary use cases Jani Nikula
2021-08-30 10:29   ` Jani Nikula
2021-08-30 10:29 ` [Intel-gfx] [PATCH 3/5] drm/edid: parse the DisplayID v2.0 VESA vendor block for MSO Jani Nikula
2021-08-30 10:29   ` Jani Nikula
2021-08-30 10:43   ` [Intel-gfx] " Jani Nikula
2021-08-30 10:43     ` Jani Nikula
2021-08-30 15:10   ` [Intel-gfx] " Ville Syrjälä
2021-08-30 15:10     ` Ville Syrjälä
2021-08-31  8:10     ` Jani Nikula [this message]
2021-08-31  8:10       ` Jani Nikula
2021-08-31 14:19       ` [Intel-gfx] " Jani Nikula
2021-08-31 14:19         ` Jani Nikula
2021-08-30 10:29 ` [Intel-gfx] [PATCH 4/5] drm/i915/edp: postpone MSO init until after EDID read Jani Nikula
2021-08-30 10:29   ` Jani Nikula
2021-08-30 10:29 ` [Intel-gfx] [PATCH 5/5] drm/i915/edp: use MSO pixel overlap from DisplayID data Jani Nikula
2021-08-30 10:29   ` Jani Nikula
2021-08-30 12:31 ` [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/displayid: VESA vendor block and drm/i915 MSO use of it Patchwork
2021-08-30 12:59 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2021-08-30 15:26 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork

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=87wno2avaq.fsf@intel.com \
    --to=jani.nikula@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=ville.syrjala@linux.intel.com \
    /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.