drm/tegra: dc: Dedicate overlay plane to cursor on older Tegra's
authorDmitry Osipenko <digetx@gmail.com>
Thu, 15 Mar 2018 01:00:25 +0000 (04:00 +0300)
committerThierry Reding <treding@nvidia.com>
Thu, 15 Mar 2018 10:42:03 +0000 (11:42 +0100)
Older Tegra's do not support RGBA format for the cursor, but instead
overlay plane could be used for it. Since there is no much use for the
overlays on a regular desktop and HW-accelerated cursor is much better
than a SW cursor, let's dedicate one overlay plane to the mouse cursor.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/gpu/drm/tegra/dc.c

index b8403ed..ead13ac 100644 (file)
@@ -864,11 +864,13 @@ static const u32 tegra124_overlay_formats[] = {
 
 static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
                                                       struct tegra_dc *dc,
-                                                      unsigned int index)
+                                                      unsigned int index,
+                                                      bool cursor)
 {
        unsigned long possible_crtcs = tegra_plane_get_possible_crtcs(drm);
        struct tegra_plane *plane;
        unsigned int num_formats;
+       enum drm_plane_type type;
        const u32 *formats;
        int err;
 
@@ -883,10 +885,14 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
        num_formats = dc->soc->num_overlay_formats;
        formats = dc->soc->overlay_formats;
 
+       if (!cursor)
+               type = DRM_PLANE_TYPE_OVERLAY;
+       else
+               type = DRM_PLANE_TYPE_CURSOR;
+
        err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
                                       &tegra_plane_funcs, formats,
-                                      num_formats, NULL,
-                                      DRM_PLANE_TYPE_OVERLAY, NULL);
+                                      num_formats, NULL, type, NULL);
        if (err < 0) {
                kfree(plane);
                return ERR_PTR(err);
@@ -938,6 +944,7 @@ static struct drm_plane *tegra_dc_add_planes(struct drm_device *drm,
                                             struct tegra_dc *dc)
 {
        struct drm_plane *planes[2], *primary;
+       unsigned int planes_num;
        unsigned int i;
        int err;
 
@@ -945,8 +952,14 @@ static struct drm_plane *tegra_dc_add_planes(struct drm_device *drm,
        if (IS_ERR(primary))
                return primary;
 
-       for (i = 0; i < 2; i++) {
-               planes[i] = tegra_dc_overlay_plane_create(drm, dc, 1 + i);
+       if (dc->soc->supports_cursor)
+               planes_num = 2;
+       else
+               planes_num = 1;
+
+       for (i = 0; i < planes_num; i++) {
+               planes[i] = tegra_dc_overlay_plane_create(drm, dc, 1 + i,
+                                                         false);
                if (IS_ERR(planes[i])) {
                        err = PTR_ERR(planes[i]);
 
@@ -1864,6 +1877,13 @@ static int tegra_dc_init(struct host1x_client *client)
                        err = PTR_ERR(cursor);
                        goto cleanup;
                }
+       } else {
+               /* dedicate one overlay to mouse cursor */
+               cursor = tegra_dc_overlay_plane_create(drm, dc, 2, true);
+               if (IS_ERR(cursor)) {
+                       err = PTR_ERR(cursor);
+                       goto cleanup;
+               }
        }
 
        err = drm_crtc_init_with_planes(drm, &dc->base, primary, cursor,