|
@@ -121,6 +121,13 @@ static const struct drm_prop_enum_list drm_dpms_enum_list[] =
|
|
|
|
|
|
DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
|
|
DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
|
|
|
|
|
|
|
|
+static const struct drm_prop_enum_list drm_plane_type_enum_list[] =
|
|
|
|
+{
|
|
|
|
+ { DRM_PLANE_TYPE_OVERLAY, "Overlay" },
|
|
|
|
+ { DRM_PLANE_TYPE_PRIMARY, "Primary" },
|
|
|
|
+ { DRM_PLANE_TYPE_CURSOR, "Cursor" },
|
|
|
|
+};
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Optional properties
|
|
* Optional properties
|
|
*/
|
|
*/
|
|
@@ -662,7 +669,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
|
|
drm_modeset_lock_all(dev);
|
|
drm_modeset_lock_all(dev);
|
|
/* remove from any CRTC */
|
|
/* remove from any CRTC */
|
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
|
- if (crtc->fb == fb) {
|
|
|
|
|
|
+ if (crtc->primary->fb == fb) {
|
|
/* should turn off the crtc */
|
|
/* should turn off the crtc */
|
|
memset(&set, 0, sizeof(struct drm_mode_set));
|
|
memset(&set, 0, sizeof(struct drm_mode_set));
|
|
set.crtc = crtc;
|
|
set.crtc = crtc;
|
|
@@ -685,9 +692,12 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
|
|
EXPORT_SYMBOL(drm_framebuffer_remove);
|
|
EXPORT_SYMBOL(drm_framebuffer_remove);
|
|
|
|
|
|
/**
|
|
/**
|
|
- * drm_crtc_init - Initialise a new CRTC object
|
|
|
|
|
|
+ * drm_crtc_init_with_planes - Initialise a new CRTC object with
|
|
|
|
+ * specified primary and cursor planes.
|
|
* @dev: DRM device
|
|
* @dev: DRM device
|
|
* @crtc: CRTC object to init
|
|
* @crtc: CRTC object to init
|
|
|
|
+ * @primary: Primary plane for CRTC
|
|
|
|
+ * @cursor: Cursor plane for CRTC
|
|
* @funcs: callbacks for the new CRTC
|
|
* @funcs: callbacks for the new CRTC
|
|
*
|
|
*
|
|
* Inits a new object created as base part of a driver crtc object.
|
|
* Inits a new object created as base part of a driver crtc object.
|
|
@@ -695,8 +705,10 @@ EXPORT_SYMBOL(drm_framebuffer_remove);
|
|
* Returns:
|
|
* Returns:
|
|
* Zero on success, error code on failure.
|
|
* Zero on success, error code on failure.
|
|
*/
|
|
*/
|
|
-int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
|
|
|
|
- const struct drm_crtc_funcs *funcs)
|
|
|
|
|
|
+int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
|
|
|
|
+ struct drm_plane *primary,
|
|
|
|
+ void *cursor,
|
|
|
|
+ const struct drm_crtc_funcs *funcs)
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
@@ -717,12 +729,16 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
|
|
list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
|
|
list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
|
|
dev->mode_config.num_crtc++;
|
|
dev->mode_config.num_crtc++;
|
|
|
|
|
|
|
|
+ crtc->primary = primary;
|
|
|
|
+ if (primary)
|
|
|
|
+ primary->possible_crtcs = 1 << drm_crtc_index(crtc);
|
|
|
|
+
|
|
out:
|
|
out:
|
|
drm_modeset_unlock_all(dev);
|
|
drm_modeset_unlock_all(dev);
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL(drm_crtc_init);
|
|
|
|
|
|
+EXPORT_SYMBOL(drm_crtc_init_with_planes);
|
|
|
|
|
|
/**
|
|
/**
|
|
* drm_crtc_cleanup - Clean up the core crtc usage
|
|
* drm_crtc_cleanup - Clean up the core crtc usage
|
|
@@ -1000,26 +1016,25 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
|
|
EXPORT_SYMBOL(drm_encoder_cleanup);
|
|
EXPORT_SYMBOL(drm_encoder_cleanup);
|
|
|
|
|
|
/**
|
|
/**
|
|
- * drm_plane_init - Initialise a new plane object
|
|
|
|
|
|
+ * drm_universal_plane_init - Initialize a new universal plane object
|
|
* @dev: DRM device
|
|
* @dev: DRM device
|
|
* @plane: plane object to init
|
|
* @plane: plane object to init
|
|
* @possible_crtcs: bitmask of possible CRTCs
|
|
* @possible_crtcs: bitmask of possible CRTCs
|
|
* @funcs: callbacks for the new plane
|
|
* @funcs: callbacks for the new plane
|
|
* @formats: array of supported formats (%DRM_FORMAT_*)
|
|
* @formats: array of supported formats (%DRM_FORMAT_*)
|
|
* @format_count: number of elements in @formats
|
|
* @format_count: number of elements in @formats
|
|
- * @priv: plane is private (hidden from userspace)?
|
|
|
|
|
|
+ * @type: type of plane (overlay, primary, cursor)
|
|
*
|
|
*
|
|
- * Inits a preallocate plane object created as base part of a driver plane
|
|
|
|
- * object.
|
|
|
|
|
|
+ * Initializes a plane object of type @type.
|
|
*
|
|
*
|
|
* Returns:
|
|
* Returns:
|
|
* Zero on success, error code on failure.
|
|
* Zero on success, error code on failure.
|
|
*/
|
|
*/
|
|
-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,
|
|
|
|
- bool priv)
|
|
|
|
|
|
+int drm_universal_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,
|
|
|
|
+ enum drm_plane_type type)
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
@@ -1044,23 +1059,53 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
|
|
memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
|
|
memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
|
|
plane->format_count = format_count;
|
|
plane->format_count = format_count;
|
|
plane->possible_crtcs = possible_crtcs;
|
|
plane->possible_crtcs = possible_crtcs;
|
|
|
|
+ plane->type = type;
|
|
|
|
|
|
- /* 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);
|
|
|
|
- }
|
|
|
|
|
|
+ list_add_tail(&plane->head, &dev->mode_config.plane_list);
|
|
|
|
+ dev->mode_config.num_total_plane++;
|
|
|
|
+ if (plane->type == DRM_PLANE_TYPE_OVERLAY)
|
|
|
|
+ dev->mode_config.num_overlay_plane++;
|
|
|
|
+
|
|
|
|
+ drm_object_attach_property(&plane->base,
|
|
|
|
+ dev->mode_config.plane_type_property,
|
|
|
|
+ plane->type);
|
|
|
|
|
|
out:
|
|
out:
|
|
drm_modeset_unlock_all(dev);
|
|
drm_modeset_unlock_all(dev);
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
+EXPORT_SYMBOL(drm_universal_plane_init);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * drm_plane_init - Initialize a legacy plane
|
|
|
|
+ * @dev: DRM device
|
|
|
|
+ * @plane: plane object to init
|
|
|
|
+ * @possible_crtcs: bitmask of possible CRTCs
|
|
|
|
+ * @funcs: callbacks for the new plane
|
|
|
|
+ * @formats: array of supported formats (%DRM_FORMAT_*)
|
|
|
|
+ * @format_count: number of elements in @formats
|
|
|
|
+ * @is_primary: plane type (primary vs overlay)
|
|
|
|
+ *
|
|
|
|
+ * Legacy API to initialize a DRM plane.
|
|
|
|
+ *
|
|
|
|
+ * New drivers should call drm_universal_plane_init() instead.
|
|
|
|
+ *
|
|
|
|
+ * Returns:
|
|
|
|
+ * Zero on success, error code on failure.
|
|
|
|
+ */
|
|
|
|
+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,
|
|
|
|
+ bool is_primary)
|
|
|
|
+{
|
|
|
|
+ enum drm_plane_type type;
|
|
|
|
+
|
|
|
|
+ type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
|
|
|
|
+ return drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
|
|
|
|
+ formats, format_count, type);
|
|
|
|
+}
|
|
EXPORT_SYMBOL(drm_plane_init);
|
|
EXPORT_SYMBOL(drm_plane_init);
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1078,11 +1123,13 @@ void drm_plane_cleanup(struct drm_plane *plane)
|
|
drm_modeset_lock_all(dev);
|
|
drm_modeset_lock_all(dev);
|
|
kfree(plane->format_types);
|
|
kfree(plane->format_types);
|
|
drm_mode_object_put(dev, &plane->base);
|
|
drm_mode_object_put(dev, &plane->base);
|
|
- /* 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--;
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ BUG_ON(list_empty(&plane->head));
|
|
|
|
+
|
|
|
|
+ list_del(&plane->head);
|
|
|
|
+ dev->mode_config.num_total_plane--;
|
|
|
|
+ if (plane->type == DRM_PLANE_TYPE_OVERLAY)
|
|
|
|
+ dev->mode_config.num_overlay_plane--;
|
|
drm_modeset_unlock_all(dev);
|
|
drm_modeset_unlock_all(dev);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(drm_plane_cleanup);
|
|
EXPORT_SYMBOL(drm_plane_cleanup);
|
|
@@ -1134,6 +1181,21 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int drm_mode_create_standard_plane_properties(struct drm_device *dev)
|
|
|
|
+{
|
|
|
|
+ struct drm_property *type;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Standard properties (apply to all planes)
|
|
|
|
+ */
|
|
|
|
+ type = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
|
|
|
|
+ "type", drm_plane_type_enum_list,
|
|
|
|
+ ARRAY_SIZE(drm_plane_type_enum_list));
|
|
|
|
+ dev->mode_config.plane_type_property = type;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
|
|
* drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
|
|
* @dev: DRM device
|
|
* @dev: DRM device
|
|
@@ -1652,8 +1714,8 @@ int drm_mode_getcrtc(struct drm_device *dev,
|
|
crtc_resp->x = crtc->x;
|
|
crtc_resp->x = crtc->x;
|
|
crtc_resp->y = crtc->y;
|
|
crtc_resp->y = crtc->y;
|
|
crtc_resp->gamma_size = crtc->gamma_size;
|
|
crtc_resp->gamma_size = crtc->gamma_size;
|
|
- if (crtc->fb)
|
|
|
|
- crtc_resp->fb_id = crtc->fb->base.id;
|
|
|
|
|
|
+ if (crtc->primary->fb)
|
|
|
|
+ crtc_resp->fb_id = crtc->primary->fb->base.id;
|
|
else
|
|
else
|
|
crtc_resp->fb_id = 0;
|
|
crtc_resp->fb_id = 0;
|
|
|
|
|
|
@@ -1897,6 +1959,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
|
|
struct drm_plane *plane;
|
|
struct drm_plane *plane;
|
|
uint32_t __user *plane_ptr;
|
|
uint32_t __user *plane_ptr;
|
|
int copied = 0, ret = 0;
|
|
int copied = 0, ret = 0;
|
|
|
|
+ unsigned num_planes;
|
|
|
|
|
|
if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
|
if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
@@ -1904,15 +1967,28 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
|
|
drm_modeset_lock_all(dev);
|
|
drm_modeset_lock_all(dev);
|
|
config = &dev->mode_config;
|
|
config = &dev->mode_config;
|
|
|
|
|
|
|
|
+ if (file_priv->universal_planes)
|
|
|
|
+ num_planes = config->num_total_plane;
|
|
|
|
+ else
|
|
|
|
+ num_planes = config->num_overlay_plane;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* This ioctl is called twice, once to determine how much space is
|
|
* This ioctl is called twice, once to determine how much space is
|
|
* needed, and the 2nd time to fill it.
|
|
* needed, and the 2nd time to fill it.
|
|
*/
|
|
*/
|
|
- if (config->num_plane &&
|
|
|
|
- (plane_resp->count_planes >= config->num_plane)) {
|
|
|
|
|
|
+ if (num_planes &&
|
|
|
|
+ (plane_resp->count_planes >= num_planes)) {
|
|
plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;
|
|
plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;
|
|
|
|
|
|
list_for_each_entry(plane, &config->plane_list, head) {
|
|
list_for_each_entry(plane, &config->plane_list, head) {
|
|
|
|
+ /*
|
|
|
|
+ * Unless userspace set the 'universal planes'
|
|
|
|
+ * capability bit, only advertise overlays.
|
|
|
|
+ */
|
|
|
|
+ if (plane->type != DRM_PLANE_TYPE_OVERLAY &&
|
|
|
|
+ !file_priv->universal_planes)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
if (put_user(plane->base.id, plane_ptr + copied)) {
|
|
if (put_user(plane->base.id, plane_ptr + copied)) {
|
|
ret = -EFAULT;
|
|
ret = -EFAULT;
|
|
goto out;
|
|
goto out;
|
|
@@ -1920,7 +1996,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
|
|
copied++;
|
|
copied++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- plane_resp->count_planes = config->num_plane;
|
|
|
|
|
|
+ plane_resp->count_planes = num_planes;
|
|
|
|
|
|
out:
|
|
out:
|
|
drm_modeset_unlock_all(dev);
|
|
drm_modeset_unlock_all(dev);
|
|
@@ -2156,19 +2232,21 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
|
|
* crtcs. Atomic modeset will have saner semantics ...
|
|
* crtcs. Atomic modeset will have saner semantics ...
|
|
*/
|
|
*/
|
|
list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head)
|
|
list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head)
|
|
- tmp->old_fb = tmp->fb;
|
|
|
|
|
|
+ tmp->old_fb = tmp->primary->fb;
|
|
|
|
|
|
fb = set->fb;
|
|
fb = set->fb;
|
|
|
|
|
|
ret = crtc->funcs->set_config(set);
|
|
ret = crtc->funcs->set_config(set);
|
|
if (ret == 0) {
|
|
if (ret == 0) {
|
|
|
|
+ crtc->primary->crtc = crtc;
|
|
|
|
+
|
|
/* crtc->fb must be updated by ->set_config, enforces this. */
|
|
/* crtc->fb must be updated by ->set_config, enforces this. */
|
|
- WARN_ON(fb != crtc->fb);
|
|
|
|
|
|
+ WARN_ON(fb != crtc->primary->fb);
|
|
}
|
|
}
|
|
|
|
|
|
list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) {
|
|
list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) {
|
|
- if (tmp->fb)
|
|
|
|
- drm_framebuffer_reference(tmp->fb);
|
|
|
|
|
|
+ if (tmp->primary->fb)
|
|
|
|
+ drm_framebuffer_reference(tmp->primary->fb);
|
|
if (tmp->old_fb)
|
|
if (tmp->old_fb)
|
|
drm_framebuffer_unreference(tmp->old_fb);
|
|
drm_framebuffer_unreference(tmp->old_fb);
|
|
}
|
|
}
|
|
@@ -2177,14 +2255,19 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(drm_mode_set_config_internal);
|
|
EXPORT_SYMBOL(drm_mode_set_config_internal);
|
|
|
|
|
|
-/*
|
|
|
|
- * Checks that the framebuffer is big enough for the CRTC viewport
|
|
|
|
- * (x, y, hdisplay, vdisplay)
|
|
|
|
|
|
+/**
|
|
|
|
+ * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
|
|
|
|
+ * CRTC viewport
|
|
|
|
+ * @crtc: CRTC that framebuffer will be displayed on
|
|
|
|
+ * @x: x panning
|
|
|
|
+ * @y: y panning
|
|
|
|
+ * @mode: mode that framebuffer will be displayed under
|
|
|
|
+ * @fb: framebuffer to check size of
|
|
*/
|
|
*/
|
|
-static int drm_crtc_check_viewport(const struct drm_crtc *crtc,
|
|
|
|
- int x, int y,
|
|
|
|
- const struct drm_display_mode *mode,
|
|
|
|
- const struct drm_framebuffer *fb)
|
|
|
|
|
|
+int drm_crtc_check_viewport(const struct drm_crtc *crtc,
|
|
|
|
+ int x, int y,
|
|
|
|
+ const struct drm_display_mode *mode,
|
|
|
|
+ const struct drm_framebuffer *fb)
|
|
|
|
|
|
{
|
|
{
|
|
int hdisplay, vdisplay;
|
|
int hdisplay, vdisplay;
|
|
@@ -2215,6 +2298,7 @@ static int drm_crtc_check_viewport(const struct drm_crtc *crtc,
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
+EXPORT_SYMBOL(drm_crtc_check_viewport);
|
|
|
|
|
|
/**
|
|
/**
|
|
* drm_mode_setcrtc - set CRTC configuration
|
|
* drm_mode_setcrtc - set CRTC configuration
|
|
@@ -2266,12 +2350,12 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
|
|
/* If we have a mode we need a framebuffer. */
|
|
/* If we have a mode we need a framebuffer. */
|
|
/* If we pass -1, set the mode with the currently bound fb */
|
|
/* If we pass -1, set the mode with the currently bound fb */
|
|
if (crtc_req->fb_id == -1) {
|
|
if (crtc_req->fb_id == -1) {
|
|
- if (!crtc->fb) {
|
|
|
|
|
|
+ if (!crtc->primary->fb) {
|
|
DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
|
|
DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
|
|
ret = -EINVAL;
|
|
ret = -EINVAL;
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
- fb = crtc->fb;
|
|
|
|
|
|
+ fb = crtc->primary->fb;
|
|
/* Make refcounting symmetric with the lookup path. */
|
|
/* Make refcounting symmetric with the lookup path. */
|
|
drm_framebuffer_reference(fb);
|
|
drm_framebuffer_reference(fb);
|
|
} else {
|
|
} else {
|
|
@@ -4065,7 +4149,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
|
|
crtc = obj_to_crtc(obj);
|
|
crtc = obj_to_crtc(obj);
|
|
|
|
|
|
mutex_lock(&crtc->mutex);
|
|
mutex_lock(&crtc->mutex);
|
|
- if (crtc->fb == NULL) {
|
|
|
|
|
|
+ if (crtc->primary->fb == NULL) {
|
|
/* The framebuffer is currently unbound, presumably
|
|
/* The framebuffer is currently unbound, presumably
|
|
* due to a hotplug event, that userspace has not
|
|
* due to a hotplug event, that userspace has not
|
|
* yet discovered.
|
|
* yet discovered.
|
|
@@ -4087,7 +4171,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
|
|
if (ret)
|
|
if (ret)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
- if (crtc->fb->pixel_format != fb->pixel_format) {
|
|
|
|
|
|
+ if (crtc->primary->fb->pixel_format != fb->pixel_format) {
|
|
DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
|
|
DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
|
|
ret = -EINVAL;
|
|
ret = -EINVAL;
|
|
goto out;
|
|
goto out;
|
|
@@ -4120,7 +4204,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
|
|
(void (*) (struct drm_pending_event *)) kfree;
|
|
(void (*) (struct drm_pending_event *)) kfree;
|
|
}
|
|
}
|
|
|
|
|
|
- old_fb = crtc->fb;
|
|
|
|
|
|
+ old_fb = crtc->primary->fb;
|
|
ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags);
|
|
ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags);
|
|
if (ret) {
|
|
if (ret) {
|
|
if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
|
|
if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
|
|
@@ -4138,7 +4222,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
|
|
* Failing to do so will screw with the reference counting
|
|
* Failing to do so will screw with the reference counting
|
|
* on framebuffers.
|
|
* on framebuffers.
|
|
*/
|
|
*/
|
|
- WARN_ON(crtc->fb != fb);
|
|
|
|
|
|
+ WARN_ON(crtc->primary->fb != fb);
|
|
/* Unref only the old framebuffer. */
|
|
/* Unref only the old framebuffer. */
|
|
fb = NULL;
|
|
fb = NULL;
|
|
}
|
|
}
|
|
@@ -4527,6 +4611,7 @@ void drm_mode_config_init(struct drm_device *dev)
|
|
|
|
|
|
drm_modeset_lock_all(dev);
|
|
drm_modeset_lock_all(dev);
|
|
drm_mode_create_standard_connector_properties(dev);
|
|
drm_mode_create_standard_connector_properties(dev);
|
|
|
|
+ drm_mode_create_standard_plane_properties(dev);
|
|
drm_modeset_unlock_all(dev);
|
|
drm_modeset_unlock_all(dev);
|
|
|
|
|
|
/* Just to be sure */
|
|
/* Just to be sure */
|
|
@@ -4534,6 +4619,8 @@ void drm_mode_config_init(struct drm_device *dev)
|
|
dev->mode_config.num_connector = 0;
|
|
dev->mode_config.num_connector = 0;
|
|
dev->mode_config.num_crtc = 0;
|
|
dev->mode_config.num_crtc = 0;
|
|
dev->mode_config.num_encoder = 0;
|
|
dev->mode_config.num_encoder = 0;
|
|
|
|
+ dev->mode_config.num_overlay_plane = 0;
|
|
|
|
+ dev->mode_config.num_total_plane = 0;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(drm_mode_config_init);
|
|
EXPORT_SYMBOL(drm_mode_config_init);
|
|
|
|
|