drm: add support for private planes
Rob Clark [Wed, 14 Dec 2011 02:19:36 +0000 (20:19 -0600)]
In cases where the scanout hw is sufficiently similar between "overlay"
and traditional crtc layers, it might be convenient to allow the driver
to create internal drm_plane helper objects used by the drm_crtc
implementation, rather than duplicate code between the plane and crtc.
A private plane is not exposed to userspace.

Signed-off-by: Rob Clark <rob@ti.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_plane.c
drivers/gpu/drm/i915/intel_sprite.c
include/drm/drm_crtc.h

index 7710bcb..5e818a8 100644 (file)
@@ -557,7 +557,8 @@ EXPORT_SYMBOL(drm_encoder_cleanup);
 int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
                   unsigned long possible_crtcs,
                   const struct drm_plane_funcs *funcs,
-                  const uint32_t *formats, uint32_t format_count)
+                  const uint32_t *formats, uint32_t format_count,
+                  bool priv)
 {
        mutex_lock(&dev->mode_config.mutex);
 
@@ -577,8 +578,16 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
        plane->format_count = format_count;
        plane->possible_crtcs = possible_crtcs;
 
-       list_add_tail(&plane->head, &dev->mode_config.plane_list);
-       dev->mode_config.num_plane++;
+       /* private planes are not exposed to userspace, but depending on
+        * display hardware, might be convenient to allow sharing programming
+        * for the scanout engine with the crtc implementation.
+        */
+       if (!priv) {
+               list_add_tail(&plane->head, &dev->mode_config.plane_list);
+               dev->mode_config.num_plane++;
+       } else {
+               INIT_LIST_HEAD(&plane->head);
+       }
 
        mutex_unlock(&dev->mode_config.mutex);
 
@@ -593,8 +602,11 @@ void drm_plane_cleanup(struct drm_plane *plane)
        mutex_lock(&dev->mode_config.mutex);
        kfree(plane->format_types);
        drm_mode_object_put(dev, &plane->base);
-       list_del(&plane->head);
-       dev->mode_config.num_plane--;
+       /* if not added to a list, it must be a private plane */
+       if (!list_empty(&plane->head)) {
+               list_del(&plane->head);
+               dev->mode_config.num_plane--;
+       }
        mutex_unlock(&dev->mode_config.mutex);
 }
 EXPORT_SYMBOL(drm_plane_cleanup);
index c785e34..bdcf770 100644 (file)
@@ -117,7 +117,7 @@ int exynos_plane_init(struct drm_device *dev, unsigned int nr)
 
        /* TODO: format */
        return drm_plane_init(dev, &exynos_plane->base, possible_crtcs,
-                             &exynos_plane_funcs, NULL, 0);
+                             &exynos_plane_funcs, NULL, 0, false);
 }
 
 int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data,
index b26e7c4..d13989f 100644 (file)
@@ -659,7 +659,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe)
        possible_crtcs = (1 << pipe);
        ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
                             &intel_plane_funcs, snb_plane_formats,
-                            ARRAY_SIZE(snb_plane_formats));
+                            ARRAY_SIZE(snb_plane_formats), false);
        if (ret)
                kfree(intel_plane);
 
index 2deb6f9..63e4fce 100644 (file)
@@ -829,7 +829,8 @@ extern int drm_plane_init(struct drm_device *dev,
                          struct drm_plane *plane,
                          unsigned long possible_crtcs,
                          const struct drm_plane_funcs *funcs,
-                         const uint32_t *formats, uint32_t format_count);
+                         const uint32_t *formats, uint32_t format_count,
+                         bool priv);
 extern void drm_plane_cleanup(struct drm_plane *plane);
 
 extern void drm_encoder_cleanup(struct drm_encoder *encoder);