]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
drm/nouveau/kms: Add format mod prop to base/ovly/nvdisp
authorJames Jones <jajones@nvidia.com>
Mon, 10 Feb 2020 23:15:53 +0000 (15:15 -0800)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 22 May 2020 01:11:15 +0000 (11:11 +1000)
Advertise support for the full list of format
modifiers supported by each class of NVIDIA
desktop GPU display hardware.  Stash the array
of modifiers in the nouveau_display struct for
use when validating userspace framebuffer
creation requests, which will be supportd in
a subsequent change.

Signed-off-by: James Jones <jajones@nvidia.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/dispnv50/base507c.c
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/wndwc57e.c
drivers/gpu/drm/nouveau/nouveau_display.h

index ee782151d332296d99ece6ae9f2dbbac1c34ebdd..511258bfbcbc4dbc7e593271afc5111abcdc56f3 100644 (file)
@@ -263,7 +263,8 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
        struct nv50_disp_base_channel_dma_v0 args = {
                .head = head,
        };
-       struct nv50_disp *disp = nv50_disp(drm->dev);
+       struct nouveau_display *disp = nouveau_display(drm->dev);
+       struct nv50_disp *disp50 = nv50_disp(drm->dev);
        struct nv50_wndw *wndw;
        int ret;
 
@@ -273,9 +274,9 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
        if (*pwndw = wndw, ret)
                return ret;
 
-       ret = nv50_dmac_create(&drm->client.device, &disp->disp->object,
+       ret = nv50_dmac_create(&drm->client.device, &disp->disp.object,
                               &oclass, head, &args, sizeof(args),
-                              disp->sync->bo.offset, &wndw->wndw);
+                              disp50->sync->bo.offset, &wndw->wndw);
        if (ret) {
                NV_ERROR(drm, "base%04x allocation failed: %d\n", oclass, ret);
                return ret;
index 6be9df1820c51366e016c4cdd7c2f4ff3850689d..8a79f06e9e26ac4d864fc6690dd833b5cb9e79f0 100644 (file)
@@ -2456,6 +2456,15 @@ nv50_display_create(struct drm_device *dev)
        if (ret)
                goto out;
 
+       /* Assign the correct format modifiers */
+       if (disp->disp->object.oclass >= TU102_DISP)
+               nouveau_display(dev)->format_modifiers = wndwc57e_modifiers;
+       else
+       if (disp->disp->object.oclass >= GF110_DISP)
+               nouveau_display(dev)->format_modifiers = disp90xx_modifiers;
+       else
+               nouveau_display(dev)->format_modifiers = disp50xx_modifiers;
+
        /* create crtc objects to represent the hw heads */
        if (disp->disp->object.oclass >= GV100_DISP)
                crtcs = nvif_rd32(&device->object, 0x610060) & 0xff;
@@ -2551,3 +2560,53 @@ out:
                nv50_display_destroy(dev);
        return ret;
 }
+
+/******************************************************************************
+ * Format modifiers
+ *****************************************************************************/
+
+/****************************************************************
+ *            Log2(block height) ----------------------------+  *
+ *            Page Kind ----------------------------------+  |  *
+ *            Gob Height/Page Kind Generation ------+     |  |  *
+ *                          Sector layout -------+  |     |  |  *
+ *                          Compression ------+  |  |     |  |  */
+const u64 disp50xx_modifiers[] = { /*         |  |  |     |  |  */
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 0),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 1),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 2),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 3),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 4),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 5),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 0),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 1),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 2),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 3),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 4),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 5),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 0),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 1),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 2),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 3),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 4),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 5),
+       DRM_FORMAT_MOD_LINEAR,
+       DRM_FORMAT_MOD_INVALID
+};
+
+/****************************************************************
+ *            Log2(block height) ----------------------------+  *
+ *            Page Kind ----------------------------------+  |  *
+ *            Gob Height/Page Kind Generation ------+     |  |  *
+ *                          Sector layout -------+  |     |  |  *
+ *                          Compression ------+  |  |     |  |  */
+const u64 disp90xx_modifiers[] = { /*         |  |  |     |  |  */
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 0),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 1),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 2),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 3),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 4),
+       DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 5),
+       DRM_FORMAT_MOD_LINEAR,
+       DRM_FORMAT_MOD_INVALID
+};
index d54fe00ac3a3c22e1e0fc06638899c156a4cb5c9..1743c3a7621649d654e2fdf2ef6e646a0d4b0404 100644 (file)
@@ -78,6 +78,10 @@ void nv50_dmac_destroy(struct nv50_dmac *);
 u32 *evo_wait(struct nv50_dmac *, int nr);
 void evo_kick(u32 *, struct nv50_dmac *);
 
+extern const u64 disp50xx_modifiers[];
+extern const u64 disp90xx_modifiers[];
+extern const u64 wndwc57e_modifiers[];
+
 #define evo_mthd(p, m, s) do {                                         \
        const u32 _m = (m), _s = (s);                                   \
        if (drm_debug_enabled(DRM_UT_KMS))                              \
index 55e764bff381d42d9f952efb56a2cad297230f48..1425a9ca86cfaddd3c89ad9a3c76633f8c6a5f26 100644 (file)
@@ -609,6 +609,29 @@ nv50_wndw_destroy(struct drm_plane *plane)
        kfree(wndw);
 }
 
+/* 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
+ * 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);
+       uint8_t i;
+
+       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;
+       }
+
+       return true;
+}
+
 const struct drm_plane_funcs
 nv50_wndw = {
        .update_plane = drm_atomic_helper_update_plane,
@@ -617,6 +640,7 @@ nv50_wndw = {
        .reset = nv50_wndw_reset,
        .atomic_duplicate_state = nv50_wndw_atomic_duplicate_state,
        .atomic_destroy_state = nv50_wndw_atomic_destroy_state,
+       .format_mod_supported = nv50_plane_format_mod_supported,
 };
 
 static int
@@ -664,7 +688,8 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
        for (nformat = 0; format[nformat]; nformat++);
 
        ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw,
-                                      format, nformat, NULL,
+                                      format, nformat,
+                                      nouveau_display(dev)->format_modifiers,
                                       type, "%s-%d", name, index);
        if (ret) {
                kfree(*pwndw);
index 35c9c52fab263ec7e8c1b99114fbe2203da0c86a..1d64741595ba92b9e817947e4dbe548ce95e74bd 100644 (file)
@@ -173,6 +173,23 @@ wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
        return true;
 }
 
+/****************************************************************
+ *            Log2(block height) ----------------------------+  *
+ *            Page Kind ----------------------------------+  |  *
+ *            Gob Height/Page Kind Generation ------+     |  |  *
+ *                          Sector layout -------+  |     |  |  *
+ *                          Compression ------+  |  |     |  |  */
+const u64 wndwc57e_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),
+       DRM_FORMAT_MOD_LINEAR,
+       DRM_FORMAT_MOD_INVALID
+};
+
 static const struct nv50_wndw_func
 wndwc57e = {
        .acquire = wndwc37e_acquire,
index c745213d9bdfce9f4449e85186f126f57e7cc98b..1dd69c50a4ed38c37aa6f0e0d528e16cd788f872 100644 (file)
@@ -32,6 +32,8 @@ struct nouveau_display {
        struct drm_property *color_vibrance_property;
 
        struct drm_atomic_state *suspend;
+
+       const u64 *format_modifiers;
 };
 
 static inline struct nouveau_display *