diff options
author | Matt Roper <matthew.d.roper@intel.com> | 2014-04-01 18:22:30 -0400 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2014-04-01 19:13:07 -0400 |
commit | e27dde3e1c5117149c50b89d688528e279756113 (patch) | |
tree | f8af6af4b70125256c657317b6192a7183ec8157 | |
parent | c32fc9c803f8ed90a7548810de48ca33a3020168 (diff) |
drm: Add support for multiple plane types (v2)
The DRM core currently only tracks "overlay"-style planes. Start
refactoring the plane handling to allow other plane types (primary and
cursor) to also be placed on the DRM plane list.
v2: Add drm_for_each_legacy_plane() iterator to smooth transition
of drivers with plane loops.
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Rob Clark <robdclark@gmail.com>
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 3 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 24 |
3 files changed, 41 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 960ca987c20f..7def92b8acc2 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -1044,6 +1044,7 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, | |||
1044 | memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); | 1044 | memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); |
1045 | plane->format_count = format_count; | 1045 | plane->format_count = format_count; |
1046 | plane->possible_crtcs = possible_crtcs; | 1046 | plane->possible_crtcs = possible_crtcs; |
1047 | plane->type = DRM_PLANE_TYPE_OVERLAY; | ||
1047 | 1048 | ||
1048 | /* private planes are not exposed to userspace, but depending on | 1049 | /* private planes are not exposed to userspace, but depending on |
1049 | * display hardware, might be convenient to allow sharing programming | 1050 | * display hardware, might be convenient to allow sharing programming |
@@ -1051,7 +1052,9 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, | |||
1051 | */ | 1052 | */ |
1052 | if (!priv) { | 1053 | if (!priv) { |
1053 | list_add_tail(&plane->head, &dev->mode_config.plane_list); | 1054 | list_add_tail(&plane->head, &dev->mode_config.plane_list); |
1054 | dev->mode_config.num_plane++; | 1055 | dev->mode_config.num_total_plane++; |
1056 | if (plane->type == DRM_PLANE_TYPE_OVERLAY) | ||
1057 | dev->mode_config.num_overlay_plane++; | ||
1055 | } else { | 1058 | } else { |
1056 | INIT_LIST_HEAD(&plane->head); | 1059 | INIT_LIST_HEAD(&plane->head); |
1057 | } | 1060 | } |
@@ -1081,7 +1084,9 @@ void drm_plane_cleanup(struct drm_plane *plane) | |||
1081 | /* if not added to a list, it must be a private plane */ | 1084 | /* if not added to a list, it must be a private plane */ |
1082 | if (!list_empty(&plane->head)) { | 1085 | if (!list_empty(&plane->head)) { |
1083 | list_del(&plane->head); | 1086 | list_del(&plane->head); |
1084 | dev->mode_config.num_plane--; | 1087 | dev->mode_config.num_total_plane--; |
1088 | if (plane->type == DRM_PLANE_TYPE_OVERLAY) | ||
1089 | dev->mode_config.num_overlay_plane--; | ||
1085 | } | 1090 | } |
1086 | drm_modeset_unlock_all(dev); | 1091 | drm_modeset_unlock_all(dev); |
1087 | } | 1092 | } |
@@ -1908,11 +1913,15 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, | |||
1908 | * This ioctl is called twice, once to determine how much space is | 1913 | * This ioctl is called twice, once to determine how much space is |
1909 | * needed, and the 2nd time to fill it. | 1914 | * needed, and the 2nd time to fill it. |
1910 | */ | 1915 | */ |
1911 | if (config->num_plane && | 1916 | if (config->num_overlay_plane && |
1912 | (plane_resp->count_planes >= config->num_plane)) { | 1917 | (plane_resp->count_planes >= config->num_overlay_plane)) { |
1913 | plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr; | 1918 | plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr; |
1914 | 1919 | ||
1915 | list_for_each_entry(plane, &config->plane_list, head) { | 1920 | list_for_each_entry(plane, &config->plane_list, head) { |
1921 | /* Only advertise overlays to userspace for now. */ | ||
1922 | if (plane->type != DRM_PLANE_TYPE_OVERLAY) | ||
1923 | continue; | ||
1924 | |||
1916 | if (put_user(plane->base.id, plane_ptr + copied)) { | 1925 | if (put_user(plane->base.id, plane_ptr + copied)) { |
1917 | ret = -EFAULT; | 1926 | ret = -EFAULT; |
1918 | goto out; | 1927 | goto out; |
@@ -1920,7 +1929,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, | |||
1920 | copied++; | 1929 | copied++; |
1921 | } | 1930 | } |
1922 | } | 1931 | } |
1923 | plane_resp->count_planes = config->num_plane; | 1932 | plane_resp->count_planes = config->num_overlay_plane; |
1924 | 1933 | ||
1925 | out: | 1934 | out: |
1926 | drm_modeset_unlock_all(dev); | 1935 | drm_modeset_unlock_all(dev); |
@@ -4534,6 +4543,8 @@ void drm_mode_config_init(struct drm_device *dev) | |||
4534 | dev->mode_config.num_connector = 0; | 4543 | dev->mode_config.num_connector = 0; |
4535 | dev->mode_config.num_crtc = 0; | 4544 | dev->mode_config.num_crtc = 0; |
4536 | dev->mode_config.num_encoder = 0; | 4545 | dev->mode_config.num_encoder = 0; |
4546 | dev->mode_config.num_overlay_plane = 0; | ||
4547 | dev->mode_config.num_total_plane = 0; | ||
4537 | } | 4548 | } |
4538 | EXPORT_SYMBOL(drm_mode_config_init); | 4549 | EXPORT_SYMBOL(drm_mode_config_init); |
4539 | 4550 | ||
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 16f271e21b9c..f30bf7b723d5 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -291,7 +291,8 @@ bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper) | |||
291 | drm_warn_on_modeset_not_all_locked(dev); | 291 | drm_warn_on_modeset_not_all_locked(dev); |
292 | 292 | ||
293 | list_for_each_entry(plane, &dev->mode_config.plane_list, head) | 293 | list_for_each_entry(plane, &dev->mode_config.plane_list, head) |
294 | drm_plane_force_disable(plane); | 294 | if (plane->type != DRM_PLANE_TYPE_PRIMARY) |
295 | drm_plane_force_disable(plane); | ||
295 | 296 | ||
296 | for (i = 0; i < fb_helper->crtc_count; i++) { | 297 | for (i = 0; i < fb_helper->crtc_count; i++) { |
297 | struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; | 298 | struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 27f828c9d7f2..3894f85dcdff 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
@@ -541,6 +541,12 @@ struct drm_plane_funcs { | |||
541 | struct drm_property *property, uint64_t val); | 541 | struct drm_property *property, uint64_t val); |
542 | }; | 542 | }; |
543 | 543 | ||
544 | enum drm_plane_type { | ||
545 | DRM_PLANE_TYPE_OVERLAY, | ||
546 | DRM_PLANE_TYPE_PRIMARY, | ||
547 | DRM_PLANE_TYPE_CURSOR, | ||
548 | }; | ||
549 | |||
544 | /** | 550 | /** |
545 | * drm_plane - central DRM plane control structure | 551 | * drm_plane - central DRM plane control structure |
546 | * @dev: DRM device this plane belongs to | 552 | * @dev: DRM device this plane belongs to |
@@ -553,6 +559,7 @@ struct drm_plane_funcs { | |||
553 | * @fb: currently bound fb | 559 | * @fb: currently bound fb |
554 | * @funcs: helper functions | 560 | * @funcs: helper functions |
555 | * @properties: property tracking for this plane | 561 | * @properties: property tracking for this plane |
562 | * @type: type of plane (overlay, primary, cursor) | ||
556 | */ | 563 | */ |
557 | struct drm_plane { | 564 | struct drm_plane { |
558 | struct drm_device *dev; | 565 | struct drm_device *dev; |
@@ -570,6 +577,8 @@ struct drm_plane { | |||
570 | const struct drm_plane_funcs *funcs; | 577 | const struct drm_plane_funcs *funcs; |
571 | 578 | ||
572 | struct drm_object_properties properties; | 579 | struct drm_object_properties properties; |
580 | |||
581 | enum drm_plane_type type; | ||
573 | }; | 582 | }; |
574 | 583 | ||
575 | /** | 584 | /** |
@@ -732,7 +741,15 @@ struct drm_mode_config { | |||
732 | struct list_head bridge_list; | 741 | struct list_head bridge_list; |
733 | int num_encoder; | 742 | int num_encoder; |
734 | struct list_head encoder_list; | 743 | struct list_head encoder_list; |
735 | int num_plane; | 744 | |
745 | /* | ||
746 | * Track # of overlay planes separately from # of total planes. By | ||
747 | * default we only advertise overlay planes to userspace; if userspace | ||
748 | * sets the "universal plane" capability bit, we'll go ahead and | ||
749 | * expose all planes. | ||
750 | */ | ||
751 | int num_overlay_plane; | ||
752 | int num_total_plane; | ||
736 | struct list_head plane_list; | 753 | struct list_head plane_list; |
737 | 754 | ||
738 | int num_crtc; | 755 | int num_crtc; |
@@ -1036,4 +1053,9 @@ static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev, | |||
1036 | return mo ? obj_to_encoder(mo) : NULL; | 1053 | return mo ? obj_to_encoder(mo) : NULL; |
1037 | } | 1054 | } |
1038 | 1055 | ||
1056 | /* Plane list iterator for legacy (overlay only) planes. */ | ||
1057 | #define drm_for_each_legacy_plane(plane, planelist) \ | ||
1058 | list_for_each_entry(plane, planelist, head) \ | ||
1059 | if (plane->type == DRM_PLANE_TYPE_OVERLAY) | ||
1060 | |||
1039 | #endif /* __DRM_CRTC_H__ */ | 1061 | #endif /* __DRM_CRTC_H__ */ |