Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/nouveau: Advertise correct modifiers on GB20x

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

authored by

James Jones and committed by
Dave Airlie
664ce102 1cf52a0d

+59 -3
+3 -1
drivers/gpu/drm/nouveau/dispnv50/disp.c
··· 2867 2867 } 2868 2868 2869 2869 /* Assign the correct format modifiers */ 2870 - if (disp->disp->object.oclass >= TU102_DISP) 2870 + if (disp->disp->object.oclass >= GB202_DISP) 2871 + nouveau_display(dev)->format_modifiers = wndwca7e_modifiers; 2872 + else if (disp->disp->object.oclass >= TU102_DISP) 2871 2873 nouveau_display(dev)->format_modifiers = wndwc57e_modifiers; 2872 2874 else 2873 2875 if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI)
+1
drivers/gpu/drm/nouveau/dispnv50/disp.h
··· 104 104 extern const u64 disp50xx_modifiers[]; 105 105 extern const u64 disp90xx_modifiers[]; 106 106 extern const u64 wndwc57e_modifiers[]; 107 + extern const u64 wndwca7e_modifiers[]; 107 108 #endif
+22 -2
drivers/gpu/drm/nouveau/dispnv50/wndw.c
··· 786 786 } 787 787 788 788 /* This function assumes the format has already been validated against the plane 789 - * and the modifier was validated against the device-wides modifier list at FB 789 + * and the modifier was validated against the device-wide modifier list at FB 790 790 * creation time. 791 791 */ 792 792 static bool nv50_plane_format_mod_supported(struct drm_plane *plane, 793 793 u32 format, u64 modifier) 794 794 { 795 795 struct nouveau_drm *drm = nouveau_drm(plane->dev); 796 + const struct drm_format_info *info = drm_format_info(format); 796 797 uint8_t i; 797 798 798 799 /* All chipsets can display all formats in linear layout */ ··· 801 800 return true; 802 801 803 802 if (drm->client.device.info.chipset < 0xc0) { 804 - const struct drm_format_info *info = drm_format_info(format); 805 803 const uint8_t kind = (modifier >> 12) & 0xff; 806 804 807 805 if (!format) return false; 808 806 809 807 for (i = 0; i < info->num_planes; i++) 810 808 if ((info->cpp[i] != 4) && kind != 0x70) return false; 809 + } else if (drm->client.device.info.chipset >= 0x1b2) { 810 + const uint8_t slayout = ((modifier >> 22) & 0x1) | 811 + ((modifier >> 25) & 0x6); 812 + 813 + if (!format) 814 + return false; 815 + 816 + /* 817 + * Note in practice this implies only formats where cpp is equal 818 + * for each plane, or >= 4 for all planes, are supported. 819 + */ 820 + for (i = 0; i < info->num_planes; i++) { 821 + if (((info->cpp[i] == 2) && slayout != 3) || 822 + ((info->cpp[i] == 1) && slayout != 2) || 823 + ((info->cpp[i] >= 4) && slayout != 1)) 824 + return false; 825 + 826 + /* 24-bit not supported. It has yet another layout */ 827 + WARN_ON(info->cpp[i] == 3); 828 + } 811 829 } 812 830 813 831 return true;
+33
drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c
··· 179 179 return 0; 180 180 } 181 181 182 + /**************************************************************** 183 + * Log2(block height) ----------------------------+ * 184 + * Page Kind ----------------------------------+ | * 185 + * Gob Height/Page Kind Generation ------+ | | * 186 + * Sector layout -------+ | | | * 187 + * Compression ------+ | | | | */ 188 + const u64 wndwca7e_modifiers[] = { /* | | | | | */ 189 + /* 4cpp+ modifiers */ 190 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 0), 191 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 1), 192 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 2), 193 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 3), 194 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 4), 195 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 5), 196 + /* 1cpp/8bpp modifiers */ 197 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 0), 198 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 1), 199 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 2), 200 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 3), 201 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 4), 202 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 5), 203 + /* 2cpp/16bpp modifiers */ 204 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 0), 205 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 1), 206 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 2), 207 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 3), 208 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 4), 209 + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 5), 210 + /* All formats support linear */ 211 + DRM_FORMAT_MOD_LINEAR, 212 + DRM_FORMAT_MOD_INVALID 213 + }; 214 + 182 215 static const struct nv50_wndw_func 183 216 wndwca7e = { 184 217 .acquire = wndwc37e_acquire,