All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/15] drm/edid: expand on struct drm_edid usage
@ 2022-06-08  7:50 ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

v2 of [1], addressing review comments.

BR,
Jani.


[1] https://patchwork.freedesktop.org/series/104309/

Jani Nikula (15):
  drm/edid: fix CTA data block collection size for CTA version 3
  drm/edid: abstract cea data block collection size
  drm/edid: add block count and data helper functions for drm_edid
  drm/edid: keep track of alloc size in drm_do_get_edid()
  drm/edid: add new interfaces around struct drm_edid
  drm/edid: add drm_edid_connector_update()
  drm/probe-helper: abstract .get_modes() connector helper call
  drm/probe-helper: add drm_connector_helper_get_modes()
  drm/edid: add drm_edid_raw() to access the raw EDID data
  drm/i915/edid: convert DP, HDMI and LVDS to drm_edid
  drm/i915/bios: convert intel_bios_init_panel() to drm_edid
  drm/edid: do invalid block filtering in-place
  drm/edid: add HF-EEODB support to EDID read and allocation
  drm/edid: take HF-EEODB extension count into account
  drm/todo: add entry for converting the subsystem to struct drm_edid

 Documentation/gpu/todo.rst                    |  25 +
 drivers/gpu/drm/drm_connector.c               |   2 +
 drivers/gpu/drm/drm_edid.c                    | 572 ++++++++++++++++--
 drivers/gpu/drm/drm_probe_helper.c            |  63 +-
 drivers/gpu/drm/i915/display/intel_bios.c     |  23 +-
 drivers/gpu/drm/i915/display/intel_bios.h     |   4 +-
 .../gpu/drm/i915/display/intel_connector.c    |   4 +-
 .../drm/i915/display/intel_display_types.h    |   4 +-
 drivers/gpu/drm/i915/display/intel_dp.c       |  74 ++-
 drivers/gpu/drm/i915/display/intel_hdmi.c     |  26 +-
 drivers/gpu/drm/i915/display/intel_lvds.c     |  37 +-
 include/drm/drm_edid.h                        |  12 +
 include/drm/drm_probe_helper.h                |   1 +
 13 files changed, 692 insertions(+), 155 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 00/15] drm/edid: expand on struct drm_edid usage
@ 2022-06-08  7:50 ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

v2 of [1], addressing review comments.

BR,
Jani.


[1] https://patchwork.freedesktop.org/series/104309/

Jani Nikula (15):
  drm/edid: fix CTA data block collection size for CTA version 3
  drm/edid: abstract cea data block collection size
  drm/edid: add block count and data helper functions for drm_edid
  drm/edid: keep track of alloc size in drm_do_get_edid()
  drm/edid: add new interfaces around struct drm_edid
  drm/edid: add drm_edid_connector_update()
  drm/probe-helper: abstract .get_modes() connector helper call
  drm/probe-helper: add drm_connector_helper_get_modes()
  drm/edid: add drm_edid_raw() to access the raw EDID data
  drm/i915/edid: convert DP, HDMI and LVDS to drm_edid
  drm/i915/bios: convert intel_bios_init_panel() to drm_edid
  drm/edid: do invalid block filtering in-place
  drm/edid: add HF-EEODB support to EDID read and allocation
  drm/edid: take HF-EEODB extension count into account
  drm/todo: add entry for converting the subsystem to struct drm_edid

 Documentation/gpu/todo.rst                    |  25 +
 drivers/gpu/drm/drm_connector.c               |   2 +
 drivers/gpu/drm/drm_edid.c                    | 572 ++++++++++++++++--
 drivers/gpu/drm/drm_probe_helper.c            |  63 +-
 drivers/gpu/drm/i915/display/intel_bios.c     |  23 +-
 drivers/gpu/drm/i915/display/intel_bios.h     |   4 +-
 .../gpu/drm/i915/display/intel_connector.c    |   4 +-
 .../drm/i915/display/intel_display_types.h    |   4 +-
 drivers/gpu/drm/i915/display/intel_dp.c       |  74 ++-
 drivers/gpu/drm/i915/display/intel_hdmi.c     |  26 +-
 drivers/gpu/drm/i915/display/intel_lvds.c     |  37 +-
 include/drm/drm_edid.h                        |  12 +
 include/drm/drm_probe_helper.h                |   1 +
 13 files changed, 692 insertions(+), 155 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 68+ messages in thread

* [PATCH v2 01/15] drm/edid: fix CTA data block collection size for CTA version 3
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

The CTA Data Block Collection is valid only for CTA extension version
3. In versions 1 and 2, it is a reserved block, which we ignore.

The DTD start offset (byte 2, or d in CTA-861 spec), which determines
the CTA Data Block Collection size, is specified slightly differently
for different versions:

Version 1:
    d = offset for the byte following the reserved data block. If no
    data is provided in the reserved data block, then d=4. If no DTDs
    are provided, then d=0

Version 2:
    d = offset for the byte following the reserved data block. If no
    data is provided in the reserved data block, then d=4. If d=0, then
    no detailed timing descriptors are provided, and no data is provided
    in the reserved data block.

Version 3:
    d = offset for the byte following the data block collection. If no
    data is provided in the data block collection, then d=4. If d=0,
    then no detailed timing descriptors are provided, and no data is
    provided in the data block collection.

Ever since commit 9e50b9d55e9c ("drm: edid: Add some bounds checking"),
we've interpreted 0 to mean there are no DTDs but it's all Data
Blocks. Per the spec, Data Blocks are only valid for version 3, where we
should interpret 0 to mean there are no data blocks.

Follow the spec (and hope the EDIDs follow it too).

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 929fc0e46751..c57f6333ea7d 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4498,8 +4498,6 @@ static const void *__cea_db_iter_edid_next(struct cea_db_iter *iter)
 
 		iter->index = 4;
 		iter->end = ext[2];
-		if (iter->end == 0)
-			iter->end = 127;
 		if (iter->end < 4 || iter->end > 127)
 			continue;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 01/15] drm/edid: fix CTA data block collection size for CTA version 3
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

The CTA Data Block Collection is valid only for CTA extension version
3. In versions 1 and 2, it is a reserved block, which we ignore.

The DTD start offset (byte 2, or d in CTA-861 spec), which determines
the CTA Data Block Collection size, is specified slightly differently
for different versions:

Version 1:
    d = offset for the byte following the reserved data block. If no
    data is provided in the reserved data block, then d=4. If no DTDs
    are provided, then d=0

Version 2:
    d = offset for the byte following the reserved data block. If no
    data is provided in the reserved data block, then d=4. If d=0, then
    no detailed timing descriptors are provided, and no data is provided
    in the reserved data block.

Version 3:
    d = offset for the byte following the data block collection. If no
    data is provided in the data block collection, then d=4. If d=0,
    then no detailed timing descriptors are provided, and no data is
    provided in the data block collection.

Ever since commit 9e50b9d55e9c ("drm: edid: Add some bounds checking"),
we've interpreted 0 to mean there are no DTDs but it's all Data
Blocks. Per the spec, Data Blocks are only valid for version 3, where we
should interpret 0 to mean there are no data blocks.

Follow the spec (and hope the EDIDs follow it too).

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 929fc0e46751..c57f6333ea7d 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4498,8 +4498,6 @@ static const void *__cea_db_iter_edid_next(struct cea_db_iter *iter)
 
 		iter->index = 4;
 		iter->end = ext[2];
-		if (iter->end == 0)
-			iter->end = 127;
 		if (iter->end < 4 || iter->end > 127)
 			continue;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 02/15] drm/edid: abstract cea data block collection size
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Add a function to get the cea data block collection size.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index c57f6333ea7d..002816509fc8 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4482,6 +4482,20 @@ __cea_db_iter_current_block(const struct cea_db_iter *iter)
 	return NULL;
 }
 
+/*
+ * References:
+ * - CTA-861-H section 7.3.3 CTA Extension Version 3
+ */
+static int cea_db_collection_size(const u8 *cta)
+{
+	u8 d = cta[2];
+
+	if (d < 4 || d > 127)
+		return 0;
+
+	return d - 4;
+}
+
 /*
  * References:
  * - VESA E-EDID v1.4
@@ -4492,15 +4506,19 @@ static const void *__cea_db_iter_edid_next(struct cea_db_iter *iter)
 	const u8 *ext;
 
 	drm_edid_iter_for_each(ext, &iter->edid_iter) {
+		int size;
+
 		/* Only support CTA Extension revision 3+ */
 		if (ext[0] != CEA_EXT || cea_revision(ext) < 3)
 			continue;
 
-		iter->index = 4;
-		iter->end = ext[2];
-		if (iter->end < 4 || iter->end > 127)
+		size = cea_db_collection_size(ext);
+		if (!size)
 			continue;
 
+		iter->index = 4;
+		iter->end = iter->index + size;
+
 		return ext;
 	}
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 02/15] drm/edid: abstract cea data block collection size
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Add a function to get the cea data block collection size.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index c57f6333ea7d..002816509fc8 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4482,6 +4482,20 @@ __cea_db_iter_current_block(const struct cea_db_iter *iter)
 	return NULL;
 }
 
+/*
+ * References:
+ * - CTA-861-H section 7.3.3 CTA Extension Version 3
+ */
+static int cea_db_collection_size(const u8 *cta)
+{
+	u8 d = cta[2];
+
+	if (d < 4 || d > 127)
+		return 0;
+
+	return d - 4;
+}
+
 /*
  * References:
  * - VESA E-EDID v1.4
@@ -4492,15 +4506,19 @@ static const void *__cea_db_iter_edid_next(struct cea_db_iter *iter)
 	const u8 *ext;
 
 	drm_edid_iter_for_each(ext, &iter->edid_iter) {
+		int size;
+
 		/* Only support CTA Extension revision 3+ */
 		if (ext[0] != CEA_EXT || cea_revision(ext) < 3)
 			continue;
 
-		iter->index = 4;
-		iter->end = ext[2];
-		if (iter->end < 4 || iter->end > 127)
+		size = cea_db_collection_size(ext);
+		if (!size)
 			continue;
 
+		iter->index = 4;
+		iter->end = iter->index + size;
+
 		return ext;
 	}
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 03/15] drm/edid: add block count and data helper functions for drm_edid
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx, Andrzej Hajda

Add drm_edid based block count and data access helper functions that
take the EDID allocated size into account.

At the moment, the allocated size should always match the EDID size
indicated by the extension count, but this will change in the future.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 42 +++++++++++++++++++++++++++++++-------
 1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 002816509fc8..f44ada4bfa5b 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1613,6 +1613,35 @@ static const void *edid_extension_block_data(const struct edid *edid, int index)
 	return edid_block_data(edid, index + 1);
 }
 
+static int drm_edid_block_count(const struct drm_edid *drm_edid)
+{
+	int num_blocks;
+
+	/* Starting point */
+	num_blocks = edid_block_count(drm_edid->edid);
+
+	/* Limit by allocated size */
+	num_blocks = min(num_blocks, (int)drm_edid->size / EDID_LENGTH);
+
+	return num_blocks;
+}
+
+static int drm_edid_extension_block_count(const struct drm_edid *drm_edid)
+{
+	return drm_edid_block_count(drm_edid) - 1;
+}
+
+static const void *drm_edid_block_data(const struct drm_edid *drm_edid, int index)
+{
+	return edid_block_data(drm_edid->edid, index);
+}
+
+static const void *drm_edid_extension_block_data(const struct drm_edid *drm_edid,
+						 int index)
+{
+	return edid_extension_block_data(drm_edid->edid, index);
+}
+
 /*
  * Initializer helper for legacy interfaces, where we have no choice but to
  * trust edid size. Not for general purpose use.
@@ -1665,8 +1694,8 @@ static const void *__drm_edid_iter_next(struct drm_edid_iter *iter)
 	if (!iter->drm_edid)
 		return NULL;
 
-	if (iter->index < edid_block_count(iter->drm_edid->edid))
-		block = edid_block_data(iter->drm_edid->edid, iter->index++);
+	if (iter->index < drm_edid_block_count(iter->drm_edid))
+		block = drm_edid_block_data(iter->drm_edid, iter->index++);
 
 	return block;
 }
@@ -3574,22 +3603,21 @@ static int add_detailed_modes(struct drm_connector *connector,
 const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
 				  int ext_id, int *ext_index)
 {
-	const struct edid *edid = drm_edid ? drm_edid->edid : NULL;
 	const u8 *edid_ext = NULL;
 	int i;
 
 	/* No EDID or EDID extensions */
-	if (!edid || !edid_extension_block_count(edid))
+	if (!drm_edid || !drm_edid_extension_block_count(drm_edid))
 		return NULL;
 
 	/* Find CEA extension */
-	for (i = *ext_index; i < edid_extension_block_count(edid); i++) {
-		edid_ext = edid_extension_block_data(edid, i);
+	for (i = *ext_index; i < drm_edid_extension_block_count(drm_edid); i++) {
+		edid_ext = drm_edid_extension_block_data(drm_edid, i);
 		if (edid_block_tag(edid_ext) == ext_id)
 			break;
 	}
 
-	if (i >= edid_extension_block_count(edid))
+	if (i >= drm_edid_extension_block_count(drm_edid))
 		return NULL;
 
 	*ext_index = i + 1;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 03/15] drm/edid: add block count and data helper functions for drm_edid
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx, Andrzej Hajda

Add drm_edid based block count and data access helper functions that
take the EDID allocated size into account.

At the moment, the allocated size should always match the EDID size
indicated by the extension count, but this will change in the future.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 42 +++++++++++++++++++++++++++++++-------
 1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 002816509fc8..f44ada4bfa5b 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1613,6 +1613,35 @@ static const void *edid_extension_block_data(const struct edid *edid, int index)
 	return edid_block_data(edid, index + 1);
 }
 
+static int drm_edid_block_count(const struct drm_edid *drm_edid)
+{
+	int num_blocks;
+
+	/* Starting point */
+	num_blocks = edid_block_count(drm_edid->edid);
+
+	/* Limit by allocated size */
+	num_blocks = min(num_blocks, (int)drm_edid->size / EDID_LENGTH);
+
+	return num_blocks;
+}
+
+static int drm_edid_extension_block_count(const struct drm_edid *drm_edid)
+{
+	return drm_edid_block_count(drm_edid) - 1;
+}
+
+static const void *drm_edid_block_data(const struct drm_edid *drm_edid, int index)
+{
+	return edid_block_data(drm_edid->edid, index);
+}
+
+static const void *drm_edid_extension_block_data(const struct drm_edid *drm_edid,
+						 int index)
+{
+	return edid_extension_block_data(drm_edid->edid, index);
+}
+
 /*
  * Initializer helper for legacy interfaces, where we have no choice but to
  * trust edid size. Not for general purpose use.
@@ -1665,8 +1694,8 @@ static const void *__drm_edid_iter_next(struct drm_edid_iter *iter)
 	if (!iter->drm_edid)
 		return NULL;
 
-	if (iter->index < edid_block_count(iter->drm_edid->edid))
-		block = edid_block_data(iter->drm_edid->edid, iter->index++);
+	if (iter->index < drm_edid_block_count(iter->drm_edid))
+		block = drm_edid_block_data(iter->drm_edid, iter->index++);
 
 	return block;
 }
@@ -3574,22 +3603,21 @@ static int add_detailed_modes(struct drm_connector *connector,
 const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
 				  int ext_id, int *ext_index)
 {
-	const struct edid *edid = drm_edid ? drm_edid->edid : NULL;
 	const u8 *edid_ext = NULL;
 	int i;
 
 	/* No EDID or EDID extensions */
-	if (!edid || !edid_extension_block_count(edid))
+	if (!drm_edid || !drm_edid_extension_block_count(drm_edid))
 		return NULL;
 
 	/* Find CEA extension */
-	for (i = *ext_index; i < edid_extension_block_count(edid); i++) {
-		edid_ext = edid_extension_block_data(edid, i);
+	for (i = *ext_index; i < drm_edid_extension_block_count(drm_edid); i++) {
+		edid_ext = drm_edid_extension_block_data(drm_edid, i);
 		if (edid_block_tag(edid_ext) == ext_id)
 			break;
 	}
 
-	if (i >= edid_extension_block_count(edid))
+	if (i >= drm_edid_extension_block_count(drm_edid))
 		return NULL;
 
 	*ext_index = i + 1;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 04/15] drm/edid: keep track of alloc size in drm_do_get_edid()
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

We'll want to return the allocated buffer size in the future. Keep track
of it.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index f44ada4bfa5b..2beaa48301c1 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2021,13 +2021,16 @@ bool drm_edid_is_valid(struct edid *edid)
 EXPORT_SYMBOL(drm_edid_is_valid);
 
 static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
-					       int invalid_blocks)
+					       int invalid_blocks,
+					       size_t *alloc_size)
 {
 	struct edid *new, *dest_block;
 	int valid_extensions = edid->extensions - invalid_blocks;
 	int i;
 
-	new = kmalloc(edid_size_by_blocks(valid_extensions + 1), GFP_KERNEL);
+	*alloc_size = edid_size_by_blocks(valid_extensions + 1);
+
+	new = kmalloc(*alloc_size, GFP_KERNEL);
 	if (!new)
 		goto out;
 
@@ -2140,7 +2143,8 @@ static void connector_bad_edid(struct drm_connector *connector,
 }
 
 /* Get override or firmware EDID */
-static struct edid *drm_get_override_edid(struct drm_connector *connector)
+static struct edid *drm_get_override_edid(struct drm_connector *connector,
+					  size_t *alloc_size)
 {
 	struct edid *override = NULL;
 
@@ -2150,6 +2154,10 @@ static struct edid *drm_get_override_edid(struct drm_connector *connector)
 	if (!override)
 		override = drm_load_edid_firmware(connector);
 
+	/* FIXME: Get alloc size from deeper down the stack */
+	if (!IS_ERR_OR_NULL(override) && alloc_size)
+		*alloc_size = edid_size(override);
+
 	return IS_ERR(override) ? NULL : override;
 }
 
@@ -2169,7 +2177,7 @@ int drm_add_override_edid_modes(struct drm_connector *connector)
 	struct edid *override;
 	int num_modes = 0;
 
-	override = drm_get_override_edid(connector);
+	override = drm_get_override_edid(connector, NULL);
 	if (override) {
 		drm_connector_update_edid_property(connector, override);
 		num_modes = drm_add_edid_modes(connector, override);
@@ -2245,12 +2253,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	enum edid_block_status status;
 	int i, invalid_blocks = 0;
 	struct edid *edid, *new;
+	size_t alloc_size = EDID_LENGTH;
 
-	edid = drm_get_override_edid(connector);
+	edid = drm_get_override_edid(connector, &alloc_size);
 	if (edid)
 		goto ok;
 
-	edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+	edid = kmalloc(alloc_size, GFP_KERNEL);
 	if (!edid)
 		return NULL;
 
@@ -2278,7 +2287,8 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	if (!edid_extension_block_count(edid))
 		goto ok;
 
-	new = krealloc(edid, edid_size(edid), GFP_KERNEL);
+	alloc_size = edid_size(edid);
+	new = krealloc(edid, alloc_size, GFP_KERNEL);
 	if (!new)
 		goto fail;
 	edid = new;
@@ -2300,7 +2310,8 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	if (invalid_blocks) {
 		connector_bad_edid(connector, edid, edid_block_count(edid));
 
-		edid = edid_filter_invalid_blocks(edid, invalid_blocks);
+		edid = edid_filter_invalid_blocks(edid, invalid_blocks,
+						  &alloc_size);
 	}
 
 ok:
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 04/15] drm/edid: keep track of alloc size in drm_do_get_edid()
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

We'll want to return the allocated buffer size in the future. Keep track
of it.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index f44ada4bfa5b..2beaa48301c1 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2021,13 +2021,16 @@ bool drm_edid_is_valid(struct edid *edid)
 EXPORT_SYMBOL(drm_edid_is_valid);
 
 static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
-					       int invalid_blocks)
+					       int invalid_blocks,
+					       size_t *alloc_size)
 {
 	struct edid *new, *dest_block;
 	int valid_extensions = edid->extensions - invalid_blocks;
 	int i;
 
-	new = kmalloc(edid_size_by_blocks(valid_extensions + 1), GFP_KERNEL);
+	*alloc_size = edid_size_by_blocks(valid_extensions + 1);
+
+	new = kmalloc(*alloc_size, GFP_KERNEL);
 	if (!new)
 		goto out;
 
@@ -2140,7 +2143,8 @@ static void connector_bad_edid(struct drm_connector *connector,
 }
 
 /* Get override or firmware EDID */
-static struct edid *drm_get_override_edid(struct drm_connector *connector)
+static struct edid *drm_get_override_edid(struct drm_connector *connector,
+					  size_t *alloc_size)
 {
 	struct edid *override = NULL;
 
@@ -2150,6 +2154,10 @@ static struct edid *drm_get_override_edid(struct drm_connector *connector)
 	if (!override)
 		override = drm_load_edid_firmware(connector);
 
+	/* FIXME: Get alloc size from deeper down the stack */
+	if (!IS_ERR_OR_NULL(override) && alloc_size)
+		*alloc_size = edid_size(override);
+
 	return IS_ERR(override) ? NULL : override;
 }
 
@@ -2169,7 +2177,7 @@ int drm_add_override_edid_modes(struct drm_connector *connector)
 	struct edid *override;
 	int num_modes = 0;
 
-	override = drm_get_override_edid(connector);
+	override = drm_get_override_edid(connector, NULL);
 	if (override) {
 		drm_connector_update_edid_property(connector, override);
 		num_modes = drm_add_edid_modes(connector, override);
@@ -2245,12 +2253,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	enum edid_block_status status;
 	int i, invalid_blocks = 0;
 	struct edid *edid, *new;
+	size_t alloc_size = EDID_LENGTH;
 
-	edid = drm_get_override_edid(connector);
+	edid = drm_get_override_edid(connector, &alloc_size);
 	if (edid)
 		goto ok;
 
-	edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+	edid = kmalloc(alloc_size, GFP_KERNEL);
 	if (!edid)
 		return NULL;
 
@@ -2278,7 +2287,8 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	if (!edid_extension_block_count(edid))
 		goto ok;
 
-	new = krealloc(edid, edid_size(edid), GFP_KERNEL);
+	alloc_size = edid_size(edid);
+	new = krealloc(edid, alloc_size, GFP_KERNEL);
 	if (!new)
 		goto fail;
 	edid = new;
@@ -2300,7 +2310,8 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	if (invalid_blocks) {
 		connector_bad_edid(connector, edid, edid_block_count(edid));
 
-		edid = edid_filter_invalid_blocks(edid, invalid_blocks);
+		edid = edid_filter_invalid_blocks(edid, invalid_blocks,
+						  &alloc_size);
 	}
 
 ok:
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 05/15] drm/edid: add new interfaces around struct drm_edid
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, David Airlie, intel-gfx

Add new functions drm_edid_read(), drm_edid_read_ddc(), and
drm_edid_read_custom() to replace drm_get_edid() and drm_do_get_edid()
for reading the EDID. The transition is expected to happen over a fairly
long time.

Note that the new drm_edid_read*() functions do not do any of the
connector updates anymore. The reading and parsing will be completely
separated from each other.

Add new functions drm_edid_alloc(), drm_edid_dup(), and drm_edid_free()
for allocating and freeing drm_edid containers.

Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 245 +++++++++++++++++++++++++++++++++----
 include/drm/drm_edid.h     |   9 ++
 2 files changed, 230 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 2beaa48301c1..2bdaf1e34a9d 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2226,29 +2226,9 @@ static enum edid_block_status edid_block_read(void *block, unsigned int block_nu
 	return status;
 }
 
-/**
- * drm_do_get_edid - get EDID data using a custom EDID block read function
- * @connector: connector we're probing
- * @read_block: EDID block read function
- * @context: private data passed to the block read function
- *
- * When the I2C adapter connected to the DDC bus is hidden behind a device that
- * exposes a different interface to read EDID blocks this function can be used
- * to get EDID data using a custom block read function.
- *
- * As in the general case the DDC bus is accessible by the kernel at the I2C
- * level, drivers must make all reasonable efforts to expose it as an I2C
- * adapter and use drm_get_edid() instead of abusing this function.
- *
- * The EDID may be overridden using debugfs override_edid or firmware EDID
- * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
- * order. Having either of them bypasses actual EDID reads.
- *
- * Return: Pointer to valid EDID or NULL if we couldn't find any.
- */
-struct edid *drm_do_get_edid(struct drm_connector *connector,
-			     read_block_fn read_block,
-			     void *context)
+static struct edid *_drm_do_get_edid(struct drm_connector *connector,
+				     read_block_fn read_block, void *context,
+				     size_t *size)
 {
 	enum edid_block_status status;
 	int i, invalid_blocks = 0;
@@ -2315,14 +2295,125 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	}
 
 ok:
+	if (size)
+		*size = alloc_size;
+
 	return edid;
 
 fail:
 	kfree(edid);
 	return NULL;
 }
+
+/**
+ * drm_do_get_edid - get EDID data using a custom EDID block read function
+ * @connector: connector we're probing
+ * @read_block: EDID block read function
+ * @context: private data passed to the block read function
+ *
+ * When the I2C adapter connected to the DDC bus is hidden behind a device that
+ * exposes a different interface to read EDID blocks this function can be used
+ * to get EDID data using a custom block read function.
+ *
+ * As in the general case the DDC bus is accessible by the kernel at the I2C
+ * level, drivers must make all reasonable efforts to expose it as an I2C
+ * adapter and use drm_get_edid() instead of abusing this function.
+ *
+ * The EDID may be overridden using debugfs override_edid or firmware EDID
+ * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
+ * order. Having either of them bypasses actual EDID reads.
+ *
+ * Return: Pointer to valid EDID or NULL if we couldn't find any.
+ */
+struct edid *drm_do_get_edid(struct drm_connector *connector,
+			     read_block_fn read_block,
+			     void *context)
+{
+	return _drm_do_get_edid(connector, read_block, context, NULL);
+}
 EXPORT_SYMBOL_GPL(drm_do_get_edid);
 
+/* Allocate struct drm_edid container *without* duplicating the edid data */
+static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
+{
+	struct drm_edid *drm_edid;
+
+	if (!edid || !size || size < EDID_LENGTH)
+		return NULL;
+
+	drm_edid = kzalloc(sizeof(*drm_edid), GFP_KERNEL);
+	if (drm_edid) {
+		drm_edid->edid = edid;
+		drm_edid->size = size;
+	}
+
+	return drm_edid;
+}
+
+/**
+ * drm_edid_alloc - Allocate a new drm_edid container
+ * @edid: Pointer to raw EDID data
+ * @size: Size of memory allocated for EDID
+ *
+ * Allocate a new drm_edid container. Do not calculate edid size from edid, pass
+ * the actual size that has been allocated for the data. There is no validation
+ * of the raw EDID data against the size, but at least the EDID base block must
+ * fit in the buffer.
+ *
+ * The returned pointer must be freed using drm_edid_free().
+ *
+ * Return: drm_edid container, or NULL on errors
+ */
+const struct drm_edid *drm_edid_alloc(const void *edid, size_t size)
+{
+	const struct drm_edid *drm_edid;
+
+	if (!edid || !size || size < EDID_LENGTH)
+		return NULL;
+
+	edid = kmemdup(edid, size, GFP_KERNEL);
+	if (!edid)
+		return NULL;
+
+	drm_edid = _drm_edid_alloc(edid, size);
+	if (!drm_edid)
+		kfree(edid);
+
+	return drm_edid;
+}
+EXPORT_SYMBOL(drm_edid_alloc);
+
+/**
+ * drm_edid_dup - Duplicate a drm_edid container
+ * @drm_edid: EDID to duplicate
+ *
+ * The returned pointer must be freed using drm_edid_free().
+ *
+ * Returns: drm_edid container copy, or NULL on errors
+ */
+const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid)
+{
+	if (!drm_edid)
+		return NULL;
+
+	return drm_edid_alloc(drm_edid->edid, drm_edid->size);
+}
+EXPORT_SYMBOL(drm_edid_dup);
+
+/**
+ * drm_edid_free - Free the drm_edid container
+ * @drm_edid: EDID to free
+ */
+void drm_edid_free(const struct drm_edid *drm_edid)
+{
+	if (!drm_edid)
+		return;
+
+	kfree(drm_edid->edid);
+	kfree(drm_edid);
+}
+EXPORT_SYMBOL(drm_edid_free);
+
 /**
  * drm_probe_ddc() - probe DDC presence
  * @adapter: I2C adapter to probe
@@ -2359,12 +2450,118 @@ struct edid *drm_get_edid(struct drm_connector *connector,
 	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
 		return NULL;
 
-	edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
+	edid = _drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter, NULL);
 	drm_connector_update_edid_property(connector, edid);
 	return edid;
 }
 EXPORT_SYMBOL(drm_get_edid);
 
+/**
+ * drm_edid_read_custom - Read EDID data using given EDID block read function
+ * @connector: Connector to use
+ * @read_block: EDID block read function
+ * @context: Private data passed to the block read function
+ *
+ * When the I2C adapter connected to the DDC bus is hidden behind a device that
+ * exposes a different interface to read EDID blocks this function can be used
+ * to get EDID data using a custom block read function.
+ *
+ * As in the general case the DDC bus is accessible by the kernel at the I2C
+ * level, drivers must make all reasonable efforts to expose it as an I2C
+ * adapter and use drm_edid_read() or drm_edid_read_ddc() instead of abusing
+ * this function.
+ *
+ * The EDID may be overridden using debugfs override_edid or firmware EDID
+ * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
+ * order. Having either of them bypasses actual EDID reads.
+ *
+ * The returned pointer must be freed using drm_edid_free().
+ *
+ * Return: Pointer to EDID, or NULL if probe/read failed.
+ */
+const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
+					    read_block_fn read_block,
+					    void *context)
+{
+	const struct drm_edid *drm_edid;
+	struct edid *edid;
+	size_t size = 0;
+
+	edid = _drm_do_get_edid(connector, read_block, context, &size);
+	if (!edid)
+		return NULL;
+
+	/* Sanity check for now */
+	drm_WARN_ON(connector->dev, !size);
+
+	drm_edid = _drm_edid_alloc(edid, size);
+	if (!drm_edid)
+		kfree(edid);
+
+	return drm_edid;
+}
+EXPORT_SYMBOL(drm_edid_read_custom);
+
+/**
+ * drm_edid_read_ddc - Read EDID data using given I2C adapter
+ * @connector: Connector to use
+ * @adapter: I2C adapter to use for DDC
+ *
+ * Read EDID using the given I2C adapter.
+ *
+ * The EDID may be overridden using debugfs override_edid or firmware EDID
+ * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
+ * order. Having either of them bypasses actual EDID reads.
+ *
+ * Prefer initializing connector->ddc with drm_connector_init_with_ddc() and
+ * using drm_edid_read() instead of this function.
+ *
+ * The returned pointer must be freed using drm_edid_free().
+ *
+ * Return: Pointer to EDID, or NULL if probe/read failed.
+ */
+const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
+					 struct i2c_adapter *adapter)
+{
+	const struct drm_edid *drm_edid;
+
+	if (connector->force == DRM_FORCE_OFF)
+		return NULL;
+
+	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
+		return NULL;
+
+	drm_edid = drm_edid_read_custom(connector, drm_do_probe_ddc_edid, adapter);
+
+	/* Note: Do *not* call connector updates here. */
+
+	return drm_edid;
+}
+EXPORT_SYMBOL(drm_edid_read_ddc);
+
+/**
+ * drm_edid_read - Read EDID data using connector's I2C adapter
+ * @connector: Connector to use
+ *
+ * Read EDID using the connector's I2C adapter.
+ *
+ * The EDID may be overridden using debugfs override_edid or firmware EDID
+ * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
+ * order. Having either of them bypasses actual EDID reads.
+ *
+ * The returned pointer must be freed using drm_edid_free().
+ *
+ * Return: Pointer to EDID, or NULL if probe/read failed.
+ */
+const struct drm_edid *drm_edid_read(struct drm_connector *connector)
+{
+	if (drm_WARN_ON(connector->dev, !connector->ddc))
+		return NULL;
+
+	return drm_edid_read_ddc(connector, connector->ddc);
+}
+EXPORT_SYMBOL(drm_edid_read);
+
 static u32 edid_extract_panel_id(const struct edid *edid)
 {
 	/*
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 95ac09ef41b2..9d2d78135dee 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -594,6 +594,15 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
 			      u8 video_code);
 
 /* Interface based on struct drm_edid */
+const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
+const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
+void drm_edid_free(const struct drm_edid *drm_edid);
+const struct drm_edid *drm_edid_read(struct drm_connector *connector);
+const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
+					 struct i2c_adapter *adapter);
+const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
+					    int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),
+					    void *context);
 const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
 				  int ext_id, int *ext_index);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 05/15] drm/edid: add new interfaces around struct drm_edid
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, David Airlie, intel-gfx

Add new functions drm_edid_read(), drm_edid_read_ddc(), and
drm_edid_read_custom() to replace drm_get_edid() and drm_do_get_edid()
for reading the EDID. The transition is expected to happen over a fairly
long time.

Note that the new drm_edid_read*() functions do not do any of the
connector updates anymore. The reading and parsing will be completely
separated from each other.

Add new functions drm_edid_alloc(), drm_edid_dup(), and drm_edid_free()
for allocating and freeing drm_edid containers.

Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 245 +++++++++++++++++++++++++++++++++----
 include/drm/drm_edid.h     |   9 ++
 2 files changed, 230 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 2beaa48301c1..2bdaf1e34a9d 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2226,29 +2226,9 @@ static enum edid_block_status edid_block_read(void *block, unsigned int block_nu
 	return status;
 }
 
-/**
- * drm_do_get_edid - get EDID data using a custom EDID block read function
- * @connector: connector we're probing
- * @read_block: EDID block read function
- * @context: private data passed to the block read function
- *
- * When the I2C adapter connected to the DDC bus is hidden behind a device that
- * exposes a different interface to read EDID blocks this function can be used
- * to get EDID data using a custom block read function.
- *
- * As in the general case the DDC bus is accessible by the kernel at the I2C
- * level, drivers must make all reasonable efforts to expose it as an I2C
- * adapter and use drm_get_edid() instead of abusing this function.
- *
- * The EDID may be overridden using debugfs override_edid or firmware EDID
- * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
- * order. Having either of them bypasses actual EDID reads.
- *
- * Return: Pointer to valid EDID or NULL if we couldn't find any.
- */
-struct edid *drm_do_get_edid(struct drm_connector *connector,
-			     read_block_fn read_block,
-			     void *context)
+static struct edid *_drm_do_get_edid(struct drm_connector *connector,
+				     read_block_fn read_block, void *context,
+				     size_t *size)
 {
 	enum edid_block_status status;
 	int i, invalid_blocks = 0;
@@ -2315,14 +2295,125 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	}
 
 ok:
+	if (size)
+		*size = alloc_size;
+
 	return edid;
 
 fail:
 	kfree(edid);
 	return NULL;
 }
+
+/**
+ * drm_do_get_edid - get EDID data using a custom EDID block read function
+ * @connector: connector we're probing
+ * @read_block: EDID block read function
+ * @context: private data passed to the block read function
+ *
+ * When the I2C adapter connected to the DDC bus is hidden behind a device that
+ * exposes a different interface to read EDID blocks this function can be used
+ * to get EDID data using a custom block read function.
+ *
+ * As in the general case the DDC bus is accessible by the kernel at the I2C
+ * level, drivers must make all reasonable efforts to expose it as an I2C
+ * adapter and use drm_get_edid() instead of abusing this function.
+ *
+ * The EDID may be overridden using debugfs override_edid or firmware EDID
+ * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
+ * order. Having either of them bypasses actual EDID reads.
+ *
+ * Return: Pointer to valid EDID or NULL if we couldn't find any.
+ */
+struct edid *drm_do_get_edid(struct drm_connector *connector,
+			     read_block_fn read_block,
+			     void *context)
+{
+	return _drm_do_get_edid(connector, read_block, context, NULL);
+}
 EXPORT_SYMBOL_GPL(drm_do_get_edid);
 
+/* Allocate struct drm_edid container *without* duplicating the edid data */
+static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
+{
+	struct drm_edid *drm_edid;
+
+	if (!edid || !size || size < EDID_LENGTH)
+		return NULL;
+
+	drm_edid = kzalloc(sizeof(*drm_edid), GFP_KERNEL);
+	if (drm_edid) {
+		drm_edid->edid = edid;
+		drm_edid->size = size;
+	}
+
+	return drm_edid;
+}
+
+/**
+ * drm_edid_alloc - Allocate a new drm_edid container
+ * @edid: Pointer to raw EDID data
+ * @size: Size of memory allocated for EDID
+ *
+ * Allocate a new drm_edid container. Do not calculate edid size from edid, pass
+ * the actual size that has been allocated for the data. There is no validation
+ * of the raw EDID data against the size, but at least the EDID base block must
+ * fit in the buffer.
+ *
+ * The returned pointer must be freed using drm_edid_free().
+ *
+ * Return: drm_edid container, or NULL on errors
+ */
+const struct drm_edid *drm_edid_alloc(const void *edid, size_t size)
+{
+	const struct drm_edid *drm_edid;
+
+	if (!edid || !size || size < EDID_LENGTH)
+		return NULL;
+
+	edid = kmemdup(edid, size, GFP_KERNEL);
+	if (!edid)
+		return NULL;
+
+	drm_edid = _drm_edid_alloc(edid, size);
+	if (!drm_edid)
+		kfree(edid);
+
+	return drm_edid;
+}
+EXPORT_SYMBOL(drm_edid_alloc);
+
+/**
+ * drm_edid_dup - Duplicate a drm_edid container
+ * @drm_edid: EDID to duplicate
+ *
+ * The returned pointer must be freed using drm_edid_free().
+ *
+ * Returns: drm_edid container copy, or NULL on errors
+ */
+const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid)
+{
+	if (!drm_edid)
+		return NULL;
+
+	return drm_edid_alloc(drm_edid->edid, drm_edid->size);
+}
+EXPORT_SYMBOL(drm_edid_dup);
+
+/**
+ * drm_edid_free - Free the drm_edid container
+ * @drm_edid: EDID to free
+ */
+void drm_edid_free(const struct drm_edid *drm_edid)
+{
+	if (!drm_edid)
+		return;
+
+	kfree(drm_edid->edid);
+	kfree(drm_edid);
+}
+EXPORT_SYMBOL(drm_edid_free);
+
 /**
  * drm_probe_ddc() - probe DDC presence
  * @adapter: I2C adapter to probe
@@ -2359,12 +2450,118 @@ struct edid *drm_get_edid(struct drm_connector *connector,
 	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
 		return NULL;
 
-	edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
+	edid = _drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter, NULL);
 	drm_connector_update_edid_property(connector, edid);
 	return edid;
 }
 EXPORT_SYMBOL(drm_get_edid);
 
+/**
+ * drm_edid_read_custom - Read EDID data using given EDID block read function
+ * @connector: Connector to use
+ * @read_block: EDID block read function
+ * @context: Private data passed to the block read function
+ *
+ * When the I2C adapter connected to the DDC bus is hidden behind a device that
+ * exposes a different interface to read EDID blocks this function can be used
+ * to get EDID data using a custom block read function.
+ *
+ * As in the general case the DDC bus is accessible by the kernel at the I2C
+ * level, drivers must make all reasonable efforts to expose it as an I2C
+ * adapter and use drm_edid_read() or drm_edid_read_ddc() instead of abusing
+ * this function.
+ *
+ * The EDID may be overridden using debugfs override_edid or firmware EDID
+ * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
+ * order. Having either of them bypasses actual EDID reads.
+ *
+ * The returned pointer must be freed using drm_edid_free().
+ *
+ * Return: Pointer to EDID, or NULL if probe/read failed.
+ */
+const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
+					    read_block_fn read_block,
+					    void *context)
+{
+	const struct drm_edid *drm_edid;
+	struct edid *edid;
+	size_t size = 0;
+
+	edid = _drm_do_get_edid(connector, read_block, context, &size);
+	if (!edid)
+		return NULL;
+
+	/* Sanity check for now */
+	drm_WARN_ON(connector->dev, !size);
+
+	drm_edid = _drm_edid_alloc(edid, size);
+	if (!drm_edid)
+		kfree(edid);
+
+	return drm_edid;
+}
+EXPORT_SYMBOL(drm_edid_read_custom);
+
+/**
+ * drm_edid_read_ddc - Read EDID data using given I2C adapter
+ * @connector: Connector to use
+ * @adapter: I2C adapter to use for DDC
+ *
+ * Read EDID using the given I2C adapter.
+ *
+ * The EDID may be overridden using debugfs override_edid or firmware EDID
+ * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
+ * order. Having either of them bypasses actual EDID reads.
+ *
+ * Prefer initializing connector->ddc with drm_connector_init_with_ddc() and
+ * using drm_edid_read() instead of this function.
+ *
+ * The returned pointer must be freed using drm_edid_free().
+ *
+ * Return: Pointer to EDID, or NULL if probe/read failed.
+ */
+const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
+					 struct i2c_adapter *adapter)
+{
+	const struct drm_edid *drm_edid;
+
+	if (connector->force == DRM_FORCE_OFF)
+		return NULL;
+
+	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
+		return NULL;
+
+	drm_edid = drm_edid_read_custom(connector, drm_do_probe_ddc_edid, adapter);
+
+	/* Note: Do *not* call connector updates here. */
+
+	return drm_edid;
+}
+EXPORT_SYMBOL(drm_edid_read_ddc);
+
+/**
+ * drm_edid_read - Read EDID data using connector's I2C adapter
+ * @connector: Connector to use
+ *
+ * Read EDID using the connector's I2C adapter.
+ *
+ * The EDID may be overridden using debugfs override_edid or firmware EDID
+ * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
+ * order. Having either of them bypasses actual EDID reads.
+ *
+ * The returned pointer must be freed using drm_edid_free().
+ *
+ * Return: Pointer to EDID, or NULL if probe/read failed.
+ */
+const struct drm_edid *drm_edid_read(struct drm_connector *connector)
+{
+	if (drm_WARN_ON(connector->dev, !connector->ddc))
+		return NULL;
+
+	return drm_edid_read_ddc(connector, connector->ddc);
+}
+EXPORT_SYMBOL(drm_edid_read);
+
 static u32 edid_extract_panel_id(const struct edid *edid)
 {
 	/*
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 95ac09ef41b2..9d2d78135dee 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -594,6 +594,15 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
 			      u8 video_code);
 
 /* Interface based on struct drm_edid */
+const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
+const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
+void drm_edid_free(const struct drm_edid *drm_edid);
+const struct drm_edid *drm_edid_read(struct drm_connector *connector);
+const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
+					 struct i2c_adapter *adapter);
+const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
+					    int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),
+					    void *context);
 const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
 				  int ext_id, int *ext_index);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 06/15] drm/edid: add drm_edid_connector_update()
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, David Airlie, intel-gfx

Add a new function drm_edid_connector_update() to replace the
combination of calls drm_connector_update_edid_property() and
drm_add_edid_modes(). Usually they are called in the drivers in this
order, however the former needs information from the latter.

Since the new drm_edid_read*() functions no longer call the connector
updates directly, and the read and update are separated, we'll need this
new function for the connector update.

This is all in drm_edid.c simply to keep struct drm_edid opaque.

Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_connector.c |  2 +
 drivers/gpu/drm/drm_edid.c      | 71 +++++++++++++++++++++++++++++++--
 include/drm/drm_edid.h          |  2 +
 3 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 1c48d162c77e..ae9c640a641a 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2088,6 +2088,8 @@ EXPORT_SYMBOL(drm_connector_set_tile_property);
  * set the connector's tile property here. See drm_connector_set_tile_property()
  * for more details.
  *
+ * This function is deprecated. Use drm_edid_connector_update() instead.
+ *
  * Returns:
  * Zero on success, negative errno on failure.
  */
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 2bdaf1e34a9d..952724788963 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -6143,8 +6143,8 @@ static int add_displayid_detailed_modes(struct drm_connector *connector,
 	return num_modes;
 }
 
-static int drm_edid_connector_update(struct drm_connector *connector,
-				     const struct drm_edid *drm_edid)
+static int _drm_edid_connector_update(struct drm_connector *connector,
+				      const struct drm_edid *drm_edid)
 {
 	int num_modes = 0;
 	u32 quirks;
@@ -6207,6 +6207,67 @@ static int drm_edid_connector_update(struct drm_connector *connector,
 	return num_modes;
 }
 
+static void _drm_update_tile_info(struct drm_connector *connector,
+				  const struct drm_edid *drm_edid);
+
+/**
+ * drm_edid_connector_update - Update connector information from EDID
+ * @connector: Connector
+ * @drm_edid: EDID
+ *
+ * Update the connector mode list, display info, ELD, HDR metadata, relevant
+ * properties, etc. from the passed in EDID.
+ *
+ * If EDID is NULL, reset the information.
+ *
+ * Return: The number of modes added or 0 if we couldn't find any.
+ */
+int drm_edid_connector_update(struct drm_connector *connector,
+			      const struct drm_edid *drm_edid)
+{
+	struct drm_device *dev = connector->dev;
+	const struct edid *old_edid = connector->edid_blob_ptr ?
+		connector->edid_blob_ptr->data : NULL;
+	const struct edid *edid = drm_edid ? drm_edid->edid : NULL;
+	size_t size = drm_edid ? drm_edid->size : 0;
+	int count, ret;
+
+	count = _drm_edid_connector_update(connector, drm_edid);
+
+	_drm_update_tile_info(connector, drm_edid);
+
+	if (old_edid && !drm_edid_are_equal(edid, old_edid)) {
+		connector->epoch_counter++;
+
+		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID changed, epoch counter %llu\n",
+			    connector->base.id, connector->name,
+			    connector->epoch_counter);
+	}
+
+	ret = drm_property_replace_global_blob(dev, &connector->edid_blob_ptr,
+					       size, edid,
+					       &connector->base,
+					       dev->mode_config.edid_property);
+	if (ret)
+		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID property update failed (%d)\n",
+			    connector->base.id, connector->name, ret);
+
+	ret = drm_object_property_set_value(&connector->base,
+					    dev->mode_config.non_desktop_property,
+					    connector->display_info.non_desktop);
+	if (ret)
+		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Non-desktop property update failed (%d)\n",
+			    connector->base.id, connector->name, ret);
+
+	ret = drm_connector_set_tile_property(connector);
+	if (ret)
+		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Tile property update failed (%d)\n",
+			    connector->base.id, connector->name, ret);
+
+	return count;
+}
+EXPORT_SYMBOL(drm_edid_connector_update);
+
 /**
  * drm_add_edid_modes - add modes from EDID data, if available
  * @connector: connector we're probing
@@ -6216,6 +6277,8 @@ static int drm_edid_connector_update(struct drm_connector *connector,
  * &drm_display_info structure and ELD in @connector with any information which
  * can be derived from the edid.
  *
+ * This function is deprecated. Use drm_edid_connector_update() instead.
+ *
  * Return: The number of modes added or 0 if we couldn't find any.
  */
 int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
@@ -6228,8 +6291,8 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
 		edid = NULL;
 	}
 
-	return drm_edid_connector_update(connector,
-					 drm_edid_legacy_init(&drm_edid, edid));
+	return _drm_edid_connector_update(connector,
+					  drm_edid_legacy_init(&drm_edid, edid));
 }
 EXPORT_SYMBOL(drm_add_edid_modes);
 
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 9d2d78135dee..aeb2fa95bc04 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -603,6 +603,8 @@ const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
 const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
 					    int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),
 					    void *context);
+int drm_edid_connector_update(struct drm_connector *connector,
+			      const struct drm_edid *edid);
 const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
 				  int ext_id, int *ext_index);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 06/15] drm/edid: add drm_edid_connector_update()
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, David Airlie, intel-gfx

Add a new function drm_edid_connector_update() to replace the
combination of calls drm_connector_update_edid_property() and
drm_add_edid_modes(). Usually they are called in the drivers in this
order, however the former needs information from the latter.

Since the new drm_edid_read*() functions no longer call the connector
updates directly, and the read and update are separated, we'll need this
new function for the connector update.

This is all in drm_edid.c simply to keep struct drm_edid opaque.

Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_connector.c |  2 +
 drivers/gpu/drm/drm_edid.c      | 71 +++++++++++++++++++++++++++++++--
 include/drm/drm_edid.h          |  2 +
 3 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 1c48d162c77e..ae9c640a641a 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2088,6 +2088,8 @@ EXPORT_SYMBOL(drm_connector_set_tile_property);
  * set the connector's tile property here. See drm_connector_set_tile_property()
  * for more details.
  *
+ * This function is deprecated. Use drm_edid_connector_update() instead.
+ *
  * Returns:
  * Zero on success, negative errno on failure.
  */
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 2bdaf1e34a9d..952724788963 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -6143,8 +6143,8 @@ static int add_displayid_detailed_modes(struct drm_connector *connector,
 	return num_modes;
 }
 
-static int drm_edid_connector_update(struct drm_connector *connector,
-				     const struct drm_edid *drm_edid)
+static int _drm_edid_connector_update(struct drm_connector *connector,
+				      const struct drm_edid *drm_edid)
 {
 	int num_modes = 0;
 	u32 quirks;
@@ -6207,6 +6207,67 @@ static int drm_edid_connector_update(struct drm_connector *connector,
 	return num_modes;
 }
 
+static void _drm_update_tile_info(struct drm_connector *connector,
+				  const struct drm_edid *drm_edid);
+
+/**
+ * drm_edid_connector_update - Update connector information from EDID
+ * @connector: Connector
+ * @drm_edid: EDID
+ *
+ * Update the connector mode list, display info, ELD, HDR metadata, relevant
+ * properties, etc. from the passed in EDID.
+ *
+ * If EDID is NULL, reset the information.
+ *
+ * Return: The number of modes added or 0 if we couldn't find any.
+ */
+int drm_edid_connector_update(struct drm_connector *connector,
+			      const struct drm_edid *drm_edid)
+{
+	struct drm_device *dev = connector->dev;
+	const struct edid *old_edid = connector->edid_blob_ptr ?
+		connector->edid_blob_ptr->data : NULL;
+	const struct edid *edid = drm_edid ? drm_edid->edid : NULL;
+	size_t size = drm_edid ? drm_edid->size : 0;
+	int count, ret;
+
+	count = _drm_edid_connector_update(connector, drm_edid);
+
+	_drm_update_tile_info(connector, drm_edid);
+
+	if (old_edid && !drm_edid_are_equal(edid, old_edid)) {
+		connector->epoch_counter++;
+
+		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID changed, epoch counter %llu\n",
+			    connector->base.id, connector->name,
+			    connector->epoch_counter);
+	}
+
+	ret = drm_property_replace_global_blob(dev, &connector->edid_blob_ptr,
+					       size, edid,
+					       &connector->base,
+					       dev->mode_config.edid_property);
+	if (ret)
+		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID property update failed (%d)\n",
+			    connector->base.id, connector->name, ret);
+
+	ret = drm_object_property_set_value(&connector->base,
+					    dev->mode_config.non_desktop_property,
+					    connector->display_info.non_desktop);
+	if (ret)
+		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Non-desktop property update failed (%d)\n",
+			    connector->base.id, connector->name, ret);
+
+	ret = drm_connector_set_tile_property(connector);
+	if (ret)
+		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Tile property update failed (%d)\n",
+			    connector->base.id, connector->name, ret);
+
+	return count;
+}
+EXPORT_SYMBOL(drm_edid_connector_update);
+
 /**
  * drm_add_edid_modes - add modes from EDID data, if available
  * @connector: connector we're probing
@@ -6216,6 +6277,8 @@ static int drm_edid_connector_update(struct drm_connector *connector,
  * &drm_display_info structure and ELD in @connector with any information which
  * can be derived from the edid.
  *
+ * This function is deprecated. Use drm_edid_connector_update() instead.
+ *
  * Return: The number of modes added or 0 if we couldn't find any.
  */
 int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
@@ -6228,8 +6291,8 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
 		edid = NULL;
 	}
 
-	return drm_edid_connector_update(connector,
-					 drm_edid_legacy_init(&drm_edid, edid));
+	return _drm_edid_connector_update(connector,
+					  drm_edid_legacy_init(&drm_edid, edid));
 }
 EXPORT_SYMBOL(drm_add_edid_modes);
 
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 9d2d78135dee..aeb2fa95bc04 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -603,6 +603,8 @@ const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
 const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
 					    int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),
 					    void *context);
+int drm_edid_connector_update(struct drm_connector *connector,
+			      const struct drm_edid *edid);
 const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
 				  int ext_id, int *ext_index);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 07/15] drm/probe-helper: abstract .get_modes() connector helper call
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Abstract the .get_modes() connector helper call, including the
override/firmware EDID fallback, for clarity.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_probe_helper.c | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 75a71649b64d..a8d26b29bfa0 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -354,6 +354,24 @@ drm_helper_probe_detect(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_helper_probe_detect);
 
+static int drm_helper_probe_get_modes(struct drm_connector *connector)
+{
+	const struct drm_connector_helper_funcs *connector_funcs =
+		connector->helper_private;
+	int count;
+
+	count = connector_funcs->get_modes(connector);
+
+	/*
+	 * Fallback for when DDC probe failed in drm_get_edid() and thus skipped
+	 * override/firmware EDID.
+	 */
+	if (count == 0 && connector->status == connector_status_connected)
+		count = drm_add_override_edid_modes(connector);
+
+	return count;
+}
+
 static int __drm_helper_update_and_validate(struct drm_connector *connector,
 					    uint32_t maxX, uint32_t maxY,
 					    struct drm_modeset_acquire_ctx *ctx)
@@ -473,8 +491,6 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_display_mode *mode;
-	const struct drm_connector_helper_funcs *connector_funcs =
-		connector->helper_private;
 	int count = 0, ret;
 	enum drm_connector_status old_status;
 	struct drm_modeset_acquire_ctx ctx;
@@ -559,14 +575,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
 		goto exit;
 	}
 
-	count = (*connector_funcs->get_modes)(connector);
-
-	/*
-	 * Fallback for when DDC probe failed in drm_get_edid() and thus skipped
-	 * override/firmware EDID.
-	 */
-	if (count == 0 && connector->status == connector_status_connected)
-		count = drm_add_override_edid_modes(connector);
+	count = drm_helper_probe_get_modes(connector);
 
 	if (count == 0 && (connector->status == connector_status_connected ||
 			   connector->status == connector_status_unknown)) {
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 07/15] drm/probe-helper: abstract .get_modes() connector helper call
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Abstract the .get_modes() connector helper call, including the
override/firmware EDID fallback, for clarity.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_probe_helper.c | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 75a71649b64d..a8d26b29bfa0 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -354,6 +354,24 @@ drm_helper_probe_detect(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_helper_probe_detect);
 
+static int drm_helper_probe_get_modes(struct drm_connector *connector)
+{
+	const struct drm_connector_helper_funcs *connector_funcs =
+		connector->helper_private;
+	int count;
+
+	count = connector_funcs->get_modes(connector);
+
+	/*
+	 * Fallback for when DDC probe failed in drm_get_edid() and thus skipped
+	 * override/firmware EDID.
+	 */
+	if (count == 0 && connector->status == connector_status_connected)
+		count = drm_add_override_edid_modes(connector);
+
+	return count;
+}
+
 static int __drm_helper_update_and_validate(struct drm_connector *connector,
 					    uint32_t maxX, uint32_t maxY,
 					    struct drm_modeset_acquire_ctx *ctx)
@@ -473,8 +491,6 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_display_mode *mode;
-	const struct drm_connector_helper_funcs *connector_funcs =
-		connector->helper_private;
 	int count = 0, ret;
 	enum drm_connector_status old_status;
 	struct drm_modeset_acquire_ctx ctx;
@@ -559,14 +575,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
 		goto exit;
 	}
 
-	count = (*connector_funcs->get_modes)(connector);
-
-	/*
-	 * Fallback for when DDC probe failed in drm_get_edid() and thus skipped
-	 * override/firmware EDID.
-	 */
-	if (count == 0 && connector->status == connector_status_connected)
-		count = drm_add_override_edid_modes(connector);
+	count = drm_helper_probe_get_modes(connector);
 
 	if (count == 0 && (connector->status == connector_status_connected ||
 			   connector->status == connector_status_unknown)) {
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 08/15] drm/probe-helper: add drm_connector_helper_get_modes()
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Add a helper function to be used as the "default" .get_modes()
hook. This also works as an example of what the driver .get_modes()
hooks are supposed to do regarding the new drm_edid_read*() and
drm_edid_connector_update() calls.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_probe_helper.c | 34 ++++++++++++++++++++++++++++++
 include/drm/drm_probe_helper.h     |  1 +
 2 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index a8d26b29bfa0..e6b8f2923aa7 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -1049,3 +1049,37 @@ int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector)
 	return count;
 }
 EXPORT_SYMBOL(drm_connector_helper_get_modes_from_ddc);
+
+/**
+ * drm_connector_helper_get_modes - Read EDID and update connector.
+ * @connector: The connector
+ *
+ * Read the EDID using drm_edid_read() (which requires that connector->ddc is
+ * set), and update the connector using the EDID.
+ *
+ * This can be used as the "default" connector helper .get_modes() hook if the
+ * driver does not need any special processing. This is sets the example what
+ * custom .get_modes() hooks should do regarding EDID read and connector update.
+ *
+ * Returns: Number of modes.
+ */
+int drm_connector_helper_get_modes(struct drm_connector *connector)
+{
+	const struct drm_edid *drm_edid;
+	int count;
+
+	drm_edid = drm_edid_read(connector);
+
+	/*
+	 * Unconditionally update the connector. If the EDID was read
+	 * succesfully, fill in the connector information derived from the
+	 * EDID. Otherwise, if the EDID is NULL, clear the connector
+	 * information.
+	 */
+	count = drm_edid_connector_update(connector, drm_edid);
+
+	drm_edid_free(drm_edid);
+
+	return count;
+}
+EXPORT_SYMBOL(drm_connector_helper_get_modes);
diff --git a/include/drm/drm_probe_helper.h b/include/drm/drm_probe_helper.h
index c80cab7a53b7..8075e02aa865 100644
--- a/include/drm/drm_probe_helper.h
+++ b/include/drm/drm_probe_helper.h
@@ -27,5 +27,6 @@ void drm_kms_helper_poll_enable(struct drm_device *dev);
 bool drm_kms_helper_is_poll_worker(void);
 
 int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector);
+int drm_connector_helper_get_modes(struct drm_connector *connector);
 
 #endif
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 08/15] drm/probe-helper: add drm_connector_helper_get_modes()
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Add a helper function to be used as the "default" .get_modes()
hook. This also works as an example of what the driver .get_modes()
hooks are supposed to do regarding the new drm_edid_read*() and
drm_edid_connector_update() calls.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_probe_helper.c | 34 ++++++++++++++++++++++++++++++
 include/drm/drm_probe_helper.h     |  1 +
 2 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index a8d26b29bfa0..e6b8f2923aa7 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -1049,3 +1049,37 @@ int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector)
 	return count;
 }
 EXPORT_SYMBOL(drm_connector_helper_get_modes_from_ddc);
+
+/**
+ * drm_connector_helper_get_modes - Read EDID and update connector.
+ * @connector: The connector
+ *
+ * Read the EDID using drm_edid_read() (which requires that connector->ddc is
+ * set), and update the connector using the EDID.
+ *
+ * This can be used as the "default" connector helper .get_modes() hook if the
+ * driver does not need any special processing. This is sets the example what
+ * custom .get_modes() hooks should do regarding EDID read and connector update.
+ *
+ * Returns: Number of modes.
+ */
+int drm_connector_helper_get_modes(struct drm_connector *connector)
+{
+	const struct drm_edid *drm_edid;
+	int count;
+
+	drm_edid = drm_edid_read(connector);
+
+	/*
+	 * Unconditionally update the connector. If the EDID was read
+	 * succesfully, fill in the connector information derived from the
+	 * EDID. Otherwise, if the EDID is NULL, clear the connector
+	 * information.
+	 */
+	count = drm_edid_connector_update(connector, drm_edid);
+
+	drm_edid_free(drm_edid);
+
+	return count;
+}
+EXPORT_SYMBOL(drm_connector_helper_get_modes);
diff --git a/include/drm/drm_probe_helper.h b/include/drm/drm_probe_helper.h
index c80cab7a53b7..8075e02aa865 100644
--- a/include/drm/drm_probe_helper.h
+++ b/include/drm/drm_probe_helper.h
@@ -27,5 +27,6 @@ void drm_kms_helper_poll_enable(struct drm_device *dev);
 bool drm_kms_helper_is_poll_worker(void);
 
 int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector);
+int drm_connector_helper_get_modes(struct drm_connector *connector);
 
 #endif
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 09/15] drm/edid: add drm_edid_raw() to access the raw EDID data
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Unfortunately, there are still plenty of interfaces around that require
a struct edid pointer, and it's impossible to change them all at
once. Add an accessor to the raw EDID data to help the transition.

While there are no such cases now, be defensive against raw EDID
extension count indicating bigger EDID than is actually allocated.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 26 ++++++++++++++++++++++++++
 include/drm/drm_edid.h     |  1 +
 2 files changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 952724788963..4e788c5cbf25 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2333,6 +2333,32 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 }
 EXPORT_SYMBOL_GPL(drm_do_get_edid);
 
+/**
+ * drm_edid_raw - Get a pointer to the raw EDID data.
+ * @drm_edid: drm_edid container
+ *
+ * Get a pointer to the raw EDID data.
+ *
+ * This is for transition only. Avoid using this like the plague.
+ *
+ * Return: Pointer to raw EDID data.
+ */
+const struct edid *drm_edid_raw(const struct drm_edid *drm_edid)
+{
+	if (!drm_edid || !drm_edid->size)
+		return NULL;
+
+	/*
+	 * Do not return pointers where relying on EDID extension count would
+	 * lead to buffer overflow.
+	 */
+	if (WARN_ON(edid_size(drm_edid->edid) > drm_edid->size))
+		return NULL;
+
+	return drm_edid->edid;
+}
+EXPORT_SYMBOL(drm_edid_raw);
+
 /* Allocate struct drm_edid container *without* duplicating the edid data */
 static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
 {
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index aeb2fa95bc04..2181977ae683 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -597,6 +597,7 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
 const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
 const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
 void drm_edid_free(const struct drm_edid *drm_edid);
+const struct edid *drm_edid_raw(const struct drm_edid *drm_edid);
 const struct drm_edid *drm_edid_read(struct drm_connector *connector);
 const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
 					 struct i2c_adapter *adapter);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 09/15] drm/edid: add drm_edid_raw() to access the raw EDID data
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Unfortunately, there are still plenty of interfaces around that require
a struct edid pointer, and it's impossible to change them all at
once. Add an accessor to the raw EDID data to help the transition.

While there are no such cases now, be defensive against raw EDID
extension count indicating bigger EDID than is actually allocated.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 26 ++++++++++++++++++++++++++
 include/drm/drm_edid.h     |  1 +
 2 files changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 952724788963..4e788c5cbf25 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2333,6 +2333,32 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 }
 EXPORT_SYMBOL_GPL(drm_do_get_edid);
 
+/**
+ * drm_edid_raw - Get a pointer to the raw EDID data.
+ * @drm_edid: drm_edid container
+ *
+ * Get a pointer to the raw EDID data.
+ *
+ * This is for transition only. Avoid using this like the plague.
+ *
+ * Return: Pointer to raw EDID data.
+ */
+const struct edid *drm_edid_raw(const struct drm_edid *drm_edid)
+{
+	if (!drm_edid || !drm_edid->size)
+		return NULL;
+
+	/*
+	 * Do not return pointers where relying on EDID extension count would
+	 * lead to buffer overflow.
+	 */
+	if (WARN_ON(edid_size(drm_edid->edid) > drm_edid->size))
+		return NULL;
+
+	return drm_edid->edid;
+}
+EXPORT_SYMBOL(drm_edid_raw);
+
 /* Allocate struct drm_edid container *without* duplicating the edid data */
 static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
 {
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index aeb2fa95bc04..2181977ae683 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -597,6 +597,7 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
 const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
 const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
 void drm_edid_free(const struct drm_edid *drm_edid);
+const struct edid *drm_edid_raw(const struct drm_edid *drm_edid);
 const struct drm_edid *drm_edid_read(struct drm_connector *connector);
 const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
 					 struct i2c_adapter *adapter);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 10/15] drm/i915/edid: convert DP, HDMI and LVDS to drm_edid
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Convert all the connectors that use cached connector edid and
detect_edid to drm_edid.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 .../gpu/drm/i915/display/intel_connector.c    |  4 +-
 .../drm/i915/display/intel_display_types.h    |  4 +-
 drivers/gpu/drm/i915/display/intel_dp.c       | 74 ++++++++++---------
 drivers/gpu/drm/i915/display/intel_hdmi.c     | 26 ++++---
 drivers/gpu/drm/i915/display/intel_lvds.c     | 37 +++++-----
 5 files changed, 79 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c
index 1dcc268927a2..d83b2a64f618 100644
--- a/drivers/gpu/drm/i915/display/intel_connector.c
+++ b/drivers/gpu/drm/i915/display/intel_connector.c
@@ -95,12 +95,12 @@ void intel_connector_destroy(struct drm_connector *connector)
 {
 	struct intel_connector *intel_connector = to_intel_connector(connector);
 
-	kfree(intel_connector->detect_edid);
+	drm_edid_free(intel_connector->detect_edid);
 
 	intel_hdcp_cleanup(intel_connector);
 
 	if (!IS_ERR_OR_NULL(intel_connector->edid))
-		kfree(intel_connector->edid);
+		drm_edid_free(intel_connector->edid);
 
 	intel_panel_fini(intel_connector);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 9b44358e8d9e..dffbc7d59587 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -590,8 +590,8 @@ struct intel_connector {
 	struct intel_panel panel;
 
 	/* Cached EDID for eDP and LVDS. May hold ERR_PTR for invalid EDID. */
-	struct edid *edid;
-	struct edid *detect_edid;
+	const struct drm_edid *edid;
+	const struct drm_edid *detect_edid;
 
 	/* Number of times hotplug detection was tried after an HPD interrupt */
 	int hotplug_retries;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index e198c6d7e3b5..64b6481225f1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3534,12 +3534,11 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
 				    intel_dp->aux.i2c_defer_count);
 		intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_FAILSAFE;
 	} else {
-		struct edid *block = intel_connector->detect_edid;
+		/* FIXME: Get rid of drm_edid_raw() */
+		const struct edid *block = drm_edid_raw(intel_connector->detect_edid);
 
-		/* We have to write the checksum
-		 * of the last block read
-		 */
-		block += intel_connector->detect_edid->extensions;
+		/* We have to write the checksum of the last block read */
+		block += block->extensions;
 
 		if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM,
 				       block->checksum) <= 0)
@@ -4418,7 +4417,7 @@ bool intel_digital_port_connected(struct intel_encoder *encoder)
 	return is_connected;
 }
 
-static struct edid *
+static const struct drm_edid *
 intel_dp_get_edid(struct intel_dp *intel_dp)
 {
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
@@ -4429,18 +4428,22 @@ intel_dp_get_edid(struct intel_dp *intel_dp)
 		if (IS_ERR(intel_connector->edid))
 			return NULL;
 
-		return drm_edid_duplicate(intel_connector->edid);
+		return drm_edid_dup(intel_connector->edid);
 	} else
-		return drm_get_edid(&intel_connector->base,
-				    &intel_dp->aux.ddc);
+		return drm_edid_read_ddc(&intel_connector->base,
+					 &intel_dp->aux.ddc);
 }
 
 static void
 intel_dp_update_dfp(struct intel_dp *intel_dp,
-		    const struct edid *edid)
+		    const struct drm_edid *drm_edid)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	struct intel_connector *connector = intel_dp->attached_connector;
+	const struct edid *edid;
+
+	/* FIXME: Get rid of drm_edid_raw() */
+	edid = drm_edid_raw(drm_edid);
 
 	intel_dp->dfp.max_bpc =
 		drm_dp_downstream_max_bpc(intel_dp->dpcd,
@@ -4540,21 +4543,24 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	struct intel_connector *connector = intel_dp->attached_connector;
-	struct edid *edid;
+	const struct drm_edid *drm_edid;
+	const struct edid *edid;
 	bool vrr_capable;
 
 	intel_dp_unset_edid(intel_dp);
-	edid = intel_dp_get_edid(intel_dp);
-	connector->detect_edid = edid;
+	drm_edid = intel_dp_get_edid(intel_dp);
+	connector->detect_edid = drm_edid;
 
 	vrr_capable = intel_vrr_is_capable(connector);
 	drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] VRR capable: %s\n",
 		    connector->base.base.id, connector->base.name, str_yes_no(vrr_capable));
 	drm_connector_set_vrr_capable_property(&connector->base, vrr_capable);
 
-	intel_dp_update_dfp(intel_dp, edid);
+	intel_dp_update_dfp(intel_dp, drm_edid);
 	intel_dp_update_420(intel_dp);
 
+	/* FIXME: Get rid of drm_edid_raw() */
+	edid = drm_edid_raw(drm_edid);
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
 		intel_dp->has_audio = drm_detect_monitor_audio(edid);
@@ -4569,7 +4575,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 	struct intel_connector *connector = intel_dp->attached_connector;
 
 	drm_dp_cec_unset_edid(&intel_dp->aux);
-	kfree(connector->detect_edid);
+	drm_edid_free(connector->detect_edid);
 	connector->detect_edid = NULL;
 
 	intel_dp->has_hdmi_sink = false;
@@ -4733,12 +4739,11 @@ intel_dp_force(struct drm_connector *connector)
 static int intel_dp_get_modes(struct drm_connector *connector)
 {
 	struct intel_connector *intel_connector = to_intel_connector(connector);
-	struct edid *edid;
+	const struct drm_edid *drm_edid;
 	int num_modes = 0;
 
-	edid = intel_connector->detect_edid;
-	if (edid)
-		num_modes = intel_connector_update_modes(connector, edid);
+	drm_edid = intel_connector->detect_edid;
+	num_modes = drm_edid_connector_update(connector, drm_edid);
 
 	/* Also add fixed mode, which may or may not be present in EDID */
 	if (intel_dp_is_edp(intel_attached_dp(intel_connector)))
@@ -4747,7 +4752,7 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 	if (num_modes)
 		return num_modes;
 
-	if (!edid) {
+	if (!drm_edid) {
 		struct intel_dp *intel_dp = intel_attached_dp(intel_connector);
 		struct drm_display_mode *mode;
 
@@ -5154,7 +5159,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 	struct drm_display_mode *fixed_mode;
 	bool has_dpcd;
 	enum pipe pipe = INVALID_PIPE;
-	struct edid *edid;
+	const struct drm_edid *drm_edid;
 
 	if (!intel_dp_is_edp(intel_dp))
 		return true;
@@ -5187,29 +5192,32 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 	}
 
 	mutex_lock(&dev->mode_config.mutex);
-	edid = drm_get_edid(connector, &intel_dp->aux.ddc);
-	if (!edid) {
+	drm_edid = drm_edid_read_ddc(connector, &intel_dp->aux.ddc);
+	if (!drm_edid) {
+		const struct edid *edid;
+
 		/* Fallback to EDID from ACPI OpRegion, if any */
+		/* FIXME: Make intel_opregion_get_edid() return drm_edid */
 		edid = intel_opregion_get_edid(intel_connector);
-		if (edid)
+		if (edid) {
+			drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) * EDID_LENGTH);
 			drm_dbg_kms(&dev_priv->drm,
 				    "[CONNECTOR:%d:%s] Using OpRegion EDID\n",
 				    connector->base.id, connector->name);
+		}
 	}
-	if (edid) {
-		if (drm_add_edid_modes(connector, edid)) {
-			drm_connector_update_edid_property(connector, edid);
-		} else {
-			kfree(edid);
-			edid = ERR_PTR(-EINVAL);
+	if (drm_edid) {
+		if (!drm_edid_connector_update(connector, drm_edid)) {
+			drm_edid_free(drm_edid);
+			drm_edid = ERR_PTR(-EINVAL);
 		}
 	} else {
-		edid = ERR_PTR(-ENOENT);
+		drm_edid = ERR_PTR(-ENOENT);
 	}
-	intel_connector->edid = edid;
+	intel_connector->edid = drm_edid;
 
 	intel_bios_init_panel(dev_priv, &intel_connector->panel,
-			      IS_ERR(edid) ? NULL : edid);
+			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
 
 	intel_panel_add_edid_fixed_modes(intel_connector,
 					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 1ae09431f53a..db33a0ccd7ee 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2340,7 +2340,7 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
 	intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
 	intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
 
-	kfree(to_intel_connector(connector)->detect_edid);
+	drm_edid_free(to_intel_connector(connector)->detect_edid);
 	to_intel_connector(connector)->detect_edid = NULL;
 }
 
@@ -2407,7 +2407,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
 	intel_wakeref_t wakeref;
-	struct edid *edid;
+	const struct drm_edid *drm_edid;
+	const struct edid *edid;
 	bool connected = false;
 	struct i2c_adapter *i2c;
 
@@ -2415,21 +2416,24 @@ intel_hdmi_set_edid(struct drm_connector *connector)
 
 	i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
 
-	edid = drm_get_edid(connector, i2c);
+	drm_edid = drm_edid_read_ddc(connector, i2c);
 
-	if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
+	if (!drm_edid && !intel_gmbus_is_forced_bit(i2c)) {
 		drm_dbg_kms(&dev_priv->drm,
 			    "HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");
 		intel_gmbus_force_bit(i2c, true);
-		edid = drm_get_edid(connector, i2c);
+		drm_edid = drm_edid_read_ddc(connector, i2c);
 		intel_gmbus_force_bit(i2c, false);
 	}
 
-	intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
+	intel_hdmi_dp_dual_mode_detect(connector, drm_edid != NULL);
 
 	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
 
-	to_intel_connector(connector)->detect_edid = edid;
+	to_intel_connector(connector)->detect_edid = drm_edid;
+
+	/* FIXME: Get rid of drm_edid_raw() */
+	edid = drm_edid_raw(drm_edid);
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
 		intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
@@ -2501,13 +2505,11 @@ intel_hdmi_force(struct drm_connector *connector)
 
 static int intel_hdmi_get_modes(struct drm_connector *connector)
 {
-	struct edid *edid;
+	const struct drm_edid *drm_edid;
 
-	edid = to_intel_connector(connector)->detect_edid;
-	if (edid == NULL)
-		return 0;
+	drm_edid = to_intel_connector(connector)->detect_edid;
 
-	return intel_connector_update_modes(connector, edid);
+	return drm_edid_connector_update(connector, drm_edid);
 }
 
 static struct i2c_adapter *
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
index e55802b45461..d4389054bf59 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.c
+++ b/drivers/gpu/drm/i915/display/intel_lvds.c
@@ -479,7 +479,7 @@ static int intel_lvds_get_modes(struct drm_connector *connector)
 
 	/* use cached edid if we have one */
 	if (!IS_ERR_OR_NULL(intel_connector->edid))
-		return drm_add_edid_modes(connector, intel_connector->edid);
+		return drm_edid_connector_update(connector, intel_connector->edid);
 
 	return intel_panel_get_modes(intel_connector);
 }
@@ -829,7 +829,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
 	struct intel_connector *intel_connector;
 	struct drm_connector *connector;
 	struct drm_encoder *encoder;
-	struct edid *edid;
+	const struct drm_edid *drm_edid;
 	i915_reg_t lvds_reg;
 	u32 lvds;
 	u8 pin;
@@ -948,27 +948,30 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
 	 * preferred mode is the right one.
 	 */
 	mutex_lock(&dev->mode_config.mutex);
-	if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC)
+	if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) {
+		const struct edid *edid;
+
+		/* FIXME: Make drm_get_edid_switcheroo() return drm_edid */
 		edid = drm_get_edid_switcheroo(connector,
-				    intel_gmbus_get_adapter(dev_priv, pin));
-	else
-		edid = drm_get_edid(connector,
-				    intel_gmbus_get_adapter(dev_priv, pin));
-	if (edid) {
-		if (drm_add_edid_modes(connector, edid)) {
-			drm_connector_update_edid_property(connector,
-								edid);
-		} else {
-			kfree(edid);
-			edid = ERR_PTR(-EINVAL);
+					       intel_gmbus_get_adapter(dev_priv, pin));
+		if (edid)
+			drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) * EDID_LENGTH);
+	} else {
+		drm_edid = drm_edid_read_ddc(connector,
+					     intel_gmbus_get_adapter(dev_priv, pin));
+	}
+	if (drm_edid) {
+		if (!drm_edid_connector_update(connector, drm_edid)) {
+			drm_edid_free(drm_edid);
+			drm_edid = ERR_PTR(-EINVAL);
 		}
 	} else {
-		edid = ERR_PTR(-ENOENT);
+		drm_edid = ERR_PTR(-ENOENT);
 	}
-	intel_connector->edid = edid;
+	intel_connector->edid = drm_edid;
 
 	intel_bios_init_panel(dev_priv, &intel_connector->panel,
-			      IS_ERR(edid) ? NULL : edid);
+			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
 
 	/* Try EDID first */
 	intel_panel_add_edid_fixed_modes(intel_connector,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 10/15] drm/i915/edid: convert DP, HDMI and LVDS to drm_edid
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Convert all the connectors that use cached connector edid and
detect_edid to drm_edid.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 .../gpu/drm/i915/display/intel_connector.c    |  4 +-
 .../drm/i915/display/intel_display_types.h    |  4 +-
 drivers/gpu/drm/i915/display/intel_dp.c       | 74 ++++++++++---------
 drivers/gpu/drm/i915/display/intel_hdmi.c     | 26 ++++---
 drivers/gpu/drm/i915/display/intel_lvds.c     | 37 +++++-----
 5 files changed, 79 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c
index 1dcc268927a2..d83b2a64f618 100644
--- a/drivers/gpu/drm/i915/display/intel_connector.c
+++ b/drivers/gpu/drm/i915/display/intel_connector.c
@@ -95,12 +95,12 @@ void intel_connector_destroy(struct drm_connector *connector)
 {
 	struct intel_connector *intel_connector = to_intel_connector(connector);
 
-	kfree(intel_connector->detect_edid);
+	drm_edid_free(intel_connector->detect_edid);
 
 	intel_hdcp_cleanup(intel_connector);
 
 	if (!IS_ERR_OR_NULL(intel_connector->edid))
-		kfree(intel_connector->edid);
+		drm_edid_free(intel_connector->edid);
 
 	intel_panel_fini(intel_connector);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 9b44358e8d9e..dffbc7d59587 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -590,8 +590,8 @@ struct intel_connector {
 	struct intel_panel panel;
 
 	/* Cached EDID for eDP and LVDS. May hold ERR_PTR for invalid EDID. */
-	struct edid *edid;
-	struct edid *detect_edid;
+	const struct drm_edid *edid;
+	const struct drm_edid *detect_edid;
 
 	/* Number of times hotplug detection was tried after an HPD interrupt */
 	int hotplug_retries;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index e198c6d7e3b5..64b6481225f1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3534,12 +3534,11 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
 				    intel_dp->aux.i2c_defer_count);
 		intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_FAILSAFE;
 	} else {
-		struct edid *block = intel_connector->detect_edid;
+		/* FIXME: Get rid of drm_edid_raw() */
+		const struct edid *block = drm_edid_raw(intel_connector->detect_edid);
 
-		/* We have to write the checksum
-		 * of the last block read
-		 */
-		block += intel_connector->detect_edid->extensions;
+		/* We have to write the checksum of the last block read */
+		block += block->extensions;
 
 		if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM,
 				       block->checksum) <= 0)
@@ -4418,7 +4417,7 @@ bool intel_digital_port_connected(struct intel_encoder *encoder)
 	return is_connected;
 }
 
-static struct edid *
+static const struct drm_edid *
 intel_dp_get_edid(struct intel_dp *intel_dp)
 {
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
@@ -4429,18 +4428,22 @@ intel_dp_get_edid(struct intel_dp *intel_dp)
 		if (IS_ERR(intel_connector->edid))
 			return NULL;
 
-		return drm_edid_duplicate(intel_connector->edid);
+		return drm_edid_dup(intel_connector->edid);
 	} else
-		return drm_get_edid(&intel_connector->base,
-				    &intel_dp->aux.ddc);
+		return drm_edid_read_ddc(&intel_connector->base,
+					 &intel_dp->aux.ddc);
 }
 
 static void
 intel_dp_update_dfp(struct intel_dp *intel_dp,
-		    const struct edid *edid)
+		    const struct drm_edid *drm_edid)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	struct intel_connector *connector = intel_dp->attached_connector;
+	const struct edid *edid;
+
+	/* FIXME: Get rid of drm_edid_raw() */
+	edid = drm_edid_raw(drm_edid);
 
 	intel_dp->dfp.max_bpc =
 		drm_dp_downstream_max_bpc(intel_dp->dpcd,
@@ -4540,21 +4543,24 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	struct intel_connector *connector = intel_dp->attached_connector;
-	struct edid *edid;
+	const struct drm_edid *drm_edid;
+	const struct edid *edid;
 	bool vrr_capable;
 
 	intel_dp_unset_edid(intel_dp);
-	edid = intel_dp_get_edid(intel_dp);
-	connector->detect_edid = edid;
+	drm_edid = intel_dp_get_edid(intel_dp);
+	connector->detect_edid = drm_edid;
 
 	vrr_capable = intel_vrr_is_capable(connector);
 	drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] VRR capable: %s\n",
 		    connector->base.base.id, connector->base.name, str_yes_no(vrr_capable));
 	drm_connector_set_vrr_capable_property(&connector->base, vrr_capable);
 
-	intel_dp_update_dfp(intel_dp, edid);
+	intel_dp_update_dfp(intel_dp, drm_edid);
 	intel_dp_update_420(intel_dp);
 
+	/* FIXME: Get rid of drm_edid_raw() */
+	edid = drm_edid_raw(drm_edid);
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
 		intel_dp->has_audio = drm_detect_monitor_audio(edid);
@@ -4569,7 +4575,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 	struct intel_connector *connector = intel_dp->attached_connector;
 
 	drm_dp_cec_unset_edid(&intel_dp->aux);
-	kfree(connector->detect_edid);
+	drm_edid_free(connector->detect_edid);
 	connector->detect_edid = NULL;
 
 	intel_dp->has_hdmi_sink = false;
@@ -4733,12 +4739,11 @@ intel_dp_force(struct drm_connector *connector)
 static int intel_dp_get_modes(struct drm_connector *connector)
 {
 	struct intel_connector *intel_connector = to_intel_connector(connector);
-	struct edid *edid;
+	const struct drm_edid *drm_edid;
 	int num_modes = 0;
 
-	edid = intel_connector->detect_edid;
-	if (edid)
-		num_modes = intel_connector_update_modes(connector, edid);
+	drm_edid = intel_connector->detect_edid;
+	num_modes = drm_edid_connector_update(connector, drm_edid);
 
 	/* Also add fixed mode, which may or may not be present in EDID */
 	if (intel_dp_is_edp(intel_attached_dp(intel_connector)))
@@ -4747,7 +4752,7 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 	if (num_modes)
 		return num_modes;
 
-	if (!edid) {
+	if (!drm_edid) {
 		struct intel_dp *intel_dp = intel_attached_dp(intel_connector);
 		struct drm_display_mode *mode;
 
@@ -5154,7 +5159,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 	struct drm_display_mode *fixed_mode;
 	bool has_dpcd;
 	enum pipe pipe = INVALID_PIPE;
-	struct edid *edid;
+	const struct drm_edid *drm_edid;
 
 	if (!intel_dp_is_edp(intel_dp))
 		return true;
@@ -5187,29 +5192,32 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 	}
 
 	mutex_lock(&dev->mode_config.mutex);
-	edid = drm_get_edid(connector, &intel_dp->aux.ddc);
-	if (!edid) {
+	drm_edid = drm_edid_read_ddc(connector, &intel_dp->aux.ddc);
+	if (!drm_edid) {
+		const struct edid *edid;
+
 		/* Fallback to EDID from ACPI OpRegion, if any */
+		/* FIXME: Make intel_opregion_get_edid() return drm_edid */
 		edid = intel_opregion_get_edid(intel_connector);
-		if (edid)
+		if (edid) {
+			drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) * EDID_LENGTH);
 			drm_dbg_kms(&dev_priv->drm,
 				    "[CONNECTOR:%d:%s] Using OpRegion EDID\n",
 				    connector->base.id, connector->name);
+		}
 	}
-	if (edid) {
-		if (drm_add_edid_modes(connector, edid)) {
-			drm_connector_update_edid_property(connector, edid);
-		} else {
-			kfree(edid);
-			edid = ERR_PTR(-EINVAL);
+	if (drm_edid) {
+		if (!drm_edid_connector_update(connector, drm_edid)) {
+			drm_edid_free(drm_edid);
+			drm_edid = ERR_PTR(-EINVAL);
 		}
 	} else {
-		edid = ERR_PTR(-ENOENT);
+		drm_edid = ERR_PTR(-ENOENT);
 	}
-	intel_connector->edid = edid;
+	intel_connector->edid = drm_edid;
 
 	intel_bios_init_panel(dev_priv, &intel_connector->panel,
-			      IS_ERR(edid) ? NULL : edid);
+			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
 
 	intel_panel_add_edid_fixed_modes(intel_connector,
 					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 1ae09431f53a..db33a0ccd7ee 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2340,7 +2340,7 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
 	intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
 	intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
 
-	kfree(to_intel_connector(connector)->detect_edid);
+	drm_edid_free(to_intel_connector(connector)->detect_edid);
 	to_intel_connector(connector)->detect_edid = NULL;
 }
 
@@ -2407,7 +2407,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
 	intel_wakeref_t wakeref;
-	struct edid *edid;
+	const struct drm_edid *drm_edid;
+	const struct edid *edid;
 	bool connected = false;
 	struct i2c_adapter *i2c;
 
@@ -2415,21 +2416,24 @@ intel_hdmi_set_edid(struct drm_connector *connector)
 
 	i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
 
-	edid = drm_get_edid(connector, i2c);
+	drm_edid = drm_edid_read_ddc(connector, i2c);
 
-	if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
+	if (!drm_edid && !intel_gmbus_is_forced_bit(i2c)) {
 		drm_dbg_kms(&dev_priv->drm,
 			    "HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");
 		intel_gmbus_force_bit(i2c, true);
-		edid = drm_get_edid(connector, i2c);
+		drm_edid = drm_edid_read_ddc(connector, i2c);
 		intel_gmbus_force_bit(i2c, false);
 	}
 
-	intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
+	intel_hdmi_dp_dual_mode_detect(connector, drm_edid != NULL);
 
 	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
 
-	to_intel_connector(connector)->detect_edid = edid;
+	to_intel_connector(connector)->detect_edid = drm_edid;
+
+	/* FIXME: Get rid of drm_edid_raw() */
+	edid = drm_edid_raw(drm_edid);
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
 		intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
@@ -2501,13 +2505,11 @@ intel_hdmi_force(struct drm_connector *connector)
 
 static int intel_hdmi_get_modes(struct drm_connector *connector)
 {
-	struct edid *edid;
+	const struct drm_edid *drm_edid;
 
-	edid = to_intel_connector(connector)->detect_edid;
-	if (edid == NULL)
-		return 0;
+	drm_edid = to_intel_connector(connector)->detect_edid;
 
-	return intel_connector_update_modes(connector, edid);
+	return drm_edid_connector_update(connector, drm_edid);
 }
 
 static struct i2c_adapter *
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
index e55802b45461..d4389054bf59 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.c
+++ b/drivers/gpu/drm/i915/display/intel_lvds.c
@@ -479,7 +479,7 @@ static int intel_lvds_get_modes(struct drm_connector *connector)
 
 	/* use cached edid if we have one */
 	if (!IS_ERR_OR_NULL(intel_connector->edid))
-		return drm_add_edid_modes(connector, intel_connector->edid);
+		return drm_edid_connector_update(connector, intel_connector->edid);
 
 	return intel_panel_get_modes(intel_connector);
 }
@@ -829,7 +829,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
 	struct intel_connector *intel_connector;
 	struct drm_connector *connector;
 	struct drm_encoder *encoder;
-	struct edid *edid;
+	const struct drm_edid *drm_edid;
 	i915_reg_t lvds_reg;
 	u32 lvds;
 	u8 pin;
@@ -948,27 +948,30 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
 	 * preferred mode is the right one.
 	 */
 	mutex_lock(&dev->mode_config.mutex);
-	if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC)
+	if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) {
+		const struct edid *edid;
+
+		/* FIXME: Make drm_get_edid_switcheroo() return drm_edid */
 		edid = drm_get_edid_switcheroo(connector,
-				    intel_gmbus_get_adapter(dev_priv, pin));
-	else
-		edid = drm_get_edid(connector,
-				    intel_gmbus_get_adapter(dev_priv, pin));
-	if (edid) {
-		if (drm_add_edid_modes(connector, edid)) {
-			drm_connector_update_edid_property(connector,
-								edid);
-		} else {
-			kfree(edid);
-			edid = ERR_PTR(-EINVAL);
+					       intel_gmbus_get_adapter(dev_priv, pin));
+		if (edid)
+			drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) * EDID_LENGTH);
+	} else {
+		drm_edid = drm_edid_read_ddc(connector,
+					     intel_gmbus_get_adapter(dev_priv, pin));
+	}
+	if (drm_edid) {
+		if (!drm_edid_connector_update(connector, drm_edid)) {
+			drm_edid_free(drm_edid);
+			drm_edid = ERR_PTR(-EINVAL);
 		}
 	} else {
-		edid = ERR_PTR(-ENOENT);
+		drm_edid = ERR_PTR(-ENOENT);
 	}
-	intel_connector->edid = edid;
+	intel_connector->edid = drm_edid;
 
 	intel_bios_init_panel(dev_priv, &intel_connector->panel,
-			      IS_ERR(edid) ? NULL : edid);
+			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
 
 	/* Try EDID first */
 	intel_panel_add_edid_fixed_modes(intel_connector,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 11/15] drm/i915/bios: convert intel_bios_init_panel() to drm_edid
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Try to use struct drm_edid where possible, even if having to fall back
to looking into struct edid down low via drm_edid_raw().

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bios.c | 23 ++++++++++++-----------
 drivers/gpu/drm/i915/display/intel_bios.h |  4 ++--
 drivers/gpu/drm/i915/display/intel_dp.c   |  2 +-
 drivers/gpu/drm/i915/display/intel_lvds.c |  2 +-
 4 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index c42b9e7d0dce..be0b4264d526 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -604,13 +604,13 @@ get_lfp_data_tail(const struct bdb_lvds_lfp_data *data,
 }
 
 static int opregion_get_panel_type(struct drm_i915_private *i915,
-				   const struct edid *edid)
+				   const struct drm_edid *drm_edid)
 {
 	return intel_opregion_get_panel_type(i915);
 }
 
 static int vbt_get_panel_type(struct drm_i915_private *i915,
-			      const struct edid *edid)
+			      const struct drm_edid *drm_edid)
 {
 	const struct bdb_lvds_options *lvds_options;
 
@@ -629,12 +629,13 @@ static int vbt_get_panel_type(struct drm_i915_private *i915,
 }
 
 static int pnpid_get_panel_type(struct drm_i915_private *i915,
-				const struct edid *edid)
+				const struct drm_edid *drm_edid)
 {
 	const struct bdb_lvds_lfp_data *data;
 	const struct bdb_lvds_lfp_data_ptrs *ptrs;
 	const struct lvds_pnp_id *edid_id;
 	struct lvds_pnp_id edid_id_nodate;
+	const struct edid *edid = drm_edid_raw(drm_edid); /* FIXME */
 	int i, best = -1;
 
 	if (!edid)
@@ -675,7 +676,7 @@ static int pnpid_get_panel_type(struct drm_i915_private *i915,
 }
 
 static int fallback_get_panel_type(struct drm_i915_private *i915,
-				   const struct edid *edid)
+				   const struct drm_edid *drm_edid)
 {
 	return 0;
 }
@@ -688,12 +689,12 @@ enum panel_type {
 };
 
 static int get_panel_type(struct drm_i915_private *i915,
-			  const struct edid *edid)
+			  const struct drm_edid *drm_edid)
 {
 	struct {
 		const char *name;
 		int (*get_panel_type)(struct drm_i915_private *i915,
-				      const struct edid *edid);
+				      const struct drm_edid *drm_edid);
 		int panel_type;
 	} panel_types[] = {
 		[PANEL_TYPE_OPREGION] = {
@@ -716,7 +717,7 @@ static int get_panel_type(struct drm_i915_private *i915,
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(panel_types); i++) {
-		panel_types[i].panel_type = panel_types[i].get_panel_type(i915, edid);
+		panel_types[i].panel_type = panel_types[i].get_panel_type(i915, drm_edid);
 
 		drm_WARN_ON(&i915->drm, panel_types[i].panel_type > 0xf &&
 			    panel_types[i].panel_type != 0xff);
@@ -747,7 +748,7 @@ static int get_panel_type(struct drm_i915_private *i915,
 static void
 parse_panel_options(struct drm_i915_private *i915,
 		    struct intel_panel *panel,
-		    const struct edid *edid)
+		    const struct drm_edid *drm_edid)
 {
 	const struct bdb_lvds_options *lvds_options;
 	int panel_type;
@@ -759,7 +760,7 @@ parse_panel_options(struct drm_i915_private *i915,
 
 	panel->vbt.lvds_dither = lvds_options->pixel_dither;
 
-	panel_type = get_panel_type(i915, edid);
+	panel_type = get_panel_type(i915, drm_edid);
 
 	panel->vbt.panel_type = panel_type;
 
@@ -3092,11 +3093,11 @@ void intel_bios_init(struct drm_i915_private *i915)
 
 void intel_bios_init_panel(struct drm_i915_private *i915,
 			   struct intel_panel *panel,
-			   const struct edid *edid)
+			   const struct drm_edid *drm_edid)
 {
 	init_vbt_panel_defaults(panel);
 
-	parse_panel_options(i915, panel, edid);
+	parse_panel_options(i915, panel, drm_edid);
 	parse_generic_dtd(i915, panel);
 	parse_lfp_data(i915, panel);
 	parse_lfp_backlight(i915, panel);
diff --git a/drivers/gpu/drm/i915/display/intel_bios.h b/drivers/gpu/drm/i915/display/intel_bios.h
index b112200ae0a0..7bcc818e8d80 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.h
+++ b/drivers/gpu/drm/i915/display/intel_bios.h
@@ -32,8 +32,8 @@
 
 #include <linux/types.h>
 
+struct drm_edid;
 struct drm_i915_private;
-struct edid;
 struct intel_bios_encoder_data;
 struct intel_crtc_state;
 struct intel_encoder;
@@ -234,7 +234,7 @@ struct mipi_pps_data {
 void intel_bios_init(struct drm_i915_private *dev_priv);
 void intel_bios_init_panel(struct drm_i915_private *dev_priv,
 			   struct intel_panel *panel,
-			   const struct edid *edid);
+			   const struct drm_edid *drm_edid);
 void intel_bios_fini_panel(struct intel_panel *panel);
 void intel_bios_driver_remove(struct drm_i915_private *dev_priv);
 bool intel_bios_is_valid_vbt(const void *buf, size_t size);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 64b6481225f1..2f47f1e7607b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5217,7 +5217,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 	intel_connector->edid = drm_edid;
 
 	intel_bios_init_panel(dev_priv, &intel_connector->panel,
-			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
+			      IS_ERR(drm_edid) ? NULL : drm_edid);
 
 	intel_panel_add_edid_fixed_modes(intel_connector,
 					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
index d4389054bf59..ed5fceb93952 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.c
+++ b/drivers/gpu/drm/i915/display/intel_lvds.c
@@ -971,7 +971,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
 	intel_connector->edid = drm_edid;
 
 	intel_bios_init_panel(dev_priv, &intel_connector->panel,
-			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
+			      IS_ERR(drm_edid) ? NULL : drm_edid);
 
 	/* Try EDID first */
 	intel_panel_add_edid_fixed_modes(intel_connector,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 11/15] drm/i915/bios: convert intel_bios_init_panel() to drm_edid
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Try to use struct drm_edid where possible, even if having to fall back
to looking into struct edid down low via drm_edid_raw().

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bios.c | 23 ++++++++++++-----------
 drivers/gpu/drm/i915/display/intel_bios.h |  4 ++--
 drivers/gpu/drm/i915/display/intel_dp.c   |  2 +-
 drivers/gpu/drm/i915/display/intel_lvds.c |  2 +-
 4 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index c42b9e7d0dce..be0b4264d526 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -604,13 +604,13 @@ get_lfp_data_tail(const struct bdb_lvds_lfp_data *data,
 }
 
 static int opregion_get_panel_type(struct drm_i915_private *i915,
-				   const struct edid *edid)
+				   const struct drm_edid *drm_edid)
 {
 	return intel_opregion_get_panel_type(i915);
 }
 
 static int vbt_get_panel_type(struct drm_i915_private *i915,
-			      const struct edid *edid)
+			      const struct drm_edid *drm_edid)
 {
 	const struct bdb_lvds_options *lvds_options;
 
@@ -629,12 +629,13 @@ static int vbt_get_panel_type(struct drm_i915_private *i915,
 }
 
 static int pnpid_get_panel_type(struct drm_i915_private *i915,
-				const struct edid *edid)
+				const struct drm_edid *drm_edid)
 {
 	const struct bdb_lvds_lfp_data *data;
 	const struct bdb_lvds_lfp_data_ptrs *ptrs;
 	const struct lvds_pnp_id *edid_id;
 	struct lvds_pnp_id edid_id_nodate;
+	const struct edid *edid = drm_edid_raw(drm_edid); /* FIXME */
 	int i, best = -1;
 
 	if (!edid)
@@ -675,7 +676,7 @@ static int pnpid_get_panel_type(struct drm_i915_private *i915,
 }
 
 static int fallback_get_panel_type(struct drm_i915_private *i915,
-				   const struct edid *edid)
+				   const struct drm_edid *drm_edid)
 {
 	return 0;
 }
@@ -688,12 +689,12 @@ enum panel_type {
 };
 
 static int get_panel_type(struct drm_i915_private *i915,
-			  const struct edid *edid)
+			  const struct drm_edid *drm_edid)
 {
 	struct {
 		const char *name;
 		int (*get_panel_type)(struct drm_i915_private *i915,
-				      const struct edid *edid);
+				      const struct drm_edid *drm_edid);
 		int panel_type;
 	} panel_types[] = {
 		[PANEL_TYPE_OPREGION] = {
@@ -716,7 +717,7 @@ static int get_panel_type(struct drm_i915_private *i915,
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(panel_types); i++) {
-		panel_types[i].panel_type = panel_types[i].get_panel_type(i915, edid);
+		panel_types[i].panel_type = panel_types[i].get_panel_type(i915, drm_edid);
 
 		drm_WARN_ON(&i915->drm, panel_types[i].panel_type > 0xf &&
 			    panel_types[i].panel_type != 0xff);
@@ -747,7 +748,7 @@ static int get_panel_type(struct drm_i915_private *i915,
 static void
 parse_panel_options(struct drm_i915_private *i915,
 		    struct intel_panel *panel,
-		    const struct edid *edid)
+		    const struct drm_edid *drm_edid)
 {
 	const struct bdb_lvds_options *lvds_options;
 	int panel_type;
@@ -759,7 +760,7 @@ parse_panel_options(struct drm_i915_private *i915,
 
 	panel->vbt.lvds_dither = lvds_options->pixel_dither;
 
-	panel_type = get_panel_type(i915, edid);
+	panel_type = get_panel_type(i915, drm_edid);
 
 	panel->vbt.panel_type = panel_type;
 
@@ -3092,11 +3093,11 @@ void intel_bios_init(struct drm_i915_private *i915)
 
 void intel_bios_init_panel(struct drm_i915_private *i915,
 			   struct intel_panel *panel,
-			   const struct edid *edid)
+			   const struct drm_edid *drm_edid)
 {
 	init_vbt_panel_defaults(panel);
 
-	parse_panel_options(i915, panel, edid);
+	parse_panel_options(i915, panel, drm_edid);
 	parse_generic_dtd(i915, panel);
 	parse_lfp_data(i915, panel);
 	parse_lfp_backlight(i915, panel);
diff --git a/drivers/gpu/drm/i915/display/intel_bios.h b/drivers/gpu/drm/i915/display/intel_bios.h
index b112200ae0a0..7bcc818e8d80 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.h
+++ b/drivers/gpu/drm/i915/display/intel_bios.h
@@ -32,8 +32,8 @@
 
 #include <linux/types.h>
 
+struct drm_edid;
 struct drm_i915_private;
-struct edid;
 struct intel_bios_encoder_data;
 struct intel_crtc_state;
 struct intel_encoder;
@@ -234,7 +234,7 @@ struct mipi_pps_data {
 void intel_bios_init(struct drm_i915_private *dev_priv);
 void intel_bios_init_panel(struct drm_i915_private *dev_priv,
 			   struct intel_panel *panel,
-			   const struct edid *edid);
+			   const struct drm_edid *drm_edid);
 void intel_bios_fini_panel(struct intel_panel *panel);
 void intel_bios_driver_remove(struct drm_i915_private *dev_priv);
 bool intel_bios_is_valid_vbt(const void *buf, size_t size);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 64b6481225f1..2f47f1e7607b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5217,7 +5217,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 	intel_connector->edid = drm_edid;
 
 	intel_bios_init_panel(dev_priv, &intel_connector->panel,
-			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
+			      IS_ERR(drm_edid) ? NULL : drm_edid);
 
 	intel_panel_add_edid_fixed_modes(intel_connector,
 					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
index d4389054bf59..ed5fceb93952 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.c
+++ b/drivers/gpu/drm/i915/display/intel_lvds.c
@@ -971,7 +971,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
 	intel_connector->edid = drm_edid;
 
 	intel_bios_init_panel(dev_priv, &intel_connector->panel,
-			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
+			      IS_ERR(drm_edid) ? NULL : drm_edid);
 
 	/* Try EDID first */
 	intel_panel_add_edid_fixed_modes(intel_connector,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 12/15] drm/edid: do invalid block filtering in-place
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Rewrite edid_filter_invalid_blocks() to filter invalid blocks
in-place. The main motivation is to not rely on passed in information on
invalid block count or the allocation size, which will be helpful in
follow-up work on HF-EEODB.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 43 ++++++++++++++++++++------------------
 1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 4e788c5cbf25..77ec5b0e436d 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2020,33 +2020,37 @@ bool drm_edid_is_valid(struct edid *edid)
 }
 EXPORT_SYMBOL(drm_edid_is_valid);
 
-static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
-					       int invalid_blocks,
+static struct edid *edid_filter_invalid_blocks(struct edid *edid,
 					       size_t *alloc_size)
 {
-	struct edid *new, *dest_block;
-	int valid_extensions = edid->extensions - invalid_blocks;
-	int i;
+	struct edid *new;
+	int i, valid_blocks = 0;
 
-	*alloc_size = edid_size_by_blocks(valid_extensions + 1);
+	for (i = 0; i < edid_block_count(edid); i++) {
+		const void *src_block = edid_block_data(edid, i);
 
-	new = kmalloc(*alloc_size, GFP_KERNEL);
-	if (!new)
-		goto out;
+		if (edid_block_valid(src_block, i == 0)) {
+			void *dst_block = (void *)edid_block_data(edid, valid_blocks);
 
-	dest_block = new;
-	for (i = 0; i < edid_block_count(edid); i++) {
-		const void *block = edid_block_data(edid, i);
+			memmove(dst_block, src_block, EDID_LENGTH);
+			valid_blocks++;
+		}
+	}
 
-		if (edid_block_valid(block, i == 0))
-			memcpy(dest_block++, block, EDID_LENGTH);
+	/* We already trusted the base block to be valid here... */
+	if (WARN_ON(!valid_blocks)) {
+		kfree(edid);
+		return NULL;
 	}
 
-	new->extensions = valid_extensions;
-	new->checksum = edid_block_compute_checksum(new);
+	edid->extensions = valid_blocks - 1;
+	edid->checksum = edid_block_compute_checksum(edid);
 
-out:
-	kfree(edid);
+	*alloc_size = edid_size_by_blocks(valid_blocks);
+
+	new = krealloc(edid, *alloc_size, GFP_KERNEL);
+	if (!new)
+		kfree(edid);
 
 	return new;
 }
@@ -2290,8 +2294,7 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
 	if (invalid_blocks) {
 		connector_bad_edid(connector, edid, edid_block_count(edid));
 
-		edid = edid_filter_invalid_blocks(edid, invalid_blocks,
-						  &alloc_size);
+		edid = edid_filter_invalid_blocks(edid, &alloc_size);
 	}
 
 ok:
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 12/15] drm/edid: do invalid block filtering in-place
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Rewrite edid_filter_invalid_blocks() to filter invalid blocks
in-place. The main motivation is to not rely on passed in information on
invalid block count or the allocation size, which will be helpful in
follow-up work on HF-EEODB.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 43 ++++++++++++++++++++------------------
 1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 4e788c5cbf25..77ec5b0e436d 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2020,33 +2020,37 @@ bool drm_edid_is_valid(struct edid *edid)
 }
 EXPORT_SYMBOL(drm_edid_is_valid);
 
-static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
-					       int invalid_blocks,
+static struct edid *edid_filter_invalid_blocks(struct edid *edid,
 					       size_t *alloc_size)
 {
-	struct edid *new, *dest_block;
-	int valid_extensions = edid->extensions - invalid_blocks;
-	int i;
+	struct edid *new;
+	int i, valid_blocks = 0;
 
-	*alloc_size = edid_size_by_blocks(valid_extensions + 1);
+	for (i = 0; i < edid_block_count(edid); i++) {
+		const void *src_block = edid_block_data(edid, i);
 
-	new = kmalloc(*alloc_size, GFP_KERNEL);
-	if (!new)
-		goto out;
+		if (edid_block_valid(src_block, i == 0)) {
+			void *dst_block = (void *)edid_block_data(edid, valid_blocks);
 
-	dest_block = new;
-	for (i = 0; i < edid_block_count(edid); i++) {
-		const void *block = edid_block_data(edid, i);
+			memmove(dst_block, src_block, EDID_LENGTH);
+			valid_blocks++;
+		}
+	}
 
-		if (edid_block_valid(block, i == 0))
-			memcpy(dest_block++, block, EDID_LENGTH);
+	/* We already trusted the base block to be valid here... */
+	if (WARN_ON(!valid_blocks)) {
+		kfree(edid);
+		return NULL;
 	}
 
-	new->extensions = valid_extensions;
-	new->checksum = edid_block_compute_checksum(new);
+	edid->extensions = valid_blocks - 1;
+	edid->checksum = edid_block_compute_checksum(edid);
 
-out:
-	kfree(edid);
+	*alloc_size = edid_size_by_blocks(valid_blocks);
+
+	new = krealloc(edid, *alloc_size, GFP_KERNEL);
+	if (!new)
+		kfree(edid);
 
 	return new;
 }
@@ -2290,8 +2294,7 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
 	if (invalid_blocks) {
 		connector_bad_edid(connector, edid, edid_block_count(edid));
 
-		edid = edid_filter_invalid_blocks(edid, invalid_blocks,
-						  &alloc_size);
+		edid = edid_filter_invalid_blocks(edid, &alloc_size);
 	}
 
 ok:
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 13/15] drm/edid: add HF-EEODB support to EDID read and allocation
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

HDMI 2.1 section 10.3.6 defines an HDMI Forum EDID Extension Override
Data Block, which may contain a different extension count than the base
block claims. Add support for reading more EDID data if available. The
extra blocks aren't parsed yet, though.

Hard-coding the EEODB parsing instead of using the iterators we have is
a bit of a bummer, but we have to be able to do this on a partially
allocated EDID while reading it.

v2:
- Check for CEA Data Block Collection size (Ville)
- Amend commit message and comment about hard-coded parsing

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 89 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 77ec5b0e436d..5cac357e50b0 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1581,6 +1581,15 @@ static bool version_greater(const struct drm_edid *drm_edid,
 		(edid->version == version && edid->revision > revision);
 }
 
+static int edid_hfeeodb_extension_block_count(const struct edid *edid);
+
+static int edid_hfeeodb_block_count(const struct edid *edid)
+{
+	int eeodb = edid_hfeeodb_extension_block_count(edid);
+
+	return eeodb ? eeodb + 1 : 0;
+}
+
 static int edid_extension_block_count(const struct edid *edid)
 {
 	return edid->extensions;
@@ -2026,6 +2035,11 @@ static struct edid *edid_filter_invalid_blocks(struct edid *edid,
 	struct edid *new;
 	int i, valid_blocks = 0;
 
+	/*
+	 * Note: If the EDID uses HF-EEODB, but has invalid blocks, we'll revert
+	 * back to regular extension count here. We don't want to start
+	 * modifying the HF-EEODB extension too.
+	 */
 	for (i = 0; i < edid_block_count(edid); i++) {
 		const void *src_block = edid_block_data(edid, i);
 
@@ -2235,7 +2249,7 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
 				     size_t *size)
 {
 	enum edid_block_status status;
-	int i, invalid_blocks = 0;
+	int i, num_blocks, invalid_blocks = 0;
 	struct edid *edid, *new;
 	size_t alloc_size = EDID_LENGTH;
 
@@ -2277,7 +2291,8 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
 		goto fail;
 	edid = new;
 
-	for (i = 1; i < edid_block_count(edid); i++) {
+	num_blocks = edid_block_count(edid);
+	for (i = 1; i < num_blocks; i++) {
 		void *block = (void *)edid_block_data(edid, i);
 
 		status = edid_block_read(block, i, read_block, context);
@@ -2288,11 +2303,31 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
 			if (status == EDID_BLOCK_READ_FAIL)
 				goto fail;
 			invalid_blocks++;
+		} else if (i == 1) {
+			/*
+			 * If the first EDID extension is a CTA extension, and
+			 * the first Data Block is HF-EEODB, override the
+			 * extension block count.
+			 *
+			 * Note: HF-EEODB could specify a smaller extension
+			 * count too, but we can't risk allocating a smaller
+			 * amount.
+			 */
+			int eeodb = edid_hfeeodb_block_count(edid);
+
+			if (eeodb > num_blocks) {
+				num_blocks = eeodb;
+				alloc_size = edid_size_by_blocks(num_blocks);
+				new = krealloc(edid, alloc_size, GFP_KERNEL);
+				if (!new)
+					goto fail;
+				edid = new;
+			}
 		}
 	}
 
 	if (invalid_blocks) {
-		connector_bad_edid(connector, edid, edid_block_count(edid));
+		connector_bad_edid(connector, edid, num_blocks);
 
 		edid = edid_filter_invalid_blocks(edid, &alloc_size);
 	}
@@ -3825,6 +3860,7 @@ static int add_detailed_modes(struct drm_connector *connector,
 #define CTA_EXT_DB_HDR_STATIC_METADATA	6
 #define CTA_EXT_DB_420_VIDEO_DATA	14
 #define CTA_EXT_DB_420_VIDEO_CAP_MAP	15
+#define CTA_EXT_DB_HF_EEODB		0x78
 #define CTA_EXT_DB_HF_SCDB		0x79
 
 #define EDID_BASIC_AUDIO	(1 << 6)
@@ -4884,6 +4920,12 @@ static bool cea_db_is_hdmi_forum_vsdb(const struct cea_db *db)
 		cea_db_payload_len(db) >= 7;
 }
 
+static bool cea_db_is_hdmi_forum_eeodb(const void *db)
+{
+	return cea_db_is_extended_tag(db, CTA_EXT_DB_HF_EEODB) &&
+		cea_db_payload_len(db) >= 2;
+}
+
 static bool cea_db_is_microsoft_vsdb(const struct cea_db *db)
 {
 	return cea_db_is_vendor(db, MICROSOFT_IEEE_OUI) &&
@@ -4918,6 +4960,47 @@ static bool cea_db_is_hdmi_hdr_metadata_block(const struct cea_db *db)
 		cea_db_payload_len(db) >= 3;
 }
 
+/*
+ * Get the HF-EEODB override extension block count from EDID.
+ *
+ * The passed in EDID may be partially read, as long as it has at least two
+ * blocks (base block and one extension block) if EDID extension count is > 0.
+ *
+ * Note that this is *not* how you should parse CTA Data Blocks in general; this
+ * is only to handle partially read EDIDs. Normally, use the CTA Data Block
+ * iterators instead.
+ *
+ * References:
+ * - HDMI 2.1 section 10.3.6 HDMI Forum EDID Extension Override Data Block
+ */
+static int edid_hfeeodb_extension_block_count(const struct edid *edid)
+{
+	const u8 *cta;
+
+	/* No extensions according to base block, no HF-EEODB. */
+	if (!edid_extension_block_count(edid))
+		return 0;
+
+	/* HF-EEODB is always in the first EDID extension block only */
+	cta = edid_extension_block_data(edid, 0);
+	if (edid_block_tag(cta) != CEA_EXT || cea_revision(cta) < 3)
+		return 0;
+
+	/* Need to have the data block collection, and at least 3 bytes. */
+	if (cea_db_collection_size(cta) < 3)
+		return 0;
+
+	/*
+	 * Sinks that include the HF-EEODB in their E-EDID shall include one and
+	 * only one instance of the HF-EEODB in the E-EDID, occupying bytes 4
+	 * through 6 of Block 1 of the E-EDID.
+	 */
+	if (!cea_db_is_hdmi_forum_eeodb(&cta[4]))
+		return 0;
+
+	return cta[4 + 2];
+}
+
 static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
 				      const u8 *db)
 {
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 13/15] drm/edid: add HF-EEODB support to EDID read and allocation
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

HDMI 2.1 section 10.3.6 defines an HDMI Forum EDID Extension Override
Data Block, which may contain a different extension count than the base
block claims. Add support for reading more EDID data if available. The
extra blocks aren't parsed yet, though.

Hard-coding the EEODB parsing instead of using the iterators we have is
a bit of a bummer, but we have to be able to do this on a partially
allocated EDID while reading it.

v2:
- Check for CEA Data Block Collection size (Ville)
- Amend commit message and comment about hard-coded parsing

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 89 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 77ec5b0e436d..5cac357e50b0 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1581,6 +1581,15 @@ static bool version_greater(const struct drm_edid *drm_edid,
 		(edid->version == version && edid->revision > revision);
 }
 
+static int edid_hfeeodb_extension_block_count(const struct edid *edid);
+
+static int edid_hfeeodb_block_count(const struct edid *edid)
+{
+	int eeodb = edid_hfeeodb_extension_block_count(edid);
+
+	return eeodb ? eeodb + 1 : 0;
+}
+
 static int edid_extension_block_count(const struct edid *edid)
 {
 	return edid->extensions;
@@ -2026,6 +2035,11 @@ static struct edid *edid_filter_invalid_blocks(struct edid *edid,
 	struct edid *new;
 	int i, valid_blocks = 0;
 
+	/*
+	 * Note: If the EDID uses HF-EEODB, but has invalid blocks, we'll revert
+	 * back to regular extension count here. We don't want to start
+	 * modifying the HF-EEODB extension too.
+	 */
 	for (i = 0; i < edid_block_count(edid); i++) {
 		const void *src_block = edid_block_data(edid, i);
 
@@ -2235,7 +2249,7 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
 				     size_t *size)
 {
 	enum edid_block_status status;
-	int i, invalid_blocks = 0;
+	int i, num_blocks, invalid_blocks = 0;
 	struct edid *edid, *new;
 	size_t alloc_size = EDID_LENGTH;
 
@@ -2277,7 +2291,8 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
 		goto fail;
 	edid = new;
 
-	for (i = 1; i < edid_block_count(edid); i++) {
+	num_blocks = edid_block_count(edid);
+	for (i = 1; i < num_blocks; i++) {
 		void *block = (void *)edid_block_data(edid, i);
 
 		status = edid_block_read(block, i, read_block, context);
@@ -2288,11 +2303,31 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
 			if (status == EDID_BLOCK_READ_FAIL)
 				goto fail;
 			invalid_blocks++;
+		} else if (i == 1) {
+			/*
+			 * If the first EDID extension is a CTA extension, and
+			 * the first Data Block is HF-EEODB, override the
+			 * extension block count.
+			 *
+			 * Note: HF-EEODB could specify a smaller extension
+			 * count too, but we can't risk allocating a smaller
+			 * amount.
+			 */
+			int eeodb = edid_hfeeodb_block_count(edid);
+
+			if (eeodb > num_blocks) {
+				num_blocks = eeodb;
+				alloc_size = edid_size_by_blocks(num_blocks);
+				new = krealloc(edid, alloc_size, GFP_KERNEL);
+				if (!new)
+					goto fail;
+				edid = new;
+			}
 		}
 	}
 
 	if (invalid_blocks) {
-		connector_bad_edid(connector, edid, edid_block_count(edid));
+		connector_bad_edid(connector, edid, num_blocks);
 
 		edid = edid_filter_invalid_blocks(edid, &alloc_size);
 	}
@@ -3825,6 +3860,7 @@ static int add_detailed_modes(struct drm_connector *connector,
 #define CTA_EXT_DB_HDR_STATIC_METADATA	6
 #define CTA_EXT_DB_420_VIDEO_DATA	14
 #define CTA_EXT_DB_420_VIDEO_CAP_MAP	15
+#define CTA_EXT_DB_HF_EEODB		0x78
 #define CTA_EXT_DB_HF_SCDB		0x79
 
 #define EDID_BASIC_AUDIO	(1 << 6)
@@ -4884,6 +4920,12 @@ static bool cea_db_is_hdmi_forum_vsdb(const struct cea_db *db)
 		cea_db_payload_len(db) >= 7;
 }
 
+static bool cea_db_is_hdmi_forum_eeodb(const void *db)
+{
+	return cea_db_is_extended_tag(db, CTA_EXT_DB_HF_EEODB) &&
+		cea_db_payload_len(db) >= 2;
+}
+
 static bool cea_db_is_microsoft_vsdb(const struct cea_db *db)
 {
 	return cea_db_is_vendor(db, MICROSOFT_IEEE_OUI) &&
@@ -4918,6 +4960,47 @@ static bool cea_db_is_hdmi_hdr_metadata_block(const struct cea_db *db)
 		cea_db_payload_len(db) >= 3;
 }
 
+/*
+ * Get the HF-EEODB override extension block count from EDID.
+ *
+ * The passed in EDID may be partially read, as long as it has at least two
+ * blocks (base block and one extension block) if EDID extension count is > 0.
+ *
+ * Note that this is *not* how you should parse CTA Data Blocks in general; this
+ * is only to handle partially read EDIDs. Normally, use the CTA Data Block
+ * iterators instead.
+ *
+ * References:
+ * - HDMI 2.1 section 10.3.6 HDMI Forum EDID Extension Override Data Block
+ */
+static int edid_hfeeodb_extension_block_count(const struct edid *edid)
+{
+	const u8 *cta;
+
+	/* No extensions according to base block, no HF-EEODB. */
+	if (!edid_extension_block_count(edid))
+		return 0;
+
+	/* HF-EEODB is always in the first EDID extension block only */
+	cta = edid_extension_block_data(edid, 0);
+	if (edid_block_tag(cta) != CEA_EXT || cea_revision(cta) < 3)
+		return 0;
+
+	/* Need to have the data block collection, and at least 3 bytes. */
+	if (cea_db_collection_size(cta) < 3)
+		return 0;
+
+	/*
+	 * Sinks that include the HF-EEODB in their E-EDID shall include one and
+	 * only one instance of the HF-EEODB in the E-EDID, occupying bytes 4
+	 * through 6 of Block 1 of the E-EDID.
+	 */
+	if (!cea_db_is_hdmi_forum_eeodb(&cta[4]))
+		return 0;
+
+	return cta[4 + 2];
+}
+
 static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
 				      const u8 *db)
 {
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 14/15] drm/edid: take HF-EEODB extension count into account
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Take the HF-EEODB extension count override into account.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5cac357e50b0..b7b1f0639115 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1629,6 +1629,19 @@ static int drm_edid_block_count(const struct drm_edid *drm_edid)
 	/* Starting point */
 	num_blocks = edid_block_count(drm_edid->edid);
 
+	/* HF-EEODB override */
+	if (drm_edid->size >= edid_size_by_blocks(2)) {
+		int eeodb;
+
+		/*
+		 * Note: HF-EEODB may specify a smaller extension count than the
+		 * regular one. Unlike in buffer allocation, here we can use it.
+		 */
+		eeodb = edid_hfeeodb_block_count(drm_edid->edid);
+		if (eeodb)
+			num_blocks = eeodb;
+	}
+
 	/* Limit by allocated size */
 	num_blocks = min(num_blocks, (int)drm_edid->size / EDID_LENGTH);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 14/15] drm/edid: take HF-EEODB extension count into account
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Take the HF-EEODB extension count override into account.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5cac357e50b0..b7b1f0639115 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1629,6 +1629,19 @@ static int drm_edid_block_count(const struct drm_edid *drm_edid)
 	/* Starting point */
 	num_blocks = edid_block_count(drm_edid->edid);
 
+	/* HF-EEODB override */
+	if (drm_edid->size >= edid_size_by_blocks(2)) {
+		int eeodb;
+
+		/*
+		 * Note: HF-EEODB may specify a smaller extension count than the
+		 * regular one. Unlike in buffer allocation, here we can use it.
+		 */
+		eeodb = edid_hfeeodb_block_count(drm_edid->edid);
+		if (eeodb)
+			num_blocks = eeodb;
+	}
+
 	/* Limit by allocated size */
 	num_blocks = min(num_blocks, (int)drm_edid->size / EDID_LENGTH);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 15/15] drm/todo: add entry for converting the subsystem to struct drm_edid
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-08  7:50   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, David Airlie, intel-gfx

We need to stop duplicating EDID validation and parsing all over the
subsystem in various broken ways.

v2: Update to reflect drm_connector_helper_get_modes()

Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 Documentation/gpu/todo.rst | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 513b20ccef1e..04ef31e3405f 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -480,6 +480,31 @@ Contact: Thomas Zimmermann <tzimmermann@suse.de>
 
 Level: Starter
 
+Convert core and drivers from struct edid to struct drm_edid
+------------------------------------------------------------
+
+Go through all drivers and drm core KMS code to convert all raw struct edid
+usage to the opaque struct drm_edid. See commit e4ccf9a777d3 ("drm/edid: add
+struct drm_edid container") for rationale.
+
+Convert drm_get_edid() and drm_do_get_edid() usage to drm_edid_read(),
+drm_edid_read_ddc(), or drm_edid_read_custom().
+
+Convert drm_add_edid_modes() and drm_connector_update_edid_property() to
+drm_edid_connector_update(). See drm_connector_helper_get_modes() for reference
+for converting the ->get_modes() hooks.
+
+Convert decentralized, direct struct edid parsing to centralized parsing in
+drm_edid.c. Prefer one-time parsing as part of drm_edid_connector_update() and
+storing the result in drm_connector->display_info over adding individual,
+exported parser functions.
+
+During the transition period, it may be necessary to use drm_edid_raw(), but do
+use it sparingly. Eventually, all of them need to go.
+
+Contact: Jani Nikula <jani.nikula@intel.com>
+
+Level: Intermediate
 
 Core refactorings
 =================
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] [PATCH v2 15/15] drm/todo: add entry for converting the subsystem to struct drm_edid
@ 2022-06-08  7:50   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-08  7:50 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, David Airlie, intel-gfx

We need to stop duplicating EDID validation and parsing all over the
subsystem in various broken ways.

v2: Update to reflect drm_connector_helper_get_modes()

Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 Documentation/gpu/todo.rst | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 513b20ccef1e..04ef31e3405f 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -480,6 +480,31 @@ Contact: Thomas Zimmermann <tzimmermann@suse.de>
 
 Level: Starter
 
+Convert core and drivers from struct edid to struct drm_edid
+------------------------------------------------------------
+
+Go through all drivers and drm core KMS code to convert all raw struct edid
+usage to the opaque struct drm_edid. See commit e4ccf9a777d3 ("drm/edid: add
+struct drm_edid container") for rationale.
+
+Convert drm_get_edid() and drm_do_get_edid() usage to drm_edid_read(),
+drm_edid_read_ddc(), or drm_edid_read_custom().
+
+Convert drm_add_edid_modes() and drm_connector_update_edid_property() to
+drm_edid_connector_update(). See drm_connector_helper_get_modes() for reference
+for converting the ->get_modes() hooks.
+
+Convert decentralized, direct struct edid parsing to centralized parsing in
+drm_edid.c. Prefer one-time parsing as part of drm_edid_connector_update() and
+storing the result in drm_connector->display_info over adding individual,
+exported parser functions.
+
+During the transition period, it may be necessary to use drm_edid_raw(), but do
+use it sparingly. Eventually, all of them need to go.
+
+Contact: Jani Nikula <jani.nikula@intel.com>
+
+Level: Intermediate
 
 Core refactorings
 =================
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/edid: expand on struct drm_edid usage (rev3)
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
                   ` (15 preceding siblings ...)
  (?)
@ 2022-06-08  8:30 ` Patchwork
  -1 siblings, 0 replies; 68+ messages in thread
From: Patchwork @ 2022-06-08  8:30 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

== Series Details ==

Series: drm/edid: expand on struct drm_edid usage (rev3)
URL   : https://patchwork.freedesktop.org/series/104309/
State : warning

== Summary ==

Error: dim checkpatch failed
cbd046eb3347 drm/edid: fix CTA data block collection size for CTA version 3
57c0da5db445 drm/edid: abstract cea data block collection size
8a18cc54c495 drm/edid: add block count and data helper functions for drm_edid
339317982780 drm/edid: keep track of alloc size in drm_do_get_edid()
20f7e6373c64 drm/edid: add new interfaces around struct drm_edid
-:320: WARNING:LONG_LINE: line length of 118 exceeds 100 columns
#320: FILE: include/drm/drm_edid.h:604:
+					    int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),

total: 0 errors, 1 warnings, 0 checks, 291 lines checked
7bb7d4b16112 drm/edid: add drm_edid_connector_update()
923ccd9981fa drm/probe-helper: abstract .get_modes() connector helper call
05977fe383c7 drm/probe-helper: add drm_connector_helper_get_modes()
-:44: WARNING:TYPO_SPELLING: 'succesfully' may be misspelled - perhaps 'successfully'?
#44: FILE: drivers/gpu/drm/drm_probe_helper.c:1075:
+	 * succesfully, fill in the connector information derived from the
 	   ^^^^^^^^^^^

total: 0 errors, 1 warnings, 0 checks, 43 lines checked
b6e91df12a6b drm/edid: add drm_edid_raw() to access the raw EDID data
e76cd9721c85 drm/i915/edid: convert DP, HDMI and LVDS to drm_edid
-:260: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "drm_edid"
#260: FILE: drivers/gpu/drm/i915/display/intel_hdmi.c:2429:
+	intel_hdmi_dp_dual_mode_detect(connector, drm_edid != NULL);

total: 0 errors, 0 warnings, 1 checks, 308 lines checked
65d8f4dc11db drm/i915/bios: convert intel_bios_init_panel() to drm_edid
e789e7b1cbc0 drm/edid: do invalid block filtering in-place
bfe12401468e drm/edid: add HF-EEODB support to EDID read and allocation
60e4c8b9d502 drm/edid: take HF-EEODB extension count into account
6707dfd9931f drm/todo: add entry for converting the subsystem to struct drm_edid



^ permalink raw reply	[flat|nested] 68+ messages in thread

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/edid: expand on struct drm_edid usage (rev3)
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
                   ` (16 preceding siblings ...)
  (?)
@ 2022-06-08  8:30 ` Patchwork
  -1 siblings, 0 replies; 68+ messages in thread
From: Patchwork @ 2022-06-08  8:30 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

== Series Details ==

Series: drm/edid: expand on struct drm_edid usage (rev3)
URL   : https://patchwork.freedesktop.org/series/104309/
State : warning

== Summary ==

Error: dim sparse failed
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
-
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1449:25: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1449:25:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1449:25:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1450:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1450:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1450:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1509:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1509:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1509:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:353:16: error: incompatible types in comparison expression (different type sizes):
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:353:16:    unsigned long *
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:353:16:    unsigned long long *
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:5786:9: error: incompatible types in conditional expression (different base types):
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:5786:9:    int
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:5786:9:    void
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:295:25: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:295:25:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:295:25:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:296:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:296:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:296:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:345:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:345:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:345:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:596:23: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:596:23:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:596:23:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:598:25: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:598:25:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:598:25:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:314:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:318:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/smu10_smumgr.c:142:9: error: incompatible types in conditional expression (different base types):
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/smu10_smumgr.c:142:9:    int
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/smu10_smumgr.c:142:9:    void
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/vega10_smumgr.c:63:9: error: incompatible types in conditional expression (different base types):
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/vega10_smumgr.c:63:9:    int
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/vega10_smumgr.c:63:9:    void
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/vega12_smumgr.c:71:9: error: incompatible types in conditional expression (different base types):
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/vega12_smumgr.c:71:9:    int
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/vega12_smumgr.c:71:9:    void
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/vega20_smumgr.c:195:9: error: incompatible types in conditional expression (different base types):
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/vega20_smumgr.c:195:9:    int
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/vega20_smumgr.c:195:9:    void
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/vega20_smumgr.c:309:9: error: incompatible types in conditional expression (different base types):
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/vega20_smumgr.c:309:9:    int
+drivers/gpu/drm/amd/amdgpu/../pm/powerplay/smumgr/vega20_smumgr.c:309:9:    void
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/amdgpu_smu.c:1085:9: error: incompatible types in conditional expression (different base types):
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/amdgpu_smu.c:1085:9:    int
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/amdgpu_smu.c:1085:9:    void
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/amdgpu_smu.c:701:17: error: incompatible types in conditional expression (different base types):
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/amdgpu_smu.c:701:17:    int
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/amdgpu_smu.c:701:17:    void
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/amdgpu_smu.c:949:9: error: incompatible types in conditional expression (different base types):
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/amdgpu_smu.c:949:9:    int
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/amdgpu_smu.c:949:9:    void
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/amdgpu_smu.c:981:9: error: incompatible types in conditional expression (different base types):
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/amdgpu_smu.c:981:9:    int
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/amdgpu_smu.c:981:9:    void
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu_cmn.c:923:17: error: incompatible types in conditional expression (different base types):
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu_cmn.c:923:17:    int
+drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu_cmn.c:923:17:    void
+drivers/gpu/drm/ast/ast_dp.c:278:66: warning: cast truncates bits from constant value (ffffffffffffff00 becomes 0)
+drivers/gpu/drm/ast/ast_dp.c:280:66: warning: cast truncates bits from constant value (ffffffffffffff00 becomes 0)
+drivers/gpu/drm/ast/ast_dp.c:281:66: warning: cast truncates bits from constant value (ffffffffffffff00 becomes 0)
+drivers/gpu/drm/ast/ast_dp.c:37:46: warning: cast truncates bits from constant value (ffffffffffffff00 becomes 0)
+drivers/gpu/drm/ast/ast_drv.c:42:5: warning: symbol 'ast_modeset' was not declared. Should it be static?
+drivers/gpu/drm/ast/ast_mode.c:678:16:    expected unsigned char [noderef] [usertype] __iomem *dstxor
+drivers/gpu/drm/ast/ast_mode.c:678:16:    got unsigned char [usertype] *
+drivers/gpu/drm/ast/ast_mode.c:678:16: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/ast/ast_mode.c:678:19: warning: cast removes address space '__iomem' of expression
+drivers/gpu/drm/drm_drv.c:426:6: warning: context imbalance in 'drm_dev_enter' - different lock contexts for basic block
+drivers/gpu/drm/gma500/framebuffer.c:268:9:    expected void *
+drivers/gpu/drm/gma500/framebuffer.c:268:9:    expected void const *
+drivers/gpu/drm/gma500/framebuffer.c:268:9:    expected void const *
+drivers/gpu/drm/gma500/framebuffer.c:268:9:    got unsigned char [noderef] [usertype] __iomem *
+drivers/gpu/drm/gma500/framebuffer.c:268:9:    got unsigned char [noderef] [usertype] __iomem *
+drivers/gpu/drm/gma500/framebuffer.c:268:9:    got unsigned char [noderef] [usertype] __iomem *
+drivers/gpu/drm/gma500/framebuffer.c:268:9: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/gma500/framebuffer.c:268:9: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/gma500/framebuffer.c:268:9: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/gma500/gma_display.c:402:25:    expected void *tmp_dst
+drivers/gpu/drm/gma500/gma_display.c:402:25:    got unsigned char [noderef] [usertype] __iomem *
+drivers/gpu/drm/gma500/gma_display.c:402:25: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/gma500/intel_bios.c:548:42:    expected void const *const p
+drivers/gpu/drm/gma500/intel_bios.c:548:42:    got unsigned char [noderef] [usertype] __iomem *
+drivers/gpu/drm/gma500/intel_bios.c:548:42: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/gma500/intel_bios.c:549:40: warning: cast removes address space '__iomem' of expression
+drivers/gpu/drm/gma500/intel_bios.c:559:24: warning: cast removes address space '__iomem' of expression
+drivers/gpu/drm/gma500/mmu.c:306:26: warning: context imbalance in 'psb_mmu_pt_alloc_map_lock' - wrong count at exit
+drivers/gpu/drm/gma500/mmu.c:346:26: warning: context imbalance in 'psb_mmu_pt_map_lock' - wrong count at exit
+drivers/gpu/drm/gma500/mmu.c:379:28: warning: context imbalance in 'psb_mmu_pt_unmap_unlock' - unexpected unlock
+drivers/gpu/drm/gma500/oaktrail_crtc.c:661:30: warning: symbol 'mrst_clock_funcs' was not declared. Should it be static?
+drivers/gpu/drm/gma500/opregion.c:298:25:    expected void volatile [noderef] __iomem *addr
+drivers/gpu/drm/gma500/opregion.c:298:25:    got struct opregion_header *header
+drivers/gpu/drm/gma500/opregion.c:298:25: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/gma500/opregion.c:328:20:    expected void const *const p
+drivers/gpu/drm/gma500/opregion.c:328:20:    got void [noderef] __iomem *[assigned] base
+drivers/gpu/drm/gma500/opregion.c:328:20: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/gma500/opregion.c:334:26:    expected struct opregion_header *header
+drivers/gpu/drm/gma500/opregion.c:334:26:    got void [noderef] __iomem *[assigned] base
+drivers/gpu/drm/gma500/opregion.c:334:26: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/gma500/opregion.c:335:23:    expected void *vbt
+drivers/gpu/drm/gma500/opregion.c:335:23:    got void [noderef] __iomem *
+drivers/gpu/drm/gma500/opregion.c:335:23: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/gma500/opregion.c:342:32:    expected struct opregion_acpi *acpi
+drivers/gpu/drm/gma500/opregion.c:342:32:    got void [noderef] __iomem *
+drivers/gpu/drm/gma500/opregion.c:342:32: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/gma500/opregion.c:347:32:    expected struct opregion_asle *asle
+drivers/gpu/drm/gma500/opregion.c:347:32:    got void [noderef] __iomem *
+drivers/gpu/drm/gma500/opregion.c:347:32: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/gma500/psb_intel_display.c:434:30: warning: symbol 'psb_clock_funcs' was not declared. Should it be static?
+drivers/gpu/drm/i2c/tda998x_drv.c:1712:50:    expected restricted __be32 const [usertype] *p
+drivers/gpu/drm/i2c/tda998x_drv.c:1712:50:    got unsigned int const [usertype] *
+drivers/gpu/drm/i2c/tda998x_drv.c:1712:50: warning: incorrect type in argument 1 (different base types)
+drivers/gpu/drm/i2c/tda998x_drv.c:1713:52:    expected restricted __be32 const [usertype] *p
+drivers/gpu/drm/i2c/tda998x_drv.c:1713:52:    got unsigned int const [usertype] *
+drivers/gpu/drm/i2c/tda998x_drv.c:1713:52: warning: incorrect type in argument 1 (different base types)
+drivers/gpu/drm/mgag200/mgag200_drv.c:23:5: warning: symbol 'mgag200_modeset' was not declared. Should it be static?
+drivers/gpu/drm/nouveau/dispnv50/disp.c:135:34: warning: cast removes address space '__iomem' of expression
+drivers/gpu/drm/nouveau/dispnv50/disp.c:198:34: warning: cast removes address space '__iomem' of expression
+drivers/gpu/drm/nouveau/dispnv50/disp.c:204:27:    expected unsigned int [usertype] *cur
+drivers/gpu/drm/nouveau/dispnv50/disp.c:204:27:    got void [noderef] __iomem *ptr
+drivers/gpu/drm/nouveau/dispnv50/disp.c:204:27: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/nouveau/dispnv50/disp.c:217:19:    expected unsigned int [usertype] *bgn
+drivers/gpu/drm/nouveau/dispnv50/disp.c:217:19:    got void [noderef] __iomem *ptr
+drivers/gpu/drm/nouveau/dispnv50/disp.c:217:19: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/nouveau/dispnv50/disp.c:258:19:    expected unsigned int [usertype] *ptr
+drivers/gpu/drm/nouveau/dispnv50/disp.c:258:19:    got void [noderef] __iomem *ptr
+drivers/gpu/drm/nouveau/dispnv50/disp.c:258:19: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/nouveau/dispnv50/disp.c:262:25:    expected unsigned int [usertype] *bgn
+drivers/gpu/drm/nouveau/dispnv50/disp.c:262:25:    got void [noderef] __iomem *ptr
+drivers/gpu/drm/nouveau/dispnv50/disp.c:262:25: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/nouveau/dispnv50/disp.c:2693:1: warning: symbol 'nv50_display_create' was not declared. Should it be static?
+drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c:40:9: warning: dubious: !x & y
+drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c:282:9: warning: dubious: !x & y
+drivers/gpu/drm/qxl/qxl_kms.c:168:19:    expected struct qxl_rom *rom
+drivers/gpu/drm/qxl/qxl_kms.c:168:19:    got void [noderef] __iomem *
+drivers/gpu/drm/qxl/qxl_kms.c:168:19: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/qxl/qxl_kms.c:186:26:    expected struct qxl_ram_header *ram_header
+drivers/gpu/drm/qxl/qxl_kms.c:186:26:    got void [noderef] __iomem *
+drivers/gpu/drm/qxl/qxl_kms.c:186:26: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/qxl/qxl_kms.c:275:21:    expected void volatile [noderef] __iomem *addr
+drivers/gpu/drm/qxl/qxl_kms.c:275:21:    got struct qxl_ram_header *ram_header
+drivers/gpu/drm/qxl/qxl_kms.c:275:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/qxl/qxl_kms.c:279:21:    expected void volatile [noderef] __iomem *addr
+drivers/gpu/drm/qxl/qxl_kms.c:279:21:    got struct qxl_rom *rom
+drivers/gpu/drm/qxl/qxl_kms.c:279:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/qxl/qxl_kms.c:323:21:    expected void volatile [noderef] __iomem *addr
+drivers/gpu/drm/qxl/qxl_kms.c:323:21:    got struct qxl_ram_header *ram_header
+drivers/gpu/drm/qxl/qxl_kms.c:323:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/qxl/qxl_kms.c:324:21:    expected void volatile [noderef] __iomem *addr
+drivers/gpu/drm/qxl/qxl_kms.c:324:21:    got struct qxl_rom *rom
+drivers/gpu/drm/qxl/qxl_kms.c:324:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/qxl/qxl_kms.c:36:5: warning: symbol 'qxl_log_level' was not declared. Should it be static?
+drivers/gpu/drm/qxl/qxl_object.c:178:29: warning: cast removes address space '__iomem' of expression
+drivers/gpu/drm/qxl/qxl_object.c:223:40:    expected void *
+drivers/gpu/drm/qxl/qxl_object.c:223:40:    got void [noderef] __iomem *
+drivers/gpu/drm/qxl/qxl_object.c:223:40: warning: incorrect type in return expression (different address spaces)
+drivers/gpu/drm/qxl/qxl_object.c:273:33:    expected void [noderef] __iomem *vaddr
+drivers/gpu/drm/qxl/qxl_object.c:273:33:    got void *pmap
+drivers/gpu/drm/qxl/qxl_object.c:273:33: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/radeon/atombios_crtc.c:313:23:    expected unsigned short [addressable] [usertype] usH_Size
+drivers/gpu/drm/radeon/atombios_crtc.c:313:23:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:313:23: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:314:32:    expected unsigned short [addressable] [usertype] usH_Blanking_Time
+drivers/gpu/drm/radeon/atombios_crtc.c:314:32:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:314:32: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:316:23:    expected unsigned short [addressable] [usertype] usV_Size
+drivers/gpu/drm/radeon/atombios_crtc.c:316:23:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:316:23: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:317:32:    expected unsigned short [addressable] [usertype] usV_Blanking_Time
+drivers/gpu/drm/radeon/atombios_crtc.c:317:32:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:317:32: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:319:29:    expected unsigned short [addressable] [usertype] usH_SyncOffset
+drivers/gpu/drm/radeon/atombios_crtc.c:319:29:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:319:29: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:321:28:    expected unsigned short [addressable] [usertype] usH_SyncWidth
+drivers/gpu/drm/radeon/atombios_crtc.c:321:28:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:321:28: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:323:29:    expected unsigned short [addressable] [usertype] usV_SyncOffset
+drivers/gpu/drm/radeon/atombios_crtc.c:323:29:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:323:29: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:325:28:    expected unsigned short [addressable] [usertype] usV_SyncWidth
+drivers/gpu/drm/radeon/atombios_crtc.c:325:28:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:325:28: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:343:39:    expected unsigned short [addressable] [assigned] [usertype] usAccess
+drivers/gpu/drm/radeon/atombios_crtc.c:343:39:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:343:39: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:360:24:    expected unsigned short [addressable] [usertype] usH_Total
+drivers/gpu/drm/radeon/atombios_crtc.c:360:24:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:360:24: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:361:23:    expected unsigned short [addressable] [usertype] usH_Disp
+drivers/gpu/drm/radeon/atombios_crtc.c:361:23:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:361:23: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:362:28:    expected unsigned short [addressable] [usertype] usH_SyncStart
+drivers/gpu/drm/radeon/atombios_crtc.c:362:28:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:362:28: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:363:28:    expected unsigned short [addressable] [usertype] usH_SyncWidth
+drivers/gpu/drm/radeon/atombios_crtc.c:363:28:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:363:28: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:365:24:    expected unsigned short [addressable] [usertype] usV_Total
+drivers/gpu/drm/radeon/atombios_crtc.c:365:24:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:365:24: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:366:23:    expected unsigned short [addressable] [usertype] usV_Disp
+drivers/gpu/drm/radeon/atombios_crtc.c:366:23:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:366:23: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:367:28:    expected unsigned short [addressable] [usertype] usV_SyncStart
+drivers/gpu/drm/radeon/atombios_crtc.c:367:28:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:367:28: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:368:28:    expected unsigned short [addressable] [usertype] usV_SyncWidth
+drivers/gpu/drm/radeon/atombios_crtc.c:368:28:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:368:28: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:389:39:    expected unsigned short [addressable] [assigned] [usertype] usAccess
+drivers/gpu/drm/radeon/atombios_crtc.c:389:39:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:389:39: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:481:52:    expected unsigned short [addressable] [usertype] usSpreadSpectrumAmountFrac
+drivers/gpu/drm/radeon/atombios_crtc.c:481:52:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:481:52: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:496:48:    expected unsigned short [addressable] [assigned] [usertype] usSpreadSpectrumAmount
+drivers/gpu/drm/radeon/atombios_crtc.c:496:48:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:496:48: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:497:46:    expected unsigned short [addressable] [assigned] [usertype] usSpreadSpectrumStep
+drivers/gpu/drm/radeon/atombios_crtc.c:497:46:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:497:46: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:500:52:    expected unsigned short [addressable] [assigned] [usertype] usSpreadSpectrumPercentage
+drivers/gpu/drm/radeon/atombios_crtc.c:500:52:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:500:52: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:515:48:    expected unsigned short [addressable] [assigned] [usertype] usSpreadSpectrumAmount
+drivers/gpu/drm/radeon/atombios_crtc.c:515:48:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:515:48: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:516:46:    expected unsigned short [addressable] [assigned] [usertype] usSpreadSpectrumStep
+drivers/gpu/drm/radeon/atombios_crtc.c:516:46:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:516:46: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:519:52:    expected unsigned short [addressable] [assigned] [usertype] usSpreadSpectrumPercentage
+drivers/gpu/drm/radeon/atombios_crtc.c:519:52:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:519:52: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:532:59:    expected unsigned short [addressable] [assigned] [usertype] usSpreadSpectrumPercentage
+drivers/gpu/drm/radeon/atombios_crtc.c:532:59:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:532:59: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:543:57:    expected unsigned short [addressable] [assigned] [usertype] usSpreadSpectrumPercentage
+drivers/gpu/drm/radeon/atombios_crtc.c:543:57:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:543:57: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:55:36:    expected unsigned short [addressable] [assigned] [usertype] usOverscanTop
+drivers/gpu/drm/radeon/atombios_crtc.c:55:36:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:55:36: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:56:39:    expected unsigned short [addressable] [assigned] [usertype] usOverscanBottom
+drivers/gpu/drm/radeon/atombios_crtc.c:56:39:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:56:39: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:57:37:    expected unsigned short [addressable] [assigned] [usertype] usOverscanLeft
+drivers/gpu/drm/radeon/atombios_crtc.c:57:37:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:57:37: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:58:38:    expected unsigned short [addressable] [assigned] [usertype] usOverscanRight
+drivers/gpu/drm/radeon/atombios_crtc.c:58:38:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:58:38: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/radeon/atombios_crtc.c:65:45:    expected unsigned short [addressable] [assigned] [usertype] usOverscanLeft
+drivers/gpu/drm/radeon/atombios_crtc.c:65:45:    got restricted __le16 [usertype]
+drivers/gpu/drm/radeon/atombios_crtc.c:65:45: warning: incorrect type in as



^ permalink raw reply	[flat|nested] 68+ messages in thread

* [Intel-gfx] ✓ Fi.CI.BAT: success for drm/edid: expand on struct drm_edid usage (rev3)
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
                   ` (17 preceding siblings ...)
  (?)
@ 2022-06-08 11:27 ` Patchwork
  -1 siblings, 0 replies; 68+ messages in thread
From: Patchwork @ 2022-06-08 11:27 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 13586 bytes --]

== Series Details ==

Series: drm/edid: expand on struct drm_edid usage (rev3)
URL   : https://patchwork.freedesktop.org/series/104309/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_11733 -> Patchwork_104309v3
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/index.html

Participating hosts (45 -> 42)
------------------------------

  Additional (3): fi-bxt-dsi bat-atsm-1 bat-dg1-5 
  Missing    (6): fi-rkl-11600 bat-dg2-8 bat-adlm-1 bat-dg2-9 bat-rpls-2 fi-bdw-samus 

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_104309v3:

### IGT changes ###

#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * igt@i915_pm_rpm@module-reload:
    - {bat-atsm-1}:       NOTRUN -> [DMESG-WARN][1] +12 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-atsm-1/igt@i915_pm_rpm@module-reload.html

  * igt@i915_selftest@live@mman:
    - {fi-jsl-1}:         [PASS][2] -> [INCOMPLETE][3]
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/fi-jsl-1/igt@i915_selftest@live@mman.html
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/fi-jsl-1/igt@i915_selftest@live@mman.html

  * igt@i915_selftest@live@workarounds:
    - {bat-atsm-1}:       NOTRUN -> [DMESG-FAIL][4]
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-atsm-1/igt@i915_selftest@live@workarounds.html

  
Known issues
------------

  Here are the changes found in Patchwork_104309v3 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@fbdev@nullptr:
    - bat-dg1-5:          NOTRUN -> [SKIP][5] ([i915#2582]) +4 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@fbdev@nullptr.html

  * igt@gem_huc_copy@huc-copy:
    - fi-bxt-dsi:         NOTRUN -> [SKIP][6] ([fdo#109271] / [i915#2190])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/fi-bxt-dsi/igt@gem_huc_copy@huc-copy.html

  * igt@gem_lmem_swapping@parallel-random-engines:
    - fi-bxt-dsi:         NOTRUN -> [SKIP][7] ([fdo#109271] / [i915#4613]) +3 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/fi-bxt-dsi/igt@gem_lmem_swapping@parallel-random-engines.html

  * igt@gem_mmap@basic:
    - bat-dg1-5:          NOTRUN -> [SKIP][8] ([i915#4083])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@gem_mmap@basic.html

  * igt@gem_tiled_blits@basic:
    - fi-bxt-dsi:         NOTRUN -> [SKIP][9] ([fdo#109271]) +13 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/fi-bxt-dsi/igt@gem_tiled_blits@basic.html
    - bat-dg1-5:          NOTRUN -> [SKIP][10] ([i915#4077]) +2 similar issues
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@gem_tiled_blits@basic.html

  * igt@gem_tiled_pread_basic:
    - bat-dg1-5:          NOTRUN -> [SKIP][11] ([i915#4079]) +1 similar issue
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@gem_tiled_pread_basic.html

  * igt@i915_pm_backlight@basic-brightness:
    - bat-dg1-5:          NOTRUN -> [SKIP][12] ([i915#1155])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@i915_pm_backlight@basic-brightness.html

  * igt@i915_selftest@live@hangcheck:
    - fi-snb-2600:        [PASS][13] -> [INCOMPLETE][14] ([i915#3921])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/fi-snb-2600/igt@i915_selftest@live@hangcheck.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/fi-snb-2600/igt@i915_selftest@live@hangcheck.html
    - bat-dg1-6:          [PASS][15] -> [DMESG-FAIL][16] ([i915#4494] / [i915#4957])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/bat-dg1-6/igt@i915_selftest@live@hangcheck.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-6/igt@i915_selftest@live@hangcheck.html

  * igt@i915_suspend@basic-s2idle-without-i915:
    - bat-dg1-5:          NOTRUN -> [INCOMPLETE][17] ([i915#6011])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@i915_suspend@basic-s2idle-without-i915.html

  * igt@kms_addfb_basic@basic-x-tiled-legacy:
    - bat-dg1-5:          NOTRUN -> [SKIP][18] ([i915#4212]) +7 similar issues
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@kms_addfb_basic@basic-x-tiled-legacy.html

  * igt@kms_addfb_basic@basic-y-tiled-legacy:
    - bat-dg1-5:          NOTRUN -> [SKIP][19] ([i915#4215])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@kms_addfb_basic@basic-y-tiled-legacy.html

  * igt@kms_busy@basic:
    - bat-dg1-5:          NOTRUN -> [SKIP][20] ([i915#1845] / [i915#4303])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@kms_busy@basic.html

  * igt@kms_chamelium@dp-crc-fast:
    - bat-dg1-5:          NOTRUN -> [SKIP][21] ([fdo#111827]) +7 similar issues
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@kms_chamelium@dp-crc-fast.html

  * igt@kms_chamelium@hdmi-edid-read:
    - fi-bxt-dsi:         NOTRUN -> [SKIP][22] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/fi-bxt-dsi/igt@kms_chamelium@hdmi-edid-read.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - bat-dg1-5:          NOTRUN -> [SKIP][23] ([i915#4103] / [i915#4213]) +1 similar issue
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html

  * igt@kms_force_connector_basic@force-load-detect:
    - bat-dg1-5:          NOTRUN -> [SKIP][24] ([fdo#109285])
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@kms_force_connector_basic@force-load-detect.html

  * igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d:
    - fi-bxt-dsi:         NOTRUN -> [SKIP][25] ([fdo#109271] / [i915#533])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/fi-bxt-dsi/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d.html

  * igt@kms_pipe_crc_basic@nonblocking-crc-pipe-a:
    - bat-dg1-5:          NOTRUN -> [SKIP][26] ([i915#4078]) +21 similar issues
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@kms_pipe_crc_basic@nonblocking-crc-pipe-a.html

  * igt@kms_psr@primary_page_flip:
    - bat-dg1-5:          NOTRUN -> [SKIP][27] ([i915#1072] / [i915#4078]) +3 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@kms_psr@primary_page_flip.html

  * igt@kms_setmode@basic-clone-single-crtc:
    - bat-dg1-5:          NOTRUN -> [SKIP][28] ([i915#3555])
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@kms_setmode@basic-clone-single-crtc.html

  * igt@prime_vgem@basic-fence-flip:
    - bat-dg1-5:          NOTRUN -> [SKIP][29] ([i915#1845] / [i915#3708])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@prime_vgem@basic-fence-flip.html

  * igt@prime_vgem@basic-fence-read:
    - bat-dg1-5:          NOTRUN -> [SKIP][30] ([i915#3708]) +2 similar issues
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@prime_vgem@basic-fence-read.html

  * igt@prime_vgem@basic-gtt:
    - bat-dg1-5:          NOTRUN -> [SKIP][31] ([i915#3708] / [i915#4077]) +1 similar issue
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@prime_vgem@basic-gtt.html

  * igt@prime_vgem@basic-userptr:
    - bat-dg1-5:          NOTRUN -> [SKIP][32] ([i915#3708] / [i915#4873])
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@prime_vgem@basic-userptr.html

  * igt@runner@aborted:
    - bat-dg1-5:          NOTRUN -> [FAIL][33] ([i915#4312] / [i915#5257])
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/bat-dg1-5/igt@runner@aborted.html

  
#### Possible fixes ####

  * igt@gem_exec_suspend@basic-s0@smem:
    - {fi-ehl-2}:         [DMESG-WARN][34] ([i915#5122]) -> [PASS][35]
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/fi-ehl-2/igt@gem_exec_suspend@basic-s0@smem.html
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/fi-ehl-2/igt@gem_exec_suspend@basic-s0@smem.html

  * igt@i915_selftest@live@gt_pm:
    - fi-tgl-1115g4:      [DMESG-FAIL][36] ([i915#3987]) -> [PASS][37]
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/fi-tgl-1115g4/igt@i915_selftest@live@gt_pm.html
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/fi-tgl-1115g4/igt@i915_selftest@live@gt_pm.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
  [fdo#109295]: https://bugs.freedesktop.org/show_bug.cgi?id=109295
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072
  [i915#1155]: https://gitlab.freedesktop.org/drm/intel/issues/1155
  [i915#1836]: https://gitlab.freedesktop.org/drm/intel/issues/1836
  [i915#1845]: https://gitlab.freedesktop.org/drm/intel/issues/1845
  [i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190
  [i915#2582]: https://gitlab.freedesktop.org/drm/intel/issues/2582
  [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
  [i915#3595]: https://gitlab.freedesktop.org/drm/intel/issues/3595
  [i915#3708]: https://gitlab.freedesktop.org/drm/intel/issues/3708
  [i915#3921]: https://gitlab.freedesktop.org/drm/intel/issues/3921
  [i915#3987]: https://gitlab.freedesktop.org/drm/intel/issues/3987
  [i915#4077]: https://gitlab.freedesktop.org/drm/intel/issues/4077
  [i915#4078]: https://gitlab.freedesktop.org/drm/intel/issues/4078
  [i915#4079]: https://gitlab.freedesktop.org/drm/intel/issues/4079
  [i915#4083]: https://gitlab.freedesktop.org/drm/intel/issues/4083
  [i915#4103]: https://gitlab.freedesktop.org/drm/intel/issues/4103
  [i915#4212]: https://gitlab.freedesktop.org/drm/intel/issues/4212
  [i915#4213]: https://gitlab.freedesktop.org/drm/intel/issues/4213
  [i915#4215]: https://gitlab.freedesktop.org/drm/intel/issues/4215
  [i915#4303]: https://gitlab.freedesktop.org/drm/intel/issues/4303
  [i915#4312]: https://gitlab.freedesktop.org/drm/intel/issues/4312
  [i915#4494]: https://gitlab.freedesktop.org/drm/intel/issues/4494
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#4873]: https://gitlab.freedesktop.org/drm/intel/issues/4873
  [i915#4957]: https://gitlab.freedesktop.org/drm/intel/issues/4957
  [i915#5122]: https://gitlab.freedesktop.org/drm/intel/issues/5122
  [i915#5257]: https://gitlab.freedesktop.org/drm/intel/issues/5257
  [i915#533]: https://gitlab.freedesktop.org/drm/intel/issues/533
  [i915#5334]: https://gitlab.freedesktop.org/drm/intel/issues/5334
  [i915#6011]: https://gitlab.freedesktop.org/drm/intel/issues/6011
  [i915#6077]: https://gitlab.freedesktop.org/drm/intel/issues/6077
  [i915#6078]: https://gitlab.freedesktop.org/drm/intel/issues/6078
  [i915#6092]: https://gitlab.freedesktop.org/drm/intel/issues/6092
  [i915#6093]: https://gitlab.freedesktop.org/drm/intel/issues/6093
  [i915#6094]: https://gitlab.freedesktop.org/drm/intel/issues/6094
  [i915#6099]: https://gitlab.freedesktop.org/drm/intel/issues/6099
  [i915#6138]: https://gitlab.freedesktop.org/drm/intel/issues/6138
  [i915#6166]: https://gitlab.freedesktop.org/drm/intel/issues/6166


Build changes
-------------

  * Linux: CI_DRM_11733 -> Patchwork_104309v3

  CI-20190529: 20190529
  CI_DRM_11733: 4a478d4716b11a64fbc702a176ec3d078a168bc5 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6512: 5efc64e9b93a2df85581ea425ee7d0f435855f13 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_104309v3: 4a478d4716b11a64fbc702a176ec3d078a168bc5 @ git://anongit.freedesktop.org/gfx-ci/linux


### Linux commits

1abc2bb5ecae drm/todo: add entry for converting the subsystem to struct drm_edid
a2196ac5621d drm/edid: take HF-EEODB extension count into account
fb1b3f8dc4c7 drm/edid: add HF-EEODB support to EDID read and allocation
62a8559e2471 drm/edid: do invalid block filtering in-place
8973c093f009 drm/i915/bios: convert intel_bios_init_panel() to drm_edid
1a301210fcc6 drm/i915/edid: convert DP, HDMI and LVDS to drm_edid
b42f4c897bd5 drm/edid: add drm_edid_raw() to access the raw EDID data
78ce3ef49be8 drm/probe-helper: add drm_connector_helper_get_modes()
68047b789992 drm/probe-helper: abstract .get_modes() connector helper call
6d0c62480e16 drm/edid: add drm_edid_connector_update()
9156f0071ec7 drm/edid: add new interfaces around struct drm_edid
a1f981940d41 drm/edid: keep track of alloc size in drm_do_get_edid()
a986c27fb8f1 drm/edid: add block count and data helper functions for drm_edid
90c263c3fc4c drm/edid: abstract cea data block collection size
33e28afdf5da drm/edid: fix CTA data block collection size for CTA version 3

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/index.html

[-- Attachment #2: Type: text/html, Size: 15006 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [Intel-gfx] ✓ Fi.CI.IGT: success for drm/edid: expand on struct drm_edid usage (rev3)
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
                   ` (18 preceding siblings ...)
  (?)
@ 2022-06-08 19:23 ` Patchwork
  -1 siblings, 0 replies; 68+ messages in thread
From: Patchwork @ 2022-06-08 19:23 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 48540 bytes --]

== Series Details ==

Series: drm/edid: expand on struct drm_edid usage (rev3)
URL   : https://patchwork.freedesktop.org/series/104309/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_11733_full -> Patchwork_104309v3_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

Participating hosts (13 -> 13)
------------------------------

  No changes in participating hosts

Known issues
------------

  Here are the changes found in Patchwork_104309v3_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_ctx_persistence@legacy-engines-hostile:
    - shard-snb:          NOTRUN -> [SKIP][1] ([fdo#109271] / [i915#1099])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-snb5/igt@gem_ctx_persistence@legacy-engines-hostile.html

  * igt@gem_eio@in-flight-contexts-10ms:
    - shard-tglb:         [PASS][2] -> [TIMEOUT][3] ([i915#3063]) +1 similar issue
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-tglb7/igt@gem_eio@in-flight-contexts-10ms.html
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-tglb3/igt@gem_eio@in-flight-contexts-10ms.html

  * igt@gem_eio@unwedge-stress:
    - shard-skl:          [PASS][4] -> [TIMEOUT][5] ([i915#3063])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-skl2/igt@gem_eio@unwedge-stress.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl1/igt@gem_eio@unwedge-stress.html

  * igt@gem_exec_balancer@parallel-contexts:
    - shard-iclb:         [PASS][6] -> [SKIP][7] ([i915#4525])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb1/igt@gem_exec_balancer@parallel-contexts.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb3/igt@gem_exec_balancer@parallel-contexts.html

  * igt@gem_exec_fair@basic-none-share@rcs0:
    - shard-iclb:         [PASS][8] -> [FAIL][9] ([i915#2842])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb3/igt@gem_exec_fair@basic-none-share@rcs0.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb6/igt@gem_exec_fair@basic-none-share@rcs0.html

  * igt@gem_exec_fair@basic-none-solo@rcs0:
    - shard-apl:          [PASS][10] -> [FAIL][11] ([i915#2842])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-apl1/igt@gem_exec_fair@basic-none-solo@rcs0.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl7/igt@gem_exec_fair@basic-none-solo@rcs0.html

  * igt@gem_exec_fair@basic-pace-share@rcs0:
    - shard-tglb:         [PASS][12] -> [FAIL][13] ([i915#2842])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-tglb5/igt@gem_exec_fair@basic-pace-share@rcs0.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-tglb3/igt@gem_exec_fair@basic-pace-share@rcs0.html

  * igt@gem_exec_fair@basic-pace-solo@rcs0:
    - shard-kbl:          [PASS][14] -> [FAIL][15] ([i915#2842]) +2 similar issues
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-kbl4/igt@gem_exec_fair@basic-pace-solo@rcs0.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl4/igt@gem_exec_fair@basic-pace-solo@rcs0.html

  * igt@gem_exec_fair@basic-throttle@rcs0:
    - shard-glk:          [PASS][16] -> [FAIL][17] ([i915#2842]) +1 similar issue
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-glk8/igt@gem_exec_fair@basic-throttle@rcs0.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-glk1/igt@gem_exec_fair@basic-throttle@rcs0.html

  * igt@gem_lmem_swapping@basic:
    - shard-skl:          NOTRUN -> [SKIP][18] ([fdo#109271] / [i915#4613])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl4/igt@gem_lmem_swapping@basic.html

  * igt@gem_ppgtt@flink-and-close-vma-leak:
    - shard-glk:          [PASS][19] -> [FAIL][20] ([i915#644])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-glk7/igt@gem_ppgtt@flink-and-close-vma-leak.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-glk8/igt@gem_ppgtt@flink-and-close-vma-leak.html

  * igt@gem_softpin@noreloc-s3:
    - shard-kbl:          [PASS][21] -> [DMESG-WARN][22] ([i915#180]) +1 similar issue
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-kbl7/igt@gem_softpin@noreloc-s3.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl6/igt@gem_softpin@noreloc-s3.html

  * igt@gem_workarounds@suspend-resume-context:
    - shard-skl:          [PASS][23] -> [INCOMPLETE][24] ([i915#4939] / [i915#5129])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-skl1/igt@gem_workarounds@suspend-resume-context.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl4/igt@gem_workarounds@suspend-resume-context.html

  * igt@i915_pm_dc@dc3co-vpb-simulation:
    - shard-kbl:          NOTRUN -> [SKIP][25] ([fdo#109271] / [i915#658])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl7/igt@i915_pm_dc@dc3co-vpb-simulation.html

  * igt@i915_pm_dc@dc6-dpms:
    - shard-iclb:         [PASS][26] -> [FAIL][27] ([i915#454])
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb5/igt@i915_pm_dc@dc6-dpms.html
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb3/igt@i915_pm_dc@dc6-dpms.html

  * igt@kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip:
    - shard-apl:          NOTRUN -> [SKIP][28] ([fdo#109271]) +103 similar issues
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl6/igt@kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip.html

  * igt@kms_ccs@pipe-a-crc-primary-rotation-180-y_tiled_gen12_mc_ccs:
    - shard-apl:          NOTRUN -> [SKIP][29] ([fdo#109271] / [i915#3886]) +2 similar issues
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl2/igt@kms_ccs@pipe-a-crc-primary-rotation-180-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-a-missing-ccs-buffer-y_tiled_gen12_mc_ccs:
    - shard-skl:          NOTRUN -> [SKIP][30] ([fdo#109271] / [i915#3886]) +1 similar issue
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl9/igt@kms_ccs@pipe-a-missing-ccs-buffer-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-b-crc-sprite-planes-basic-y_tiled_gen12_rc_ccs_cc:
    - shard-kbl:          NOTRUN -> [SKIP][31] ([fdo#109271] / [i915#3886]) +2 similar issues
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl7/igt@kms_ccs@pipe-b-crc-sprite-planes-basic-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-d-missing-ccs-buffer-y_tiled_gen12_rc_ccs:
    - shard-kbl:          NOTRUN -> [SKIP][32] ([fdo#109271]) +76 similar issues
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl7/igt@kms_ccs@pipe-d-missing-ccs-buffer-y_tiled_gen12_rc_ccs.html

  * igt@kms_color_chamelium@pipe-a-ctm-max:
    - shard-kbl:          NOTRUN -> [SKIP][33] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl7/igt@kms_color_chamelium@pipe-a-ctm-max.html
    - shard-snb:          NOTRUN -> [SKIP][34] ([fdo#109271] / [fdo#111827]) +3 similar issues
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-snb5/igt@kms_color_chamelium@pipe-a-ctm-max.html

  * igt@kms_color_chamelium@pipe-b-ctm-red-to-blue:
    - shard-skl:          NOTRUN -> [SKIP][35] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl10/igt@kms_color_chamelium@pipe-b-ctm-red-to-blue.html

  * igt@kms_color_chamelium@pipe-c-ctm-negative:
    - shard-apl:          NOTRUN -> [SKIP][36] ([fdo#109271] / [fdo#111827]) +3 similar issues
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl2/igt@kms_color_chamelium@pipe-c-ctm-negative.html

  * igt@kms_content_protection@atomic:
    - shard-apl:          NOTRUN -> [TIMEOUT][37] ([i915#1319])
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl7/igt@kms_content_protection@atomic.html

  * igt@kms_cursor_crc@pipe-a-cursor-suspend:
    - shard-apl:          [PASS][38] -> [DMESG-WARN][39] ([i915#180]) +2 similar issues
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-apl3/igt@kms_cursor_crc@pipe-a-cursor-suspend.html
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl4/igt@kms_cursor_crc@pipe-a-cursor-suspend.html

  * igt@kms_cursor_crc@pipe-d-cursor-max-size-onscreen:
    - shard-snb:          NOTRUN -> [SKIP][40] ([fdo#109271]) +54 similar issues
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-snb5/igt@kms_cursor_crc@pipe-d-cursor-max-size-onscreen.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
    - shard-iclb:         [PASS][41] -> [FAIL][42] ([i915#2346])
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb6/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb7/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html

  * igt@kms_flip@2x-flip-vs-expired-vblank@ab-hdmi-a1-hdmi-a2:
    - shard-glk:          [PASS][43] -> [FAIL][44] ([i915#79]) +1 similar issue
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-glk7/igt@kms_flip@2x-flip-vs-expired-vblank@ab-hdmi-a1-hdmi-a2.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-glk1/igt@kms_flip@2x-flip-vs-expired-vblank@ab-hdmi-a1-hdmi-a2.html

  * igt@kms_flip@flip-vs-suspend-interruptible@c-edp1:
    - shard-skl:          [PASS][45] -> [INCOMPLETE][46] ([i915#4939]) +1 similar issue
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-skl4/igt@kms_flip@flip-vs-suspend-interruptible@c-edp1.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl7/igt@kms_flip@flip-vs-suspend-interruptible@c-edp1.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling:
    - shard-iclb:         [PASS][47] -> [SKIP][48] ([i915#3701])
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb4/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb2/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-onoff:
    - shard-skl:          NOTRUN -> [SKIP][49] ([fdo#109271]) +100 similar issues
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl4/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-onoff.html

  * igt@kms_pipe_crc_basic@disable-crc-after-crtc-pipe-d:
    - shard-apl:          NOTRUN -> [SKIP][50] ([fdo#109271] / [i915#533]) +2 similar issues
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl6/igt@kms_pipe_crc_basic@disable-crc-after-crtc-pipe-d.html
    - shard-skl:          NOTRUN -> [SKIP][51] ([fdo#109271] / [i915#533])
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl10/igt@kms_pipe_crc_basic@disable-crc-after-crtc-pipe-d.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c:
    - shard-kbl:          NOTRUN -> [DMESG-WARN][52] ([i915#180])
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl1/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c.html

  * igt@kms_plane_alpha_blend@pipe-c-alpha-basic:
    - shard-skl:          NOTRUN -> [FAIL][53] ([fdo#108145] / [i915#265])
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl9/igt@kms_plane_alpha_blend@pipe-c-alpha-basic.html

  * igt@kms_plane_alpha_blend@pipe-c-alpha-opaque-fb:
    - shard-kbl:          NOTRUN -> [FAIL][54] ([fdo#108145] / [i915#265]) +1 similar issue
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl3/igt@kms_plane_alpha_blend@pipe-c-alpha-opaque-fb.html

  * igt@kms_plane_scaling@plane-downscale-with-pixel-format-factor-0-5@pipe-a-edp-1:
    - shard-iclb:         [PASS][55] -> [SKIP][56] ([i915#5176]) +2 similar issues
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb4/igt@kms_plane_scaling@plane-downscale-with-pixel-format-factor-0-5@pipe-a-edp-1.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb2/igt@kms_plane_scaling@plane-downscale-with-pixel-format-factor-0-5@pipe-a-edp-1.html

  * igt@kms_psr2_su@page_flip-xrgb8888:
    - shard-skl:          NOTRUN -> [SKIP][57] ([fdo#109271] / [i915#658]) +1 similar issue
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl10/igt@kms_psr2_su@page_flip-xrgb8888.html
    - shard-apl:          NOTRUN -> [SKIP][58] ([fdo#109271] / [i915#658]) +1 similar issue
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl6/igt@kms_psr2_su@page_flip-xrgb8888.html

  * igt@kms_psr@psr2_cursor_plane_move:
    - shard-iclb:         [PASS][59] -> [SKIP][60] ([fdo#109441]) +1 similar issue
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb2/igt@kms_psr@psr2_cursor_plane_move.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb5/igt@kms_psr@psr2_cursor_plane_move.html

  * igt@kms_sysfs_edid_timing:
    - shard-skl:          NOTRUN -> [FAIL][61] ([IGT#2])
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl9/igt@kms_sysfs_edid_timing.html

  * igt@kms_writeback@writeback-check-output:
    - shard-skl:          NOTRUN -> [SKIP][62] ([fdo#109271] / [i915#2437])
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl9/igt@kms_writeback@writeback-check-output.html

  * igt@kms_writeback@writeback-fb-id:
    - shard-apl:          NOTRUN -> [SKIP][63] ([fdo#109271] / [i915#2437])
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl4/igt@kms_writeback@writeback-fb-id.html

  * igt@sw_sync@sync_merge_same:
    - shard-kbl:          NOTRUN -> [FAIL][64] ([i915#6140])
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl7/igt@sw_sync@sync_merge_same.html
    - shard-snb:          NOTRUN -> [FAIL][65] ([i915#6140])
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-snb5/igt@sw_sync@sync_merge_same.html

  * igt@sysfs_clients@fair-7:
    - shard-apl:          NOTRUN -> [SKIP][66] ([fdo#109271] / [i915#2994]) +1 similar issue
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl4/igt@sysfs_clients@fair-7.html

  * igt@sysfs_clients@sema-10:
    - shard-skl:          NOTRUN -> [SKIP][67] ([fdo#109271] / [i915#2994]) +1 similar issue
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl10/igt@sysfs_clients@sema-10.html

  
#### Possible fixes ####

  * igt@fbdev@unaligned-read:
    - {shard-rkl}:        [SKIP][68] ([i915#2582]) -> [PASS][69]
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@fbdev@unaligned-read.html
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@fbdev@unaligned-read.html

  * igt@feature_discovery@psr2:
    - {shard-rkl}:        [SKIP][70] ([i915#658]) -> [PASS][71]
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@feature_discovery@psr2.html
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@feature_discovery@psr2.html

  * igt@gem_ctx_isolation@preservation-s3@bcs0:
    - shard-apl:          [DMESG-WARN][72] ([i915#180]) -> [PASS][73] +1 similar issue
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-apl2/igt@gem_ctx_isolation@preservation-s3@bcs0.html
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl2/igt@gem_ctx_isolation@preservation-s3@bcs0.html

  * igt@gem_ctx_persistence@many-contexts:
    - {shard-rkl}:        [FAIL][74] ([i915#2410]) -> [PASS][75]
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@gem_ctx_persistence@many-contexts.html
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-1/igt@gem_ctx_persistence@many-contexts.html

  * igt@gem_exec_balancer@parallel-keep-submit-fence:
    - shard-iclb:         [SKIP][76] ([i915#4525]) -> [PASS][77]
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb7/igt@gem_exec_balancer@parallel-keep-submit-fence.html
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb1/igt@gem_exec_balancer@parallel-keep-submit-fence.html

  * igt@gem_exec_endless@dispatch@vcs1:
    - {shard-tglu}:       [INCOMPLETE][78] ([i915#3778]) -> [PASS][79]
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-tglu-2/igt@gem_exec_endless@dispatch@vcs1.html
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-tglu-3/igt@gem_exec_endless@dispatch@vcs1.html

  * igt@gem_exec_fair@basic-flow@rcs0:
    - shard-tglb:         [FAIL][80] ([i915#2842]) -> [PASS][81]
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-tglb5/igt@gem_exec_fair@basic-flow@rcs0.html
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-tglb3/igt@gem_exec_fair@basic-flow@rcs0.html

  * igt@gem_exec_fair@basic-none@bcs0:
    - shard-iclb:         [FAIL][82] ([i915#2842]) -> [PASS][83]
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb6/igt@gem_exec_fair@basic-none@bcs0.html
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb8/igt@gem_exec_fair@basic-none@bcs0.html

  * igt@gem_exec_fair@basic-none@vcs1:
    - shard-kbl:          [FAIL][84] ([i915#2842]) -> [PASS][85] +2 similar issues
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-kbl6/igt@gem_exec_fair@basic-none@vcs1.html
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl3/igt@gem_exec_fair@basic-none@vcs1.html

  * igt@gem_exec_fair@basic-none@vecs0:
    - shard-apl:          [FAIL][86] ([i915#2842]) -> [PASS][87]
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-apl1/igt@gem_exec_fair@basic-none@vecs0.html
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl8/igt@gem_exec_fair@basic-none@vecs0.html

  * igt@gem_exec_fair@basic-throttle@rcs0:
    - shard-iclb:         [FAIL][88] ([i915#2849]) -> [PASS][89]
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb8/igt@gem_exec_fair@basic-throttle@rcs0.html
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb3/igt@gem_exec_fair@basic-throttle@rcs0.html

  * igt@gem_huc_copy@huc-copy:
    - shard-tglb:         [SKIP][90] ([i915#2190]) -> [PASS][91]
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-tglb7/igt@gem_huc_copy@huc-copy.html
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-tglb2/igt@gem_huc_copy@huc-copy.html

  * igt@gem_mmap_wc@set-cache-level:
    - {shard-rkl}:        [SKIP][92] ([i915#1850]) -> [PASS][93]
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@gem_mmap_wc@set-cache-level.html
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@gem_mmap_wc@set-cache-level.html

  * igt@gen9_exec_parse@allowed-single:
    - shard-skl:          [DMESG-WARN][94] ([i915#5566] / [i915#716]) -> [PASS][95]
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-skl7/igt@gen9_exec_parse@allowed-single.html
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl10/igt@gen9_exec_parse@allowed-single.html
    - shard-apl:          [DMESG-WARN][96] ([i915#5566] / [i915#716]) -> [PASS][97]
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-apl7/igt@gen9_exec_parse@allowed-single.html
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl6/igt@gen9_exec_parse@allowed-single.html

  * igt@i915_pm_rpm@modeset-lpsp-stress:
    - {shard-rkl}:        [SKIP][98] ([i915#1397]) -> [PASS][99]
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@i915_pm_rpm@modeset-lpsp-stress.html
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@i915_pm_rpm@modeset-lpsp-stress.html

  * igt@i915_selftest@live@gt_heartbeat:
    - shard-apl:          [DMESG-FAIL][100] ([i915#5334]) -> [PASS][101]
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-apl4/igt@i915_selftest@live@gt_heartbeat.html
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl7/igt@i915_selftest@live@gt_heartbeat.html

  * igt@i915_selftest@live@hangcheck:
    - shard-snb:          [INCOMPLETE][102] ([i915#3921]) -> [PASS][103]
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-snb7/igt@i915_selftest@live@hangcheck.html
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-snb5/igt@i915_selftest@live@hangcheck.html

  * igt@kms_color@pipe-a-ctm-max:
    - {shard-rkl}:        [SKIP][104] ([i915#1149] / [i915#1849] / [i915#4070] / [i915#4098]) -> [PASS][105] +1 similar issue
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@kms_color@pipe-a-ctm-max.html
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@kms_color@pipe-a-ctm-max.html

  * igt@kms_cursor_crc@pipe-a-cursor-128x42-onscreen:
    - {shard-rkl}:        [SKIP][106] ([fdo#112022] / [i915#4070]) -> [PASS][107] +9 similar issues
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@kms_cursor_crc@pipe-a-cursor-128x42-onscreen.html
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@kms_cursor_crc@pipe-a-cursor-128x42-onscreen.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
    - {shard-rkl}:        [SKIP][108] ([fdo#111825] / [i915#4070]) -> [PASS][109] +5 similar issues
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html

  * igt@kms_dither@fb-8bpc-vs-panel-8bpc@hdmi-a-1-pipe-a:
    - shard-glk:          [SKIP][110] ([fdo#109271]) -> [PASS][111]
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-glk8/igt@kms_dither@fb-8bpc-vs-panel-8bpc@hdmi-a-1-pipe-a.html
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-glk3/igt@kms_dither@fb-8bpc-vs-panel-8bpc@hdmi-a-1-pipe-a.html

  * igt@kms_draw_crc@draw-method-rgb565-pwrite-untiled:
    - {shard-rkl}:        [SKIP][112] ([fdo#111314] / [i915#4098] / [i915#4369]) -> [PASS][113] +6 similar issues
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@kms_draw_crc@draw-method-rgb565-pwrite-untiled.html
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@kms_draw_crc@draw-method-rgb565-pwrite-untiled.html

  * igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling:
    - shard-iclb:         [SKIP][114] ([i915#3701]) -> [PASS][115]
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb2/igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling.html
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb5/igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling.html

  * igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling:
    - {shard-rkl}:        [SKIP][116] ([i915#3701]) -> [PASS][117]
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling.html
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling.html

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-mmap-gtt:
    - {shard-rkl}:        [SKIP][118] ([i915#1849] / [i915#4098]) -> [PASS][119] +30 similar issues
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-mmap-gtt.html
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@fbc-suspend:
    - shard-kbl:          [DMESG-WARN][120] ([i915#180]) -> [PASS][121] +3 similar issues
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-kbl6/igt@kms_frontbuffer_tracking@fbc-suspend.html
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl1/igt@kms_frontbuffer_tracking@fbc-suspend.html

  * igt@kms_hdr@bpc-switch-dpms@pipe-a-dp-1:
    - shard-kbl:          [FAIL][122] ([i915#1188]) -> [PASS][123]
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-kbl7/igt@kms_hdr@bpc-switch-dpms@pipe-a-dp-1.html
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl6/igt@kms_hdr@bpc-switch-dpms@pipe-a-dp-1.html

  * igt@kms_invalid_mode@zero-hdisplay:
    - {shard-rkl}:        [SKIP][124] ([i915#4278]) -> [PASS][125] +1 similar issue
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@kms_invalid_mode@zero-hdisplay.html
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@kms_invalid_mode@zero-hdisplay.html

  * igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a-planes:
    - {shard-rkl}:        [SKIP][126] ([i915#3558]) -> [PASS][127] +1 similar issue
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a-planes.html
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a-planes.html

  * igt@kms_plane_alpha_blend@pipe-a-alpha-basic:
    - {shard-rkl}:        [SKIP][128] ([i915#1849] / [i915#4070] / [i915#4098]) -> [PASS][129] +7 similar issues
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@kms_plane_alpha_blend@pipe-a-alpha-basic.html
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@kms_plane_alpha_blend@pipe-a-alpha-basic.html

  * igt@kms_plane_multiple@atomic-pipe-b-tiling-y:
    - {shard-rkl}:        [SKIP][130] ([i915#3558] / [i915#4070]) -> [PASS][131]
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@kms_plane_multiple@atomic-pipe-b-tiling-y.html
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@kms_plane_multiple@atomic-pipe-b-tiling-y.html

  * igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-pixel-formats@pipe-b-edp-1:
    - shard-iclb:         [SKIP][132] ([i915#5176]) -> [PASS][133] +1 similar issue
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb3/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-pixel-formats@pipe-b-edp-1.html
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb6/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-pixel-formats@pipe-b-edp-1.html

  * igt@kms_properties@plane-properties-legacy:
    - {shard-rkl}:        [SKIP][134] ([i915#1849]) -> [PASS][135]
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@kms_properties@plane-properties-legacy.html
   [135]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@kms_properties@plane-properties-legacy.html

  * igt@kms_psr@primary_render:
    - {shard-rkl}:        [SKIP][136] ([i915#1072]) -> [PASS][137] +1 similar issue
   [136]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@kms_psr@primary_render.html
   [137]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@kms_psr@primary_render.html

  * igt@kms_psr@psr2_sprite_plane_move:
    - shard-iclb:         [SKIP][138] ([fdo#109441]) -> [PASS][139] +2 similar issues
   [138]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb4/igt@kms_psr@psr2_sprite_plane_move.html
   [139]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb2/igt@kms_psr@psr2_sprite_plane_move.html

  * igt@kms_psr_stress_test@flip-primary-invalidate-overlay:
    - shard-iclb:         [SKIP][140] ([i915#5519]) -> [PASS][141]
   [140]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb1/igt@kms_psr_stress_test@flip-primary-invalidate-overlay.html
   [141]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb4/igt@kms_psr_stress_test@flip-primary-invalidate-overlay.html

  * igt@kms_rotation_crc@primary-rotation-90:
    - {shard-rkl}:        [SKIP][142] ([i915#1845] / [i915#4098]) -> [PASS][143] +35 similar issues
   [142]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-rkl-1/igt@kms_rotation_crc@primary-rotation-90.html
   [143]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-rkl-6/igt@kms_rotation_crc@primary-rotation-90.html

  * igt@perf@polling:
    - shard-skl:          [FAIL][144] ([i915#1542]) -> [PASS][145]
   [144]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-skl4/igt@perf@polling.html
   [145]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl7/igt@perf@polling.html

  * igt@perf@polling-small-buf:
    - shard-skl:          [FAIL][146] ([i915#1722]) -> [PASS][147]
   [146]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-skl4/igt@perf@polling-small-buf.html
   [147]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl7/igt@perf@polling-small-buf.html

  * igt@perf_pmu@module-unload:
    - {shard-dg1}:        [FAIL][148] ([i915#6054]) -> [PASS][149]
   [148]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-dg1-17/igt@perf_pmu@module-unload.html
   [149]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-dg1-15/igt@perf_pmu@module-unload.html

  
#### Warnings ####

  * igt@gem_eio@unwedge-stress:
    - shard-tglb:         [FAIL][150] ([i915#5784]) -> [TIMEOUT][151] ([i915#3063])
   [150]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-tglb5/igt@gem_eio@unwedge-stress.html
   [151]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-tglb6/igt@gem_eio@unwedge-stress.html

  * igt@gem_exec_balancer@parallel-ordering:
    - shard-iclb:         [SKIP][152] ([i915#4525]) -> [FAIL][153] ([i915#6117])
   [152]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb7/igt@gem_exec_balancer@parallel-ordering.html
   [153]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb4/igt@gem_exec_balancer@parallel-ordering.html

  * igt@i915_pm_dc@dc3co-vpb-simulation:
    - shard-iclb:         [SKIP][154] ([i915#658]) -> [SKIP][155] ([i915#588])
   [154]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb4/igt@i915_pm_dc@dc3co-vpb-simulation.html
   [155]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb2/igt@i915_pm_dc@dc3co-vpb-simulation.html

  * igt@kms_fbcon_fbt@fbc-suspend:
    - shard-apl:          [INCOMPLETE][156] ([i915#180] / [i915#1982]) -> [FAIL][157] ([i915#4767])
   [156]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-apl8/igt@kms_fbcon_fbt@fbc-suspend.html
   [157]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl4/igt@kms_fbcon_fbt@fbc-suspend.html

  * igt@kms_hdr@bpc-switch-suspend@pipe-a-dp-1:
    - shard-kbl:          [FAIL][158] ([i915#1188]) -> [DMESG-FAIL][159] ([i915#180])
   [158]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-kbl4/igt@kms_hdr@bpc-switch-suspend@pipe-a-dp-1.html
   [159]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl1/igt@kms_hdr@bpc-switch-suspend@pipe-a-dp-1.html

  * igt@kms_psr2_sf@cursor-plane-move-continuous-exceed-sf:
    - shard-iclb:         [SKIP][160] ([i915#2920]) -> [SKIP][161] ([i915#658])
   [160]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb2/igt@kms_psr2_sf@cursor-plane-move-continuous-exceed-sf.html
   [161]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb5/igt@kms_psr2_sf@cursor-plane-move-continuous-exceed-sf.html

  * igt@kms_psr2_sf@overlay-plane-move-continuous-sf:
    - shard-iclb:         [SKIP][162] ([i915#658]) -> [SKIP][163] ([i915#2920])
   [162]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb4/igt@kms_psr2_sf@overlay-plane-move-continuous-sf.html
   [163]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb2/igt@kms_psr2_sf@overlay-plane-move-continuous-sf.html

  * igt@kms_psr2_su@page_flip-p010:
    - shard-iclb:         [SKIP][164] ([fdo#109642] / [fdo#111068] / [i915#658]) -> [FAIL][165] ([i915#5939])
   [164]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-iclb4/igt@kms_psr2_su@page_flip-p010.html
   [165]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-iclb2/igt@kms_psr2_su@page_flip-p010.html

  * igt@kms_vblank@pipe-d-query-busy:
    - shard-skl:          [SKIP][166] ([fdo#109271] / [i915#1888]) -> [SKIP][167] ([fdo#109271])
   [166]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-skl10/igt@kms_vblank@pipe-d-query-busy.html
   [167]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl7/igt@kms_vblank@pipe-d-query-busy.html

  * igt@runner@aborted:
    - shard-skl:          ([FAIL][168], [FAIL][169], [FAIL][170], [FAIL][171], [FAIL][172]) ([i915#2029] / [i915#3002] / [i915#4312] / [i915#5257]) -> ([FAIL][173], [FAIL][174]) ([i915#3002] / [i915#4312] / [i915#5257])
   [168]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-skl2/igt@runner@aborted.html
   [169]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-skl2/igt@runner@aborted.html
   [170]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-skl7/igt@runner@aborted.html
   [171]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-skl1/igt@runner@aborted.html
   [172]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-skl2/igt@runner@aborted.html
   [173]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl4/igt@runner@aborted.html
   [174]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-skl10/igt@runner@aborted.html
    - shard-apl:          ([FAIL][175], [FAIL][176], [FAIL][177], [FAIL][178], [FAIL][179], [FAIL][180], [FAIL][181]) ([fdo#109271] / [i915#180] / [i915#3002] / [i915#4312] / [i915#5257]) -> ([FAIL][182], [FAIL][183], [FAIL][184], [FAIL][185], [FAIL][186]) ([i915#180] / [i915#3002] / [i915#4312] / [i915#5257])
   [175]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-apl4/igt@runner@aborted.html
   [176]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-apl7/igt@runner@aborted.html
   [177]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-apl4/igt@runner@aborted.html
   [178]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-apl2/igt@runner@aborted.html
   [179]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-apl1/igt@runner@aborted.html
   [180]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-apl4/igt@runner@aborted.html
   [181]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-apl8/igt@runner@aborted.html
   [182]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl4/igt@runner@aborted.html
   [183]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl4/igt@runner@aborted.html
   [184]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl3/igt@runner@aborted.html
   [185]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl8/igt@runner@aborted.html
   [186]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-apl8/igt@runner@aborted.html
    - shard-kbl:          ([FAIL][187], [FAIL][188], [FAIL][189], [FAIL][190], [FAIL][191], [FAIL][192], [FAIL][193]) ([fdo#109271] / [i915#180] / [i915#3002] / [i915#4312] / [i915#5257]) -> ([FAIL][194], [FAIL][195], [FAIL][196], [FAIL][197], [FAIL][198], [FAIL][199]) ([i915#180] / [i915#3002] / [i915#4312] / [i915#5257])
   [187]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-kbl6/igt@runner@aborted.html
   [188]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-kbl3/igt@runner@aborted.html
   [189]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-kbl1/igt@runner@aborted.html
   [190]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-kbl6/igt@runner@aborted.html
   [191]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-kbl6/igt@runner@aborted.html
   [192]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-kbl1/igt@runner@aborted.html
   [193]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11733/shard-kbl6/igt@runner@aborted.html
   [194]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl7/igt@runner@aborted.html
   [195]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl1/igt@runner@aborted.html
   [196]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl1/igt@runner@aborted.html
   [197]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl6/igt@runner@aborted.html
   [198]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl3/igt@runner@aborted.html
   [199]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/shard-kbl1/igt@runner@aborted.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [IGT#2]: https://gitlab.freedesktop.org/drm/igt-gpu-tools/issues/2
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109279]: https://bugs.freedesktop.org/show_bug.cgi?id=109279
  [fdo#109283]: https://bugs.freedesktop.org/show_bug.cgi?id=109283
  [fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
  [fdo#109291]: https://bugs.freedesktop.org/show_bug.cgi?id=109291
  [fdo#109300]: https://bugs.freedesktop.org/show_bug.cgi?id=109300
  [fdo#109308]: https://bugs.freedesktop.org/show_bug.cgi?id=109308
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
  [fdo#110723]: https://bugs.freedesktop.org/show_bug.cgi?id=110723
  [fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
  [fdo#111314]: https://bugs.freedesktop.org/show_bug.cgi?id=111314
  [fdo#111614]: https://bugs.freedesktop.org/show_bug.cgi?id=111614
  [fdo#111615]: https://bugs.freedesktop.org/show_bug.cgi?id=111615
  [fdo#111825]: https://bugs.freedesktop.org/show_bug.cgi?id=111825
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [fdo#112022]: https://bugs.freedesktop.org/show_bug.cgi?id=112022
  [fdo#112283]: https://bugs.freedesktop.org/show_bug.cgi?id=112283
  [i915#1063]: https://gitlab.freedesktop.org/drm/intel/issues/1063
  [i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072
  [i915#1099]: https://gitlab.freedesktop.org/drm/intel/issues/1099
  [i915#1149]: https://gitlab.freedesktop.org/drm/intel/issues/1149
  [i915#1188]: https://gitlab.freedesktop.org/drm/intel/issues/1188
  [i915#1319]: https://gitlab.freedesktop.org/drm/intel/issues/1319
  [i915#132]: https://gitlab.freedesktop.org/drm/intel/issues/132
  [i915#1397]: https://gitlab.freedesktop.org/drm/intel/issues/1397
  [i915#1542]: https://gitlab.freedesktop.org/drm/intel/issues/1542
  [i915#1722]: https://gitlab.freedesktop.org/drm/intel/issues/1722
  [i915#1769]: https://gitlab.freedesktop.org/drm/intel/issues/1769
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#1825]: https://gitlab.freedesktop.org/drm/intel/issues/1825
  [i915#1839]: https://gitlab.freedesktop.org/drm/intel/issues/1839
  [i915#1845]: https://gitlab.freedesktop.org/drm/intel/issues/1845
  [i915#1849]: https://gitlab.freedesktop.org/drm/intel/issues/1849
  [i915#1850]: https://gitlab.freedesktop.org/drm/intel/issues/1850
  [i915#1888]: https://gitlab.freedesktop.org/drm/intel/issues/1888
  [i915#1911]: https://gitlab.freedesktop.org/drm/intel/issues/1911
  [i915#1937]: https://gitlab.freedesktop.org/drm/intel/issues/1937
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2029]: https://gitlab.freedesktop.org/drm/intel/issues/2029
  [i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190
  [i915#2346]: https://gitlab.freedesktop.org/drm/intel/issues/2346
  [i915#2410]: https://gitlab.freedesktop.org/drm/intel/issues/2410
  [i915#2433]: https://gitlab.freedesktop.org/drm/intel/issues/2433
  [i915#2437]: https://gitlab.freedesktop.org/drm/intel/issues/2437
  [i915#2527]: https://gitlab.freedesktop.org/drm/intel/issues/2527
  [i915#2530]: https://gitlab.freedesktop.org/drm/intel/issues/2530
  [i915#2582]: https://gitlab.freedesktop.org/drm/intel/issues/2582
  [i915#2587]: https://gitlab.freedesktop.org/drm/intel/issues/2587
  [i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
  [i915#2672]: https://gitlab.freedesktop.org/drm/intel/issues/2672
  [i915#2842]: https://gitlab.freedesktop.org/drm/intel/issues/2842
  [i915#2849]: https://gitlab.freedesktop.org/drm/intel/issues/2849
  [i915#2920]: https://gitlab.freedesktop.org/drm/intel/issues/2920
  [i915#2994]: https://gitlab.freedesktop.org/drm/intel/issues/2994
  [i915#3002]: https://gitlab.freedesktop.org/drm/intel/issues/3002
  [i915#3063]: https://gitlab.freedesktop.org/drm/intel/issues/3063
  [i915#3281]: https://gitlab.freedesktop.org/drm/intel/issues/3281
  [i915#3282]: https://gitlab.freedesktop.org/drm/intel/issues/3282
  [i915#3297]: https://gitlab.freedesktop.org/drm/intel/issues/3297
  [i915#3318]: https://gitlab.freedesktop.org/drm/intel/issues/3318
  [i915#3319]: https://gitlab.freedesktop.org/drm/intel/issues/3319
  [i915#3359]: https://gitlab.freedesktop.org/drm/intel/issues/3359
  [i915#3458]: https://gitlab.freedesktop.org/drm/intel/issues/3458
  [i915#3464]: https://gitlab.freedesktop.org/drm/intel/issues/3464
  [i915#3536]: https://gitlab.freedesktop.org/drm/intel/issues/3536
  [i915#3539]: https://gitlab.freedesktop.org/drm/intel/issues/3539
  [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
  [i915#3558]: https://gitlab.freedesktop.org/drm/intel/issues/3558
  [i915#3637]: https://gitlab.freedesktop.org/drm/intel/issues/3637
  [i915#3638]: https://gitlab.freedesktop.org/drm/intel/issues/3638
  [i915#3689]: https://gitlab.freedesktop.org/drm/intel/issues/3689
  [i915#3701]: https://gitlab.freedesktop.org/drm/intel/issues/3701
  [i915#3708]: https://gitlab.freedesktop.org/drm/intel/issues/3708
  [i915#3734]: https://gitlab.freedesktop.org/drm/intel/issues/3734
  [i915#3742]: https://gitlab.freedesktop.org/drm/intel/issues/3742
  [i915#3778]: https://gitlab.freedesktop.org/drm/intel/issues/3778
  [i915#3810]: https://gitlab.freedesktop.org/drm/intel/issues/3810
  [i915#3828]: https://gitlab.freedesktop.org/drm/intel/issues/3828
  [i915#3840]: https://gitlab.freedesktop.org/drm/intel/issues/3840
  [i915#3886]: https://gitlab.freedesktop.org/drm/intel/issues/3886
  [i915#3921]: https://gitlab.freedesktop.org/drm/intel/issues/3921
  [i915#3987]: https://gitlab.freedesktop.org/drm/intel/issues/3987
  [i915#3989]: https://gitlab.freedesktop.org/drm/intel/issues/3989
  [i915#4036]: https://gitlab.freedesktop.org/drm/intel/issues/4036
  [i915#4070]: https://gitlab.freedesktop.org/drm/intel/issues/4070
  [i915#4077]: https://gitlab.freedesktop.org/drm/intel/issues/4077
  [i915#4078]: https://gitlab.freedesktop.org/drm/intel/issues/4078
  [i915#4079]: https://gitlab.freedesktop.org/drm/intel/issues/4079
  [i915#4083]: https://gitlab.freedesktop.org/drm/intel/issues/4083
  [i915#4098]: https://gitlab.freedesktop.org/drm/intel/issues/4098
  [i915#4103]: https://gitlab.freedesktop.org/drm/intel/issues/4103
  [i915#4212]: https://gitlab.freedesktop.org/drm/intel/issues/4212
  [i915#4270]: https://gitlab.freedesktop.org/drm/intel/issues/4270
  [i915#4278]: https://gitlab.freedesktop.org/drm/intel/issues/4278
  [i915#4312]: https://gitlab.freedesktop.org/drm/intel/issues/4312
  [i915#4369]: https://gitlab.freedesktop.org/drm/intel/issues/4369
  [i915#4387]: https://gitlab.freedesktop.org/drm/intel/issues/4387
  [i915#4494]: https://gitlab.freedesktop.org/drm/intel/issues/4494
  [i915#4525]: https://gitlab.freedesktop.org/drm/intel/issues/4525
  [i915#4538]: https://gitlab.freedesktop.org/drm/intel/issues/4538
  [i915#454]: https://gitlab.freedesktop.org/drm/intel/issues/454
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#4767]: https://gitlab.freedesktop.org/drm/intel/issues/4767
  [i915#4812]: https://gitlab.freedesktop.org/drm/intel/issues/4812
  [i915#4833]: https://gitlab.freedesktop.org/drm/intel/issues/4833
  [i915#4842]: https://gitlab.freedesktop.org/drm/intel/issues/4842
  [i915#4852]: https://gitlab.freedesktop.org/drm/intel/issues/4852
  [i915#4860]: https://gitlab.freedesktop.org/drm/intel/issues/4860
  [i915#4893]: https://gitlab.freedesktop.org/drm/intel/issues/4893
  [i915#4939]: https://gitlab.freedesktop.org/drm/intel/issues/4939
  [i915#4957]: https://gitlab.freedesktop.org/drm/intel/issues/4957
  [i915#4958]: https://gitlab.freedesktop.org/drm/intel/issues/4958
  [i915#5129]: https://gitlab.freedesktop.org/drm/intel/issues/5129
  [i915#5176]: https://gitlab.freedesktop.org/drm/intel/issues/5176
  [i915#5235]: https://gitlab.freedesktop.org/drm/intel/issues/5235
  [i915#5257]: https://gitlab.freedesktop.org/drm/intel/issues/5257
  [i915#5286]: https://gitlab.freedesktop.org/drm/intel/issues/5286
  [i915#5287]: https://gitlab.freedesktop.org/drm/intel/issues/5287
  [i915#5288]: https://gitlab.freedesktop.org/drm/intel/issues/5288
  [i915#5289]: https://gitlab.freedesktop.org/drm/intel/issues/5289
  [i915#5325]: https://gitlab.freedesktop.org/drm/intel/issues/5325
  [i915#533]: https://gitlab.freedesktop.org/drm/intel/issues/533
  [i915#5334]: https://gitlab.freedesktop.org/drm/intel/issues/5334
  [i915#5439]: https://gitlab.freedesktop.org/drm/intel/issues/5439
  [i915#5461]: https://gitlab.freedesktop.org/drm/intel/issues/5461
  [i915#5519]: https://gitlab.freedesktop.org/drm/intel/issues/5519
  [i915#5563]: https://gitlab.freedesktop.org/drm/intel/issues/5563
  [i915#5566]: https://gitlab.freedesktop.org/drm/intel/issues/5566
  [i915#5784]: https://gitlab.freedesktop.org/drm/intel/issues/5784
  [i915#588]: https://gitlab.freedesktop.org/drm/intel/issues/588
  [i915#5939]: https://gitlab.freedesktop.org/drm/intel/issues/5939
  [i915#6054]: https://gitlab.freedesktop.org/drm/intel/issues/6054
  [i915#6095]: https://gitlab.freedesktop.org/drm/intel/issues/6095
  [i915#6117]: https://gitlab.freedesktop.org/drm/intel/issues/6117
  [i915#6140]: https://gitlab.freedesktop.org/drm/intel/issues/6140
  [i915#644]: https://gitlab.freedesktop.org/drm/intel/issues/644
  [i915#658]: https://gitlab.freedesktop.org/drm/intel/issues/658
  [i915#716]: https://gitlab.freedesktop.org/drm/intel/issues/716
  [i915#79]: https://gitlab.freedesktop.org/drm/intel/issues/79


Build changes
-------------

  * Linux: CI_DRM_11733 -> Patchwork_104309v3

  CI-20190529: 20190529
  CI_DRM_11733: 4a478d4716b11a64fbc702a176ec3d078a168bc5 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6512: 5efc64e9b93a2df85581ea425ee7d0f435855f13 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_104309v3: 4a478d4716b11a64fbc702a176ec3d078a168bc5 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_104309v3/index.html

[-- Attachment #2: Type: text/html, Size: 53792 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 01/15] drm/edid: fix CTA data block collection size for CTA version 3
  2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
@ 2022-06-10 18:56     ` Ville Syrjälä
  -1 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 18:56 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:31AM +0300, Jani Nikula wrote:
> The CTA Data Block Collection is valid only for CTA extension version
> 3. In versions 1 and 2, it is a reserved block, which we ignore.
> 
> The DTD start offset (byte 2, or d in CTA-861 spec), which determines
> the CTA Data Block Collection size, is specified slightly differently
> for different versions:
> 
> Version 1:
>     d = offset for the byte following the reserved data block. If no
>     data is provided in the reserved data block, then d=4. If no DTDs
>     are provided, then d=0
> 
> Version 2:
>     d = offset for the byte following the reserved data block. If no
>     data is provided in the reserved data block, then d=4. If d=0, then
>     no detailed timing descriptors are provided, and no data is provided
>     in the reserved data block.
> 
> Version 3:
>     d = offset for the byte following the data block collection. If no
>     data is provided in the data block collection, then d=4. If d=0,
>     then no detailed timing descriptors are provided, and no data is
>     provided in the data block collection.
> 
> Ever since commit 9e50b9d55e9c ("drm: edid: Add some bounds checking"),
> we've interpreted 0 to mean there are no DTDs but it's all Data
> Blocks. Per the spec, Data Blocks are only valid for version 3, where we
> should interpret 0 to mean there are no data blocks.
> 
> Follow the spec (and hope the EDIDs follow it too).
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/drm_edid.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 929fc0e46751..c57f6333ea7d 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4498,8 +4498,6 @@ static const void *__cea_db_iter_edid_next(struct cea_db_iter *iter)
>  
>  		iter->index = 4;
>  		iter->end = ext[2];
> -		if (iter->end == 0)
> -			iter->end = 127;

Not really sure how I came up with this interpretation of the spec.

Looks like I at least fixed up the 18byte descriptor parsing
correctly in commit 7304b9810a73 ("drm/edid: Check the number
of detailed timing descriptors in the CEA ext block")

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

>  		if (iter->end < 4 || iter->end > 127)
>  			continue;
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 01/15] drm/edid: fix CTA data block collection size for CTA version 3
@ 2022-06-10 18:56     ` Ville Syrjälä
  0 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 18:56 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:31AM +0300, Jani Nikula wrote:
> The CTA Data Block Collection is valid only for CTA extension version
> 3. In versions 1 and 2, it is a reserved block, which we ignore.
> 
> The DTD start offset (byte 2, or d in CTA-861 spec), which determines
> the CTA Data Block Collection size, is specified slightly differently
> for different versions:
> 
> Version 1:
>     d = offset for the byte following the reserved data block. If no
>     data is provided in the reserved data block, then d=4. If no DTDs
>     are provided, then d=0
> 
> Version 2:
>     d = offset for the byte following the reserved data block. If no
>     data is provided in the reserved data block, then d=4. If d=0, then
>     no detailed timing descriptors are provided, and no data is provided
>     in the reserved data block.
> 
> Version 3:
>     d = offset for the byte following the data block collection. If no
>     data is provided in the data block collection, then d=4. If d=0,
>     then no detailed timing descriptors are provided, and no data is
>     provided in the data block collection.
> 
> Ever since commit 9e50b9d55e9c ("drm: edid: Add some bounds checking"),
> we've interpreted 0 to mean there are no DTDs but it's all Data
> Blocks. Per the spec, Data Blocks are only valid for version 3, where we
> should interpret 0 to mean there are no data blocks.
> 
> Follow the spec (and hope the EDIDs follow it too).
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/drm_edid.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 929fc0e46751..c57f6333ea7d 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4498,8 +4498,6 @@ static const void *__cea_db_iter_edid_next(struct cea_db_iter *iter)
>  
>  		iter->index = 4;
>  		iter->end = ext[2];
> -		if (iter->end == 0)
> -			iter->end = 127;

Not really sure how I came up with this interpretation of the spec.

Looks like I at least fixed up the 18byte descriptor parsing
correctly in commit 7304b9810a73 ("drm/edid: Check the number
of detailed timing descriptors in the CEA ext block")

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

>  		if (iter->end < 4 || iter->end > 127)
>  			continue;
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 02/15] drm/edid: abstract cea data block collection size
  2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
@ 2022-06-10 18:58     ` Ville Syrjälä
  -1 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 18:58 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:32AM +0300, Jani Nikula wrote:
> Add a function to get the cea data block collection size.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c | 24 +++++++++++++++++++++---
>  1 file changed, 21 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index c57f6333ea7d..002816509fc8 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4482,6 +4482,20 @@ __cea_db_iter_current_block(const struct cea_db_iter *iter)
>  	return NULL;
>  }
>  
> +/*
> + * References:
> + * - CTA-861-H section 7.3.3 CTA Extension Version 3
> + */
> +static int cea_db_collection_size(const u8 *cta)
> +{
> +	u8 d = cta[2];
> +
> +	if (d < 4 || d > 127)
> +		return 0;
> +
> +	return d - 4;
> +}
> +
>  /*
>   * References:
>   * - VESA E-EDID v1.4
> @@ -4492,15 +4506,19 @@ static const void *__cea_db_iter_edid_next(struct cea_db_iter *iter)
>  	const u8 *ext;
>  
>  	drm_edid_iter_for_each(ext, &iter->edid_iter) {
> +		int size;
> +
>  		/* Only support CTA Extension revision 3+ */
>  		if (ext[0] != CEA_EXT || cea_revision(ext) < 3)
>  			continue;
>  
> -		iter->index = 4;
> -		iter->end = ext[2];
> -		if (iter->end < 4 || iter->end > 127)
> +		size = cea_db_collection_size(ext);
> +		if (!size)
>  			continue;
>  
> +		iter->index = 4;
> +		iter->end = iter->index + size;
> +
>  		return ext;
>  	}
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 02/15] drm/edid: abstract cea data block collection size
@ 2022-06-10 18:58     ` Ville Syrjälä
  0 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 18:58 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:32AM +0300, Jani Nikula wrote:
> Add a function to get the cea data block collection size.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c | 24 +++++++++++++++++++++---
>  1 file changed, 21 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index c57f6333ea7d..002816509fc8 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4482,6 +4482,20 @@ __cea_db_iter_current_block(const struct cea_db_iter *iter)
>  	return NULL;
>  }
>  
> +/*
> + * References:
> + * - CTA-861-H section 7.3.3 CTA Extension Version 3
> + */
> +static int cea_db_collection_size(const u8 *cta)
> +{
> +	u8 d = cta[2];
> +
> +	if (d < 4 || d > 127)
> +		return 0;
> +
> +	return d - 4;
> +}
> +
>  /*
>   * References:
>   * - VESA E-EDID v1.4
> @@ -4492,15 +4506,19 @@ static const void *__cea_db_iter_edid_next(struct cea_db_iter *iter)
>  	const u8 *ext;
>  
>  	drm_edid_iter_for_each(ext, &iter->edid_iter) {
> +		int size;
> +
>  		/* Only support CTA Extension revision 3+ */
>  		if (ext[0] != CEA_EXT || cea_revision(ext) < 3)
>  			continue;
>  
> -		iter->index = 4;
> -		iter->end = ext[2];
> -		if (iter->end < 4 || iter->end > 127)
> +		size = cea_db_collection_size(ext);
> +		if (!size)
>  			continue;
>  
> +		iter->index = 4;
> +		iter->end = iter->index + size;
> +
>  		return ext;
>  	}
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 06/15] drm/edid: add drm_edid_connector_update()
  2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
@ 2022-06-10 19:15     ` Ville Syrjälä
  -1 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:15 UTC (permalink / raw)
  To: Jani Nikula; +Cc: David Airlie, intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:36AM +0300, Jani Nikula wrote:
> Add a new function drm_edid_connector_update() to replace the
> combination of calls drm_connector_update_edid_property() and
> drm_add_edid_modes(). Usually they are called in the drivers in this
> order, however the former needs information from the latter.
> 
> Since the new drm_edid_read*() functions no longer call the connector
> updates directly, and the read and update are separated, we'll need this
> new function for the connector update.
> 
> This is all in drm_edid.c simply to keep struct drm_edid opaque.
> 
> Cc: David Airlie <airlied@linux.ie>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/drm_connector.c |  2 +
>  drivers/gpu/drm/drm_edid.c      | 71 +++++++++++++++++++++++++++++++--
>  include/drm/drm_edid.h          |  2 +
>  3 files changed, 71 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 1c48d162c77e..ae9c640a641a 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -2088,6 +2088,8 @@ EXPORT_SYMBOL(drm_connector_set_tile_property);
>   * set the connector's tile property here. See drm_connector_set_tile_property()
>   * for more details.
>   *
> + * This function is deprecated. Use drm_edid_connector_update() instead.
> + *
>   * Returns:
>   * Zero on success, negative errno on failure.
>   */
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 2bdaf1e34a9d..952724788963 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -6143,8 +6143,8 @@ static int add_displayid_detailed_modes(struct drm_connector *connector,
>  	return num_modes;
>  }
>  
> -static int drm_edid_connector_update(struct drm_connector *connector,
> -				     const struct drm_edid *drm_edid)
> +static int _drm_edid_connector_update(struct drm_connector *connector,
> +				      const struct drm_edid *drm_edid)
>  {
>  	int num_modes = 0;
>  	u32 quirks;
> @@ -6207,6 +6207,67 @@ static int drm_edid_connector_update(struct drm_connector *connector,
>  	return num_modes;
>  }
>  
> +static void _drm_update_tile_info(struct drm_connector *connector,
> +				  const struct drm_edid *drm_edid);
> +
> +/**
> + * drm_edid_connector_update - Update connector information from EDID
> + * @connector: Connector
> + * @drm_edid: EDID
> + *
> + * Update the connector mode list, display info, ELD, HDR metadata, relevant
> + * properties, etc. from the passed in EDID.
> + *
> + * If EDID is NULL, reset the information.
> + *
> + * Return: The number of modes added or 0 if we couldn't find any.
> + */
> +int drm_edid_connector_update(struct drm_connector *connector,
> +			      const struct drm_edid *drm_edid)
> +{
> +	struct drm_device *dev = connector->dev;
> +	const struct edid *old_edid = connector->edid_blob_ptr ?
> +		connector->edid_blob_ptr->data : NULL;
> +	const struct edid *edid = drm_edid ? drm_edid->edid : NULL;
> +	size_t size = drm_edid ? drm_edid->size : 0;
> +	int count, ret;
> +
> +	count = _drm_edid_connector_update(connector, drm_edid);
> +
> +	_drm_update_tile_info(connector, drm_edid);
> +
> +	if (old_edid && !drm_edid_are_equal(edid, old_edid)) {

The old_edid check looks a bit odd. Can't really see why we'd not
want to bump the epoch counter when we go from not having and EDID
to having one. This issue already seems to exist in the current code,
although that one also skips the epoch counter bump if the new EDID
is missing, so even more odd.

This also brings me to the slight annoynace of having this code
duplicated in two places. I worry we'll end up accumulating different
bugs in each copy. Can't we refactor to have just one copy?

> +		connector->epoch_counter++;
> +
> +		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID changed, epoch counter %llu\n",
> +			    connector->base.id, connector->name,
> +			    connector->epoch_counter);
> +	}
> +
> +	ret = drm_property_replace_global_blob(dev, &connector->edid_blob_ptr,
> +					       size, edid,
> +					       &connector->base,
> +					       dev->mode_config.edid_property);
> +	if (ret)
> +		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID property update failed (%d)\n",
> +			    connector->base.id, connector->name, ret);
> +
> +	ret = drm_object_property_set_value(&connector->base,
> +					    dev->mode_config.non_desktop_property,
> +					    connector->display_info.non_desktop);
> +	if (ret)
> +		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Non-desktop property update failed (%d)\n",
> +			    connector->base.id, connector->name, ret);
> +
> +	ret = drm_connector_set_tile_property(connector);
> +	if (ret)
> +		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Tile property update failed (%d)\n",
> +			    connector->base.id, connector->name, ret);
> +
> +	return count;
> +}
> +EXPORT_SYMBOL(drm_edid_connector_update);
> +
>  /**
>   * drm_add_edid_modes - add modes from EDID data, if available
>   * @connector: connector we're probing
> @@ -6216,6 +6277,8 @@ static int drm_edid_connector_update(struct drm_connector *connector,
>   * &drm_display_info structure and ELD in @connector with any information which
>   * can be derived from the edid.
>   *
> + * This function is deprecated. Use drm_edid_connector_update() instead.
> + *
>   * Return: The number of modes added or 0 if we couldn't find any.
>   */
>  int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
> @@ -6228,8 +6291,8 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
>  		edid = NULL;
>  	}
>  
> -	return drm_edid_connector_update(connector,
> -					 drm_edid_legacy_init(&drm_edid, edid));
> +	return _drm_edid_connector_update(connector,
> +					  drm_edid_legacy_init(&drm_edid, edid));
>  }
>  EXPORT_SYMBOL(drm_add_edid_modes);
>  
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 9d2d78135dee..aeb2fa95bc04 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -603,6 +603,8 @@ const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
>  const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
>  					    int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),
>  					    void *context);
> +int drm_edid_connector_update(struct drm_connector *connector,
> +			      const struct drm_edid *edid);
>  const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
>  				  int ext_id, int *ext_index);
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 06/15] drm/edid: add drm_edid_connector_update()
@ 2022-06-10 19:15     ` Ville Syrjälä
  0 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:15 UTC (permalink / raw)
  To: Jani Nikula; +Cc: David Airlie, intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:36AM +0300, Jani Nikula wrote:
> Add a new function drm_edid_connector_update() to replace the
> combination of calls drm_connector_update_edid_property() and
> drm_add_edid_modes(). Usually they are called in the drivers in this
> order, however the former needs information from the latter.
> 
> Since the new drm_edid_read*() functions no longer call the connector
> updates directly, and the read and update are separated, we'll need this
> new function for the connector update.
> 
> This is all in drm_edid.c simply to keep struct drm_edid opaque.
> 
> Cc: David Airlie <airlied@linux.ie>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/drm_connector.c |  2 +
>  drivers/gpu/drm/drm_edid.c      | 71 +++++++++++++++++++++++++++++++--
>  include/drm/drm_edid.h          |  2 +
>  3 files changed, 71 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 1c48d162c77e..ae9c640a641a 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -2088,6 +2088,8 @@ EXPORT_SYMBOL(drm_connector_set_tile_property);
>   * set the connector's tile property here. See drm_connector_set_tile_property()
>   * for more details.
>   *
> + * This function is deprecated. Use drm_edid_connector_update() instead.
> + *
>   * Returns:
>   * Zero on success, negative errno on failure.
>   */
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 2bdaf1e34a9d..952724788963 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -6143,8 +6143,8 @@ static int add_displayid_detailed_modes(struct drm_connector *connector,
>  	return num_modes;
>  }
>  
> -static int drm_edid_connector_update(struct drm_connector *connector,
> -				     const struct drm_edid *drm_edid)
> +static int _drm_edid_connector_update(struct drm_connector *connector,
> +				      const struct drm_edid *drm_edid)
>  {
>  	int num_modes = 0;
>  	u32 quirks;
> @@ -6207,6 +6207,67 @@ static int drm_edid_connector_update(struct drm_connector *connector,
>  	return num_modes;
>  }
>  
> +static void _drm_update_tile_info(struct drm_connector *connector,
> +				  const struct drm_edid *drm_edid);
> +
> +/**
> + * drm_edid_connector_update - Update connector information from EDID
> + * @connector: Connector
> + * @drm_edid: EDID
> + *
> + * Update the connector mode list, display info, ELD, HDR metadata, relevant
> + * properties, etc. from the passed in EDID.
> + *
> + * If EDID is NULL, reset the information.
> + *
> + * Return: The number of modes added or 0 if we couldn't find any.
> + */
> +int drm_edid_connector_update(struct drm_connector *connector,
> +			      const struct drm_edid *drm_edid)
> +{
> +	struct drm_device *dev = connector->dev;
> +	const struct edid *old_edid = connector->edid_blob_ptr ?
> +		connector->edid_blob_ptr->data : NULL;
> +	const struct edid *edid = drm_edid ? drm_edid->edid : NULL;
> +	size_t size = drm_edid ? drm_edid->size : 0;
> +	int count, ret;
> +
> +	count = _drm_edid_connector_update(connector, drm_edid);
> +
> +	_drm_update_tile_info(connector, drm_edid);
> +
> +	if (old_edid && !drm_edid_are_equal(edid, old_edid)) {

The old_edid check looks a bit odd. Can't really see why we'd not
want to bump the epoch counter when we go from not having and EDID
to having one. This issue already seems to exist in the current code,
although that one also skips the epoch counter bump if the new EDID
is missing, so even more odd.

This also brings me to the slight annoynace of having this code
duplicated in two places. I worry we'll end up accumulating different
bugs in each copy. Can't we refactor to have just one copy?

> +		connector->epoch_counter++;
> +
> +		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID changed, epoch counter %llu\n",
> +			    connector->base.id, connector->name,
> +			    connector->epoch_counter);
> +	}
> +
> +	ret = drm_property_replace_global_blob(dev, &connector->edid_blob_ptr,
> +					       size, edid,
> +					       &connector->base,
> +					       dev->mode_config.edid_property);
> +	if (ret)
> +		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID property update failed (%d)\n",
> +			    connector->base.id, connector->name, ret);
> +
> +	ret = drm_object_property_set_value(&connector->base,
> +					    dev->mode_config.non_desktop_property,
> +					    connector->display_info.non_desktop);
> +	if (ret)
> +		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Non-desktop property update failed (%d)\n",
> +			    connector->base.id, connector->name, ret);
> +
> +	ret = drm_connector_set_tile_property(connector);
> +	if (ret)
> +		drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Tile property update failed (%d)\n",
> +			    connector->base.id, connector->name, ret);
> +
> +	return count;
> +}
> +EXPORT_SYMBOL(drm_edid_connector_update);
> +
>  /**
>   * drm_add_edid_modes - add modes from EDID data, if available
>   * @connector: connector we're probing
> @@ -6216,6 +6277,8 @@ static int drm_edid_connector_update(struct drm_connector *connector,
>   * &drm_display_info structure and ELD in @connector with any information which
>   * can be derived from the edid.
>   *
> + * This function is deprecated. Use drm_edid_connector_update() instead.
> + *
>   * Return: The number of modes added or 0 if we couldn't find any.
>   */
>  int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
> @@ -6228,8 +6291,8 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
>  		edid = NULL;
>  	}
>  
> -	return drm_edid_connector_update(connector,
> -					 drm_edid_legacy_init(&drm_edid, edid));
> +	return _drm_edid_connector_update(connector,
> +					  drm_edid_legacy_init(&drm_edid, edid));
>  }
>  EXPORT_SYMBOL(drm_add_edid_modes);
>  
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 9d2d78135dee..aeb2fa95bc04 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -603,6 +603,8 @@ const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
>  const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
>  					    int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),
>  					    void *context);
> +int drm_edid_connector_update(struct drm_connector *connector,
> +			      const struct drm_edid *edid);
>  const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
>  				  int ext_id, int *ext_index);
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 10/15] drm/i915/edid: convert DP, HDMI and LVDS to drm_edid
  2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
@ 2022-06-10 19:21     ` Ville Syrjälä
  -1 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:21 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:40AM +0300, Jani Nikula wrote:
> Convert all the connectors that use cached connector edid and
> detect_edid to drm_edid.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  .../gpu/drm/i915/display/intel_connector.c    |  4 +-
>  .../drm/i915/display/intel_display_types.h    |  4 +-
>  drivers/gpu/drm/i915/display/intel_dp.c       | 74 ++++++++++---------
>  drivers/gpu/drm/i915/display/intel_hdmi.c     | 26 ++++---
>  drivers/gpu/drm/i915/display/intel_lvds.c     | 37 +++++-----
>  5 files changed, 79 insertions(+), 66 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c
> index 1dcc268927a2..d83b2a64f618 100644
> --- a/drivers/gpu/drm/i915/display/intel_connector.c
> +++ b/drivers/gpu/drm/i915/display/intel_connector.c
> @@ -95,12 +95,12 @@ void intel_connector_destroy(struct drm_connector *connector)
>  {
>  	struct intel_connector *intel_connector = to_intel_connector(connector);
>  
> -	kfree(intel_connector->detect_edid);
> +	drm_edid_free(intel_connector->detect_edid);
>  
>  	intel_hdcp_cleanup(intel_connector);
>  
>  	if (!IS_ERR_OR_NULL(intel_connector->edid))
> -		kfree(intel_connector->edid);
> +		drm_edid_free(intel_connector->edid);
>  
>  	intel_panel_fini(intel_connector);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 9b44358e8d9e..dffbc7d59587 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -590,8 +590,8 @@ struct intel_connector {
>  	struct intel_panel panel;
>  
>  	/* Cached EDID for eDP and LVDS. May hold ERR_PTR for invalid EDID. */
> -	struct edid *edid;
> -	struct edid *detect_edid;
> +	const struct drm_edid *edid;
> +	const struct drm_edid *detect_edid;
>  
>  	/* Number of times hotplug detection was tried after an HPD interrupt */
>  	int hotplug_retries;
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index e198c6d7e3b5..64b6481225f1 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -3534,12 +3534,11 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
>  				    intel_dp->aux.i2c_defer_count);
>  		intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_FAILSAFE;
>  	} else {
> -		struct edid *block = intel_connector->detect_edid;
> +		/* FIXME: Get rid of drm_edid_raw() */
> +		const struct edid *block = drm_edid_raw(intel_connector->detect_edid);
>  
> -		/* We have to write the checksum
> -		 * of the last block read
> -		 */
> -		block += intel_connector->detect_edid->extensions;
> +		/* We have to write the checksum of the last block read */
> +		block += block->extensions;
>  
>  		if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM,
>  				       block->checksum) <= 0)
> @@ -4418,7 +4417,7 @@ bool intel_digital_port_connected(struct intel_encoder *encoder)
>  	return is_connected;
>  }
>  
> -static struct edid *
> +static const struct drm_edid *
>  intel_dp_get_edid(struct intel_dp *intel_dp)
>  {
>  	struct intel_connector *intel_connector = intel_dp->attached_connector;
> @@ -4429,18 +4428,22 @@ intel_dp_get_edid(struct intel_dp *intel_dp)
>  		if (IS_ERR(intel_connector->edid))
>  			return NULL;
>  
> -		return drm_edid_duplicate(intel_connector->edid);
> +		return drm_edid_dup(intel_connector->edid);
>  	} else
> -		return drm_get_edid(&intel_connector->base,
> -				    &intel_dp->aux.ddc);
> +		return drm_edid_read_ddc(&intel_connector->base,
> +					 &intel_dp->aux.ddc);
>  }
>  
>  static void
>  intel_dp_update_dfp(struct intel_dp *intel_dp,
> -		    const struct edid *edid)
> +		    const struct drm_edid *drm_edid)
>  {
>  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>  	struct intel_connector *connector = intel_dp->attached_connector;
> +	const struct edid *edid;
> +
> +	/* FIXME: Get rid of drm_edid_raw() */
> +	edid = drm_edid_raw(drm_edid);
>  
>  	intel_dp->dfp.max_bpc =
>  		drm_dp_downstream_max_bpc(intel_dp->dpcd,
> @@ -4540,21 +4543,24 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
>  {
>  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>  	struct intel_connector *connector = intel_dp->attached_connector;
> -	struct edid *edid;
> +	const struct drm_edid *drm_edid;
> +	const struct edid *edid;
>  	bool vrr_capable;
>  
>  	intel_dp_unset_edid(intel_dp);
> -	edid = intel_dp_get_edid(intel_dp);
> -	connector->detect_edid = edid;
> +	drm_edid = intel_dp_get_edid(intel_dp);
> +	connector->detect_edid = drm_edid;
>  
>  	vrr_capable = intel_vrr_is_capable(connector);
>  	drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] VRR capable: %s\n",
>  		    connector->base.base.id, connector->base.name, str_yes_no(vrr_capable));
>  	drm_connector_set_vrr_capable_property(&connector->base, vrr_capable);
>  
> -	intel_dp_update_dfp(intel_dp, edid);
> +	intel_dp_update_dfp(intel_dp, drm_edid);
>  	intel_dp_update_420(intel_dp);
>  
> +	/* FIXME: Get rid of drm_edid_raw() */
> +	edid = drm_edid_raw(drm_edid);
>  	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
>  		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
>  		intel_dp->has_audio = drm_detect_monitor_audio(edid);
> @@ -4569,7 +4575,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
>  	struct intel_connector *connector = intel_dp->attached_connector;
>  
>  	drm_dp_cec_unset_edid(&intel_dp->aux);
> -	kfree(connector->detect_edid);
> +	drm_edid_free(connector->detect_edid);
>  	connector->detect_edid = NULL;
>  
>  	intel_dp->has_hdmi_sink = false;
> @@ -4733,12 +4739,11 @@ intel_dp_force(struct drm_connector *connector)
>  static int intel_dp_get_modes(struct drm_connector *connector)
>  {
>  	struct intel_connector *intel_connector = to_intel_connector(connector);
> -	struct edid *edid;
> +	const struct drm_edid *drm_edid;
>  	int num_modes = 0;
>  
> -	edid = intel_connector->detect_edid;
> -	if (edid)
> -		num_modes = intel_connector_update_modes(connector, edid);
> +	drm_edid = intel_connector->detect_edid;
> +	num_modes = drm_edid_connector_update(connector, drm_edid);
>  
>  	/* Also add fixed mode, which may or may not be present in EDID */
>  	if (intel_dp_is_edp(intel_attached_dp(intel_connector)))
> @@ -4747,7 +4752,7 @@ static int intel_dp_get_modes(struct drm_connector *connector)
>  	if (num_modes)
>  		return num_modes;
>  
> -	if (!edid) {
> +	if (!drm_edid) {
>  		struct intel_dp *intel_dp = intel_attached_dp(intel_connector);
>  		struct drm_display_mode *mode;
>  
> @@ -5154,7 +5159,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
>  	struct drm_display_mode *fixed_mode;
>  	bool has_dpcd;
>  	enum pipe pipe = INVALID_PIPE;
> -	struct edid *edid;
> +	const struct drm_edid *drm_edid;
>  
>  	if (!intel_dp_is_edp(intel_dp))
>  		return true;
> @@ -5187,29 +5192,32 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
>  	}
>  
>  	mutex_lock(&dev->mode_config.mutex);
> -	edid = drm_get_edid(connector, &intel_dp->aux.ddc);
> -	if (!edid) {
> +	drm_edid = drm_edid_read_ddc(connector, &intel_dp->aux.ddc);
> +	if (!drm_edid) {
> +		const struct edid *edid;
> +
>  		/* Fallback to EDID from ACPI OpRegion, if any */
> +		/* FIXME: Make intel_opregion_get_edid() return drm_edid */
>  		edid = intel_opregion_get_edid(intel_connector);
> -		if (edid)
> +		if (edid) {
> +			drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) * EDID_LENGTH);

Didn't drm_edid_alloc() duplicate the whole edid?
Are we potentially leaking here now?

>  			drm_dbg_kms(&dev_priv->drm,
>  				    "[CONNECTOR:%d:%s] Using OpRegion EDID\n",
>  				    connector->base.id, connector->name);
> +		}
>  	}
> -	if (edid) {
> -		if (drm_add_edid_modes(connector, edid)) {
> -			drm_connector_update_edid_property(connector, edid);
> -		} else {
> -			kfree(edid);
> -			edid = ERR_PTR(-EINVAL);
> +	if (drm_edid) {
> +		if (!drm_edid_connector_update(connector, drm_edid)) {
> +			drm_edid_free(drm_edid);
> +			drm_edid = ERR_PTR(-EINVAL);
>  		}
>  	} else {
> -		edid = ERR_PTR(-ENOENT);
> +		drm_edid = ERR_PTR(-ENOENT);
>  	}
> -	intel_connector->edid = edid;
> +	intel_connector->edid = drm_edid;
>  
>  	intel_bios_init_panel(dev_priv, &intel_connector->panel,
> -			      IS_ERR(edid) ? NULL : edid);
> +			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
>  
>  	intel_panel_add_edid_fixed_modes(intel_connector,
>  					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index 1ae09431f53a..db33a0ccd7ee 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -2340,7 +2340,7 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
>  	intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
>  	intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
>  
> -	kfree(to_intel_connector(connector)->detect_edid);
> +	drm_edid_free(to_intel_connector(connector)->detect_edid);
>  	to_intel_connector(connector)->detect_edid = NULL;
>  }
>  
> @@ -2407,7 +2407,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
>  	struct drm_i915_private *dev_priv = to_i915(connector->dev);
>  	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
>  	intel_wakeref_t wakeref;
> -	struct edid *edid;
> +	const struct drm_edid *drm_edid;
> +	const struct edid *edid;
>  	bool connected = false;
>  	struct i2c_adapter *i2c;
>  
> @@ -2415,21 +2416,24 @@ intel_hdmi_set_edid(struct drm_connector *connector)
>  
>  	i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
>  
> -	edid = drm_get_edid(connector, i2c);
> +	drm_edid = drm_edid_read_ddc(connector, i2c);
>  
> -	if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
> +	if (!drm_edid && !intel_gmbus_is_forced_bit(i2c)) {
>  		drm_dbg_kms(&dev_priv->drm,
>  			    "HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");
>  		intel_gmbus_force_bit(i2c, true);
> -		edid = drm_get_edid(connector, i2c);
> +		drm_edid = drm_edid_read_ddc(connector, i2c);
>  		intel_gmbus_force_bit(i2c, false);
>  	}
>  
> -	intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
> +	intel_hdmi_dp_dual_mode_detect(connector, drm_edid != NULL);
>  
>  	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
>  
> -	to_intel_connector(connector)->detect_edid = edid;
> +	to_intel_connector(connector)->detect_edid = drm_edid;
> +
> +	/* FIXME: Get rid of drm_edid_raw() */
> +	edid = drm_edid_raw(drm_edid);
>  	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
>  		intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
>  		intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
> @@ -2501,13 +2505,11 @@ intel_hdmi_force(struct drm_connector *connector)
>  
>  static int intel_hdmi_get_modes(struct drm_connector *connector)
>  {
> -	struct edid *edid;
> +	const struct drm_edid *drm_edid;
>  
> -	edid = to_intel_connector(connector)->detect_edid;
> -	if (edid == NULL)
> -		return 0;
> +	drm_edid = to_intel_connector(connector)->detect_edid;
>  
> -	return intel_connector_update_modes(connector, edid);
> +	return drm_edid_connector_update(connector, drm_edid);
>  }
>  
>  static struct i2c_adapter *
> diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
> index e55802b45461..d4389054bf59 100644
> --- a/drivers/gpu/drm/i915/display/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/display/intel_lvds.c
> @@ -479,7 +479,7 @@ static int intel_lvds_get_modes(struct drm_connector *connector)
>  
>  	/* use cached edid if we have one */
>  	if (!IS_ERR_OR_NULL(intel_connector->edid))
> -		return drm_add_edid_modes(connector, intel_connector->edid);
> +		return drm_edid_connector_update(connector, intel_connector->edid);
>  
>  	return intel_panel_get_modes(intel_connector);
>  }
> @@ -829,7 +829,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
>  	struct intel_connector *intel_connector;
>  	struct drm_connector *connector;
>  	struct drm_encoder *encoder;
> -	struct edid *edid;
> +	const struct drm_edid *drm_edid;
>  	i915_reg_t lvds_reg;
>  	u32 lvds;
>  	u8 pin;
> @@ -948,27 +948,30 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
>  	 * preferred mode is the right one.
>  	 */
>  	mutex_lock(&dev->mode_config.mutex);
> -	if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC)
> +	if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) {
> +		const struct edid *edid;
> +
> +		/* FIXME: Make drm_get_edid_switcheroo() return drm_edid */
>  		edid = drm_get_edid_switcheroo(connector,
> -				    intel_gmbus_get_adapter(dev_priv, pin));
> -	else
> -		edid = drm_get_edid(connector,
> -				    intel_gmbus_get_adapter(dev_priv, pin));
> -	if (edid) {
> -		if (drm_add_edid_modes(connector, edid)) {
> -			drm_connector_update_edid_property(connector,
> -								edid);
> -		} else {
> -			kfree(edid);
> -			edid = ERR_PTR(-EINVAL);
> +					       intel_gmbus_get_adapter(dev_priv, pin));
> +		if (edid)
> +			drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) * EDID_LENGTH);
> +	} else {
> +		drm_edid = drm_edid_read_ddc(connector,
> +					     intel_gmbus_get_adapter(dev_priv, pin));
> +	}
> +	if (drm_edid) {
> +		if (!drm_edid_connector_update(connector, drm_edid)) {
> +			drm_edid_free(drm_edid);
> +			drm_edid = ERR_PTR(-EINVAL);
>  		}
>  	} else {
> -		edid = ERR_PTR(-ENOENT);
> +		drm_edid = ERR_PTR(-ENOENT);
>  	}
> -	intel_connector->edid = edid;
> +	intel_connector->edid = drm_edid;
>  
>  	intel_bios_init_panel(dev_priv, &intel_connector->panel,
> -			      IS_ERR(edid) ? NULL : edid);
> +			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
>  
>  	/* Try EDID first */
>  	intel_panel_add_edid_fixed_modes(intel_connector,
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 10/15] drm/i915/edid: convert DP, HDMI and LVDS to drm_edid
@ 2022-06-10 19:21     ` Ville Syrjälä
  0 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:21 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:40AM +0300, Jani Nikula wrote:
> Convert all the connectors that use cached connector edid and
> detect_edid to drm_edid.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  .../gpu/drm/i915/display/intel_connector.c    |  4 +-
>  .../drm/i915/display/intel_display_types.h    |  4 +-
>  drivers/gpu/drm/i915/display/intel_dp.c       | 74 ++++++++++---------
>  drivers/gpu/drm/i915/display/intel_hdmi.c     | 26 ++++---
>  drivers/gpu/drm/i915/display/intel_lvds.c     | 37 +++++-----
>  5 files changed, 79 insertions(+), 66 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c
> index 1dcc268927a2..d83b2a64f618 100644
> --- a/drivers/gpu/drm/i915/display/intel_connector.c
> +++ b/drivers/gpu/drm/i915/display/intel_connector.c
> @@ -95,12 +95,12 @@ void intel_connector_destroy(struct drm_connector *connector)
>  {
>  	struct intel_connector *intel_connector = to_intel_connector(connector);
>  
> -	kfree(intel_connector->detect_edid);
> +	drm_edid_free(intel_connector->detect_edid);
>  
>  	intel_hdcp_cleanup(intel_connector);
>  
>  	if (!IS_ERR_OR_NULL(intel_connector->edid))
> -		kfree(intel_connector->edid);
> +		drm_edid_free(intel_connector->edid);
>  
>  	intel_panel_fini(intel_connector);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 9b44358e8d9e..dffbc7d59587 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -590,8 +590,8 @@ struct intel_connector {
>  	struct intel_panel panel;
>  
>  	/* Cached EDID for eDP and LVDS. May hold ERR_PTR for invalid EDID. */
> -	struct edid *edid;
> -	struct edid *detect_edid;
> +	const struct drm_edid *edid;
> +	const struct drm_edid *detect_edid;
>  
>  	/* Number of times hotplug detection was tried after an HPD interrupt */
>  	int hotplug_retries;
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index e198c6d7e3b5..64b6481225f1 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -3534,12 +3534,11 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
>  				    intel_dp->aux.i2c_defer_count);
>  		intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_FAILSAFE;
>  	} else {
> -		struct edid *block = intel_connector->detect_edid;
> +		/* FIXME: Get rid of drm_edid_raw() */
> +		const struct edid *block = drm_edid_raw(intel_connector->detect_edid);
>  
> -		/* We have to write the checksum
> -		 * of the last block read
> -		 */
> -		block += intel_connector->detect_edid->extensions;
> +		/* We have to write the checksum of the last block read */
> +		block += block->extensions;
>  
>  		if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM,
>  				       block->checksum) <= 0)
> @@ -4418,7 +4417,7 @@ bool intel_digital_port_connected(struct intel_encoder *encoder)
>  	return is_connected;
>  }
>  
> -static struct edid *
> +static const struct drm_edid *
>  intel_dp_get_edid(struct intel_dp *intel_dp)
>  {
>  	struct intel_connector *intel_connector = intel_dp->attached_connector;
> @@ -4429,18 +4428,22 @@ intel_dp_get_edid(struct intel_dp *intel_dp)
>  		if (IS_ERR(intel_connector->edid))
>  			return NULL;
>  
> -		return drm_edid_duplicate(intel_connector->edid);
> +		return drm_edid_dup(intel_connector->edid);
>  	} else
> -		return drm_get_edid(&intel_connector->base,
> -				    &intel_dp->aux.ddc);
> +		return drm_edid_read_ddc(&intel_connector->base,
> +					 &intel_dp->aux.ddc);
>  }
>  
>  static void
>  intel_dp_update_dfp(struct intel_dp *intel_dp,
> -		    const struct edid *edid)
> +		    const struct drm_edid *drm_edid)
>  {
>  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>  	struct intel_connector *connector = intel_dp->attached_connector;
> +	const struct edid *edid;
> +
> +	/* FIXME: Get rid of drm_edid_raw() */
> +	edid = drm_edid_raw(drm_edid);
>  
>  	intel_dp->dfp.max_bpc =
>  		drm_dp_downstream_max_bpc(intel_dp->dpcd,
> @@ -4540,21 +4543,24 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
>  {
>  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>  	struct intel_connector *connector = intel_dp->attached_connector;
> -	struct edid *edid;
> +	const struct drm_edid *drm_edid;
> +	const struct edid *edid;
>  	bool vrr_capable;
>  
>  	intel_dp_unset_edid(intel_dp);
> -	edid = intel_dp_get_edid(intel_dp);
> -	connector->detect_edid = edid;
> +	drm_edid = intel_dp_get_edid(intel_dp);
> +	connector->detect_edid = drm_edid;
>  
>  	vrr_capable = intel_vrr_is_capable(connector);
>  	drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] VRR capable: %s\n",
>  		    connector->base.base.id, connector->base.name, str_yes_no(vrr_capable));
>  	drm_connector_set_vrr_capable_property(&connector->base, vrr_capable);
>  
> -	intel_dp_update_dfp(intel_dp, edid);
> +	intel_dp_update_dfp(intel_dp, drm_edid);
>  	intel_dp_update_420(intel_dp);
>  
> +	/* FIXME: Get rid of drm_edid_raw() */
> +	edid = drm_edid_raw(drm_edid);
>  	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
>  		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
>  		intel_dp->has_audio = drm_detect_monitor_audio(edid);
> @@ -4569,7 +4575,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
>  	struct intel_connector *connector = intel_dp->attached_connector;
>  
>  	drm_dp_cec_unset_edid(&intel_dp->aux);
> -	kfree(connector->detect_edid);
> +	drm_edid_free(connector->detect_edid);
>  	connector->detect_edid = NULL;
>  
>  	intel_dp->has_hdmi_sink = false;
> @@ -4733,12 +4739,11 @@ intel_dp_force(struct drm_connector *connector)
>  static int intel_dp_get_modes(struct drm_connector *connector)
>  {
>  	struct intel_connector *intel_connector = to_intel_connector(connector);
> -	struct edid *edid;
> +	const struct drm_edid *drm_edid;
>  	int num_modes = 0;
>  
> -	edid = intel_connector->detect_edid;
> -	if (edid)
> -		num_modes = intel_connector_update_modes(connector, edid);
> +	drm_edid = intel_connector->detect_edid;
> +	num_modes = drm_edid_connector_update(connector, drm_edid);
>  
>  	/* Also add fixed mode, which may or may not be present in EDID */
>  	if (intel_dp_is_edp(intel_attached_dp(intel_connector)))
> @@ -4747,7 +4752,7 @@ static int intel_dp_get_modes(struct drm_connector *connector)
>  	if (num_modes)
>  		return num_modes;
>  
> -	if (!edid) {
> +	if (!drm_edid) {
>  		struct intel_dp *intel_dp = intel_attached_dp(intel_connector);
>  		struct drm_display_mode *mode;
>  
> @@ -5154,7 +5159,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
>  	struct drm_display_mode *fixed_mode;
>  	bool has_dpcd;
>  	enum pipe pipe = INVALID_PIPE;
> -	struct edid *edid;
> +	const struct drm_edid *drm_edid;
>  
>  	if (!intel_dp_is_edp(intel_dp))
>  		return true;
> @@ -5187,29 +5192,32 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
>  	}
>  
>  	mutex_lock(&dev->mode_config.mutex);
> -	edid = drm_get_edid(connector, &intel_dp->aux.ddc);
> -	if (!edid) {
> +	drm_edid = drm_edid_read_ddc(connector, &intel_dp->aux.ddc);
> +	if (!drm_edid) {
> +		const struct edid *edid;
> +
>  		/* Fallback to EDID from ACPI OpRegion, if any */
> +		/* FIXME: Make intel_opregion_get_edid() return drm_edid */
>  		edid = intel_opregion_get_edid(intel_connector);
> -		if (edid)
> +		if (edid) {
> +			drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) * EDID_LENGTH);

Didn't drm_edid_alloc() duplicate the whole edid?
Are we potentially leaking here now?

>  			drm_dbg_kms(&dev_priv->drm,
>  				    "[CONNECTOR:%d:%s] Using OpRegion EDID\n",
>  				    connector->base.id, connector->name);
> +		}
>  	}
> -	if (edid) {
> -		if (drm_add_edid_modes(connector, edid)) {
> -			drm_connector_update_edid_property(connector, edid);
> -		} else {
> -			kfree(edid);
> -			edid = ERR_PTR(-EINVAL);
> +	if (drm_edid) {
> +		if (!drm_edid_connector_update(connector, drm_edid)) {
> +			drm_edid_free(drm_edid);
> +			drm_edid = ERR_PTR(-EINVAL);
>  		}
>  	} else {
> -		edid = ERR_PTR(-ENOENT);
> +		drm_edid = ERR_PTR(-ENOENT);
>  	}
> -	intel_connector->edid = edid;
> +	intel_connector->edid = drm_edid;
>  
>  	intel_bios_init_panel(dev_priv, &intel_connector->panel,
> -			      IS_ERR(edid) ? NULL : edid);
> +			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
>  
>  	intel_panel_add_edid_fixed_modes(intel_connector,
>  					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index 1ae09431f53a..db33a0ccd7ee 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -2340,7 +2340,7 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
>  	intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
>  	intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
>  
> -	kfree(to_intel_connector(connector)->detect_edid);
> +	drm_edid_free(to_intel_connector(connector)->detect_edid);
>  	to_intel_connector(connector)->detect_edid = NULL;
>  }
>  
> @@ -2407,7 +2407,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
>  	struct drm_i915_private *dev_priv = to_i915(connector->dev);
>  	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
>  	intel_wakeref_t wakeref;
> -	struct edid *edid;
> +	const struct drm_edid *drm_edid;
> +	const struct edid *edid;
>  	bool connected = false;
>  	struct i2c_adapter *i2c;
>  
> @@ -2415,21 +2416,24 @@ intel_hdmi_set_edid(struct drm_connector *connector)
>  
>  	i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
>  
> -	edid = drm_get_edid(connector, i2c);
> +	drm_edid = drm_edid_read_ddc(connector, i2c);
>  
> -	if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
> +	if (!drm_edid && !intel_gmbus_is_forced_bit(i2c)) {
>  		drm_dbg_kms(&dev_priv->drm,
>  			    "HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");
>  		intel_gmbus_force_bit(i2c, true);
> -		edid = drm_get_edid(connector, i2c);
> +		drm_edid = drm_edid_read_ddc(connector, i2c);
>  		intel_gmbus_force_bit(i2c, false);
>  	}
>  
> -	intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
> +	intel_hdmi_dp_dual_mode_detect(connector, drm_edid != NULL);
>  
>  	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
>  
> -	to_intel_connector(connector)->detect_edid = edid;
> +	to_intel_connector(connector)->detect_edid = drm_edid;
> +
> +	/* FIXME: Get rid of drm_edid_raw() */
> +	edid = drm_edid_raw(drm_edid);
>  	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
>  		intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
>  		intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
> @@ -2501,13 +2505,11 @@ intel_hdmi_force(struct drm_connector *connector)
>  
>  static int intel_hdmi_get_modes(struct drm_connector *connector)
>  {
> -	struct edid *edid;
> +	const struct drm_edid *drm_edid;
>  
> -	edid = to_intel_connector(connector)->detect_edid;
> -	if (edid == NULL)
> -		return 0;
> +	drm_edid = to_intel_connector(connector)->detect_edid;
>  
> -	return intel_connector_update_modes(connector, edid);
> +	return drm_edid_connector_update(connector, drm_edid);
>  }
>  
>  static struct i2c_adapter *
> diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
> index e55802b45461..d4389054bf59 100644
> --- a/drivers/gpu/drm/i915/display/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/display/intel_lvds.c
> @@ -479,7 +479,7 @@ static int intel_lvds_get_modes(struct drm_connector *connector)
>  
>  	/* use cached edid if we have one */
>  	if (!IS_ERR_OR_NULL(intel_connector->edid))
> -		return drm_add_edid_modes(connector, intel_connector->edid);
> +		return drm_edid_connector_update(connector, intel_connector->edid);
>  
>  	return intel_panel_get_modes(intel_connector);
>  }
> @@ -829,7 +829,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
>  	struct intel_connector *intel_connector;
>  	struct drm_connector *connector;
>  	struct drm_encoder *encoder;
> -	struct edid *edid;
> +	const struct drm_edid *drm_edid;
>  	i915_reg_t lvds_reg;
>  	u32 lvds;
>  	u8 pin;
> @@ -948,27 +948,30 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
>  	 * preferred mode is the right one.
>  	 */
>  	mutex_lock(&dev->mode_config.mutex);
> -	if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC)
> +	if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) {
> +		const struct edid *edid;
> +
> +		/* FIXME: Make drm_get_edid_switcheroo() return drm_edid */
>  		edid = drm_get_edid_switcheroo(connector,
> -				    intel_gmbus_get_adapter(dev_priv, pin));
> -	else
> -		edid = drm_get_edid(connector,
> -				    intel_gmbus_get_adapter(dev_priv, pin));
> -	if (edid) {
> -		if (drm_add_edid_modes(connector, edid)) {
> -			drm_connector_update_edid_property(connector,
> -								edid);
> -		} else {
> -			kfree(edid);
> -			edid = ERR_PTR(-EINVAL);
> +					       intel_gmbus_get_adapter(dev_priv, pin));
> +		if (edid)
> +			drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) * EDID_LENGTH);
> +	} else {
> +		drm_edid = drm_edid_read_ddc(connector,
> +					     intel_gmbus_get_adapter(dev_priv, pin));
> +	}
> +	if (drm_edid) {
> +		if (!drm_edid_connector_update(connector, drm_edid)) {
> +			drm_edid_free(drm_edid);
> +			drm_edid = ERR_PTR(-EINVAL);
>  		}
>  	} else {
> -		edid = ERR_PTR(-ENOENT);
> +		drm_edid = ERR_PTR(-ENOENT);
>  	}
> -	intel_connector->edid = edid;
> +	intel_connector->edid = drm_edid;
>  
>  	intel_bios_init_panel(dev_priv, &intel_connector->panel,
> -			      IS_ERR(edid) ? NULL : edid);
> +			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
>  
>  	/* Try EDID first */
>  	intel_panel_add_edid_fixed_modes(intel_connector,
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 09/15] drm/edid: add drm_edid_raw() to access the raw EDID data
  2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
@ 2022-06-10 19:29     ` Ville Syrjälä
  -1 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:29 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:39AM +0300, Jani Nikula wrote:
> Unfortunately, there are still plenty of interfaces around that require
> a struct edid pointer, and it's impossible to change them all at
> once. Add an accessor to the raw EDID data to help the transition.
> 
> While there are no such cases now, be defensive against raw EDID
> extension count indicating bigger EDID than is actually allocated.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c | 26 ++++++++++++++++++++++++++
>  include/drm/drm_edid.h     |  1 +
>  2 files changed, 27 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 952724788963..4e788c5cbf25 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2333,6 +2333,32 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  }
>  EXPORT_SYMBOL_GPL(drm_do_get_edid);
>  
> +/**
> + * drm_edid_raw - Get a pointer to the raw EDID data.
> + * @drm_edid: drm_edid container
> + *
> + * Get a pointer to the raw EDID data.
> + *
> + * This is for transition only. Avoid using this like the plague.
> + *
> + * Return: Pointer to raw EDID data.
> + */
> +const struct edid *drm_edid_raw(const struct drm_edid *drm_edid)
> +{
> +	if (!drm_edid || !drm_edid->size)
> +		return NULL;
> +
> +	/*
> +	 * Do not return pointers where relying on EDID extension count would
> +	 * lead to buffer overflow.
> +	 */
> +	if (WARN_ON(edid_size(drm_edid->edid) > drm_edid->size))
> +		return NULL;
> +
> +	return drm_edid->edid;
> +}
> +EXPORT_SYMBOL(drm_edid_raw);
> +
>  /* Allocate struct drm_edid container *without* duplicating the edid data */
>  static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
>  {
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index aeb2fa95bc04..2181977ae683 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -597,6 +597,7 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
>  const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
>  const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
>  void drm_edid_free(const struct drm_edid *drm_edid);
> +const struct edid *drm_edid_raw(const struct drm_edid *drm_edid);
>  const struct drm_edid *drm_edid_read(struct drm_connector *connector);
>  const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
>  					 struct i2c_adapter *adapter);
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 09/15] drm/edid: add drm_edid_raw() to access the raw EDID data
@ 2022-06-10 19:29     ` Ville Syrjälä
  0 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:29 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:39AM +0300, Jani Nikula wrote:
> Unfortunately, there are still plenty of interfaces around that require
> a struct edid pointer, and it's impossible to change them all at
> once. Add an accessor to the raw EDID data to help the transition.
> 
> While there are no such cases now, be defensive against raw EDID
> extension count indicating bigger EDID than is actually allocated.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c | 26 ++++++++++++++++++++++++++
>  include/drm/drm_edid.h     |  1 +
>  2 files changed, 27 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 952724788963..4e788c5cbf25 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2333,6 +2333,32 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  }
>  EXPORT_SYMBOL_GPL(drm_do_get_edid);
>  
> +/**
> + * drm_edid_raw - Get a pointer to the raw EDID data.
> + * @drm_edid: drm_edid container
> + *
> + * Get a pointer to the raw EDID data.
> + *
> + * This is for transition only. Avoid using this like the plague.
> + *
> + * Return: Pointer to raw EDID data.
> + */
> +const struct edid *drm_edid_raw(const struct drm_edid *drm_edid)
> +{
> +	if (!drm_edid || !drm_edid->size)
> +		return NULL;
> +
> +	/*
> +	 * Do not return pointers where relying on EDID extension count would
> +	 * lead to buffer overflow.
> +	 */
> +	if (WARN_ON(edid_size(drm_edid->edid) > drm_edid->size))
> +		return NULL;
> +
> +	return drm_edid->edid;
> +}
> +EXPORT_SYMBOL(drm_edid_raw);
> +
>  /* Allocate struct drm_edid container *without* duplicating the edid data */
>  static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
>  {
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index aeb2fa95bc04..2181977ae683 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -597,6 +597,7 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
>  const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
>  const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
>  void drm_edid_free(const struct drm_edid *drm_edid);
> +const struct edid *drm_edid_raw(const struct drm_edid *drm_edid);
>  const struct drm_edid *drm_edid_read(struct drm_connector *connector);
>  const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
>  					 struct i2c_adapter *adapter);
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 11/15] drm/i915/bios: convert intel_bios_init_panel() to drm_edid
  2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
@ 2022-06-10 19:29     ` Ville Syrjälä
  -1 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:29 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:41AM +0300, Jani Nikula wrote:
> Try to use struct drm_edid where possible, even if having to fall back
> to looking into struct edid down low via drm_edid_raw().
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/display/intel_bios.c | 23 ++++++++++++-----------
>  drivers/gpu/drm/i915/display/intel_bios.h |  4 ++--
>  drivers/gpu/drm/i915/display/intel_dp.c   |  2 +-
>  drivers/gpu/drm/i915/display/intel_lvds.c |  2 +-
>  4 files changed, 16 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
> index c42b9e7d0dce..be0b4264d526 100644
> --- a/drivers/gpu/drm/i915/display/intel_bios.c
> +++ b/drivers/gpu/drm/i915/display/intel_bios.c
> @@ -604,13 +604,13 @@ get_lfp_data_tail(const struct bdb_lvds_lfp_data *data,
>  }
>  
>  static int opregion_get_panel_type(struct drm_i915_private *i915,
> -				   const struct edid *edid)
> +				   const struct drm_edid *drm_edid)
>  {
>  	return intel_opregion_get_panel_type(i915);
>  }
>  
>  static int vbt_get_panel_type(struct drm_i915_private *i915,
> -			      const struct edid *edid)
> +			      const struct drm_edid *drm_edid)
>  {
>  	const struct bdb_lvds_options *lvds_options;
>  
> @@ -629,12 +629,13 @@ static int vbt_get_panel_type(struct drm_i915_private *i915,
>  }
>  
>  static int pnpid_get_panel_type(struct drm_i915_private *i915,
> -				const struct edid *edid)
> +				const struct drm_edid *drm_edid)
>  {
>  	const struct bdb_lvds_lfp_data *data;
>  	const struct bdb_lvds_lfp_data_ptrs *ptrs;
>  	const struct lvds_pnp_id *edid_id;
>  	struct lvds_pnp_id edid_id_nodate;
> +	const struct edid *edid = drm_edid_raw(drm_edid); /* FIXME */
>  	int i, best = -1;
>  
>  	if (!edid)
> @@ -675,7 +676,7 @@ static int pnpid_get_panel_type(struct drm_i915_private *i915,
>  }
>  
>  static int fallback_get_panel_type(struct drm_i915_private *i915,
> -				   const struct edid *edid)
> +				   const struct drm_edid *drm_edid)
>  {
>  	return 0;
>  }
> @@ -688,12 +689,12 @@ enum panel_type {
>  };
>  
>  static int get_panel_type(struct drm_i915_private *i915,
> -			  const struct edid *edid)
> +			  const struct drm_edid *drm_edid)
>  {
>  	struct {
>  		const char *name;
>  		int (*get_panel_type)(struct drm_i915_private *i915,
> -				      const struct edid *edid);
> +				      const struct drm_edid *drm_edid);
>  		int panel_type;
>  	} panel_types[] = {
>  		[PANEL_TYPE_OPREGION] = {
> @@ -716,7 +717,7 @@ static int get_panel_type(struct drm_i915_private *i915,
>  	int i;
>  
>  	for (i = 0; i < ARRAY_SIZE(panel_types); i++) {
> -		panel_types[i].panel_type = panel_types[i].get_panel_type(i915, edid);
> +		panel_types[i].panel_type = panel_types[i].get_panel_type(i915, drm_edid);
>  
>  		drm_WARN_ON(&i915->drm, panel_types[i].panel_type > 0xf &&
>  			    panel_types[i].panel_type != 0xff);
> @@ -747,7 +748,7 @@ static int get_panel_type(struct drm_i915_private *i915,
>  static void
>  parse_panel_options(struct drm_i915_private *i915,
>  		    struct intel_panel *panel,
> -		    const struct edid *edid)
> +		    const struct drm_edid *drm_edid)
>  {
>  	const struct bdb_lvds_options *lvds_options;
>  	int panel_type;
> @@ -759,7 +760,7 @@ parse_panel_options(struct drm_i915_private *i915,
>  
>  	panel->vbt.lvds_dither = lvds_options->pixel_dither;
>  
> -	panel_type = get_panel_type(i915, edid);
> +	panel_type = get_panel_type(i915, drm_edid);
>  
>  	panel->vbt.panel_type = panel_type;
>  
> @@ -3092,11 +3093,11 @@ void intel_bios_init(struct drm_i915_private *i915)
>  
>  void intel_bios_init_panel(struct drm_i915_private *i915,
>  			   struct intel_panel *panel,
> -			   const struct edid *edid)
> +			   const struct drm_edid *drm_edid)
>  {
>  	init_vbt_panel_defaults(panel);
>  
> -	parse_panel_options(i915, panel, edid);
> +	parse_panel_options(i915, panel, drm_edid);
>  	parse_generic_dtd(i915, panel);
>  	parse_lfp_data(i915, panel);
>  	parse_lfp_backlight(i915, panel);
> diff --git a/drivers/gpu/drm/i915/display/intel_bios.h b/drivers/gpu/drm/i915/display/intel_bios.h
> index b112200ae0a0..7bcc818e8d80 100644
> --- a/drivers/gpu/drm/i915/display/intel_bios.h
> +++ b/drivers/gpu/drm/i915/display/intel_bios.h
> @@ -32,8 +32,8 @@
>  
>  #include <linux/types.h>
>  
> +struct drm_edid;
>  struct drm_i915_private;
> -struct edid;
>  struct intel_bios_encoder_data;
>  struct intel_crtc_state;
>  struct intel_encoder;
> @@ -234,7 +234,7 @@ struct mipi_pps_data {
>  void intel_bios_init(struct drm_i915_private *dev_priv);
>  void intel_bios_init_panel(struct drm_i915_private *dev_priv,
>  			   struct intel_panel *panel,
> -			   const struct edid *edid);
> +			   const struct drm_edid *drm_edid);
>  void intel_bios_fini_panel(struct intel_panel *panel);
>  void intel_bios_driver_remove(struct drm_i915_private *dev_priv);
>  bool intel_bios_is_valid_vbt(const void *buf, size_t size);
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 64b6481225f1..2f47f1e7607b 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -5217,7 +5217,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
>  	intel_connector->edid = drm_edid;
>  
>  	intel_bios_init_panel(dev_priv, &intel_connector->panel,
> -			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
> +			      IS_ERR(drm_edid) ? NULL : drm_edid);
>  
>  	intel_panel_add_edid_fixed_modes(intel_connector,
>  					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
> diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
> index d4389054bf59..ed5fceb93952 100644
> --- a/drivers/gpu/drm/i915/display/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/display/intel_lvds.c
> @@ -971,7 +971,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
>  	intel_connector->edid = drm_edid;
>  
>  	intel_bios_init_panel(dev_priv, &intel_connector->panel,
> -			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
> +			      IS_ERR(drm_edid) ? NULL : drm_edid);
>  
>  	/* Try EDID first */
>  	intel_panel_add_edid_fixed_modes(intel_connector,
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 11/15] drm/i915/bios: convert intel_bios_init_panel() to drm_edid
@ 2022-06-10 19:29     ` Ville Syrjälä
  0 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:29 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:41AM +0300, Jani Nikula wrote:
> Try to use struct drm_edid where possible, even if having to fall back
> to looking into struct edid down low via drm_edid_raw().
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/display/intel_bios.c | 23 ++++++++++++-----------
>  drivers/gpu/drm/i915/display/intel_bios.h |  4 ++--
>  drivers/gpu/drm/i915/display/intel_dp.c   |  2 +-
>  drivers/gpu/drm/i915/display/intel_lvds.c |  2 +-
>  4 files changed, 16 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
> index c42b9e7d0dce..be0b4264d526 100644
> --- a/drivers/gpu/drm/i915/display/intel_bios.c
> +++ b/drivers/gpu/drm/i915/display/intel_bios.c
> @@ -604,13 +604,13 @@ get_lfp_data_tail(const struct bdb_lvds_lfp_data *data,
>  }
>  
>  static int opregion_get_panel_type(struct drm_i915_private *i915,
> -				   const struct edid *edid)
> +				   const struct drm_edid *drm_edid)
>  {
>  	return intel_opregion_get_panel_type(i915);
>  }
>  
>  static int vbt_get_panel_type(struct drm_i915_private *i915,
> -			      const struct edid *edid)
> +			      const struct drm_edid *drm_edid)
>  {
>  	const struct bdb_lvds_options *lvds_options;
>  
> @@ -629,12 +629,13 @@ static int vbt_get_panel_type(struct drm_i915_private *i915,
>  }
>  
>  static int pnpid_get_panel_type(struct drm_i915_private *i915,
> -				const struct edid *edid)
> +				const struct drm_edid *drm_edid)
>  {
>  	const struct bdb_lvds_lfp_data *data;
>  	const struct bdb_lvds_lfp_data_ptrs *ptrs;
>  	const struct lvds_pnp_id *edid_id;
>  	struct lvds_pnp_id edid_id_nodate;
> +	const struct edid *edid = drm_edid_raw(drm_edid); /* FIXME */
>  	int i, best = -1;
>  
>  	if (!edid)
> @@ -675,7 +676,7 @@ static int pnpid_get_panel_type(struct drm_i915_private *i915,
>  }
>  
>  static int fallback_get_panel_type(struct drm_i915_private *i915,
> -				   const struct edid *edid)
> +				   const struct drm_edid *drm_edid)
>  {
>  	return 0;
>  }
> @@ -688,12 +689,12 @@ enum panel_type {
>  };
>  
>  static int get_panel_type(struct drm_i915_private *i915,
> -			  const struct edid *edid)
> +			  const struct drm_edid *drm_edid)
>  {
>  	struct {
>  		const char *name;
>  		int (*get_panel_type)(struct drm_i915_private *i915,
> -				      const struct edid *edid);
> +				      const struct drm_edid *drm_edid);
>  		int panel_type;
>  	} panel_types[] = {
>  		[PANEL_TYPE_OPREGION] = {
> @@ -716,7 +717,7 @@ static int get_panel_type(struct drm_i915_private *i915,
>  	int i;
>  
>  	for (i = 0; i < ARRAY_SIZE(panel_types); i++) {
> -		panel_types[i].panel_type = panel_types[i].get_panel_type(i915, edid);
> +		panel_types[i].panel_type = panel_types[i].get_panel_type(i915, drm_edid);
>  
>  		drm_WARN_ON(&i915->drm, panel_types[i].panel_type > 0xf &&
>  			    panel_types[i].panel_type != 0xff);
> @@ -747,7 +748,7 @@ static int get_panel_type(struct drm_i915_private *i915,
>  static void
>  parse_panel_options(struct drm_i915_private *i915,
>  		    struct intel_panel *panel,
> -		    const struct edid *edid)
> +		    const struct drm_edid *drm_edid)
>  {
>  	const struct bdb_lvds_options *lvds_options;
>  	int panel_type;
> @@ -759,7 +760,7 @@ parse_panel_options(struct drm_i915_private *i915,
>  
>  	panel->vbt.lvds_dither = lvds_options->pixel_dither;
>  
> -	panel_type = get_panel_type(i915, edid);
> +	panel_type = get_panel_type(i915, drm_edid);
>  
>  	panel->vbt.panel_type = panel_type;
>  
> @@ -3092,11 +3093,11 @@ void intel_bios_init(struct drm_i915_private *i915)
>  
>  void intel_bios_init_panel(struct drm_i915_private *i915,
>  			   struct intel_panel *panel,
> -			   const struct edid *edid)
> +			   const struct drm_edid *drm_edid)
>  {
>  	init_vbt_panel_defaults(panel);
>  
> -	parse_panel_options(i915, panel, edid);
> +	parse_panel_options(i915, panel, drm_edid);
>  	parse_generic_dtd(i915, panel);
>  	parse_lfp_data(i915, panel);
>  	parse_lfp_backlight(i915, panel);
> diff --git a/drivers/gpu/drm/i915/display/intel_bios.h b/drivers/gpu/drm/i915/display/intel_bios.h
> index b112200ae0a0..7bcc818e8d80 100644
> --- a/drivers/gpu/drm/i915/display/intel_bios.h
> +++ b/drivers/gpu/drm/i915/display/intel_bios.h
> @@ -32,8 +32,8 @@
>  
>  #include <linux/types.h>
>  
> +struct drm_edid;
>  struct drm_i915_private;
> -struct edid;
>  struct intel_bios_encoder_data;
>  struct intel_crtc_state;
>  struct intel_encoder;
> @@ -234,7 +234,7 @@ struct mipi_pps_data {
>  void intel_bios_init(struct drm_i915_private *dev_priv);
>  void intel_bios_init_panel(struct drm_i915_private *dev_priv,
>  			   struct intel_panel *panel,
> -			   const struct edid *edid);
> +			   const struct drm_edid *drm_edid);
>  void intel_bios_fini_panel(struct intel_panel *panel);
>  void intel_bios_driver_remove(struct drm_i915_private *dev_priv);
>  bool intel_bios_is_valid_vbt(const void *buf, size_t size);
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 64b6481225f1..2f47f1e7607b 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -5217,7 +5217,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
>  	intel_connector->edid = drm_edid;
>  
>  	intel_bios_init_panel(dev_priv, &intel_connector->panel,
> -			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
> +			      IS_ERR(drm_edid) ? NULL : drm_edid);
>  
>  	intel_panel_add_edid_fixed_modes(intel_connector,
>  					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
> diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
> index d4389054bf59..ed5fceb93952 100644
> --- a/drivers/gpu/drm/i915/display/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/display/intel_lvds.c
> @@ -971,7 +971,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
>  	intel_connector->edid = drm_edid;
>  
>  	intel_bios_init_panel(dev_priv, &intel_connector->panel,
> -			      IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
> +			      IS_ERR(drm_edid) ? NULL : drm_edid);
>  
>  	/* Try EDID first */
>  	intel_panel_add_edid_fixed_modes(intel_connector,
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 12/15] drm/edid: do invalid block filtering in-place
  2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
@ 2022-06-10 19:30     ` Ville Syrjälä
  -1 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:30 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:42AM +0300, Jani Nikula wrote:
> Rewrite edid_filter_invalid_blocks() to filter invalid blocks
> in-place. The main motivation is to not rely on passed in information on
> invalid block count or the allocation size, which will be helpful in
> follow-up work on HF-EEODB.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c | 43 ++++++++++++++++++++------------------
>  1 file changed, 23 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 4e788c5cbf25..77ec5b0e436d 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2020,33 +2020,37 @@ bool drm_edid_is_valid(struct edid *edid)
>  }
>  EXPORT_SYMBOL(drm_edid_is_valid);
>  
> -static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
> -					       int invalid_blocks,
> +static struct edid *edid_filter_invalid_blocks(struct edid *edid,
>  					       size_t *alloc_size)
>  {
> -	struct edid *new, *dest_block;
> -	int valid_extensions = edid->extensions - invalid_blocks;
> -	int i;
> +	struct edid *new;
> +	int i, valid_blocks = 0;
>  
> -	*alloc_size = edid_size_by_blocks(valid_extensions + 1);
> +	for (i = 0; i < edid_block_count(edid); i++) {
> +		const void *src_block = edid_block_data(edid, i);
>  
> -	new = kmalloc(*alloc_size, GFP_KERNEL);
> -	if (!new)
> -		goto out;
> +		if (edid_block_valid(src_block, i == 0)) {
> +			void *dst_block = (void *)edid_block_data(edid, valid_blocks);
>  
> -	dest_block = new;
> -	for (i = 0; i < edid_block_count(edid); i++) {
> -		const void *block = edid_block_data(edid, i);
> +			memmove(dst_block, src_block, EDID_LENGTH);
> +			valid_blocks++;
> +		}
> +	}
>  
> -		if (edid_block_valid(block, i == 0))
> -			memcpy(dest_block++, block, EDID_LENGTH);
> +	/* We already trusted the base block to be valid here... */
> +	if (WARN_ON(!valid_blocks)) {
> +		kfree(edid);
> +		return NULL;
>  	}
>  
> -	new->extensions = valid_extensions;
> -	new->checksum = edid_block_compute_checksum(new);
> +	edid->extensions = valid_blocks - 1;
> +	edid->checksum = edid_block_compute_checksum(edid);
>  
> -out:
> -	kfree(edid);
> +	*alloc_size = edid_size_by_blocks(valid_blocks);
> +
> +	new = krealloc(edid, *alloc_size, GFP_KERNEL);
> +	if (!new)
> +		kfree(edid);
>  
>  	return new;
>  }
> @@ -2290,8 +2294,7 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
>  	if (invalid_blocks) {
>  		connector_bad_edid(connector, edid, edid_block_count(edid));
>  
> -		edid = edid_filter_invalid_blocks(edid, invalid_blocks,
> -						  &alloc_size);
> +		edid = edid_filter_invalid_blocks(edid, &alloc_size);
>  	}
>  
>  ok:
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 12/15] drm/edid: do invalid block filtering in-place
@ 2022-06-10 19:30     ` Ville Syrjälä
  0 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:30 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:42AM +0300, Jani Nikula wrote:
> Rewrite edid_filter_invalid_blocks() to filter invalid blocks
> in-place. The main motivation is to not rely on passed in information on
> invalid block count or the allocation size, which will be helpful in
> follow-up work on HF-EEODB.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c | 43 ++++++++++++++++++++------------------
>  1 file changed, 23 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 4e788c5cbf25..77ec5b0e436d 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2020,33 +2020,37 @@ bool drm_edid_is_valid(struct edid *edid)
>  }
>  EXPORT_SYMBOL(drm_edid_is_valid);
>  
> -static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
> -					       int invalid_blocks,
> +static struct edid *edid_filter_invalid_blocks(struct edid *edid,
>  					       size_t *alloc_size)
>  {
> -	struct edid *new, *dest_block;
> -	int valid_extensions = edid->extensions - invalid_blocks;
> -	int i;
> +	struct edid *new;
> +	int i, valid_blocks = 0;
>  
> -	*alloc_size = edid_size_by_blocks(valid_extensions + 1);
> +	for (i = 0; i < edid_block_count(edid); i++) {
> +		const void *src_block = edid_block_data(edid, i);
>  
> -	new = kmalloc(*alloc_size, GFP_KERNEL);
> -	if (!new)
> -		goto out;
> +		if (edid_block_valid(src_block, i == 0)) {
> +			void *dst_block = (void *)edid_block_data(edid, valid_blocks);
>  
> -	dest_block = new;
> -	for (i = 0; i < edid_block_count(edid); i++) {
> -		const void *block = edid_block_data(edid, i);
> +			memmove(dst_block, src_block, EDID_LENGTH);
> +			valid_blocks++;
> +		}
> +	}
>  
> -		if (edid_block_valid(block, i == 0))
> -			memcpy(dest_block++, block, EDID_LENGTH);
> +	/* We already trusted the base block to be valid here... */
> +	if (WARN_ON(!valid_blocks)) {
> +		kfree(edid);
> +		return NULL;
>  	}
>  
> -	new->extensions = valid_extensions;
> -	new->checksum = edid_block_compute_checksum(new);
> +	edid->extensions = valid_blocks - 1;
> +	edid->checksum = edid_block_compute_checksum(edid);
>  
> -out:
> -	kfree(edid);
> +	*alloc_size = edid_size_by_blocks(valid_blocks);
> +
> +	new = krealloc(edid, *alloc_size, GFP_KERNEL);
> +	if (!new)
> +		kfree(edid);
>  
>  	return new;
>  }
> @@ -2290,8 +2294,7 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
>  	if (invalid_blocks) {
>  		connector_bad_edid(connector, edid, edid_block_count(edid));
>  
> -		edid = edid_filter_invalid_blocks(edid, invalid_blocks,
> -						  &alloc_size);
> +		edid = edid_filter_invalid_blocks(edid, &alloc_size);
>  	}
>  
>  ok:
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 13/15] drm/edid: add HF-EEODB support to EDID read and allocation
  2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
@ 2022-06-10 19:30     ` Ville Syrjälä
  -1 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:30 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:43AM +0300, Jani Nikula wrote:
> HDMI 2.1 section 10.3.6 defines an HDMI Forum EDID Extension Override
> Data Block, which may contain a different extension count than the base
> block claims. Add support for reading more EDID data if available. The
> extra blocks aren't parsed yet, though.
> 
> Hard-coding the EEODB parsing instead of using the iterators we have is
> a bit of a bummer, but we have to be able to do this on a partially
> allocated EDID while reading it.
> 
> v2:
> - Check for CEA Data Block Collection size (Ville)
> - Amend commit message and comment about hard-coded parsing
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c | 89 ++++++++++++++++++++++++++++++++++++--
>  1 file changed, 86 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 77ec5b0e436d..5cac357e50b0 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1581,6 +1581,15 @@ static bool version_greater(const struct drm_edid *drm_edid,
>  		(edid->version == version && edid->revision > revision);
>  }
>  
> +static int edid_hfeeodb_extension_block_count(const struct edid *edid);
> +
> +static int edid_hfeeodb_block_count(const struct edid *edid)
> +{
> +	int eeodb = edid_hfeeodb_extension_block_count(edid);
> +
> +	return eeodb ? eeodb + 1 : 0;
> +}
> +
>  static int edid_extension_block_count(const struct edid *edid)
>  {
>  	return edid->extensions;
> @@ -2026,6 +2035,11 @@ static struct edid *edid_filter_invalid_blocks(struct edid *edid,
>  	struct edid *new;
>  	int i, valid_blocks = 0;
>  
> +	/*
> +	 * Note: If the EDID uses HF-EEODB, but has invalid blocks, we'll revert
> +	 * back to regular extension count here. We don't want to start
> +	 * modifying the HF-EEODB extension too.
> +	 */
>  	for (i = 0; i < edid_block_count(edid); i++) {
>  		const void *src_block = edid_block_data(edid, i);
>  
> @@ -2235,7 +2249,7 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
>  				     size_t *size)
>  {
>  	enum edid_block_status status;
> -	int i, invalid_blocks = 0;
> +	int i, num_blocks, invalid_blocks = 0;
>  	struct edid *edid, *new;
>  	size_t alloc_size = EDID_LENGTH;
>  
> @@ -2277,7 +2291,8 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
>  		goto fail;
>  	edid = new;
>  
> -	for (i = 1; i < edid_block_count(edid); i++) {
> +	num_blocks = edid_block_count(edid);
> +	for (i = 1; i < num_blocks; i++) {
>  		void *block = (void *)edid_block_data(edid, i);
>  
>  		status = edid_block_read(block, i, read_block, context);
> @@ -2288,11 +2303,31 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
>  			if (status == EDID_BLOCK_READ_FAIL)
>  				goto fail;
>  			invalid_blocks++;
> +		} else if (i == 1) {
> +			/*
> +			 * If the first EDID extension is a CTA extension, and
> +			 * the first Data Block is HF-EEODB, override the
> +			 * extension block count.
> +			 *
> +			 * Note: HF-EEODB could specify a smaller extension
> +			 * count too, but we can't risk allocating a smaller
> +			 * amount.
> +			 */
> +			int eeodb = edid_hfeeodb_block_count(edid);
> +
> +			if (eeodb > num_blocks) {
> +				num_blocks = eeodb;
> +				alloc_size = edid_size_by_blocks(num_blocks);
> +				new = krealloc(edid, alloc_size, GFP_KERNEL);
> +				if (!new)
> +					goto fail;
> +				edid = new;
> +			}
>  		}
>  	}
>  
>  	if (invalid_blocks) {
> -		connector_bad_edid(connector, edid, edid_block_count(edid));
> +		connector_bad_edid(connector, edid, num_blocks);
>  
>  		edid = edid_filter_invalid_blocks(edid, &alloc_size);
>  	}
> @@ -3825,6 +3860,7 @@ static int add_detailed_modes(struct drm_connector *connector,
>  #define CTA_EXT_DB_HDR_STATIC_METADATA	6
>  #define CTA_EXT_DB_420_VIDEO_DATA	14
>  #define CTA_EXT_DB_420_VIDEO_CAP_MAP	15
> +#define CTA_EXT_DB_HF_EEODB		0x78
>  #define CTA_EXT_DB_HF_SCDB		0x79
>  
>  #define EDID_BASIC_AUDIO	(1 << 6)
> @@ -4884,6 +4920,12 @@ static bool cea_db_is_hdmi_forum_vsdb(const struct cea_db *db)
>  		cea_db_payload_len(db) >= 7;
>  }
>  
> +static bool cea_db_is_hdmi_forum_eeodb(const void *db)
> +{
> +	return cea_db_is_extended_tag(db, CTA_EXT_DB_HF_EEODB) &&
> +		cea_db_payload_len(db) >= 2;
> +}
> +
>  static bool cea_db_is_microsoft_vsdb(const struct cea_db *db)
>  {
>  	return cea_db_is_vendor(db, MICROSOFT_IEEE_OUI) &&
> @@ -4918,6 +4960,47 @@ static bool cea_db_is_hdmi_hdr_metadata_block(const struct cea_db *db)
>  		cea_db_payload_len(db) >= 3;
>  }
>  
> +/*
> + * Get the HF-EEODB override extension block count from EDID.
> + *
> + * The passed in EDID may be partially read, as long as it has at least two
> + * blocks (base block and one extension block) if EDID extension count is > 0.
> + *
> + * Note that this is *not* how you should parse CTA Data Blocks in general; this
> + * is only to handle partially read EDIDs. Normally, use the CTA Data Block
> + * iterators instead.
> + *
> + * References:
> + * - HDMI 2.1 section 10.3.6 HDMI Forum EDID Extension Override Data Block
> + */
> +static int edid_hfeeodb_extension_block_count(const struct edid *edid)
> +{
> +	const u8 *cta;
> +
> +	/* No extensions according to base block, no HF-EEODB. */
> +	if (!edid_extension_block_count(edid))
> +		return 0;
> +
> +	/* HF-EEODB is always in the first EDID extension block only */
> +	cta = edid_extension_block_data(edid, 0);
> +	if (edid_block_tag(cta) != CEA_EXT || cea_revision(cta) < 3)
> +		return 0;
> +
> +	/* Need to have the data block collection, and at least 3 bytes. */
> +	if (cea_db_collection_size(cta) < 3)
> +		return 0;
> +
> +	/*
> +	 * Sinks that include the HF-EEODB in their E-EDID shall include one and
> +	 * only one instance of the HF-EEODB in the E-EDID, occupying bytes 4
> +	 * through 6 of Block 1 of the E-EDID.
> +	 */
> +	if (!cea_db_is_hdmi_forum_eeodb(&cta[4]))
> +		return 0;
> +
> +	return cta[4 + 2];
> +}
> +
>  static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
>  				      const u8 *db)
>  {
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 13/15] drm/edid: add HF-EEODB support to EDID read and allocation
@ 2022-06-10 19:30     ` Ville Syrjälä
  0 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:30 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:43AM +0300, Jani Nikula wrote:
> HDMI 2.1 section 10.3.6 defines an HDMI Forum EDID Extension Override
> Data Block, which may contain a different extension count than the base
> block claims. Add support for reading more EDID data if available. The
> extra blocks aren't parsed yet, though.
> 
> Hard-coding the EEODB parsing instead of using the iterators we have is
> a bit of a bummer, but we have to be able to do this on a partially
> allocated EDID while reading it.
> 
> v2:
> - Check for CEA Data Block Collection size (Ville)
> - Amend commit message and comment about hard-coded parsing
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c | 89 ++++++++++++++++++++++++++++++++++++--
>  1 file changed, 86 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 77ec5b0e436d..5cac357e50b0 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1581,6 +1581,15 @@ static bool version_greater(const struct drm_edid *drm_edid,
>  		(edid->version == version && edid->revision > revision);
>  }
>  
> +static int edid_hfeeodb_extension_block_count(const struct edid *edid);
> +
> +static int edid_hfeeodb_block_count(const struct edid *edid)
> +{
> +	int eeodb = edid_hfeeodb_extension_block_count(edid);
> +
> +	return eeodb ? eeodb + 1 : 0;
> +}
> +
>  static int edid_extension_block_count(const struct edid *edid)
>  {
>  	return edid->extensions;
> @@ -2026,6 +2035,11 @@ static struct edid *edid_filter_invalid_blocks(struct edid *edid,
>  	struct edid *new;
>  	int i, valid_blocks = 0;
>  
> +	/*
> +	 * Note: If the EDID uses HF-EEODB, but has invalid blocks, we'll revert
> +	 * back to regular extension count here. We don't want to start
> +	 * modifying the HF-EEODB extension too.
> +	 */
>  	for (i = 0; i < edid_block_count(edid); i++) {
>  		const void *src_block = edid_block_data(edid, i);
>  
> @@ -2235,7 +2249,7 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
>  				     size_t *size)
>  {
>  	enum edid_block_status status;
> -	int i, invalid_blocks = 0;
> +	int i, num_blocks, invalid_blocks = 0;
>  	struct edid *edid, *new;
>  	size_t alloc_size = EDID_LENGTH;
>  
> @@ -2277,7 +2291,8 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
>  		goto fail;
>  	edid = new;
>  
> -	for (i = 1; i < edid_block_count(edid); i++) {
> +	num_blocks = edid_block_count(edid);
> +	for (i = 1; i < num_blocks; i++) {
>  		void *block = (void *)edid_block_data(edid, i);
>  
>  		status = edid_block_read(block, i, read_block, context);
> @@ -2288,11 +2303,31 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
>  			if (status == EDID_BLOCK_READ_FAIL)
>  				goto fail;
>  			invalid_blocks++;
> +		} else if (i == 1) {
> +			/*
> +			 * If the first EDID extension is a CTA extension, and
> +			 * the first Data Block is HF-EEODB, override the
> +			 * extension block count.
> +			 *
> +			 * Note: HF-EEODB could specify a smaller extension
> +			 * count too, but we can't risk allocating a smaller
> +			 * amount.
> +			 */
> +			int eeodb = edid_hfeeodb_block_count(edid);
> +
> +			if (eeodb > num_blocks) {
> +				num_blocks = eeodb;
> +				alloc_size = edid_size_by_blocks(num_blocks);
> +				new = krealloc(edid, alloc_size, GFP_KERNEL);
> +				if (!new)
> +					goto fail;
> +				edid = new;
> +			}
>  		}
>  	}
>  
>  	if (invalid_blocks) {
> -		connector_bad_edid(connector, edid, edid_block_count(edid));
> +		connector_bad_edid(connector, edid, num_blocks);
>  
>  		edid = edid_filter_invalid_blocks(edid, &alloc_size);
>  	}
> @@ -3825,6 +3860,7 @@ static int add_detailed_modes(struct drm_connector *connector,
>  #define CTA_EXT_DB_HDR_STATIC_METADATA	6
>  #define CTA_EXT_DB_420_VIDEO_DATA	14
>  #define CTA_EXT_DB_420_VIDEO_CAP_MAP	15
> +#define CTA_EXT_DB_HF_EEODB		0x78
>  #define CTA_EXT_DB_HF_SCDB		0x79
>  
>  #define EDID_BASIC_AUDIO	(1 << 6)
> @@ -4884,6 +4920,12 @@ static bool cea_db_is_hdmi_forum_vsdb(const struct cea_db *db)
>  		cea_db_payload_len(db) >= 7;
>  }
>  
> +static bool cea_db_is_hdmi_forum_eeodb(const void *db)
> +{
> +	return cea_db_is_extended_tag(db, CTA_EXT_DB_HF_EEODB) &&
> +		cea_db_payload_len(db) >= 2;
> +}
> +
>  static bool cea_db_is_microsoft_vsdb(const struct cea_db *db)
>  {
>  	return cea_db_is_vendor(db, MICROSOFT_IEEE_OUI) &&
> @@ -4918,6 +4960,47 @@ static bool cea_db_is_hdmi_hdr_metadata_block(const struct cea_db *db)
>  		cea_db_payload_len(db) >= 3;
>  }
>  
> +/*
> + * Get the HF-EEODB override extension block count from EDID.
> + *
> + * The passed in EDID may be partially read, as long as it has at least two
> + * blocks (base block and one extension block) if EDID extension count is > 0.
> + *
> + * Note that this is *not* how you should parse CTA Data Blocks in general; this
> + * is only to handle partially read EDIDs. Normally, use the CTA Data Block
> + * iterators instead.
> + *
> + * References:
> + * - HDMI 2.1 section 10.3.6 HDMI Forum EDID Extension Override Data Block
> + */
> +static int edid_hfeeodb_extension_block_count(const struct edid *edid)
> +{
> +	const u8 *cta;
> +
> +	/* No extensions according to base block, no HF-EEODB. */
> +	if (!edid_extension_block_count(edid))
> +		return 0;
> +
> +	/* HF-EEODB is always in the first EDID extension block only */
> +	cta = edid_extension_block_data(edid, 0);
> +	if (edid_block_tag(cta) != CEA_EXT || cea_revision(cta) < 3)
> +		return 0;
> +
> +	/* Need to have the data block collection, and at least 3 bytes. */
> +	if (cea_db_collection_size(cta) < 3)
> +		return 0;
> +
> +	/*
> +	 * Sinks that include the HF-EEODB in their E-EDID shall include one and
> +	 * only one instance of the HF-EEODB in the E-EDID, occupying bytes 4
> +	 * through 6 of Block 1 of the E-EDID.
> +	 */
> +	if (!cea_db_is_hdmi_forum_eeodb(&cta[4]))
> +		return 0;
> +
> +	return cta[4 + 2];
> +}
> +
>  static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
>  				      const u8 *db)
>  {
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 14/15] drm/edid: take HF-EEODB extension count into account
  2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
@ 2022-06-10 19:34     ` Ville Syrjälä
  -1 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:34 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:44AM +0300, Jani Nikula wrote:
> Take the HF-EEODB extension count override into account.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/drm_edid.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 5cac357e50b0..b7b1f0639115 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1629,6 +1629,19 @@ static int drm_edid_block_count(const struct drm_edid *drm_edid)
>  	/* Starting point */
>  	num_blocks = edid_block_count(drm_edid->edid);
>  
> +	/* HF-EEODB override */
> +	if (drm_edid->size >= edid_size_by_blocks(2)) {
> +		int eeodb;
> +
> +		/*
> +		 * Note: HF-EEODB may specify a smaller extension count than the
> +		 * regular one. Unlike in buffer allocation, here we can use it.
> +		 */

Such a sink would be in violation of the spec. But the spec does
explicitly say sources are to ignore the normal ext count in those
cases. So this would seem to do what the spec asks of us.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> +		eeodb = edid_hfeeodb_block_count(drm_edid->edid);
> +		if (eeodb)
> +			num_blocks = eeodb;
> +	}
> +
>  	/* Limit by allocated size */
>  	num_blocks = min(num_blocks, (int)drm_edid->size / EDID_LENGTH);
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 14/15] drm/edid: take HF-EEODB extension count into account
@ 2022-06-10 19:34     ` Ville Syrjälä
  0 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:34 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:44AM +0300, Jani Nikula wrote:
> Take the HF-EEODB extension count override into account.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/drm_edid.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 5cac357e50b0..b7b1f0639115 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1629,6 +1629,19 @@ static int drm_edid_block_count(const struct drm_edid *drm_edid)
>  	/* Starting point */
>  	num_blocks = edid_block_count(drm_edid->edid);
>  
> +	/* HF-EEODB override */
> +	if (drm_edid->size >= edid_size_by_blocks(2)) {
> +		int eeodb;
> +
> +		/*
> +		 * Note: HF-EEODB may specify a smaller extension count than the
> +		 * regular one. Unlike in buffer allocation, here we can use it.
> +		 */

Such a sink would be in violation of the spec. But the spec does
explicitly say sources are to ignore the normal ext count in those
cases. So this would seem to do what the spec asks of us.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> +		eeodb = edid_hfeeodb_block_count(drm_edid->edid);
> +		if (eeodb)
> +			num_blocks = eeodb;
> +	}
> +
>  	/* Limit by allocated size */
>  	num_blocks = min(num_blocks, (int)drm_edid->size / EDID_LENGTH);
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 04/15] drm/edid: keep track of alloc size in drm_do_get_edid()
  2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
@ 2022-06-10 19:35     ` Ville Syrjälä
  -1 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:35 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:34AM +0300, Jani Nikula wrote:
> We'll want to return the allocated buffer size in the future. Keep track
> of it.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c | 27 +++++++++++++++++++--------
>  1 file changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index f44ada4bfa5b..2beaa48301c1 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2021,13 +2021,16 @@ bool drm_edid_is_valid(struct edid *edid)
>  EXPORT_SYMBOL(drm_edid_is_valid);
>  
>  static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
> -					       int invalid_blocks)
> +					       int invalid_blocks,
> +					       size_t *alloc_size)
>  {
>  	struct edid *new, *dest_block;
>  	int valid_extensions = edid->extensions - invalid_blocks;
>  	int i;
>  
> -	new = kmalloc(edid_size_by_blocks(valid_extensions + 1), GFP_KERNEL);
> +	*alloc_size = edid_size_by_blocks(valid_extensions + 1);
> +
> +	new = kmalloc(*alloc_size, GFP_KERNEL);
>  	if (!new)
>  		goto out;
>  
> @@ -2140,7 +2143,8 @@ static void connector_bad_edid(struct drm_connector *connector,
>  }
>  
>  /* Get override or firmware EDID */
> -static struct edid *drm_get_override_edid(struct drm_connector *connector)
> +static struct edid *drm_get_override_edid(struct drm_connector *connector,
> +					  size_t *alloc_size)
>  {
>  	struct edid *override = NULL;
>  
> @@ -2150,6 +2154,10 @@ static struct edid *drm_get_override_edid(struct drm_connector *connector)
>  	if (!override)
>  		override = drm_load_edid_firmware(connector);
>  
> +	/* FIXME: Get alloc size from deeper down the stack */
> +	if (!IS_ERR_OR_NULL(override) && alloc_size)
> +		*alloc_size = edid_size(override);
> +
>  	return IS_ERR(override) ? NULL : override;
>  }
>  
> @@ -2169,7 +2177,7 @@ int drm_add_override_edid_modes(struct drm_connector *connector)
>  	struct edid *override;
>  	int num_modes = 0;
>  
> -	override = drm_get_override_edid(connector);
> +	override = drm_get_override_edid(connector, NULL);
>  	if (override) {
>  		drm_connector_update_edid_property(connector, override);
>  		num_modes = drm_add_edid_modes(connector, override);
> @@ -2245,12 +2253,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  	enum edid_block_status status;
>  	int i, invalid_blocks = 0;
>  	struct edid *edid, *new;
> +	size_t alloc_size = EDID_LENGTH;
>  
> -	edid = drm_get_override_edid(connector);
> +	edid = drm_get_override_edid(connector, &alloc_size);
>  	if (edid)
>  		goto ok;
>  
> -	edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
> +	edid = kmalloc(alloc_size, GFP_KERNEL);
>  	if (!edid)
>  		return NULL;
>  
> @@ -2278,7 +2287,8 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  	if (!edid_extension_block_count(edid))
>  		goto ok;
>  
> -	new = krealloc(edid, edid_size(edid), GFP_KERNEL);
> +	alloc_size = edid_size(edid);
> +	new = krealloc(edid, alloc_size, GFP_KERNEL);
>  	if (!new)
>  		goto fail;
>  	edid = new;
> @@ -2300,7 +2310,8 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  	if (invalid_blocks) {
>  		connector_bad_edid(connector, edid, edid_block_count(edid));
>  
> -		edid = edid_filter_invalid_blocks(edid, invalid_blocks);
> +		edid = edid_filter_invalid_blocks(edid, invalid_blocks,
> +						  &alloc_size);
>  	}
>  
>  ok:
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 04/15] drm/edid: keep track of alloc size in drm_do_get_edid()
@ 2022-06-10 19:35     ` Ville Syrjälä
  0 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:35 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:34AM +0300, Jani Nikula wrote:
> We'll want to return the allocated buffer size in the future. Keep track
> of it.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c | 27 +++++++++++++++++++--------
>  1 file changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index f44ada4bfa5b..2beaa48301c1 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2021,13 +2021,16 @@ bool drm_edid_is_valid(struct edid *edid)
>  EXPORT_SYMBOL(drm_edid_is_valid);
>  
>  static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
> -					       int invalid_blocks)
> +					       int invalid_blocks,
> +					       size_t *alloc_size)
>  {
>  	struct edid *new, *dest_block;
>  	int valid_extensions = edid->extensions - invalid_blocks;
>  	int i;
>  
> -	new = kmalloc(edid_size_by_blocks(valid_extensions + 1), GFP_KERNEL);
> +	*alloc_size = edid_size_by_blocks(valid_extensions + 1);
> +
> +	new = kmalloc(*alloc_size, GFP_KERNEL);
>  	if (!new)
>  		goto out;
>  
> @@ -2140,7 +2143,8 @@ static void connector_bad_edid(struct drm_connector *connector,
>  }
>  
>  /* Get override or firmware EDID */
> -static struct edid *drm_get_override_edid(struct drm_connector *connector)
> +static struct edid *drm_get_override_edid(struct drm_connector *connector,
> +					  size_t *alloc_size)
>  {
>  	struct edid *override = NULL;
>  
> @@ -2150,6 +2154,10 @@ static struct edid *drm_get_override_edid(struct drm_connector *connector)
>  	if (!override)
>  		override = drm_load_edid_firmware(connector);
>  
> +	/* FIXME: Get alloc size from deeper down the stack */
> +	if (!IS_ERR_OR_NULL(override) && alloc_size)
> +		*alloc_size = edid_size(override);
> +
>  	return IS_ERR(override) ? NULL : override;
>  }
>  
> @@ -2169,7 +2177,7 @@ int drm_add_override_edid_modes(struct drm_connector *connector)
>  	struct edid *override;
>  	int num_modes = 0;
>  
> -	override = drm_get_override_edid(connector);
> +	override = drm_get_override_edid(connector, NULL);
>  	if (override) {
>  		drm_connector_update_edid_property(connector, override);
>  		num_modes = drm_add_edid_modes(connector, override);
> @@ -2245,12 +2253,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  	enum edid_block_status status;
>  	int i, invalid_blocks = 0;
>  	struct edid *edid, *new;
> +	size_t alloc_size = EDID_LENGTH;
>  
> -	edid = drm_get_override_edid(connector);
> +	edid = drm_get_override_edid(connector, &alloc_size);
>  	if (edid)
>  		goto ok;
>  
> -	edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
> +	edid = kmalloc(alloc_size, GFP_KERNEL);
>  	if (!edid)
>  		return NULL;
>  
> @@ -2278,7 +2287,8 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  	if (!edid_extension_block_count(edid))
>  		goto ok;
>  
> -	new = krealloc(edid, edid_size(edid), GFP_KERNEL);
> +	alloc_size = edid_size(edid);
> +	new = krealloc(edid, alloc_size, GFP_KERNEL);
>  	if (!new)
>  		goto fail;
>  	edid = new;
> @@ -2300,7 +2310,8 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  	if (invalid_blocks) {
>  		connector_bad_edid(connector, edid, edid_block_count(edid));
>  
> -		edid = edid_filter_invalid_blocks(edid, invalid_blocks);
> +		edid = edid_filter_invalid_blocks(edid, invalid_blocks,
> +						  &alloc_size);
>  	}
>  
>  ok:
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 05/15] drm/edid: add new interfaces around struct drm_edid
  2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
@ 2022-06-10 19:35     ` Ville Syrjälä
  -1 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:35 UTC (permalink / raw)
  To: Jani Nikula; +Cc: David Airlie, intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:35AM +0300, Jani Nikula wrote:
> Add new functions drm_edid_read(), drm_edid_read_ddc(), and
> drm_edid_read_custom() to replace drm_get_edid() and drm_do_get_edid()
> for reading the EDID. The transition is expected to happen over a fairly
> long time.
> 
> Note that the new drm_edid_read*() functions do not do any of the
> connector updates anymore. The reading and parsing will be completely
> separated from each other.
> 
> Add new functions drm_edid_alloc(), drm_edid_dup(), and drm_edid_free()
> for allocating and freeing drm_edid containers.
> 
> Cc: David Airlie <airlied@linux.ie>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c | 245 +++++++++++++++++++++++++++++++++----
>  include/drm/drm_edid.h     |   9 ++
>  2 files changed, 230 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 2beaa48301c1..2bdaf1e34a9d 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2226,29 +2226,9 @@ static enum edid_block_status edid_block_read(void *block, unsigned int block_nu
>  	return status;
>  }
>  
> -/**
> - * drm_do_get_edid - get EDID data using a custom EDID block read function
> - * @connector: connector we're probing
> - * @read_block: EDID block read function
> - * @context: private data passed to the block read function
> - *
> - * When the I2C adapter connected to the DDC bus is hidden behind a device that
> - * exposes a different interface to read EDID blocks this function can be used
> - * to get EDID data using a custom block read function.
> - *
> - * As in the general case the DDC bus is accessible by the kernel at the I2C
> - * level, drivers must make all reasonable efforts to expose it as an I2C
> - * adapter and use drm_get_edid() instead of abusing this function.
> - *
> - * The EDID may be overridden using debugfs override_edid or firmware EDID
> - * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> - * order. Having either of them bypasses actual EDID reads.
> - *
> - * Return: Pointer to valid EDID or NULL if we couldn't find any.
> - */
> -struct edid *drm_do_get_edid(struct drm_connector *connector,
> -			     read_block_fn read_block,
> -			     void *context)
> +static struct edid *_drm_do_get_edid(struct drm_connector *connector,
> +				     read_block_fn read_block, void *context,
> +				     size_t *size)
>  {
>  	enum edid_block_status status;
>  	int i, invalid_blocks = 0;
> @@ -2315,14 +2295,125 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  	}
>  
>  ok:
> +	if (size)
> +		*size = alloc_size;
> +
>  	return edid;
>  
>  fail:
>  	kfree(edid);
>  	return NULL;
>  }
> +
> +/**
> + * drm_do_get_edid - get EDID data using a custom EDID block read function
> + * @connector: connector we're probing
> + * @read_block: EDID block read function
> + * @context: private data passed to the block read function
> + *
> + * When the I2C adapter connected to the DDC bus is hidden behind a device that
> + * exposes a different interface to read EDID blocks this function can be used
> + * to get EDID data using a custom block read function.
> + *
> + * As in the general case the DDC bus is accessible by the kernel at the I2C
> + * level, drivers must make all reasonable efforts to expose it as an I2C
> + * adapter and use drm_get_edid() instead of abusing this function.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * Return: Pointer to valid EDID or NULL if we couldn't find any.
> + */
> +struct edid *drm_do_get_edid(struct drm_connector *connector,
> +			     read_block_fn read_block,
> +			     void *context)
> +{
> +	return _drm_do_get_edid(connector, read_block, context, NULL);
> +}
>  EXPORT_SYMBOL_GPL(drm_do_get_edid);
>  
> +/* Allocate struct drm_edid container *without* duplicating the edid data */
> +static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
> +{
> +	struct drm_edid *drm_edid;
> +
> +	if (!edid || !size || size < EDID_LENGTH)
> +		return NULL;
> +
> +	drm_edid = kzalloc(sizeof(*drm_edid), GFP_KERNEL);
> +	if (drm_edid) {
> +		drm_edid->edid = edid;
> +		drm_edid->size = size;
> +	}
> +
> +	return drm_edid;
> +}
> +
> +/**
> + * drm_edid_alloc - Allocate a new drm_edid container
> + * @edid: Pointer to raw EDID data
> + * @size: Size of memory allocated for EDID
> + *
> + * Allocate a new drm_edid container. Do not calculate edid size from edid, pass
> + * the actual size that has been allocated for the data. There is no validation
> + * of the raw EDID data against the size, but at least the EDID base block must
> + * fit in the buffer.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: drm_edid container, or NULL on errors
> + */
> +const struct drm_edid *drm_edid_alloc(const void *edid, size_t size)
> +{
> +	const struct drm_edid *drm_edid;
> +
> +	if (!edid || !size || size < EDID_LENGTH)
> +		return NULL;
> +
> +	edid = kmemdup(edid, size, GFP_KERNEL);
> +	if (!edid)
> +		return NULL;
> +
> +	drm_edid = _drm_edid_alloc(edid, size);
> +	if (!drm_edid)
> +		kfree(edid);
> +
> +	return drm_edid;
> +}
> +EXPORT_SYMBOL(drm_edid_alloc);
> +
> +/**
> + * drm_edid_dup - Duplicate a drm_edid container
> + * @drm_edid: EDID to duplicate
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Returns: drm_edid container copy, or NULL on errors
> + */
> +const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid)
> +{
> +	if (!drm_edid)
> +		return NULL;
> +
> +	return drm_edid_alloc(drm_edid->edid, drm_edid->size);
> +}
> +EXPORT_SYMBOL(drm_edid_dup);
> +
> +/**
> + * drm_edid_free - Free the drm_edid container
> + * @drm_edid: EDID to free
> + */
> +void drm_edid_free(const struct drm_edid *drm_edid)
> +{
> +	if (!drm_edid)
> +		return;
> +
> +	kfree(drm_edid->edid);
> +	kfree(drm_edid);
> +}
> +EXPORT_SYMBOL(drm_edid_free);
> +
>  /**
>   * drm_probe_ddc() - probe DDC presence
>   * @adapter: I2C adapter to probe
> @@ -2359,12 +2450,118 @@ struct edid *drm_get_edid(struct drm_connector *connector,
>  	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
>  		return NULL;
>  
> -	edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
> +	edid = _drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter, NULL);
>  	drm_connector_update_edid_property(connector, edid);
>  	return edid;
>  }
>  EXPORT_SYMBOL(drm_get_edid);
>  
> +/**
> + * drm_edid_read_custom - Read EDID data using given EDID block read function
> + * @connector: Connector to use
> + * @read_block: EDID block read function
> + * @context: Private data passed to the block read function
> + *
> + * When the I2C adapter connected to the DDC bus is hidden behind a device that
> + * exposes a different interface to read EDID blocks this function can be used
> + * to get EDID data using a custom block read function.
> + *
> + * As in the general case the DDC bus is accessible by the kernel at the I2C
> + * level, drivers must make all reasonable efforts to expose it as an I2C
> + * adapter and use drm_edid_read() or drm_edid_read_ddc() instead of abusing
> + * this function.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: Pointer to EDID, or NULL if probe/read failed.
> + */
> +const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
> +					    read_block_fn read_block,
> +					    void *context)
> +{
> +	const struct drm_edid *drm_edid;
> +	struct edid *edid;
> +	size_t size = 0;
> +
> +	edid = _drm_do_get_edid(connector, read_block, context, &size);
> +	if (!edid)
> +		return NULL;
> +
> +	/* Sanity check for now */
> +	drm_WARN_ON(connector->dev, !size);
> +
> +	drm_edid = _drm_edid_alloc(edid, size);
> +	if (!drm_edid)
> +		kfree(edid);
> +
> +	return drm_edid;
> +}
> +EXPORT_SYMBOL(drm_edid_read_custom);
> +
> +/**
> + * drm_edid_read_ddc - Read EDID data using given I2C adapter
> + * @connector: Connector to use
> + * @adapter: I2C adapter to use for DDC
> + *
> + * Read EDID using the given I2C adapter.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * Prefer initializing connector->ddc with drm_connector_init_with_ddc() and
> + * using drm_edid_read() instead of this function.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: Pointer to EDID, or NULL if probe/read failed.
> + */
> +const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
> +					 struct i2c_adapter *adapter)
> +{
> +	const struct drm_edid *drm_edid;
> +
> +	if (connector->force == DRM_FORCE_OFF)
> +		return NULL;
> +
> +	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
> +		return NULL;
> +
> +	drm_edid = drm_edid_read_custom(connector, drm_do_probe_ddc_edid, adapter);
> +
> +	/* Note: Do *not* call connector updates here. */
> +
> +	return drm_edid;
> +}
> +EXPORT_SYMBOL(drm_edid_read_ddc);
> +
> +/**
> + * drm_edid_read - Read EDID data using connector's I2C adapter
> + * @connector: Connector to use
> + *
> + * Read EDID using the connector's I2C adapter.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: Pointer to EDID, or NULL if probe/read failed.
> + */
> +const struct drm_edid *drm_edid_read(struct drm_connector *connector)
> +{
> +	if (drm_WARN_ON(connector->dev, !connector->ddc))
> +		return NULL;
> +
> +	return drm_edid_read_ddc(connector, connector->ddc);
> +}
> +EXPORT_SYMBOL(drm_edid_read);
> +
>  static u32 edid_extract_panel_id(const struct edid *edid)
>  {
>  	/*
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 95ac09ef41b2..9d2d78135dee 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -594,6 +594,15 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
>  			      u8 video_code);
>  
>  /* Interface based on struct drm_edid */
> +const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
> +const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
> +void drm_edid_free(const struct drm_edid *drm_edid);
> +const struct drm_edid *drm_edid_read(struct drm_connector *connector);
> +const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
> +					 struct i2c_adapter *adapter);
> +const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
> +					    int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),
> +					    void *context);
>  const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
>  				  int ext_id, int *ext_index);
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 05/15] drm/edid: add new interfaces around struct drm_edid
@ 2022-06-10 19:35     ` Ville Syrjälä
  0 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:35 UTC (permalink / raw)
  To: Jani Nikula; +Cc: David Airlie, intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:35AM +0300, Jani Nikula wrote:
> Add new functions drm_edid_read(), drm_edid_read_ddc(), and
> drm_edid_read_custom() to replace drm_get_edid() and drm_do_get_edid()
> for reading the EDID. The transition is expected to happen over a fairly
> long time.
> 
> Note that the new drm_edid_read*() functions do not do any of the
> connector updates anymore. The reading and parsing will be completely
> separated from each other.
> 
> Add new functions drm_edid_alloc(), drm_edid_dup(), and drm_edid_free()
> for allocating and freeing drm_edid containers.
> 
> Cc: David Airlie <airlied@linux.ie>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c | 245 +++++++++++++++++++++++++++++++++----
>  include/drm/drm_edid.h     |   9 ++
>  2 files changed, 230 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 2beaa48301c1..2bdaf1e34a9d 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2226,29 +2226,9 @@ static enum edid_block_status edid_block_read(void *block, unsigned int block_nu
>  	return status;
>  }
>  
> -/**
> - * drm_do_get_edid - get EDID data using a custom EDID block read function
> - * @connector: connector we're probing
> - * @read_block: EDID block read function
> - * @context: private data passed to the block read function
> - *
> - * When the I2C adapter connected to the DDC bus is hidden behind a device that
> - * exposes a different interface to read EDID blocks this function can be used
> - * to get EDID data using a custom block read function.
> - *
> - * As in the general case the DDC bus is accessible by the kernel at the I2C
> - * level, drivers must make all reasonable efforts to expose it as an I2C
> - * adapter and use drm_get_edid() instead of abusing this function.
> - *
> - * The EDID may be overridden using debugfs override_edid or firmware EDID
> - * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> - * order. Having either of them bypasses actual EDID reads.
> - *
> - * Return: Pointer to valid EDID or NULL if we couldn't find any.
> - */
> -struct edid *drm_do_get_edid(struct drm_connector *connector,
> -			     read_block_fn read_block,
> -			     void *context)
> +static struct edid *_drm_do_get_edid(struct drm_connector *connector,
> +				     read_block_fn read_block, void *context,
> +				     size_t *size)
>  {
>  	enum edid_block_status status;
>  	int i, invalid_blocks = 0;
> @@ -2315,14 +2295,125 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  	}
>  
>  ok:
> +	if (size)
> +		*size = alloc_size;
> +
>  	return edid;
>  
>  fail:
>  	kfree(edid);
>  	return NULL;
>  }
> +
> +/**
> + * drm_do_get_edid - get EDID data using a custom EDID block read function
> + * @connector: connector we're probing
> + * @read_block: EDID block read function
> + * @context: private data passed to the block read function
> + *
> + * When the I2C adapter connected to the DDC bus is hidden behind a device that
> + * exposes a different interface to read EDID blocks this function can be used
> + * to get EDID data using a custom block read function.
> + *
> + * As in the general case the DDC bus is accessible by the kernel at the I2C
> + * level, drivers must make all reasonable efforts to expose it as an I2C
> + * adapter and use drm_get_edid() instead of abusing this function.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * Return: Pointer to valid EDID or NULL if we couldn't find any.
> + */
> +struct edid *drm_do_get_edid(struct drm_connector *connector,
> +			     read_block_fn read_block,
> +			     void *context)
> +{
> +	return _drm_do_get_edid(connector, read_block, context, NULL);
> +}
>  EXPORT_SYMBOL_GPL(drm_do_get_edid);
>  
> +/* Allocate struct drm_edid container *without* duplicating the edid data */
> +static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
> +{
> +	struct drm_edid *drm_edid;
> +
> +	if (!edid || !size || size < EDID_LENGTH)
> +		return NULL;
> +
> +	drm_edid = kzalloc(sizeof(*drm_edid), GFP_KERNEL);
> +	if (drm_edid) {
> +		drm_edid->edid = edid;
> +		drm_edid->size = size;
> +	}
> +
> +	return drm_edid;
> +}
> +
> +/**
> + * drm_edid_alloc - Allocate a new drm_edid container
> + * @edid: Pointer to raw EDID data
> + * @size: Size of memory allocated for EDID
> + *
> + * Allocate a new drm_edid container. Do not calculate edid size from edid, pass
> + * the actual size that has been allocated for the data. There is no validation
> + * of the raw EDID data against the size, but at least the EDID base block must
> + * fit in the buffer.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: drm_edid container, or NULL on errors
> + */
> +const struct drm_edid *drm_edid_alloc(const void *edid, size_t size)
> +{
> +	const struct drm_edid *drm_edid;
> +
> +	if (!edid || !size || size < EDID_LENGTH)
> +		return NULL;
> +
> +	edid = kmemdup(edid, size, GFP_KERNEL);
> +	if (!edid)
> +		return NULL;
> +
> +	drm_edid = _drm_edid_alloc(edid, size);
> +	if (!drm_edid)
> +		kfree(edid);
> +
> +	return drm_edid;
> +}
> +EXPORT_SYMBOL(drm_edid_alloc);
> +
> +/**
> + * drm_edid_dup - Duplicate a drm_edid container
> + * @drm_edid: EDID to duplicate
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Returns: drm_edid container copy, or NULL on errors
> + */
> +const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid)
> +{
> +	if (!drm_edid)
> +		return NULL;
> +
> +	return drm_edid_alloc(drm_edid->edid, drm_edid->size);
> +}
> +EXPORT_SYMBOL(drm_edid_dup);
> +
> +/**
> + * drm_edid_free - Free the drm_edid container
> + * @drm_edid: EDID to free
> + */
> +void drm_edid_free(const struct drm_edid *drm_edid)
> +{
> +	if (!drm_edid)
> +		return;
> +
> +	kfree(drm_edid->edid);
> +	kfree(drm_edid);
> +}
> +EXPORT_SYMBOL(drm_edid_free);
> +
>  /**
>   * drm_probe_ddc() - probe DDC presence
>   * @adapter: I2C adapter to probe
> @@ -2359,12 +2450,118 @@ struct edid *drm_get_edid(struct drm_connector *connector,
>  	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
>  		return NULL;
>  
> -	edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
> +	edid = _drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter, NULL);
>  	drm_connector_update_edid_property(connector, edid);
>  	return edid;
>  }
>  EXPORT_SYMBOL(drm_get_edid);
>  
> +/**
> + * drm_edid_read_custom - Read EDID data using given EDID block read function
> + * @connector: Connector to use
> + * @read_block: EDID block read function
> + * @context: Private data passed to the block read function
> + *
> + * When the I2C adapter connected to the DDC bus is hidden behind a device that
> + * exposes a different interface to read EDID blocks this function can be used
> + * to get EDID data using a custom block read function.
> + *
> + * As in the general case the DDC bus is accessible by the kernel at the I2C
> + * level, drivers must make all reasonable efforts to expose it as an I2C
> + * adapter and use drm_edid_read() or drm_edid_read_ddc() instead of abusing
> + * this function.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: Pointer to EDID, or NULL if probe/read failed.
> + */
> +const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
> +					    read_block_fn read_block,
> +					    void *context)
> +{
> +	const struct drm_edid *drm_edid;
> +	struct edid *edid;
> +	size_t size = 0;
> +
> +	edid = _drm_do_get_edid(connector, read_block, context, &size);
> +	if (!edid)
> +		return NULL;
> +
> +	/* Sanity check for now */
> +	drm_WARN_ON(connector->dev, !size);
> +
> +	drm_edid = _drm_edid_alloc(edid, size);
> +	if (!drm_edid)
> +		kfree(edid);
> +
> +	return drm_edid;
> +}
> +EXPORT_SYMBOL(drm_edid_read_custom);
> +
> +/**
> + * drm_edid_read_ddc - Read EDID data using given I2C adapter
> + * @connector: Connector to use
> + * @adapter: I2C adapter to use for DDC
> + *
> + * Read EDID using the given I2C adapter.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * Prefer initializing connector->ddc with drm_connector_init_with_ddc() and
> + * using drm_edid_read() instead of this function.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: Pointer to EDID, or NULL if probe/read failed.
> + */
> +const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
> +					 struct i2c_adapter *adapter)
> +{
> +	const struct drm_edid *drm_edid;
> +
> +	if (connector->force == DRM_FORCE_OFF)
> +		return NULL;
> +
> +	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
> +		return NULL;
> +
> +	drm_edid = drm_edid_read_custom(connector, drm_do_probe_ddc_edid, adapter);
> +
> +	/* Note: Do *not* call connector updates here. */
> +
> +	return drm_edid;
> +}
> +EXPORT_SYMBOL(drm_edid_read_ddc);
> +
> +/**
> + * drm_edid_read - Read EDID data using connector's I2C adapter
> + * @connector: Connector to use
> + *
> + * Read EDID using the connector's I2C adapter.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: Pointer to EDID, or NULL if probe/read failed.
> + */
> +const struct drm_edid *drm_edid_read(struct drm_connector *connector)
> +{
> +	if (drm_WARN_ON(connector->dev, !connector->ddc))
> +		return NULL;
> +
> +	return drm_edid_read_ddc(connector, connector->ddc);
> +}
> +EXPORT_SYMBOL(drm_edid_read);
> +
>  static u32 edid_extract_panel_id(const struct edid *edid)
>  {
>  	/*
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 95ac09ef41b2..9d2d78135dee 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -594,6 +594,15 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
>  			      u8 video_code);
>  
>  /* Interface based on struct drm_edid */
> +const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
> +const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
> +void drm_edid_free(const struct drm_edid *drm_edid);
> +const struct drm_edid *drm_edid_read(struct drm_connector *connector);
> +const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
> +					 struct i2c_adapter *adapter);
> +const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
> +					    int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),
> +					    void *context);
>  const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
>  				  int ext_id, int *ext_index);
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 07/15] drm/probe-helper: abstract .get_modes() connector helper call
  2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
@ 2022-06-10 19:36     ` Ville Syrjälä
  -1 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:36 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:37AM +0300, Jani Nikula wrote:
> Abstract the .get_modes() connector helper call, including the
> override/firmware EDID fallback, for clarity.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_probe_helper.c | 29 +++++++++++++++++++----------
>  1 file changed, 19 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index 75a71649b64d..a8d26b29bfa0 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -354,6 +354,24 @@ drm_helper_probe_detect(struct drm_connector *connector,
>  }
>  EXPORT_SYMBOL(drm_helper_probe_detect);
>  
> +static int drm_helper_probe_get_modes(struct drm_connector *connector)
> +{
> +	const struct drm_connector_helper_funcs *connector_funcs =
> +		connector->helper_private;
> +	int count;
> +
> +	count = connector_funcs->get_modes(connector);
> +
> +	/*
> +	 * Fallback for when DDC probe failed in drm_get_edid() and thus skipped
> +	 * override/firmware EDID.
> +	 */
> +	if (count == 0 && connector->status == connector_status_connected)
> +		count = drm_add_override_edid_modes(connector);
> +
> +	return count;
> +}
> +
>  static int __drm_helper_update_and_validate(struct drm_connector *connector,
>  					    uint32_t maxX, uint32_t maxY,
>  					    struct drm_modeset_acquire_ctx *ctx)
> @@ -473,8 +491,6 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
>  {
>  	struct drm_device *dev = connector->dev;
>  	struct drm_display_mode *mode;
> -	const struct drm_connector_helper_funcs *connector_funcs =
> -		connector->helper_private;
>  	int count = 0, ret;
>  	enum drm_connector_status old_status;
>  	struct drm_modeset_acquire_ctx ctx;
> @@ -559,14 +575,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
>  		goto exit;
>  	}
>  
> -	count = (*connector_funcs->get_modes)(connector);
> -
> -	/*
> -	 * Fallback for when DDC probe failed in drm_get_edid() and thus skipped
> -	 * override/firmware EDID.
> -	 */
> -	if (count == 0 && connector->status == connector_status_connected)
> -		count = drm_add_override_edid_modes(connector);
> +	count = drm_helper_probe_get_modes(connector);
>  
>  	if (count == 0 && (connector->status == connector_status_connected ||
>  			   connector->status == connector_status_unknown)) {
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 07/15] drm/probe-helper: abstract .get_modes() connector helper call
@ 2022-06-10 19:36     ` Ville Syrjälä
  0 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:36 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:37AM +0300, Jani Nikula wrote:
> Abstract the .get_modes() connector helper call, including the
> override/firmware EDID fallback, for clarity.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_probe_helper.c | 29 +++++++++++++++++++----------
>  1 file changed, 19 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index 75a71649b64d..a8d26b29bfa0 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -354,6 +354,24 @@ drm_helper_probe_detect(struct drm_connector *connector,
>  }
>  EXPORT_SYMBOL(drm_helper_probe_detect);
>  
> +static int drm_helper_probe_get_modes(struct drm_connector *connector)
> +{
> +	const struct drm_connector_helper_funcs *connector_funcs =
> +		connector->helper_private;
> +	int count;
> +
> +	count = connector_funcs->get_modes(connector);
> +
> +	/*
> +	 * Fallback for when DDC probe failed in drm_get_edid() and thus skipped
> +	 * override/firmware EDID.
> +	 */
> +	if (count == 0 && connector->status == connector_status_connected)
> +		count = drm_add_override_edid_modes(connector);
> +
> +	return count;
> +}
> +
>  static int __drm_helper_update_and_validate(struct drm_connector *connector,
>  					    uint32_t maxX, uint32_t maxY,
>  					    struct drm_modeset_acquire_ctx *ctx)
> @@ -473,8 +491,6 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
>  {
>  	struct drm_device *dev = connector->dev;
>  	struct drm_display_mode *mode;
> -	const struct drm_connector_helper_funcs *connector_funcs =
> -		connector->helper_private;
>  	int count = 0, ret;
>  	enum drm_connector_status old_status;
>  	struct drm_modeset_acquire_ctx ctx;
> @@ -559,14 +575,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
>  		goto exit;
>  	}
>  
> -	count = (*connector_funcs->get_modes)(connector);
> -
> -	/*
> -	 * Fallback for when DDC probe failed in drm_get_edid() and thus skipped
> -	 * override/firmware EDID.
> -	 */
> -	if (count == 0 && connector->status == connector_status_connected)
> -		count = drm_add_override_edid_modes(connector);
> +	count = drm_helper_probe_get_modes(connector);
>  
>  	if (count == 0 && (connector->status == connector_status_connected ||
>  			   connector->status == connector_status_unknown)) {
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 05/15] drm/edid: add new interfaces around struct drm_edid
  2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
@ 2022-06-10 19:43     ` Ville Syrjälä
  -1 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:43 UTC (permalink / raw)
  To: Jani Nikula; +Cc: David Airlie, intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:35AM +0300, Jani Nikula wrote:
> Add new functions drm_edid_read(), drm_edid_read_ddc(), and
> drm_edid_read_custom() to replace drm_get_edid() and drm_do_get_edid()
> for reading the EDID. The transition is expected to happen over a fairly
> long time.
> 
> Note that the new drm_edid_read*() functions do not do any of the
> connector updates anymore. The reading and parsing will be completely
> separated from each other.
> 
> Add new functions drm_edid_alloc(), drm_edid_dup(), and drm_edid_free()
> for allocating and freeing drm_edid containers.
> 
> Cc: David Airlie <airlied@linux.ie>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/drm_edid.c | 245 +++++++++++++++++++++++++++++++++----
>  include/drm/drm_edid.h     |   9 ++
>  2 files changed, 230 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 2beaa48301c1..2bdaf1e34a9d 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2226,29 +2226,9 @@ static enum edid_block_status edid_block_read(void *block, unsigned int block_nu
>  	return status;
>  }
>  
> -/**
> - * drm_do_get_edid - get EDID data using a custom EDID block read function
> - * @connector: connector we're probing
> - * @read_block: EDID block read function
> - * @context: private data passed to the block read function
> - *
> - * When the I2C adapter connected to the DDC bus is hidden behind a device that
> - * exposes a different interface to read EDID blocks this function can be used
> - * to get EDID data using a custom block read function.
> - *
> - * As in the general case the DDC bus is accessible by the kernel at the I2C
> - * level, drivers must make all reasonable efforts to expose it as an I2C
> - * adapter and use drm_get_edid() instead of abusing this function.
> - *
> - * The EDID may be overridden using debugfs override_edid or firmware EDID
> - * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> - * order. Having either of them bypasses actual EDID reads.
> - *
> - * Return: Pointer to valid EDID or NULL if we couldn't find any.
> - */
> -struct edid *drm_do_get_edid(struct drm_connector *connector,
> -			     read_block_fn read_block,
> -			     void *context)
> +static struct edid *_drm_do_get_edid(struct drm_connector *connector,
> +				     read_block_fn read_block, void *context,
> +				     size_t *size)
>  {
>  	enum edid_block_status status;
>  	int i, invalid_blocks = 0;
> @@ -2315,14 +2295,125 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  	}
>  
>  ok:
> +	if (size)
> +		*size = alloc_size;
> +
>  	return edid;
>  
>  fail:
>  	kfree(edid);
>  	return NULL;
>  }
> +
> +/**
> + * drm_do_get_edid - get EDID data using a custom EDID block read function
> + * @connector: connector we're probing
> + * @read_block: EDID block read function
> + * @context: private data passed to the block read function
> + *
> + * When the I2C adapter connected to the DDC bus is hidden behind a device that
> + * exposes a different interface to read EDID blocks this function can be used
> + * to get EDID data using a custom block read function.
> + *
> + * As in the general case the DDC bus is accessible by the kernel at the I2C
> + * level, drivers must make all reasonable efforts to expose it as an I2C
> + * adapter and use drm_get_edid() instead of abusing this function.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * Return: Pointer to valid EDID or NULL if we couldn't find any.
> + */
> +struct edid *drm_do_get_edid(struct drm_connector *connector,
> +			     read_block_fn read_block,
> +			     void *context)
> +{
> +	return _drm_do_get_edid(connector, read_block, context, NULL);
> +}
>  EXPORT_SYMBOL_GPL(drm_do_get_edid);
>  
> +/* Allocate struct drm_edid container *without* duplicating the edid data */
> +static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
> +{
> +	struct drm_edid *drm_edid;
> +
> +	if (!edid || !size || size < EDID_LENGTH)
> +		return NULL;
> +
> +	drm_edid = kzalloc(sizeof(*drm_edid), GFP_KERNEL);
> +	if (drm_edid) {
> +		drm_edid->edid = edid;
> +		drm_edid->size = size;
> +	}
> +
> +	return drm_edid;
> +}
> +
> +/**
> + * drm_edid_alloc - Allocate a new drm_edid container
> + * @edid: Pointer to raw EDID data
> + * @size: Size of memory allocated for EDID
> + *
> + * Allocate a new drm_edid container. Do not calculate edid size from edid, pass
> + * the actual size that has been allocated for the data. There is no validation
> + * of the raw EDID data against the size, but at least the EDID base block must
> + * fit in the buffer.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: drm_edid container, or NULL on errors
> + */
> +const struct drm_edid *drm_edid_alloc(const void *edid, size_t size)
> +{
> +	const struct drm_edid *drm_edid;
> +
> +	if (!edid || !size || size < EDID_LENGTH)
> +		return NULL;
> +
> +	edid = kmemdup(edid, size, GFP_KERNEL);
> +	if (!edid)
> +		return NULL;
> +
> +	drm_edid = _drm_edid_alloc(edid, size);
> +	if (!drm_edid)
> +		kfree(edid);
> +
> +	return drm_edid;
> +}
> +EXPORT_SYMBOL(drm_edid_alloc);
> +
> +/**
> + * drm_edid_dup - Duplicate a drm_edid container
> + * @drm_edid: EDID to duplicate
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Returns: drm_edid container copy, or NULL on errors
> + */
> +const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid)
> +{
> +	if (!drm_edid)
> +		return NULL;
> +
> +	return drm_edid_alloc(drm_edid->edid, drm_edid->size);
> +}
> +EXPORT_SYMBOL(drm_edid_dup);
> +
> +/**
> + * drm_edid_free - Free the drm_edid container
> + * @drm_edid: EDID to free
> + */
> +void drm_edid_free(const struct drm_edid *drm_edid)
> +{
> +	if (!drm_edid)
> +		return;
> +
> +	kfree(drm_edid->edid);
> +	kfree(drm_edid);
> +}
> +EXPORT_SYMBOL(drm_edid_free);
> +
>  /**
>   * drm_probe_ddc() - probe DDC presence
>   * @adapter: I2C adapter to probe
> @@ -2359,12 +2450,118 @@ struct edid *drm_get_edid(struct drm_connector *connector,
>  	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
>  		return NULL;
>  
> -	edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
> +	edid = _drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter, NULL);
>  	drm_connector_update_edid_property(connector, edid);
>  	return edid;
>  }
>  EXPORT_SYMBOL(drm_get_edid);
>  
> +/**
> + * drm_edid_read_custom - Read EDID data using given EDID block read function
> + * @connector: Connector to use
> + * @read_block: EDID block read function
> + * @context: Private data passed to the block read function
> + *
> + * When the I2C adapter connected to the DDC bus is hidden behind a device that
> + * exposes a different interface to read EDID blocks this function can be used
> + * to get EDID data using a custom block read function.
> + *
> + * As in the general case the DDC bus is accessible by the kernel at the I2C
> + * level, drivers must make all reasonable efforts to expose it as an I2C
> + * adapter and use drm_edid_read() or drm_edid_read_ddc() instead of abusing
> + * this function.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: Pointer to EDID, or NULL if probe/read failed.
> + */
> +const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
> +					    read_block_fn read_block,
> +					    void *context)
> +{
> +	const struct drm_edid *drm_edid;
> +	struct edid *edid;
> +	size_t size = 0;
> +
> +	edid = _drm_do_get_edid(connector, read_block, context, &size);
> +	if (!edid)
> +		return NULL;
> +
> +	/* Sanity check for now */
> +	drm_WARN_ON(connector->dev, !size);
> +
> +	drm_edid = _drm_edid_alloc(edid, size);
> +	if (!drm_edid)
> +		kfree(edid);
> +
> +	return drm_edid;
> +}
> +EXPORT_SYMBOL(drm_edid_read_custom);
> +
> +/**
> + * drm_edid_read_ddc - Read EDID data using given I2C adapter
> + * @connector: Connector to use
> + * @adapter: I2C adapter to use for DDC
> + *
> + * Read EDID using the given I2C adapter.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * Prefer initializing connector->ddc with drm_connector_init_with_ddc() and
> + * using drm_edid_read() instead of this function.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: Pointer to EDID, or NULL if probe/read failed.
> + */
> +const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
> +					 struct i2c_adapter *adapter)
> +{
> +	const struct drm_edid *drm_edid;
> +
> +	if (connector->force == DRM_FORCE_OFF)
> +		return NULL;
> +
> +	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
> +		return NULL;
> +
> +	drm_edid = drm_edid_read_custom(connector, drm_do_probe_ddc_edid, adapter);
> +
> +	/* Note: Do *not* call connector updates here. */
> +
> +	return drm_edid;
> +}
> +EXPORT_SYMBOL(drm_edid_read_ddc);
> +
> +/**
> + * drm_edid_read - Read EDID data using connector's I2C adapter
> + * @connector: Connector to use
> + *
> + * Read EDID using the connector's I2C adapter.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: Pointer to EDID, or NULL if probe/read failed.
> + */
> +const struct drm_edid *drm_edid_read(struct drm_connector *connector)
> +{
> +	if (drm_WARN_ON(connector->dev, !connector->ddc))
> +		return NULL;
> +
> +	return drm_edid_read_ddc(connector, connector->ddc);
> +}
> +EXPORT_SYMBOL(drm_edid_read);

I'm wondering if we need this drm_edid_read() vs. drm_edid_read_ddc()
split? Ie. are there cases where connector->ddc wouldn't be populated
for some reason but we still want to use drm_edid_read_ddc()?

> +
>  static u32 edid_extract_panel_id(const struct edid *edid)
>  {
>  	/*
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 95ac09ef41b2..9d2d78135dee 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -594,6 +594,15 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
>  			      u8 video_code);
>  
>  /* Interface based on struct drm_edid */
> +const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
> +const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
> +void drm_edid_free(const struct drm_edid *drm_edid);
> +const struct drm_edid *drm_edid_read(struct drm_connector *connector);
> +const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
> +					 struct i2c_adapter *adapter);
> +const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
> +					    int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),
> +					    void *context);
>  const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
>  				  int ext_id, int *ext_index);
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 05/15] drm/edid: add new interfaces around struct drm_edid
@ 2022-06-10 19:43     ` Ville Syrjälä
  0 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:43 UTC (permalink / raw)
  To: Jani Nikula; +Cc: David Airlie, intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:35AM +0300, Jani Nikula wrote:
> Add new functions drm_edid_read(), drm_edid_read_ddc(), and
> drm_edid_read_custom() to replace drm_get_edid() and drm_do_get_edid()
> for reading the EDID. The transition is expected to happen over a fairly
> long time.
> 
> Note that the new drm_edid_read*() functions do not do any of the
> connector updates anymore. The reading and parsing will be completely
> separated from each other.
> 
> Add new functions drm_edid_alloc(), drm_edid_dup(), and drm_edid_free()
> for allocating and freeing drm_edid containers.
> 
> Cc: David Airlie <airlied@linux.ie>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/drm_edid.c | 245 +++++++++++++++++++++++++++++++++----
>  include/drm/drm_edid.h     |   9 ++
>  2 files changed, 230 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 2beaa48301c1..2bdaf1e34a9d 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2226,29 +2226,9 @@ static enum edid_block_status edid_block_read(void *block, unsigned int block_nu
>  	return status;
>  }
>  
> -/**
> - * drm_do_get_edid - get EDID data using a custom EDID block read function
> - * @connector: connector we're probing
> - * @read_block: EDID block read function
> - * @context: private data passed to the block read function
> - *
> - * When the I2C adapter connected to the DDC bus is hidden behind a device that
> - * exposes a different interface to read EDID blocks this function can be used
> - * to get EDID data using a custom block read function.
> - *
> - * As in the general case the DDC bus is accessible by the kernel at the I2C
> - * level, drivers must make all reasonable efforts to expose it as an I2C
> - * adapter and use drm_get_edid() instead of abusing this function.
> - *
> - * The EDID may be overridden using debugfs override_edid or firmware EDID
> - * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> - * order. Having either of them bypasses actual EDID reads.
> - *
> - * Return: Pointer to valid EDID or NULL if we couldn't find any.
> - */
> -struct edid *drm_do_get_edid(struct drm_connector *connector,
> -			     read_block_fn read_block,
> -			     void *context)
> +static struct edid *_drm_do_get_edid(struct drm_connector *connector,
> +				     read_block_fn read_block, void *context,
> +				     size_t *size)
>  {
>  	enum edid_block_status status;
>  	int i, invalid_blocks = 0;
> @@ -2315,14 +2295,125 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  	}
>  
>  ok:
> +	if (size)
> +		*size = alloc_size;
> +
>  	return edid;
>  
>  fail:
>  	kfree(edid);
>  	return NULL;
>  }
> +
> +/**
> + * drm_do_get_edid - get EDID data using a custom EDID block read function
> + * @connector: connector we're probing
> + * @read_block: EDID block read function
> + * @context: private data passed to the block read function
> + *
> + * When the I2C adapter connected to the DDC bus is hidden behind a device that
> + * exposes a different interface to read EDID blocks this function can be used
> + * to get EDID data using a custom block read function.
> + *
> + * As in the general case the DDC bus is accessible by the kernel at the I2C
> + * level, drivers must make all reasonable efforts to expose it as an I2C
> + * adapter and use drm_get_edid() instead of abusing this function.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * Return: Pointer to valid EDID or NULL if we couldn't find any.
> + */
> +struct edid *drm_do_get_edid(struct drm_connector *connector,
> +			     read_block_fn read_block,
> +			     void *context)
> +{
> +	return _drm_do_get_edid(connector, read_block, context, NULL);
> +}
>  EXPORT_SYMBOL_GPL(drm_do_get_edid);
>  
> +/* Allocate struct drm_edid container *without* duplicating the edid data */
> +static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
> +{
> +	struct drm_edid *drm_edid;
> +
> +	if (!edid || !size || size < EDID_LENGTH)
> +		return NULL;
> +
> +	drm_edid = kzalloc(sizeof(*drm_edid), GFP_KERNEL);
> +	if (drm_edid) {
> +		drm_edid->edid = edid;
> +		drm_edid->size = size;
> +	}
> +
> +	return drm_edid;
> +}
> +
> +/**
> + * drm_edid_alloc - Allocate a new drm_edid container
> + * @edid: Pointer to raw EDID data
> + * @size: Size of memory allocated for EDID
> + *
> + * Allocate a new drm_edid container. Do not calculate edid size from edid, pass
> + * the actual size that has been allocated for the data. There is no validation
> + * of the raw EDID data against the size, but at least the EDID base block must
> + * fit in the buffer.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: drm_edid container, or NULL on errors
> + */
> +const struct drm_edid *drm_edid_alloc(const void *edid, size_t size)
> +{
> +	const struct drm_edid *drm_edid;
> +
> +	if (!edid || !size || size < EDID_LENGTH)
> +		return NULL;
> +
> +	edid = kmemdup(edid, size, GFP_KERNEL);
> +	if (!edid)
> +		return NULL;
> +
> +	drm_edid = _drm_edid_alloc(edid, size);
> +	if (!drm_edid)
> +		kfree(edid);
> +
> +	return drm_edid;
> +}
> +EXPORT_SYMBOL(drm_edid_alloc);
> +
> +/**
> + * drm_edid_dup - Duplicate a drm_edid container
> + * @drm_edid: EDID to duplicate
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Returns: drm_edid container copy, or NULL on errors
> + */
> +const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid)
> +{
> +	if (!drm_edid)
> +		return NULL;
> +
> +	return drm_edid_alloc(drm_edid->edid, drm_edid->size);
> +}
> +EXPORT_SYMBOL(drm_edid_dup);
> +
> +/**
> + * drm_edid_free - Free the drm_edid container
> + * @drm_edid: EDID to free
> + */
> +void drm_edid_free(const struct drm_edid *drm_edid)
> +{
> +	if (!drm_edid)
> +		return;
> +
> +	kfree(drm_edid->edid);
> +	kfree(drm_edid);
> +}
> +EXPORT_SYMBOL(drm_edid_free);
> +
>  /**
>   * drm_probe_ddc() - probe DDC presence
>   * @adapter: I2C adapter to probe
> @@ -2359,12 +2450,118 @@ struct edid *drm_get_edid(struct drm_connector *connector,
>  	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
>  		return NULL;
>  
> -	edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
> +	edid = _drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter, NULL);
>  	drm_connector_update_edid_property(connector, edid);
>  	return edid;
>  }
>  EXPORT_SYMBOL(drm_get_edid);
>  
> +/**
> + * drm_edid_read_custom - Read EDID data using given EDID block read function
> + * @connector: Connector to use
> + * @read_block: EDID block read function
> + * @context: Private data passed to the block read function
> + *
> + * When the I2C adapter connected to the DDC bus is hidden behind a device that
> + * exposes a different interface to read EDID blocks this function can be used
> + * to get EDID data using a custom block read function.
> + *
> + * As in the general case the DDC bus is accessible by the kernel at the I2C
> + * level, drivers must make all reasonable efforts to expose it as an I2C
> + * adapter and use drm_edid_read() or drm_edid_read_ddc() instead of abusing
> + * this function.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: Pointer to EDID, or NULL if probe/read failed.
> + */
> +const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
> +					    read_block_fn read_block,
> +					    void *context)
> +{
> +	const struct drm_edid *drm_edid;
> +	struct edid *edid;
> +	size_t size = 0;
> +
> +	edid = _drm_do_get_edid(connector, read_block, context, &size);
> +	if (!edid)
> +		return NULL;
> +
> +	/* Sanity check for now */
> +	drm_WARN_ON(connector->dev, !size);
> +
> +	drm_edid = _drm_edid_alloc(edid, size);
> +	if (!drm_edid)
> +		kfree(edid);
> +
> +	return drm_edid;
> +}
> +EXPORT_SYMBOL(drm_edid_read_custom);
> +
> +/**
> + * drm_edid_read_ddc - Read EDID data using given I2C adapter
> + * @connector: Connector to use
> + * @adapter: I2C adapter to use for DDC
> + *
> + * Read EDID using the given I2C adapter.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * Prefer initializing connector->ddc with drm_connector_init_with_ddc() and
> + * using drm_edid_read() instead of this function.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: Pointer to EDID, or NULL if probe/read failed.
> + */
> +const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
> +					 struct i2c_adapter *adapter)
> +{
> +	const struct drm_edid *drm_edid;
> +
> +	if (connector->force == DRM_FORCE_OFF)
> +		return NULL;
> +
> +	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
> +		return NULL;
> +
> +	drm_edid = drm_edid_read_custom(connector, drm_do_probe_ddc_edid, adapter);
> +
> +	/* Note: Do *not* call connector updates here. */
> +
> +	return drm_edid;
> +}
> +EXPORT_SYMBOL(drm_edid_read_ddc);
> +
> +/**
> + * drm_edid_read - Read EDID data using connector's I2C adapter
> + * @connector: Connector to use
> + *
> + * Read EDID using the connector's I2C adapter.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * The returned pointer must be freed using drm_edid_free().
> + *
> + * Return: Pointer to EDID, or NULL if probe/read failed.
> + */
> +const struct drm_edid *drm_edid_read(struct drm_connector *connector)
> +{
> +	if (drm_WARN_ON(connector->dev, !connector->ddc))
> +		return NULL;
> +
> +	return drm_edid_read_ddc(connector, connector->ddc);
> +}
> +EXPORT_SYMBOL(drm_edid_read);

I'm wondering if we need this drm_edid_read() vs. drm_edid_read_ddc()
split? Ie. are there cases where connector->ddc wouldn't be populated
for some reason but we still want to use drm_edid_read_ddc()?

> +
>  static u32 edid_extract_panel_id(const struct edid *edid)
>  {
>  	/*
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 95ac09ef41b2..9d2d78135dee 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -594,6 +594,15 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
>  			      u8 video_code);
>  
>  /* Interface based on struct drm_edid */
> +const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
> +const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
> +void drm_edid_free(const struct drm_edid *drm_edid);
> +const struct drm_edid *drm_edid_read(struct drm_connector *connector);
> +const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
> +					 struct i2c_adapter *adapter);
> +const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
> +					    int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),
> +					    void *context);
>  const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
>  				  int ext_id, int *ext_index);
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 08/15] drm/probe-helper: add drm_connector_helper_get_modes()
  2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
@ 2022-06-10 19:44     ` Ville Syrjälä
  -1 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:44 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:38AM +0300, Jani Nikula wrote:
> Add a helper function to be used as the "default" .get_modes()
> hook. This also works as an example of what the driver .get_modes()
> hooks are supposed to do regarding the new drm_edid_read*() and
> drm_edid_connector_update() calls.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_probe_helper.c | 34 ++++++++++++++++++++++++++++++
>  include/drm/drm_probe_helper.h     |  1 +
>  2 files changed, 35 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index a8d26b29bfa0..e6b8f2923aa7 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -1049,3 +1049,37 @@ int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector)
>  	return count;
>  }
>  EXPORT_SYMBOL(drm_connector_helper_get_modes_from_ddc);
> +
> +/**
> + * drm_connector_helper_get_modes - Read EDID and update connector.
> + * @connector: The connector
> + *
> + * Read the EDID using drm_edid_read() (which requires that connector->ddc is
> + * set), and update the connector using the EDID.
> + *
> + * This can be used as the "default" connector helper .get_modes() hook if the
> + * driver does not need any special processing. This is sets the example what
> + * custom .get_modes() hooks should do regarding EDID read and connector update.
> + *
> + * Returns: Number of modes.
> + */
> +int drm_connector_helper_get_modes(struct drm_connector *connector)
> +{
> +	const struct drm_edid *drm_edid;
> +	int count;
> +
> +	drm_edid = drm_edid_read(connector);
> +
> +	/*
> +	 * Unconditionally update the connector. If the EDID was read
> +	 * succesfully, fill in the connector information derived from the
> +	 * EDID. Otherwise, if the EDID is NULL, clear the connector
> +	 * information.
> +	 */
> +	count = drm_edid_connector_update(connector, drm_edid);
> +
> +	drm_edid_free(drm_edid);
> +
> +	return count;
> +}
> +EXPORT_SYMBOL(drm_connector_helper_get_modes);
> diff --git a/include/drm/drm_probe_helper.h b/include/drm/drm_probe_helper.h
> index c80cab7a53b7..8075e02aa865 100644
> --- a/include/drm/drm_probe_helper.h
> +++ b/include/drm/drm_probe_helper.h
> @@ -27,5 +27,6 @@ void drm_kms_helper_poll_enable(struct drm_device *dev);
>  bool drm_kms_helper_is_poll_worker(void);
>  
>  int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector);
> +int drm_connector_helper_get_modes(struct drm_connector *connector);
>  
>  #endif
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 08/15] drm/probe-helper: add drm_connector_helper_get_modes()
@ 2022-06-10 19:44     ` Ville Syrjälä
  0 siblings, 0 replies; 68+ messages in thread
From: Ville Syrjälä @ 2022-06-10 19:44 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Jun 08, 2022 at 10:50:38AM +0300, Jani Nikula wrote:
> Add a helper function to be used as the "default" .get_modes()
> hook. This also works as an example of what the driver .get_modes()
> hooks are supposed to do regarding the new drm_edid_read*() and
> drm_edid_connector_update() calls.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_probe_helper.c | 34 ++++++++++++++++++++++++++++++
>  include/drm/drm_probe_helper.h     |  1 +
>  2 files changed, 35 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index a8d26b29bfa0..e6b8f2923aa7 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -1049,3 +1049,37 @@ int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector)
>  	return count;
>  }
>  EXPORT_SYMBOL(drm_connector_helper_get_modes_from_ddc);
> +
> +/**
> + * drm_connector_helper_get_modes - Read EDID and update connector.
> + * @connector: The connector
> + *
> + * Read the EDID using drm_edid_read() (which requires that connector->ddc is
> + * set), and update the connector using the EDID.
> + *
> + * This can be used as the "default" connector helper .get_modes() hook if the
> + * driver does not need any special processing. This is sets the example what
> + * custom .get_modes() hooks should do regarding EDID read and connector update.
> + *
> + * Returns: Number of modes.
> + */
> +int drm_connector_helper_get_modes(struct drm_connector *connector)
> +{
> +	const struct drm_edid *drm_edid;
> +	int count;
> +
> +	drm_edid = drm_edid_read(connector);
> +
> +	/*
> +	 * Unconditionally update the connector. If the EDID was read
> +	 * succesfully, fill in the connector information derived from the
> +	 * EDID. Otherwise, if the EDID is NULL, clear the connector
> +	 * information.
> +	 */
> +	count = drm_edid_connector_update(connector, drm_edid);
> +
> +	drm_edid_free(drm_edid);
> +
> +	return count;
> +}
> +EXPORT_SYMBOL(drm_connector_helper_get_modes);
> diff --git a/include/drm/drm_probe_helper.h b/include/drm/drm_probe_helper.h
> index c80cab7a53b7..8075e02aa865 100644
> --- a/include/drm/drm_probe_helper.h
> +++ b/include/drm/drm_probe_helper.h
> @@ -27,5 +27,6 @@ void drm_kms_helper_poll_enable(struct drm_device *dev);
>  bool drm_kms_helper_is_poll_worker(void);
>  
>  int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector);
> +int drm_connector_helper_get_modes(struct drm_connector *connector);
>  
>  #endif
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 05/15] drm/edid: add new interfaces around struct drm_edid
  2022-06-10 19:43     ` [Intel-gfx] " Ville Syrjälä
@ 2022-06-13  8:37       ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-13  8:37 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: David Airlie, intel-gfx, dri-devel

On Fri, 10 Jun 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Wed, Jun 08, 2022 at 10:50:35AM +0300, Jani Nikula wrote:
>> Add new functions drm_edid_read(), drm_edid_read_ddc(), and
>> drm_edid_read_custom() to replace drm_get_edid() and drm_do_get_edid()
>> for reading the EDID. The transition is expected to happen over a fairly
>> long time.
>> 
>> Note that the new drm_edid_read*() functions do not do any of the
>> connector updates anymore. The reading and parsing will be completely
>> separated from each other.
>> 
>> Add new functions drm_edid_alloc(), drm_edid_dup(), and drm_edid_free()
>> for allocating and freeing drm_edid containers.
>> 
>> Cc: David Airlie <airlied@linux.ie>
>> Cc: Daniel Vetter <daniel@ffwll.ch>
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>>  drivers/gpu/drm/drm_edid.c | 245 +++++++++++++++++++++++++++++++++----
>>  include/drm/drm_edid.h     |   9 ++
>>  2 files changed, 230 insertions(+), 24 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> index 2beaa48301c1..2bdaf1e34a9d 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -2226,29 +2226,9 @@ static enum edid_block_status edid_block_read(void *block, unsigned int block_nu
>>  	return status;
>>  }
>>  
>> -/**
>> - * drm_do_get_edid - get EDID data using a custom EDID block read function
>> - * @connector: connector we're probing
>> - * @read_block: EDID block read function
>> - * @context: private data passed to the block read function
>> - *
>> - * When the I2C adapter connected to the DDC bus is hidden behind a device that
>> - * exposes a different interface to read EDID blocks this function can be used
>> - * to get EDID data using a custom block read function.
>> - *
>> - * As in the general case the DDC bus is accessible by the kernel at the I2C
>> - * level, drivers must make all reasonable efforts to expose it as an I2C
>> - * adapter and use drm_get_edid() instead of abusing this function.
>> - *
>> - * The EDID may be overridden using debugfs override_edid or firmware EDID
>> - * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
>> - * order. Having either of them bypasses actual EDID reads.
>> - *
>> - * Return: Pointer to valid EDID or NULL if we couldn't find any.
>> - */
>> -struct edid *drm_do_get_edid(struct drm_connector *connector,
>> -			     read_block_fn read_block,
>> -			     void *context)
>> +static struct edid *_drm_do_get_edid(struct drm_connector *connector,
>> +				     read_block_fn read_block, void *context,
>> +				     size_t *size)
>>  {
>>  	enum edid_block_status status;
>>  	int i, invalid_blocks = 0;
>> @@ -2315,14 +2295,125 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>>  	}
>>  
>>  ok:
>> +	if (size)
>> +		*size = alloc_size;
>> +
>>  	return edid;
>>  
>>  fail:
>>  	kfree(edid);
>>  	return NULL;
>>  }
>> +
>> +/**
>> + * drm_do_get_edid - get EDID data using a custom EDID block read function
>> + * @connector: connector we're probing
>> + * @read_block: EDID block read function
>> + * @context: private data passed to the block read function
>> + *
>> + * When the I2C adapter connected to the DDC bus is hidden behind a device that
>> + * exposes a different interface to read EDID blocks this function can be used
>> + * to get EDID data using a custom block read function.
>> + *
>> + * As in the general case the DDC bus is accessible by the kernel at the I2C
>> + * level, drivers must make all reasonable efforts to expose it as an I2C
>> + * adapter and use drm_get_edid() instead of abusing this function.
>> + *
>> + * The EDID may be overridden using debugfs override_edid or firmware EDID
>> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
>> + * order. Having either of them bypasses actual EDID reads.
>> + *
>> + * Return: Pointer to valid EDID or NULL if we couldn't find any.
>> + */
>> +struct edid *drm_do_get_edid(struct drm_connector *connector,
>> +			     read_block_fn read_block,
>> +			     void *context)
>> +{
>> +	return _drm_do_get_edid(connector, read_block, context, NULL);
>> +}
>>  EXPORT_SYMBOL_GPL(drm_do_get_edid);
>>  
>> +/* Allocate struct drm_edid container *without* duplicating the edid data */
>> +static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
>> +{
>> +	struct drm_edid *drm_edid;
>> +
>> +	if (!edid || !size || size < EDID_LENGTH)
>> +		return NULL;
>> +
>> +	drm_edid = kzalloc(sizeof(*drm_edid), GFP_KERNEL);
>> +	if (drm_edid) {
>> +		drm_edid->edid = edid;
>> +		drm_edid->size = size;
>> +	}
>> +
>> +	return drm_edid;
>> +}
>> +
>> +/**
>> + * drm_edid_alloc - Allocate a new drm_edid container
>> + * @edid: Pointer to raw EDID data
>> + * @size: Size of memory allocated for EDID
>> + *
>> + * Allocate a new drm_edid container. Do not calculate edid size from edid, pass
>> + * the actual size that has been allocated for the data. There is no validation
>> + * of the raw EDID data against the size, but at least the EDID base block must
>> + * fit in the buffer.
>> + *
>> + * The returned pointer must be freed using drm_edid_free().
>> + *
>> + * Return: drm_edid container, or NULL on errors
>> + */
>> +const struct drm_edid *drm_edid_alloc(const void *edid, size_t size)
>> +{
>> +	const struct drm_edid *drm_edid;
>> +
>> +	if (!edid || !size || size < EDID_LENGTH)
>> +		return NULL;
>> +
>> +	edid = kmemdup(edid, size, GFP_KERNEL);
>> +	if (!edid)
>> +		return NULL;
>> +
>> +	drm_edid = _drm_edid_alloc(edid, size);
>> +	if (!drm_edid)
>> +		kfree(edid);
>> +
>> +	return drm_edid;
>> +}
>> +EXPORT_SYMBOL(drm_edid_alloc);
>> +
>> +/**
>> + * drm_edid_dup - Duplicate a drm_edid container
>> + * @drm_edid: EDID to duplicate
>> + *
>> + * The returned pointer must be freed using drm_edid_free().
>> + *
>> + * Returns: drm_edid container copy, or NULL on errors
>> + */
>> +const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid)
>> +{
>> +	if (!drm_edid)
>> +		return NULL;
>> +
>> +	return drm_edid_alloc(drm_edid->edid, drm_edid->size);
>> +}
>> +EXPORT_SYMBOL(drm_edid_dup);
>> +
>> +/**
>> + * drm_edid_free - Free the drm_edid container
>> + * @drm_edid: EDID to free
>> + */
>> +void drm_edid_free(const struct drm_edid *drm_edid)
>> +{
>> +	if (!drm_edid)
>> +		return;
>> +
>> +	kfree(drm_edid->edid);
>> +	kfree(drm_edid);
>> +}
>> +EXPORT_SYMBOL(drm_edid_free);
>> +
>>  /**
>>   * drm_probe_ddc() - probe DDC presence
>>   * @adapter: I2C adapter to probe
>> @@ -2359,12 +2450,118 @@ struct edid *drm_get_edid(struct drm_connector *connector,
>>  	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
>>  		return NULL;
>>  
>> -	edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
>> +	edid = _drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter, NULL);
>>  	drm_connector_update_edid_property(connector, edid);
>>  	return edid;
>>  }
>>  EXPORT_SYMBOL(drm_get_edid);
>>  
>> +/**
>> + * drm_edid_read_custom - Read EDID data using given EDID block read function
>> + * @connector: Connector to use
>> + * @read_block: EDID block read function
>> + * @context: Private data passed to the block read function
>> + *
>> + * When the I2C adapter connected to the DDC bus is hidden behind a device that
>> + * exposes a different interface to read EDID blocks this function can be used
>> + * to get EDID data using a custom block read function.
>> + *
>> + * As in the general case the DDC bus is accessible by the kernel at the I2C
>> + * level, drivers must make all reasonable efforts to expose it as an I2C
>> + * adapter and use drm_edid_read() or drm_edid_read_ddc() instead of abusing
>> + * this function.
>> + *
>> + * The EDID may be overridden using debugfs override_edid or firmware EDID
>> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
>> + * order. Having either of them bypasses actual EDID reads.
>> + *
>> + * The returned pointer must be freed using drm_edid_free().
>> + *
>> + * Return: Pointer to EDID, or NULL if probe/read failed.
>> + */
>> +const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
>> +					    read_block_fn read_block,
>> +					    void *context)
>> +{
>> +	const struct drm_edid *drm_edid;
>> +	struct edid *edid;
>> +	size_t size = 0;
>> +
>> +	edid = _drm_do_get_edid(connector, read_block, context, &size);
>> +	if (!edid)
>> +		return NULL;
>> +
>> +	/* Sanity check for now */
>> +	drm_WARN_ON(connector->dev, !size);
>> +
>> +	drm_edid = _drm_edid_alloc(edid, size);
>> +	if (!drm_edid)
>> +		kfree(edid);
>> +
>> +	return drm_edid;
>> +}
>> +EXPORT_SYMBOL(drm_edid_read_custom);
>> +
>> +/**
>> + * drm_edid_read_ddc - Read EDID data using given I2C adapter
>> + * @connector: Connector to use
>> + * @adapter: I2C adapter to use for DDC
>> + *
>> + * Read EDID using the given I2C adapter.
>> + *
>> + * The EDID may be overridden using debugfs override_edid or firmware EDID
>> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
>> + * order. Having either of them bypasses actual EDID reads.
>> + *
>> + * Prefer initializing connector->ddc with drm_connector_init_with_ddc() and
>> + * using drm_edid_read() instead of this function.
>> + *
>> + * The returned pointer must be freed using drm_edid_free().
>> + *
>> + * Return: Pointer to EDID, or NULL if probe/read failed.
>> + */
>> +const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
>> +					 struct i2c_adapter *adapter)
>> +{
>> +	const struct drm_edid *drm_edid;
>> +
>> +	if (connector->force == DRM_FORCE_OFF)
>> +		return NULL;
>> +
>> +	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
>> +		return NULL;
>> +
>> +	drm_edid = drm_edid_read_custom(connector, drm_do_probe_ddc_edid, adapter);
>> +
>> +	/* Note: Do *not* call connector updates here. */
>> +
>> +	return drm_edid;
>> +}
>> +EXPORT_SYMBOL(drm_edid_read_ddc);
>> +
>> +/**
>> + * drm_edid_read - Read EDID data using connector's I2C adapter
>> + * @connector: Connector to use
>> + *
>> + * Read EDID using the connector's I2C adapter.
>> + *
>> + * The EDID may be overridden using debugfs override_edid or firmware EDID
>> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
>> + * order. Having either of them bypasses actual EDID reads.
>> + *
>> + * The returned pointer must be freed using drm_edid_free().
>> + *
>> + * Return: Pointer to EDID, or NULL if probe/read failed.
>> + */
>> +const struct drm_edid *drm_edid_read(struct drm_connector *connector)
>> +{
>> +	if (drm_WARN_ON(connector->dev, !connector->ddc))
>> +		return NULL;
>> +
>> +	return drm_edid_read_ddc(connector, connector->ddc);
>> +}
>> +EXPORT_SYMBOL(drm_edid_read);
>
> I'm wondering if we need this drm_edid_read() vs. drm_edid_read_ddc()
> split? Ie. are there cases where connector->ddc wouldn't be populated
> for some reason but we still want to use drm_edid_read_ddc()?

I want to promote initializing connector->ddc and using drm_edid_read()
with that. However, for e.g. i915, HDMI is the only connector where we
have connector->ddc initialized. I just didn't want to take on
converting that part too, not yet, not as part of this series.

BR,
Jani.


>
>> +
>>  static u32 edid_extract_panel_id(const struct edid *edid)
>>  {
>>  	/*
>> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
>> index 95ac09ef41b2..9d2d78135dee 100644
>> --- a/include/drm/drm_edid.h
>> +++ b/include/drm/drm_edid.h
>> @@ -594,6 +594,15 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
>>  			      u8 video_code);
>>  
>>  /* Interface based on struct drm_edid */
>> +const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
>> +const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
>> +void drm_edid_free(const struct drm_edid *drm_edid);
>> +const struct drm_edid *drm_edid_read(struct drm_connector *connector);
>> +const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
>> +					 struct i2c_adapter *adapter);
>> +const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
>> +					    int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),
>> +					    void *context);
>>  const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
>>  				  int ext_id, int *ext_index);
>>  
>> -- 
>> 2.30.2

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 05/15] drm/edid: add new interfaces around struct drm_edid
@ 2022-06-13  8:37       ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-13  8:37 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: David Airlie, intel-gfx, dri-devel

On Fri, 10 Jun 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Wed, Jun 08, 2022 at 10:50:35AM +0300, Jani Nikula wrote:
>> Add new functions drm_edid_read(), drm_edid_read_ddc(), and
>> drm_edid_read_custom() to replace drm_get_edid() and drm_do_get_edid()
>> for reading the EDID. The transition is expected to happen over a fairly
>> long time.
>> 
>> Note that the new drm_edid_read*() functions do not do any of the
>> connector updates anymore. The reading and parsing will be completely
>> separated from each other.
>> 
>> Add new functions drm_edid_alloc(), drm_edid_dup(), and drm_edid_free()
>> for allocating and freeing drm_edid containers.
>> 
>> Cc: David Airlie <airlied@linux.ie>
>> Cc: Daniel Vetter <daniel@ffwll.ch>
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>>  drivers/gpu/drm/drm_edid.c | 245 +++++++++++++++++++++++++++++++++----
>>  include/drm/drm_edid.h     |   9 ++
>>  2 files changed, 230 insertions(+), 24 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> index 2beaa48301c1..2bdaf1e34a9d 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -2226,29 +2226,9 @@ static enum edid_block_status edid_block_read(void *block, unsigned int block_nu
>>  	return status;
>>  }
>>  
>> -/**
>> - * drm_do_get_edid - get EDID data using a custom EDID block read function
>> - * @connector: connector we're probing
>> - * @read_block: EDID block read function
>> - * @context: private data passed to the block read function
>> - *
>> - * When the I2C adapter connected to the DDC bus is hidden behind a device that
>> - * exposes a different interface to read EDID blocks this function can be used
>> - * to get EDID data using a custom block read function.
>> - *
>> - * As in the general case the DDC bus is accessible by the kernel at the I2C
>> - * level, drivers must make all reasonable efforts to expose it as an I2C
>> - * adapter and use drm_get_edid() instead of abusing this function.
>> - *
>> - * The EDID may be overridden using debugfs override_edid or firmware EDID
>> - * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
>> - * order. Having either of them bypasses actual EDID reads.
>> - *
>> - * Return: Pointer to valid EDID or NULL if we couldn't find any.
>> - */
>> -struct edid *drm_do_get_edid(struct drm_connector *connector,
>> -			     read_block_fn read_block,
>> -			     void *context)
>> +static struct edid *_drm_do_get_edid(struct drm_connector *connector,
>> +				     read_block_fn read_block, void *context,
>> +				     size_t *size)
>>  {
>>  	enum edid_block_status status;
>>  	int i, invalid_blocks = 0;
>> @@ -2315,14 +2295,125 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>>  	}
>>  
>>  ok:
>> +	if (size)
>> +		*size = alloc_size;
>> +
>>  	return edid;
>>  
>>  fail:
>>  	kfree(edid);
>>  	return NULL;
>>  }
>> +
>> +/**
>> + * drm_do_get_edid - get EDID data using a custom EDID block read function
>> + * @connector: connector we're probing
>> + * @read_block: EDID block read function
>> + * @context: private data passed to the block read function
>> + *
>> + * When the I2C adapter connected to the DDC bus is hidden behind a device that
>> + * exposes a different interface to read EDID blocks this function can be used
>> + * to get EDID data using a custom block read function.
>> + *
>> + * As in the general case the DDC bus is accessible by the kernel at the I2C
>> + * level, drivers must make all reasonable efforts to expose it as an I2C
>> + * adapter and use drm_get_edid() instead of abusing this function.
>> + *
>> + * The EDID may be overridden using debugfs override_edid or firmware EDID
>> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
>> + * order. Having either of them bypasses actual EDID reads.
>> + *
>> + * Return: Pointer to valid EDID or NULL if we couldn't find any.
>> + */
>> +struct edid *drm_do_get_edid(struct drm_connector *connector,
>> +			     read_block_fn read_block,
>> +			     void *context)
>> +{
>> +	return _drm_do_get_edid(connector, read_block, context, NULL);
>> +}
>>  EXPORT_SYMBOL_GPL(drm_do_get_edid);
>>  
>> +/* Allocate struct drm_edid container *without* duplicating the edid data */
>> +static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
>> +{
>> +	struct drm_edid *drm_edid;
>> +
>> +	if (!edid || !size || size < EDID_LENGTH)
>> +		return NULL;
>> +
>> +	drm_edid = kzalloc(sizeof(*drm_edid), GFP_KERNEL);
>> +	if (drm_edid) {
>> +		drm_edid->edid = edid;
>> +		drm_edid->size = size;
>> +	}
>> +
>> +	return drm_edid;
>> +}
>> +
>> +/**
>> + * drm_edid_alloc - Allocate a new drm_edid container
>> + * @edid: Pointer to raw EDID data
>> + * @size: Size of memory allocated for EDID
>> + *
>> + * Allocate a new drm_edid container. Do not calculate edid size from edid, pass
>> + * the actual size that has been allocated for the data. There is no validation
>> + * of the raw EDID data against the size, but at least the EDID base block must
>> + * fit in the buffer.
>> + *
>> + * The returned pointer must be freed using drm_edid_free().
>> + *
>> + * Return: drm_edid container, or NULL on errors
>> + */
>> +const struct drm_edid *drm_edid_alloc(const void *edid, size_t size)
>> +{
>> +	const struct drm_edid *drm_edid;
>> +
>> +	if (!edid || !size || size < EDID_LENGTH)
>> +		return NULL;
>> +
>> +	edid = kmemdup(edid, size, GFP_KERNEL);
>> +	if (!edid)
>> +		return NULL;
>> +
>> +	drm_edid = _drm_edid_alloc(edid, size);
>> +	if (!drm_edid)
>> +		kfree(edid);
>> +
>> +	return drm_edid;
>> +}
>> +EXPORT_SYMBOL(drm_edid_alloc);
>> +
>> +/**
>> + * drm_edid_dup - Duplicate a drm_edid container
>> + * @drm_edid: EDID to duplicate
>> + *
>> + * The returned pointer must be freed using drm_edid_free().
>> + *
>> + * Returns: drm_edid container copy, or NULL on errors
>> + */
>> +const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid)
>> +{
>> +	if (!drm_edid)
>> +		return NULL;
>> +
>> +	return drm_edid_alloc(drm_edid->edid, drm_edid->size);
>> +}
>> +EXPORT_SYMBOL(drm_edid_dup);
>> +
>> +/**
>> + * drm_edid_free - Free the drm_edid container
>> + * @drm_edid: EDID to free
>> + */
>> +void drm_edid_free(const struct drm_edid *drm_edid)
>> +{
>> +	if (!drm_edid)
>> +		return;
>> +
>> +	kfree(drm_edid->edid);
>> +	kfree(drm_edid);
>> +}
>> +EXPORT_SYMBOL(drm_edid_free);
>> +
>>  /**
>>   * drm_probe_ddc() - probe DDC presence
>>   * @adapter: I2C adapter to probe
>> @@ -2359,12 +2450,118 @@ struct edid *drm_get_edid(struct drm_connector *connector,
>>  	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
>>  		return NULL;
>>  
>> -	edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
>> +	edid = _drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter, NULL);
>>  	drm_connector_update_edid_property(connector, edid);
>>  	return edid;
>>  }
>>  EXPORT_SYMBOL(drm_get_edid);
>>  
>> +/**
>> + * drm_edid_read_custom - Read EDID data using given EDID block read function
>> + * @connector: Connector to use
>> + * @read_block: EDID block read function
>> + * @context: Private data passed to the block read function
>> + *
>> + * When the I2C adapter connected to the DDC bus is hidden behind a device that
>> + * exposes a different interface to read EDID blocks this function can be used
>> + * to get EDID data using a custom block read function.
>> + *
>> + * As in the general case the DDC bus is accessible by the kernel at the I2C
>> + * level, drivers must make all reasonable efforts to expose it as an I2C
>> + * adapter and use drm_edid_read() or drm_edid_read_ddc() instead of abusing
>> + * this function.
>> + *
>> + * The EDID may be overridden using debugfs override_edid or firmware EDID
>> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
>> + * order. Having either of them bypasses actual EDID reads.
>> + *
>> + * The returned pointer must be freed using drm_edid_free().
>> + *
>> + * Return: Pointer to EDID, or NULL if probe/read failed.
>> + */
>> +const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
>> +					    read_block_fn read_block,
>> +					    void *context)
>> +{
>> +	const struct drm_edid *drm_edid;
>> +	struct edid *edid;
>> +	size_t size = 0;
>> +
>> +	edid = _drm_do_get_edid(connector, read_block, context, &size);
>> +	if (!edid)
>> +		return NULL;
>> +
>> +	/* Sanity check for now */
>> +	drm_WARN_ON(connector->dev, !size);
>> +
>> +	drm_edid = _drm_edid_alloc(edid, size);
>> +	if (!drm_edid)
>> +		kfree(edid);
>> +
>> +	return drm_edid;
>> +}
>> +EXPORT_SYMBOL(drm_edid_read_custom);
>> +
>> +/**
>> + * drm_edid_read_ddc - Read EDID data using given I2C adapter
>> + * @connector: Connector to use
>> + * @adapter: I2C adapter to use for DDC
>> + *
>> + * Read EDID using the given I2C adapter.
>> + *
>> + * The EDID may be overridden using debugfs override_edid or firmware EDID
>> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
>> + * order. Having either of them bypasses actual EDID reads.
>> + *
>> + * Prefer initializing connector->ddc with drm_connector_init_with_ddc() and
>> + * using drm_edid_read() instead of this function.
>> + *
>> + * The returned pointer must be freed using drm_edid_free().
>> + *
>> + * Return: Pointer to EDID, or NULL if probe/read failed.
>> + */
>> +const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
>> +					 struct i2c_adapter *adapter)
>> +{
>> +	const struct drm_edid *drm_edid;
>> +
>> +	if (connector->force == DRM_FORCE_OFF)
>> +		return NULL;
>> +
>> +	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
>> +		return NULL;
>> +
>> +	drm_edid = drm_edid_read_custom(connector, drm_do_probe_ddc_edid, adapter);
>> +
>> +	/* Note: Do *not* call connector updates here. */
>> +
>> +	return drm_edid;
>> +}
>> +EXPORT_SYMBOL(drm_edid_read_ddc);
>> +
>> +/**
>> + * drm_edid_read - Read EDID data using connector's I2C adapter
>> + * @connector: Connector to use
>> + *
>> + * Read EDID using the connector's I2C adapter.
>> + *
>> + * The EDID may be overridden using debugfs override_edid or firmware EDID
>> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
>> + * order. Having either of them bypasses actual EDID reads.
>> + *
>> + * The returned pointer must be freed using drm_edid_free().
>> + *
>> + * Return: Pointer to EDID, or NULL if probe/read failed.
>> + */
>> +const struct drm_edid *drm_edid_read(struct drm_connector *connector)
>> +{
>> +	if (drm_WARN_ON(connector->dev, !connector->ddc))
>> +		return NULL;
>> +
>> +	return drm_edid_read_ddc(connector, connector->ddc);
>> +}
>> +EXPORT_SYMBOL(drm_edid_read);
>
> I'm wondering if we need this drm_edid_read() vs. drm_edid_read_ddc()
> split? Ie. are there cases where connector->ddc wouldn't be populated
> for some reason but we still want to use drm_edid_read_ddc()?

I want to promote initializing connector->ddc and using drm_edid_read()
with that. However, for e.g. i915, HDMI is the only connector where we
have connector->ddc initialized. I just didn't want to take on
converting that part too, not yet, not as part of this series.

BR,
Jani.


>
>> +
>>  static u32 edid_extract_panel_id(const struct edid *edid)
>>  {
>>  	/*
>> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
>> index 95ac09ef41b2..9d2d78135dee 100644
>> --- a/include/drm/drm_edid.h
>> +++ b/include/drm/drm_edid.h
>> @@ -594,6 +594,15 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
>>  			      u8 video_code);
>>  
>>  /* Interface based on struct drm_edid */
>> +const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
>> +const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
>> +void drm_edid_free(const struct drm_edid *drm_edid);
>> +const struct drm_edid *drm_edid_read(struct drm_connector *connector);
>> +const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
>> +					 struct i2c_adapter *adapter);
>> +const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
>> +					    int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),
>> +					    void *context);
>>  const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
>>  				  int ext_id, int *ext_index);
>>  
>> -- 
>> 2.30.2

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 00/15] drm/edid: expand on struct drm_edid usage
  2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
@ 2022-06-13  9:37   ` Jani Nikula
  -1 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-13  9:37 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

On Wed, 08 Jun 2022, Jani Nikula <jani.nikula@intel.com> wrote:
> v2 of [1], addressing review comments.
>
> BR,
> Jani.
>
>
> [1] https://patchwork.freedesktop.org/series/104309/
>
> Jani Nikula (15):
>   drm/edid: fix CTA data block collection size for CTA version 3
>   drm/edid: abstract cea data block collection size
>   drm/edid: add block count and data helper functions for drm_edid
>   drm/edid: keep track of alloc size in drm_do_get_edid()
>   drm/edid: add new interfaces around struct drm_edid
>   drm/probe-helper: abstract .get_modes() connector helper call

Thanks for the reviews, pushed the above patches to drm-misc-next.

BR,
Jani.


>   drm/edid: add drm_edid_connector_update()
>   drm/probe-helper: add drm_connector_helper_get_modes()
>   drm/edid: add drm_edid_raw() to access the raw EDID data
>   drm/i915/edid: convert DP, HDMI and LVDS to drm_edid
>   drm/i915/bios: convert intel_bios_init_panel() to drm_edid
>   drm/edid: do invalid block filtering in-place
>   drm/edid: add HF-EEODB support to EDID read and allocation
>   drm/edid: take HF-EEODB extension count into account
>   drm/todo: add entry for converting the subsystem to struct drm_edid
>
>  Documentation/gpu/todo.rst                    |  25 +
>  drivers/gpu/drm/drm_connector.c               |   2 +
>  drivers/gpu/drm/drm_edid.c                    | 572 ++++++++++++++++--
>  drivers/gpu/drm/drm_probe_helper.c            |  63 +-
>  drivers/gpu/drm/i915/display/intel_bios.c     |  23 +-
>  drivers/gpu/drm/i915/display/intel_bios.h     |   4 +-
>  .../gpu/drm/i915/display/intel_connector.c    |   4 +-
>  .../drm/i915/display/intel_display_types.h    |   4 +-
>  drivers/gpu/drm/i915/display/intel_dp.c       |  74 ++-
>  drivers/gpu/drm/i915/display/intel_hdmi.c     |  26 +-
>  drivers/gpu/drm/i915/display/intel_lvds.c     |  37 +-
>  include/drm/drm_edid.h                        |  12 +
>  include/drm/drm_probe_helper.h                |   1 +
>  13 files changed, 692 insertions(+), 155 deletions(-)

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Intel-gfx] [PATCH v2 00/15] drm/edid: expand on struct drm_edid usage
@ 2022-06-13  9:37   ` Jani Nikula
  0 siblings, 0 replies; 68+ messages in thread
From: Jani Nikula @ 2022-06-13  9:37 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

On Wed, 08 Jun 2022, Jani Nikula <jani.nikula@intel.com> wrote:
> v2 of [1], addressing review comments.
>
> BR,
> Jani.
>
>
> [1] https://patchwork.freedesktop.org/series/104309/
>
> Jani Nikula (15):
>   drm/edid: fix CTA data block collection size for CTA version 3
>   drm/edid: abstract cea data block collection size
>   drm/edid: add block count and data helper functions for drm_edid
>   drm/edid: keep track of alloc size in drm_do_get_edid()
>   drm/edid: add new interfaces around struct drm_edid
>   drm/probe-helper: abstract .get_modes() connector helper call

Thanks for the reviews, pushed the above patches to drm-misc-next.

BR,
Jani.


>   drm/edid: add drm_edid_connector_update()
>   drm/probe-helper: add drm_connector_helper_get_modes()
>   drm/edid: add drm_edid_raw() to access the raw EDID data
>   drm/i915/edid: convert DP, HDMI and LVDS to drm_edid
>   drm/i915/bios: convert intel_bios_init_panel() to drm_edid
>   drm/edid: do invalid block filtering in-place
>   drm/edid: add HF-EEODB support to EDID read and allocation
>   drm/edid: take HF-EEODB extension count into account
>   drm/todo: add entry for converting the subsystem to struct drm_edid
>
>  Documentation/gpu/todo.rst                    |  25 +
>  drivers/gpu/drm/drm_connector.c               |   2 +
>  drivers/gpu/drm/drm_edid.c                    | 572 ++++++++++++++++--
>  drivers/gpu/drm/drm_probe_helper.c            |  63 +-
>  drivers/gpu/drm/i915/display/intel_bios.c     |  23 +-
>  drivers/gpu/drm/i915/display/intel_bios.h     |   4 +-
>  .../gpu/drm/i915/display/intel_connector.c    |   4 +-
>  .../drm/i915/display/intel_display_types.h    |   4 +-
>  drivers/gpu/drm/i915/display/intel_dp.c       |  74 ++-
>  drivers/gpu/drm/i915/display/intel_hdmi.c     |  26 +-
>  drivers/gpu/drm/i915/display/intel_lvds.c     |  37 +-
>  include/drm/drm_edid.h                        |  12 +
>  include/drm/drm_probe_helper.h                |   1 +
>  13 files changed, 692 insertions(+), 155 deletions(-)

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 68+ messages in thread

end of thread, other threads:[~2022-06-13  9:37 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08  7:50 [PATCH v2 00/15] drm/edid: expand on struct drm_edid usage Jani Nikula
2022-06-08  7:50 ` [Intel-gfx] " Jani Nikula
2022-06-08  7:50 ` [PATCH v2 01/15] drm/edid: fix CTA data block collection size for CTA version 3 Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-10 18:56   ` Ville Syrjälä
2022-06-10 18:56     ` [Intel-gfx] " Ville Syrjälä
2022-06-08  7:50 ` [PATCH v2 02/15] drm/edid: abstract cea data block collection size Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-10 18:58   ` Ville Syrjälä
2022-06-10 18:58     ` [Intel-gfx] " Ville Syrjälä
2022-06-08  7:50 ` [PATCH v2 03/15] drm/edid: add block count and data helper functions for drm_edid Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-08  7:50 ` [PATCH v2 04/15] drm/edid: keep track of alloc size in drm_do_get_edid() Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-10 19:35   ` Ville Syrjälä
2022-06-10 19:35     ` [Intel-gfx] " Ville Syrjälä
2022-06-08  7:50 ` [PATCH v2 05/15] drm/edid: add new interfaces around struct drm_edid Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-10 19:35   ` Ville Syrjälä
2022-06-10 19:35     ` [Intel-gfx] " Ville Syrjälä
2022-06-10 19:43   ` Ville Syrjälä
2022-06-10 19:43     ` [Intel-gfx] " Ville Syrjälä
2022-06-13  8:37     ` Jani Nikula
2022-06-13  8:37       ` [Intel-gfx] " Jani Nikula
2022-06-08  7:50 ` [PATCH v2 06/15] drm/edid: add drm_edid_connector_update() Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-10 19:15   ` Ville Syrjälä
2022-06-10 19:15     ` [Intel-gfx] " Ville Syrjälä
2022-06-08  7:50 ` [PATCH v2 07/15] drm/probe-helper: abstract .get_modes() connector helper call Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-10 19:36   ` Ville Syrjälä
2022-06-10 19:36     ` [Intel-gfx] " Ville Syrjälä
2022-06-08  7:50 ` [PATCH v2 08/15] drm/probe-helper: add drm_connector_helper_get_modes() Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-10 19:44   ` Ville Syrjälä
2022-06-10 19:44     ` [Intel-gfx] " Ville Syrjälä
2022-06-08  7:50 ` [PATCH v2 09/15] drm/edid: add drm_edid_raw() to access the raw EDID data Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-10 19:29   ` Ville Syrjälä
2022-06-10 19:29     ` [Intel-gfx] " Ville Syrjälä
2022-06-08  7:50 ` [PATCH v2 10/15] drm/i915/edid: convert DP, HDMI and LVDS to drm_edid Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-10 19:21   ` Ville Syrjälä
2022-06-10 19:21     ` [Intel-gfx] " Ville Syrjälä
2022-06-08  7:50 ` [PATCH v2 11/15] drm/i915/bios: convert intel_bios_init_panel() " Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-10 19:29   ` Ville Syrjälä
2022-06-10 19:29     ` [Intel-gfx] " Ville Syrjälä
2022-06-08  7:50 ` [PATCH v2 12/15] drm/edid: do invalid block filtering in-place Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-10 19:30   ` Ville Syrjälä
2022-06-10 19:30     ` [Intel-gfx] " Ville Syrjälä
2022-06-08  7:50 ` [PATCH v2 13/15] drm/edid: add HF-EEODB support to EDID read and allocation Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-10 19:30   ` Ville Syrjälä
2022-06-10 19:30     ` [Intel-gfx] " Ville Syrjälä
2022-06-08  7:50 ` [PATCH v2 14/15] drm/edid: take HF-EEODB extension count into account Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-10 19:34   ` Ville Syrjälä
2022-06-10 19:34     ` [Intel-gfx] " Ville Syrjälä
2022-06-08  7:50 ` [PATCH v2 15/15] drm/todo: add entry for converting the subsystem to struct drm_edid Jani Nikula
2022-06-08  7:50   ` [Intel-gfx] " Jani Nikula
2022-06-08  8:30 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/edid: expand on struct drm_edid usage (rev3) Patchwork
2022-06-08  8:30 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2022-06-08 11:27 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-06-08 19:23 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
2022-06-13  9:37 ` [PATCH v2 00/15] drm/edid: expand on struct drm_edid usage Jani Nikula
2022-06-13  9:37   ` [Intel-gfx] " Jani Nikula

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.