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);
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);
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);
/* 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,
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);
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);