]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/nouveau: Advertise correct modifiers on GB20x
authorJames Jones <jajones@nvidia.com>
Thu, 30 Oct 2025 18:11:53 +0000 (11:11 -0700)
committerDave Airlie <airlied@redhat.com>
Thu, 6 Nov 2025 01:02:08 +0000 (11:02 +1000)
8 and 16 bit formats use a different layout on
GB20x than they did on prior chips. Add the
corresponding DRM format modifiers to the list of
modifiers supported by the display engine on such
chips, and filter the supported modifiers for each
format based on its bytes per pixel in
nv50_plane_format_mod_supported().

Note this logic will need to be updated when GB10
support is added, since it is a GB20x chip that
uses the pre-GB20x sector layout for all formats.

Fixes: 6cc6e08d4542 ("drm/nouveau/kms: add support for GB20x")
Signed-off-by: James Jones <jajones@nvidia.com>
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20251030181153.1208-3-jajones@nvidia.com
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/nouveau/dispnv50/disp.h
drivers/gpu/drm/nouveau/dispnv50/wndw.c
drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c

index e97e39abf3a22368e4884c4db740a9d62acebdd0..12b1dba8e05d51993e04da376c57049af31e21da 100644 (file)
@@ -2867,7 +2867,9 @@ nv50_display_create(struct drm_device *dev)
        }
 
        /* Assign the correct format modifiers */
-       if (disp->disp->object.oclass >= TU102_DISP)
+       if (disp->disp->object.oclass >= GB202_DISP)
+               nouveau_display(dev)->format_modifiers = wndwca7e_modifiers;
+       else if (disp->disp->object.oclass >= TU102_DISP)
                nouveau_display(dev)->format_modifiers = wndwc57e_modifiers;
        else
        if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI)
index 15f9242b72ac71d1e777f1279a64246d3e367e49..5d998f0319dcc2ffe33f58a7613c88650e3235b6 100644 (file)
@@ -104,4 +104,5 @@ struct nouveau_encoder *nv50_real_outp(struct drm_encoder *encoder);
 extern const u64 disp50xx_modifiers[];
 extern const u64 disp90xx_modifiers[];
 extern const u64 wndwc57e_modifiers[];
+extern const u64 wndwca7e_modifiers[];
 #endif
index e2c55f4b9c5a141f2ec8c9a7c9a86b95c9b0f1fb..ef9e410babbfbab4985c67477d3a27b8f63d195e 100644 (file)
@@ -786,13 +786,14 @@ nv50_wndw_destroy(struct drm_plane *plane)
 }
 
 /* This function assumes the format has already been validated against the plane
- * and the modifier was validated against the device-wides modifier list at FB
+ * and the modifier was validated against the device-wide modifier list at FB
  * creation time.
  */
 static bool nv50_plane_format_mod_supported(struct drm_plane *plane,
                                            u32 format, u64 modifier)
 {
        struct nouveau_drm *drm = nouveau_drm(plane->dev);
+       const struct drm_format_info *info = drm_format_info(format);
        uint8_t i;
 
        /* All chipsets can display all formats in linear layout */
@@ -800,13 +801,32 @@ static bool nv50_plane_format_mod_supported(struct drm_plane *plane,
                return true;
 
        if (drm->client.device.info.chipset < 0xc0) {
-               const struct drm_format_info *info = drm_format_info(format);
                const uint8_t kind = (modifier >> 12) & 0xff;
 
                if (!format) return false;
 
                for (i = 0; i < info->num_planes; i++)
                        if ((info->cpp[i] != 4) && kind != 0x70) return false;
+       } else if (drm->client.device.info.chipset >= 0x1b2) {
+               const uint8_t slayout = ((modifier >> 22) & 0x1) |
+                       ((modifier >> 25) & 0x6);
+
+               if (!format)
+                       return false;
+
+               /*
+                * Note in practice this implies only formats where cpp is equal
+                * for each plane, or >= 4 for all planes, are supported.
+                */
+               for (i = 0; i < info->num_planes; i++) {
+                       if (((info->cpp[i] == 2) && slayout != 3) ||
+                           ((info->cpp[i] == 1) && slayout != 2) ||
+                           ((info->cpp[i] >= 4) && slayout != 1))
+                               return false;
+
+                       /* 24-bit not supported. It has yet another layout */
+                       WARN_ON(info->cpp[i] == 3);
+               }
        }
 
        return true;
index 0d8e9a9d1a5730fbd803c5ac01ddc1c9f3593630..2cec8cfbd5461983999439c25d022dee8e704010 100644 (file)
@@ -179,6 +179,39 @@ wndwca7e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
        return 0;
 }
 
+/****************************************************************
+ *            Log2(block height) ----------------------------+  *
+ *            Page Kind ----------------------------------+  |  *
+ *            Gob Height/Page Kind Generation ------+     |  |  *
+ *                          Sector layout -------+  |     |  |  *
+ *                          Compression ------+  |  |     |  |  */
+const u64 wndwca7e_modifiers[] = { /*         |  |  |     |  |  */
+       /* 4cpp+ modifiers */
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 0),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 1),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 2),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 3),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 4),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 5),
+       /* 1cpp/8bpp modifiers */
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 0),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 1),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 2),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 3),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 4),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 5),
+       /* 2cpp/16bpp modifiers */
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 0),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 1),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 2),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 3),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 4),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 5),
+       /* All formats support linear */
+       DRM_FORMAT_MOD_LINEAR,
+       DRM_FORMAT_MOD_INVALID
+};
+
 static const struct nv50_wndw_func
 wndwca7e = {
        .acquire = wndwc37e_acquire,