diff options
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 189 |
1 files changed, 138 insertions, 51 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 960ca987c20f..d8b7099abece 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -121,6 +121,13 @@ static const struct drm_prop_enum_list drm_dpms_enum_list[] = | |||
121 | 121 | ||
122 | DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list) | 122 | DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list) |
123 | 123 | ||
124 | static const struct drm_prop_enum_list drm_plane_type_enum_list[] = | ||
125 | { | ||
126 | { DRM_PLANE_TYPE_OVERLAY, "Overlay" }, | ||
127 | { DRM_PLANE_TYPE_PRIMARY, "Primary" }, | ||
128 | { DRM_PLANE_TYPE_CURSOR, "Cursor" }, | ||
129 | }; | ||
130 | |||
124 | /* | 131 | /* |
125 | * Optional properties | 132 | * Optional properties |
126 | */ | 133 | */ |
@@ -662,7 +669,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) | |||
662 | drm_modeset_lock_all(dev); | 669 | drm_modeset_lock_all(dev); |
663 | /* remove from any CRTC */ | 670 | /* remove from any CRTC */ |
664 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 671 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
665 | if (crtc->fb == fb) { | 672 | if (crtc->primary->fb == fb) { |
666 | /* should turn off the crtc */ | 673 | /* should turn off the crtc */ |
667 | memset(&set, 0, sizeof(struct drm_mode_set)); | 674 | memset(&set, 0, sizeof(struct drm_mode_set)); |
668 | set.crtc = crtc; | 675 | set.crtc = crtc; |
@@ -685,9 +692,12 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) | |||
685 | EXPORT_SYMBOL(drm_framebuffer_remove); | 692 | EXPORT_SYMBOL(drm_framebuffer_remove); |
686 | 693 | ||
687 | /** | 694 | /** |
688 | * drm_crtc_init - Initialise a new CRTC object | 695 | * drm_crtc_init_with_planes - Initialise a new CRTC object with |
696 | * specified primary and cursor planes. | ||
689 | * @dev: DRM device | 697 | * @dev: DRM device |
690 | * @crtc: CRTC object to init | 698 | * @crtc: CRTC object to init |
699 | * @primary: Primary plane for CRTC | ||
700 | * @cursor: Cursor plane for CRTC | ||
691 | * @funcs: callbacks for the new CRTC | 701 | * @funcs: callbacks for the new CRTC |
692 | * | 702 | * |
693 | * Inits a new object created as base part of a driver crtc object. | 703 | * Inits a new object created as base part of a driver crtc object. |
@@ -695,8 +705,10 @@ EXPORT_SYMBOL(drm_framebuffer_remove); | |||
695 | * Returns: | 705 | * Returns: |
696 | * Zero on success, error code on failure. | 706 | * Zero on success, error code on failure. |
697 | */ | 707 | */ |
698 | int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, | 708 | int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, |
699 | const struct drm_crtc_funcs *funcs) | 709 | struct drm_plane *primary, |
710 | void *cursor, | ||
711 | const struct drm_crtc_funcs *funcs) | ||
700 | { | 712 | { |
701 | int ret; | 713 | int ret; |
702 | 714 | ||
@@ -717,12 +729,16 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, | |||
717 | list_add_tail(&crtc->head, &dev->mode_config.crtc_list); | 729 | list_add_tail(&crtc->head, &dev->mode_config.crtc_list); |
718 | dev->mode_config.num_crtc++; | 730 | dev->mode_config.num_crtc++; |
719 | 731 | ||
732 | crtc->primary = primary; | ||
733 | if (primary) | ||
734 | primary->possible_crtcs = 1 << drm_crtc_index(crtc); | ||
735 | |||
720 | out: | 736 | out: |
721 | drm_modeset_unlock_all(dev); | 737 | drm_modeset_unlock_all(dev); |
722 | 738 | ||
723 | return ret; | 739 | return ret; |
724 | } | 740 | } |
725 | EXPORT_SYMBOL(drm_crtc_init); | 741 | EXPORT_SYMBOL(drm_crtc_init_with_planes); |
726 | 742 | ||
727 | /** | 743 | /** |
728 | * drm_crtc_cleanup - Clean up the core crtc usage | 744 | * drm_crtc_cleanup - Clean up the core crtc usage |
@@ -1000,26 +1016,25 @@ void drm_encoder_cleanup(struct drm_encoder *encoder) | |||
1000 | EXPORT_SYMBOL(drm_encoder_cleanup); | 1016 | EXPORT_SYMBOL(drm_encoder_cleanup); |
1001 | 1017 | ||
1002 | /** | 1018 | /** |
1003 | * drm_plane_init - Initialise a new plane object | 1019 | * drm_universal_plane_init - Initialize a new universal plane object |
1004 | * @dev: DRM device | 1020 | * @dev: DRM device |
1005 | * @plane: plane object to init | 1021 | * @plane: plane object to init |
1006 | * @possible_crtcs: bitmask of possible CRTCs | 1022 | * @possible_crtcs: bitmask of possible CRTCs |
1007 | * @funcs: callbacks for the new plane | 1023 | * @funcs: callbacks for the new plane |
1008 | * @formats: array of supported formats (%DRM_FORMAT_*) | 1024 | * @formats: array of supported formats (%DRM_FORMAT_*) |
1009 | * @format_count: number of elements in @formats | 1025 | * @format_count: number of elements in @formats |
1010 | * @priv: plane is private (hidden from userspace)? | 1026 | * @type: type of plane (overlay, primary, cursor) |
1011 | * | 1027 | * |
1012 | * Inits a preallocate plane object created as base part of a driver plane | 1028 | * Initializes a plane object of type @type. |
1013 | * object. | ||
1014 | * | 1029 | * |
1015 | * Returns: | 1030 | * Returns: |
1016 | * Zero on success, error code on failure. | 1031 | * Zero on success, error code on failure. |
1017 | */ | 1032 | */ |
1018 | int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, | 1033 | int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, |
1019 | unsigned long possible_crtcs, | 1034 | unsigned long possible_crtcs, |
1020 | const struct drm_plane_funcs *funcs, | 1035 | const struct drm_plane_funcs *funcs, |
1021 | const uint32_t *formats, uint32_t format_count, | 1036 | const uint32_t *formats, uint32_t format_count, |
1022 | bool priv) | 1037 | enum drm_plane_type type) |
1023 | { | 1038 | { |
1024 | int ret; | 1039 | int ret; |
1025 | 1040 | ||
@@ -1044,23 +1059,53 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, | |||
1044 | memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); | 1059 | memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); |
1045 | plane->format_count = format_count; | 1060 | plane->format_count = format_count; |
1046 | plane->possible_crtcs = possible_crtcs; | 1061 | plane->possible_crtcs = possible_crtcs; |
1062 | plane->type = type; | ||
1047 | 1063 | ||
1048 | /* private planes are not exposed to userspace, but depending on | 1064 | list_add_tail(&plane->head, &dev->mode_config.plane_list); |
1049 | * display hardware, might be convenient to allow sharing programming | 1065 | dev->mode_config.num_total_plane++; |
1050 | * for the scanout engine with the crtc implementation. | 1066 | if (plane->type == DRM_PLANE_TYPE_OVERLAY) |
1051 | */ | 1067 | dev->mode_config.num_overlay_plane++; |
1052 | if (!priv) { | 1068 | |
1053 | list_add_tail(&plane->head, &dev->mode_config.plane_list); | 1069 | drm_object_attach_property(&plane->base, |
1054 | dev->mode_config.num_plane++; | 1070 | dev->mode_config.plane_type_property, |
1055 | } else { | 1071 | plane->type); |
1056 | INIT_LIST_HEAD(&plane->head); | ||
1057 | } | ||
1058 | 1072 | ||
1059 | out: | 1073 | out: |
1060 | drm_modeset_unlock_all(dev); | 1074 | drm_modeset_unlock_all(dev); |
1061 | 1075 | ||
1062 | return ret; | 1076 | return ret; |
1063 | } | 1077 | } |
1078 | EXPORT_SYMBOL(drm_universal_plane_init); | ||
1079 | |||
1080 | /** | ||
1081 | * drm_plane_init - Initialize a legacy plane | ||
1082 | * @dev: DRM device | ||
1083 | * @plane: plane object to init | ||
1084 | * @possible_crtcs: bitmask of possible CRTCs | ||
1085 | * @funcs: callbacks for the new plane | ||
1086 | * @formats: array of supported formats (%DRM_FORMAT_*) | ||
1087 | * @format_count: number of elements in @formats | ||
1088 | * @is_primary: plane type (primary vs overlay) | ||
1089 | * | ||
1090 | * Legacy API to initialize a DRM plane. | ||
1091 | * | ||
1092 | * New drivers should call drm_universal_plane_init() instead. | ||
1093 | * | ||
1094 | * Returns: | ||
1095 | * Zero on success, error code on failure. | ||
1096 | */ | ||
1097 | int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, | ||
1098 | unsigned long possible_crtcs, | ||
1099 | const struct drm_plane_funcs *funcs, | ||
1100 | const uint32_t *formats, uint32_t format_count, | ||
1101 | bool is_primary) | ||
1102 | { | ||
1103 | enum drm_plane_type type; | ||
1104 | |||
1105 | type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; | ||
1106 | return drm_universal_plane_init(dev, plane, possible_crtcs, funcs, | ||
1107 | formats, format_count, type); | ||
1108 | } | ||
1064 | EXPORT_SYMBOL(drm_plane_init); | 1109 | EXPORT_SYMBOL(drm_plane_init); |
1065 | 1110 | ||
1066 | /** | 1111 | /** |
@@ -1078,11 +1123,13 @@ void drm_plane_cleanup(struct drm_plane *plane) | |||
1078 | drm_modeset_lock_all(dev); | 1123 | drm_modeset_lock_all(dev); |
1079 | kfree(plane->format_types); | 1124 | kfree(plane->format_types); |
1080 | drm_mode_object_put(dev, &plane->base); | 1125 | drm_mode_object_put(dev, &plane->base); |
1081 | /* if not added to a list, it must be a private plane */ | 1126 | |
1082 | if (!list_empty(&plane->head)) { | 1127 | BUG_ON(list_empty(&plane->head)); |
1083 | list_del(&plane->head); | 1128 | |
1084 | dev->mode_config.num_plane--; | 1129 | list_del(&plane->head); |
1085 | } | 1130 | dev->mode_config.num_total_plane--; |
1131 | if (plane->type == DRM_PLANE_TYPE_OVERLAY) | ||
1132 | dev->mode_config.num_overlay_plane--; | ||
1086 | drm_modeset_unlock_all(dev); | 1133 | drm_modeset_unlock_all(dev); |
1087 | } | 1134 | } |
1088 | EXPORT_SYMBOL(drm_plane_cleanup); | 1135 | EXPORT_SYMBOL(drm_plane_cleanup); |
@@ -1134,6 +1181,21 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev) | |||
1134 | return 0; | 1181 | return 0; |
1135 | } | 1182 | } |
1136 | 1183 | ||
1184 | static int drm_mode_create_standard_plane_properties(struct drm_device *dev) | ||
1185 | { | ||
1186 | struct drm_property *type; | ||
1187 | |||
1188 | /* | ||
1189 | * Standard properties (apply to all planes) | ||
1190 | */ | ||
1191 | type = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, | ||
1192 | "type", drm_plane_type_enum_list, | ||
1193 | ARRAY_SIZE(drm_plane_type_enum_list)); | ||
1194 | dev->mode_config.plane_type_property = type; | ||
1195 | |||
1196 | return 0; | ||
1197 | } | ||
1198 | |||
1137 | /** | 1199 | /** |
1138 | * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties | 1200 | * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties |
1139 | * @dev: DRM device | 1201 | * @dev: DRM device |
@@ -1652,8 +1714,8 @@ int drm_mode_getcrtc(struct drm_device *dev, | |||
1652 | crtc_resp->x = crtc->x; | 1714 | crtc_resp->x = crtc->x; |
1653 | crtc_resp->y = crtc->y; | 1715 | crtc_resp->y = crtc->y; |
1654 | crtc_resp->gamma_size = crtc->gamma_size; | 1716 | crtc_resp->gamma_size = crtc->gamma_size; |
1655 | if (crtc->fb) | 1717 | if (crtc->primary->fb) |
1656 | crtc_resp->fb_id = crtc->fb->base.id; | 1718 | crtc_resp->fb_id = crtc->primary->fb->base.id; |
1657 | else | 1719 | else |
1658 | crtc_resp->fb_id = 0; | 1720 | crtc_resp->fb_id = 0; |
1659 | 1721 | ||
@@ -1897,6 +1959,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, | |||
1897 | struct drm_plane *plane; | 1959 | struct drm_plane *plane; |
1898 | uint32_t __user *plane_ptr; | 1960 | uint32_t __user *plane_ptr; |
1899 | int copied = 0, ret = 0; | 1961 | int copied = 0, ret = 0; |
1962 | unsigned num_planes; | ||
1900 | 1963 | ||
1901 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 1964 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
1902 | return -EINVAL; | 1965 | return -EINVAL; |
@@ -1904,15 +1967,28 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, | |||
1904 | drm_modeset_lock_all(dev); | 1967 | drm_modeset_lock_all(dev); |
1905 | config = &dev->mode_config; | 1968 | config = &dev->mode_config; |
1906 | 1969 | ||
1970 | if (file_priv->universal_planes) | ||
1971 | num_planes = config->num_total_plane; | ||
1972 | else | ||
1973 | num_planes = config->num_overlay_plane; | ||
1974 | |||
1907 | /* | 1975 | /* |
1908 | * This ioctl is called twice, once to determine how much space is | 1976 | * This ioctl is called twice, once to determine how much space is |
1909 | * needed, and the 2nd time to fill it. | 1977 | * needed, and the 2nd time to fill it. |
1910 | */ | 1978 | */ |
1911 | if (config->num_plane && | 1979 | if (num_planes && |
1912 | (plane_resp->count_planes >= config->num_plane)) { | 1980 | (plane_resp->count_planes >= num_planes)) { |
1913 | plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr; | 1981 | plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr; |
1914 | 1982 | ||
1915 | list_for_each_entry(plane, &config->plane_list, head) { | 1983 | list_for_each_entry(plane, &config->plane_list, head) { |
1984 | /* | ||
1985 | * Unless userspace set the 'universal planes' | ||
1986 | * capability bit, only advertise overlays. | ||
1987 | */ | ||
1988 | if (plane->type != DRM_PLANE_TYPE_OVERLAY && | ||
1989 | !file_priv->universal_planes) | ||
1990 | continue; | ||
1991 | |||
1916 | if (put_user(plane->base.id, plane_ptr + copied)) { | 1992 | if (put_user(plane->base.id, plane_ptr + copied)) { |
1917 | ret = -EFAULT; | 1993 | ret = -EFAULT; |
1918 | goto out; | 1994 | goto out; |
@@ -1920,7 +1996,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, | |||
1920 | copied++; | 1996 | copied++; |
1921 | } | 1997 | } |
1922 | } | 1998 | } |
1923 | plane_resp->count_planes = config->num_plane; | 1999 | plane_resp->count_planes = num_planes; |
1924 | 2000 | ||
1925 | out: | 2001 | out: |
1926 | drm_modeset_unlock_all(dev); | 2002 | drm_modeset_unlock_all(dev); |
@@ -2156,19 +2232,21 @@ int drm_mode_set_config_internal(struct drm_mode_set *set) | |||
2156 | * crtcs. Atomic modeset will have saner semantics ... | 2232 | * crtcs. Atomic modeset will have saner semantics ... |
2157 | */ | 2233 | */ |
2158 | list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) | 2234 | list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) |
2159 | tmp->old_fb = tmp->fb; | 2235 | tmp->old_fb = tmp->primary->fb; |
2160 | 2236 | ||
2161 | fb = set->fb; | 2237 | fb = set->fb; |
2162 | 2238 | ||
2163 | ret = crtc->funcs->set_config(set); | 2239 | ret = crtc->funcs->set_config(set); |
2164 | if (ret == 0) { | 2240 | if (ret == 0) { |
2241 | crtc->primary->crtc = crtc; | ||
2242 | |||
2165 | /* crtc->fb must be updated by ->set_config, enforces this. */ | 2243 | /* crtc->fb must be updated by ->set_config, enforces this. */ |
2166 | WARN_ON(fb != crtc->fb); | 2244 | WARN_ON(fb != crtc->primary->fb); |
2167 | } | 2245 | } |
2168 | 2246 | ||
2169 | list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) { | 2247 | list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) { |
2170 | if (tmp->fb) | 2248 | if (tmp->primary->fb) |
2171 | drm_framebuffer_reference(tmp->fb); | 2249 | drm_framebuffer_reference(tmp->primary->fb); |
2172 | if (tmp->old_fb) | 2250 | if (tmp->old_fb) |
2173 | drm_framebuffer_unreference(tmp->old_fb); | 2251 | drm_framebuffer_unreference(tmp->old_fb); |
2174 | } | 2252 | } |
@@ -2177,14 +2255,19 @@ int drm_mode_set_config_internal(struct drm_mode_set *set) | |||
2177 | } | 2255 | } |
2178 | EXPORT_SYMBOL(drm_mode_set_config_internal); | 2256 | EXPORT_SYMBOL(drm_mode_set_config_internal); |
2179 | 2257 | ||
2180 | /* | 2258 | /** |
2181 | * Checks that the framebuffer is big enough for the CRTC viewport | 2259 | * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the |
2182 | * (x, y, hdisplay, vdisplay) | 2260 | * CRTC viewport |
2261 | * @crtc: CRTC that framebuffer will be displayed on | ||
2262 | * @x: x panning | ||
2263 | * @y: y panning | ||
2264 | * @mode: mode that framebuffer will be displayed under | ||
2265 | * @fb: framebuffer to check size of | ||
2183 | */ | 2266 | */ |
2184 | static int drm_crtc_check_viewport(const struct drm_crtc *crtc, | 2267 | int drm_crtc_check_viewport(const struct drm_crtc *crtc, |
2185 | int x, int y, | 2268 | int x, int y, |
2186 | const struct drm_display_mode *mode, | 2269 | const struct drm_display_mode *mode, |
2187 | const struct drm_framebuffer *fb) | 2270 | const struct drm_framebuffer *fb) |
2188 | 2271 | ||
2189 | { | 2272 | { |
2190 | int hdisplay, vdisplay; | 2273 | int hdisplay, vdisplay; |
@@ -2215,6 +2298,7 @@ static int drm_crtc_check_viewport(const struct drm_crtc *crtc, | |||
2215 | 2298 | ||
2216 | return 0; | 2299 | return 0; |
2217 | } | 2300 | } |
2301 | EXPORT_SYMBOL(drm_crtc_check_viewport); | ||
2218 | 2302 | ||
2219 | /** | 2303 | /** |
2220 | * drm_mode_setcrtc - set CRTC configuration | 2304 | * drm_mode_setcrtc - set CRTC configuration |
@@ -2266,12 +2350,12 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, | |||
2266 | /* If we have a mode we need a framebuffer. */ | 2350 | /* If we have a mode we need a framebuffer. */ |
2267 | /* If we pass -1, set the mode with the currently bound fb */ | 2351 | /* If we pass -1, set the mode with the currently bound fb */ |
2268 | if (crtc_req->fb_id == -1) { | 2352 | if (crtc_req->fb_id == -1) { |
2269 | if (!crtc->fb) { | 2353 | if (!crtc->primary->fb) { |
2270 | DRM_DEBUG_KMS("CRTC doesn't have current FB\n"); | 2354 | DRM_DEBUG_KMS("CRTC doesn't have current FB\n"); |
2271 | ret = -EINVAL; | 2355 | ret = -EINVAL; |
2272 | goto out; | 2356 | goto out; |
2273 | } | 2357 | } |
2274 | fb = crtc->fb; | 2358 | fb = crtc->primary->fb; |
2275 | /* Make refcounting symmetric with the lookup path. */ | 2359 | /* Make refcounting symmetric with the lookup path. */ |
2276 | drm_framebuffer_reference(fb); | 2360 | drm_framebuffer_reference(fb); |
2277 | } else { | 2361 | } else { |
@@ -4065,7 +4149,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, | |||
4065 | crtc = obj_to_crtc(obj); | 4149 | crtc = obj_to_crtc(obj); |
4066 | 4150 | ||
4067 | mutex_lock(&crtc->mutex); | 4151 | mutex_lock(&crtc->mutex); |
4068 | if (crtc->fb == NULL) { | 4152 | if (crtc->primary->fb == NULL) { |
4069 | /* The framebuffer is currently unbound, presumably | 4153 | /* The framebuffer is currently unbound, presumably |
4070 | * due to a hotplug event, that userspace has not | 4154 | * due to a hotplug event, that userspace has not |
4071 | * yet discovered. | 4155 | * yet discovered. |
@@ -4087,7 +4171,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, | |||
4087 | if (ret) | 4171 | if (ret) |
4088 | goto out; | 4172 | goto out; |
4089 | 4173 | ||
4090 | if (crtc->fb->pixel_format != fb->pixel_format) { | 4174 | if (crtc->primary->fb->pixel_format != fb->pixel_format) { |
4091 | DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); | 4175 | DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); |
4092 | ret = -EINVAL; | 4176 | ret = -EINVAL; |
4093 | goto out; | 4177 | goto out; |
@@ -4120,7 +4204,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, | |||
4120 | (void (*) (struct drm_pending_event *)) kfree; | 4204 | (void (*) (struct drm_pending_event *)) kfree; |
4121 | } | 4205 | } |
4122 | 4206 | ||
4123 | old_fb = crtc->fb; | 4207 | old_fb = crtc->primary->fb; |
4124 | ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags); | 4208 | ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags); |
4125 | if (ret) { | 4209 | if (ret) { |
4126 | if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { | 4210 | if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { |
@@ -4138,7 +4222,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, | |||
4138 | * Failing to do so will screw with the reference counting | 4222 | * Failing to do so will screw with the reference counting |
4139 | * on framebuffers. | 4223 | * on framebuffers. |
4140 | */ | 4224 | */ |
4141 | WARN_ON(crtc->fb != fb); | 4225 | WARN_ON(crtc->primary->fb != fb); |
4142 | /* Unref only the old framebuffer. */ | 4226 | /* Unref only the old framebuffer. */ |
4143 | fb = NULL; | 4227 | fb = NULL; |
4144 | } | 4228 | } |
@@ -4527,6 +4611,7 @@ void drm_mode_config_init(struct drm_device *dev) | |||
4527 | 4611 | ||
4528 | drm_modeset_lock_all(dev); | 4612 | drm_modeset_lock_all(dev); |
4529 | drm_mode_create_standard_connector_properties(dev); | 4613 | drm_mode_create_standard_connector_properties(dev); |
4614 | drm_mode_create_standard_plane_properties(dev); | ||
4530 | drm_modeset_unlock_all(dev); | 4615 | drm_modeset_unlock_all(dev); |
4531 | 4616 | ||
4532 | /* Just to be sure */ | 4617 | /* Just to be sure */ |
@@ -4534,6 +4619,8 @@ void drm_mode_config_init(struct drm_device *dev) | |||
4534 | dev->mode_config.num_connector = 0; | 4619 | dev->mode_config.num_connector = 0; |
4535 | dev->mode_config.num_crtc = 0; | 4620 | dev->mode_config.num_crtc = 0; |
4536 | dev->mode_config.num_encoder = 0; | 4621 | dev->mode_config.num_encoder = 0; |
4622 | dev->mode_config.num_overlay_plane = 0; | ||
4623 | dev->mode_config.num_total_plane = 0; | ||
4537 | } | 4624 | } |
4538 | EXPORT_SYMBOL(drm_mode_config_init); | 4625 | EXPORT_SYMBOL(drm_mode_config_init); |
4539 | 4626 | ||