]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/displayid: fix Tiled Display Topology ID size
authorJani Nikula <jani.nikula@intel.com>
Wed, 10 Jun 2026 14:15:49 +0000 (17:15 +0300)
committerJani Nikula <jani.nikula@intel.com>
Mon, 15 Jun 2026 10:50:42 +0000 (13:50 +0300)
The Tiled Display Topology ID of a DisplayID Tiled Display Topology Data
Block consists of three fields:

- Tiled Display Manufacturer/Vendor ID Field (3 bytes)
- Tiled Display Product ID Code Field (2 bytes)
- Tiled Display Serial Number Field (4 bytes)

i.e. a total of 9 bytes, not 8.

The DisplayID Tiled Display Topology ID is used as the tile group
identifier.

Update both struct displayid_tiled_block topology_id member and struct
drm_tile_group group_data member to full 9 bytes.

The group data was missing the last byte of the serial number. I don't
know whether there are known bug reports that might be linked to this,
but it's plausible the last byte could be the differentiating part for
the tile groups, and fewer tile groups might have been created than
intended.

Fixes: b49b55bd4fba ("drm/displayid: add displayid defines and edid extension (v2)")
Fixes: 138f9ebb9755 ("drm: add tile_group support. (v3)")
Cc: Dave Airlie <airlied@redhat.com>
Cc: stable@vger.kernel.org # v3.19+
Reviewed-by: Dave Airlie <airlied@redhat.com>
Link: https://patch.msgid.link/20260610141549.555605-1-jani.nikula@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/drm_connector.c
drivers/gpu/drm/drm_displayid_internal.h
include/drm/drm_connector.h

index 47dc53c4a738ffef8b21ccdd64605bc43137d827..29634757c06d1973bb16e0f0ab0600a4e821c329 100644 (file)
@@ -3576,7 +3576,7 @@ EXPORT_SYMBOL(drm_mode_put_tile_group);
 /**
  * drm_mode_get_tile_group - get a reference to an existing tile group
  * @dev: DRM device
- * @topology: 8-bytes unique per monitor.
+ * @topology_id: 9-byte unique ID per monitor.
  *
  * Use the unique bytes to get a reference to an existing tile group.
  *
@@ -3584,14 +3584,14 @@ EXPORT_SYMBOL(drm_mode_put_tile_group);
  * tile group or NULL if not found.
  */
 struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
-                                              const char topology[8])
+                                              const char topology_id[9])
 {
        struct drm_tile_group *tg;
        int id;
 
        mutex_lock(&dev->mode_config.idr_mutex);
        idr_for_each_entry(&dev->mode_config.tile_idr, tg, id) {
-               if (!memcmp(tg->group_data, topology, 8)) {
+               if (!memcmp(tg->group_data, topology_id, sizeof(tg->group_data))) {
                        if (!kref_get_unless_zero(&tg->refcount))
                                tg = NULL;
                        mutex_unlock(&dev->mode_config.idr_mutex);
@@ -3606,7 +3606,7 @@ EXPORT_SYMBOL(drm_mode_get_tile_group);
 /**
  * drm_mode_create_tile_group - create a tile group from a displayid description
  * @dev: DRM device
- * @topology: 8-bytes unique per monitor.
+ * @topology_id: 9-byte unique ID per monitor.
  *
  * Create a tile group for the unique monitor, and get a unique
  * identifier for the tile group.
@@ -3615,7 +3615,7 @@ EXPORT_SYMBOL(drm_mode_get_tile_group);
  * new tile group or NULL.
  */
 struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
-                                                 const char topology[8])
+                                                 const char topology_id[9])
 {
        struct drm_tile_group *tg;
        int ret;
@@ -3625,7 +3625,7 @@ struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
                return NULL;
 
        kref_init(&tg->refcount);
-       memcpy(tg->group_data, topology, 8);
+       memcpy(tg->group_data, topology_id, sizeof(tg->group_data));
        tg->dev = dev;
 
        mutex_lock(&dev->mode_config.idr_mutex);
index 5b1b32f73516620a1bdeec94fdd8622f7af309f2..4590d6a3d82152a0309ddb49984a9122d485d38b 100644 (file)
@@ -109,7 +109,7 @@ struct displayid_tiled_block {
        u8 topo[3];
        u8 tile_size[4];
        u8 tile_pixel_bezel[5];
-       u8 topology_id[8];
+       u8 topology_id[9];
 } __packed;
 
 struct displayid_detailed_timings_1 {
index f83f28cae207578b0e4ebdec8df7520db0fc5ba6..877b5ca87e95bf0624a01787a959c4cb7343ad0d 100644 (file)
@@ -2608,13 +2608,13 @@ struct drm_tile_group {
        struct kref refcount;
        struct drm_device *dev;
        int id;
-       u8 group_data[8];
+       u8 group_data[9];
 };
 
 struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
-                                                 const char topology[8]);
+                                                 const char topology_id[9]);
 struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
-                                              const char topology[8]);
+                                              const char topology_id[9]);
 void drm_mode_put_tile_group(struct drm_device *dev,
                             struct drm_tile_group *tg);