drm/amd/display: Expose support for NV12 on suitable planes
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Fri, 15 Mar 2019 19:45:34 +0000 (15:45 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 15 Apr 2019 05:19:35 +0000 (00:19 -0500)
[Why]
Hardware can support video surfaces and DC tells us which planes are
suitable via DC plane caps.

[How]
The supported formats array will now vary based on what DC tells us,
so create an array and fill it dynamically based on plane types and
caps.

Ideally we'd query support for every format via DC plane caps, but for
the framework is in place to do so later with this.

Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: Sun peng Li <Sunpeng.Li@amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

index fd5646c11bb25991fda8ea2b7c49f78ef05cc692..dfc28b7433bf42f72a71a8bcf909499dfc338e51 100644 (file)
@@ -4121,46 +4121,71 @@ static const u32 cursor_formats[] = {
        DRM_FORMAT_ARGB8888
 };
 
-static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
-                               struct drm_plane *plane,
-                               unsigned long possible_crtcs,
-                               const struct dc_plane_cap *plane_cap)
+static int get_plane_formats(const struct drm_plane *plane,
+                            const struct dc_plane_cap *plane_cap,
+                            uint32_t *formats, int max_formats)
 {
-       int res = -EPERM;
+       int i, num_formats = 0;
+
+       /*
+        * TODO: Query support for each group of formats directly from
+        * DC plane caps. This will require adding more formats to the
+        * caps list.
+        */
 
        switch (plane->type) {
        case DRM_PLANE_TYPE_PRIMARY:
-               res = drm_universal_plane_init(
-                               dm->adev->ddev,
-                               plane,
-                               possible_crtcs,
-                               &dm_plane_funcs,
-                               rgb_formats,
-                               ARRAY_SIZE(rgb_formats),
-                               NULL, plane->type, NULL);
+               for (i = 0; i < ARRAY_SIZE(rgb_formats); ++i) {
+                       if (num_formats >= max_formats)
+                               break;
+
+                       formats[num_formats++] = rgb_formats[i];
+               }
+
+               if (plane_cap && plane_cap->supports_nv12)
+                       formats[num_formats++] = DRM_FORMAT_NV12;
                break;
+
        case DRM_PLANE_TYPE_OVERLAY:
-               res = drm_universal_plane_init(
-                               dm->adev->ddev,
-                               plane,
-                               possible_crtcs,
-                               &dm_plane_funcs,
-                               overlay_formats,
-                               ARRAY_SIZE(overlay_formats),
-                               NULL, plane->type, NULL);
+               for (i = 0; i < ARRAY_SIZE(overlay_formats); ++i) {
+                       if (num_formats >= max_formats)
+                               break;
+
+                       formats[num_formats++] = overlay_formats[i];
+               }
                break;
+
        case DRM_PLANE_TYPE_CURSOR:
-               res = drm_universal_plane_init(
-                               dm->adev->ddev,
-                               plane,
-                               possible_crtcs,
-                               &dm_plane_funcs,
-                               cursor_formats,
-                               ARRAY_SIZE(cursor_formats),
-                               NULL, plane->type, NULL);
+               for (i = 0; i < ARRAY_SIZE(cursor_formats); ++i) {
+                       if (num_formats >= max_formats)
+                               break;
+
+                       formats[num_formats++] = cursor_formats[i];
+               }
                break;
        }
 
+       return num_formats;
+}
+
+static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
+                               struct drm_plane *plane,
+                               unsigned long possible_crtcs,
+                               const struct dc_plane_cap *plane_cap)
+{
+       uint32_t formats[32];
+       int num_formats;
+       int res = -EPERM;
+
+       num_formats = get_plane_formats(plane, plane_cap, formats,
+                                       ARRAY_SIZE(formats));
+
+       res = drm_universal_plane_init(dm->adev->ddev, plane, possible_crtcs,
+                                      &dm_plane_funcs, formats, num_formats,
+                                      NULL, plane->type, NULL);
+       if (res)
+               return res;
+
        if (plane->type == DRM_PLANE_TYPE_OVERLAY &&
            plane_cap && plane_cap->per_pixel_alpha) {
                unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
@@ -4176,8 +4201,7 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
        if (plane->funcs->reset)
                plane->funcs->reset(plane);
 
-
-       return res;
+       return 0;
 }
 
 static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,