From: Ville Syrjälä <[email protected]>

Allocate the dumb buffer based on the cursor hardware capabilities
when userspace has asked for it via the DRM_MODE_DUMB_CURSOR flag.

Cc: Daniel Stone <[email protected]>
Signed-off-by: Ville Syrjälä <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_cursor.c  | 38 ++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_cursor.h  |  3 ++
 drivers/gpu/drm/i915/display/intel_display.c |  5 ++-
 3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c 
b/drivers/gpu/drm/i915/display/intel_cursor.c
index c47c84935871..fffb25c91146 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -998,6 +998,44 @@ static void intel_cursor_add_size_hints_property(struct 
intel_plane *plane)
        drm_plane_add_size_hints_property(&plane->base, hints, num_hints);
 }
 
+int intel_cursor_dumb_create(struct intel_display *display,
+                            struct drm_mode_create_dumb *args)
+{
+       const struct drm_mode_config *mode_config = &display->drm->mode_config;
+       int cpp = DIV_ROUND_UP(args->bpp, 8);
+
+       if (cpp != 4)
+               return -EINVAL;
+
+       if (args->width > mode_config->cursor_width)
+               return -EINVAL;
+
+       if (args->height > mode_config->cursor_height)
+               return -EINVAL;
+
+       if (display->platform.i845g || display->platform.i865g) {
+               if (!IS_ALIGNED(args->width, 64))
+                       return -EINVAL;
+
+               args->pitch = roundup_pow_of_two(args->width) * 4;
+       } else {
+               switch (args->width) {
+               case 64:
+               case 128:
+               case 256:
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               args->pitch = args->width * 4;
+       }
+
+       args->size = mul_u32_u32(args->pitch, args->height);
+
+       return 0;
+}
+
 struct intel_plane *
 intel_cursor_plane_create(struct intel_display *display,
                          enum pipe pipe)
diff --git a/drivers/gpu/drm/i915/display/intel_cursor.h 
b/drivers/gpu/drm/i915/display/intel_cursor.h
index 65a9e7eb88c2..cd3ae2d6042e 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.h
+++ b/drivers/gpu/drm/i915/display/intel_cursor.h
@@ -7,6 +7,7 @@
 #define _INTEL_CURSOR_H_
 
 enum pipe;
+struct drm_mode_create_dumb;
 struct intel_display;
 struct intel_plane;
 struct kthread_work;
@@ -16,5 +17,7 @@ intel_cursor_plane_create(struct intel_display *display,
                          enum pipe pipe);
 
 void intel_cursor_unpin_work(struct kthread_work *base);
+int intel_cursor_dumb_create(struct intel_display *display,
+                            struct drm_mode_create_dumb *args);
 
 #endif
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index bd4317291ba5..6772d4dd94c7 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -574,7 +574,10 @@ int intel_display_dumb_create(struct drm_device *drm,
 {
        struct intel_display *display = to_intel_display(drm);
 
-       return intel_plane_dumb_create(display, args);
+       if (args->flags & DRM_MODE_DUMB_CURSOR)
+               return intel_cursor_dumb_create(display, args);
+       else
+               return intel_plane_dumb_create(display, args);
 }
 
 void intel_set_plane_visible(struct intel_crtc_state *crtc_state,
-- 
2.49.1

Reply via email to