The 'atomic' mechanism allows for multiple properties to be updated, checked, and commited atomically. This will be the basis of atomic- modeset and nuclear-pageflip. The basic flow is: state = dev->atomic_begin(); for (... one or more ...) obj->set_property(obj, state, prop, value); if (dev->atomic_check(state)) dev->atomic_commit(state); dev->atomic_end(state); The split of check and commit steps is to allow for ioctls with a test-only flag (which would skip the commit step). Signed-off-by: Rob Clark <robdclark@xxxxxxxxx> --- drivers/gpu/drm/Makefile | 3 +- drivers/gpu/drm/armada/armada_crtc.c | 4 +- drivers/gpu/drm/armada/armada_output.c | 3 +- drivers/gpu/drm/armada/armada_overlay.c | 4 +- drivers/gpu/drm/ast/ast_drv.c | 6 ++ drivers/gpu/drm/ast/ast_drv.h | 1 + drivers/gpu/drm/cirrus/cirrus_drv.c | 6 ++ drivers/gpu/drm/cirrus/cirrus_drv.h | 1 + drivers/gpu/drm/drm_atomic.c | 135 ++++++++++++++++++++++++++ drivers/gpu/drm/drm_crtc.c | 141 +++++++++++++++++----------- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 4 +- drivers/gpu/drm/exynos/exynos_drm_drv.c | 7 ++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 4 +- drivers/gpu/drm/gma500/cdv_intel_crt.c | 4 +- drivers/gpu/drm/gma500/cdv_intel_dp.c | 4 +- drivers/gpu/drm/gma500/cdv_intel_hdmi.c | 4 +- drivers/gpu/drm/gma500/cdv_intel_lvds.c | 4 +- drivers/gpu/drm/gma500/mdfld_dsi_output.c | 4 +- drivers/gpu/drm/gma500/psb_drv.c | 7 ++ drivers/gpu/drm/gma500/psb_drv.h | 1 + drivers/gpu/drm/gma500/psb_intel_drv.h | 4 +- drivers/gpu/drm/gma500/psb_intel_lvds.c | 4 +- drivers/gpu/drm/gma500/psb_intel_sdvo.c | 4 +- drivers/gpu/drm/i915/i915_drv.c | 8 ++ drivers/gpu/drm/i915/intel_crt.c | 4 +- drivers/gpu/drm/i915/intel_dp.c | 4 +- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_hdmi.c | 4 +- drivers/gpu/drm/i915/intel_lvds.c | 4 +- drivers/gpu/drm/i915/intel_sdvo.c | 4 +- drivers/gpu/drm/i915/intel_tv.c | 5 +- drivers/gpu/drm/mgag200/mgag200_drv.c | 7 ++ drivers/gpu/drm/mgag200/mgag200_drv.h | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | 4 +- drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 4 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 4 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 4 +- drivers/gpu/drm/msm/msm_drv.c | 6 ++ drivers/gpu/drm/msm/msm_drv.h | 1 + drivers/gpu/drm/nouveau/dispnv04/overlay.c | 6 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 3 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 7 ++ drivers/gpu/drm/nouveau/nouveau_drm.h | 1 + drivers/gpu/drm/omapdrm/omap_crtc.c | 7 +- drivers/gpu/drm/omapdrm/omap_drv.c | 6 ++ drivers/gpu/drm/omapdrm/omap_drv.h | 5 +- drivers/gpu/drm/omapdrm/omap_plane.c | 4 +- drivers/gpu/drm/qxl/qxl_display.c | 4 +- drivers/gpu/drm/qxl/qxl_drv.c | 9 ++ drivers/gpu/drm/radeon/radeon_connectors.c | 9 +- drivers/gpu/drm/radeon/radeon_drv.c | 9 ++ drivers/gpu/drm/rcar-du/rcar_du_drv.c | 7 ++ drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +- drivers/gpu/drm/shmobile/shmob_drm_drv.c | 7 ++ drivers/gpu/drm/tilcdc/tilcdc_drv.c | 6 ++ drivers/gpu/drm/tilcdc/tilcdc_drv.h | 1 + drivers/gpu/drm/tilcdc/tilcdc_slave.c | 3 +- drivers/gpu/drm/udl/udl_connector.c | 6 +- drivers/gpu/drm/udl/udl_drv.c | 8 ++ drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 7 ++ drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 1 + drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 4 +- include/drm/drmP.h | 77 +++++++++++++++ include/drm/drm_atomic.h | 100 ++++++++++++++++++++ include/drm/drm_crtc.h | 14 +-- 66 files changed, 630 insertions(+), 113 deletions(-) create mode 100644 drivers/gpu/drm/drm_atomic.c create mode 100644 include/drm/drm_atomic.h diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 292a79d..8b75c6e 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -13,7 +13,8 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ drm_crtc.o drm_modes.o drm_edid.o \ drm_info.o drm_debugfs.o drm_encoder_slave.o \ drm_trace_points.o drm_global.o drm_prime.o \ - drm_rect.o drm_vma_manager.o drm_flip_work.o + drm_rect.o drm_vma_manager.o drm_flip_work.o \ + drm_atomic.o drm-$(CONFIG_COMPAT) += drm_ioc32.o drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 0a14d24..8276739 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -958,8 +958,8 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc, } static int -armada_drm_crtc_set_property(struct drm_crtc *crtc, - struct drm_property *property, uint64_t val) +armada_drm_crtc_set_property(struct drm_crtc *crtc, void *state, + struct drm_property *property, uint64_t val, void *blob_data) { struct armada_private *priv = crtc->dev->dev_private; struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); diff --git a/drivers/gpu/drm/armada/armada_output.c b/drivers/gpu/drm/armada/armada_output.c index d685a54..aa3e788 100644 --- a/drivers/gpu/drm/armada/armada_output.c +++ b/drivers/gpu/drm/armada/armada_output.c @@ -54,7 +54,8 @@ static void armada_drm_connector_destroy(struct drm_connector *conn) } static int armada_drm_connector_set_property(struct drm_connector *conn, - struct drm_property *property, uint64_t value) + void *state, struct drm_property *property, uint64_t value, + void *blob_data) { struct armada_connector *dconn = drm_to_armada_conn(conn); diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index ef68c42..04ac427 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c @@ -282,8 +282,8 @@ static void armada_plane_destroy(struct drm_plane *plane) kfree(plane); } -static int armada_plane_set_property(struct drm_plane *plane, - struct drm_property *property, uint64_t val) +static int armada_plane_set_property(struct drm_plane *plane, void *state, + struct drm_property *property, uint64_t val, void *blob_data) { struct armada_private *priv = plane->dev->dev_private; struct armada_plane *dplane = drm_to_armada_plane(plane); diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 5137f15..68335ea 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -216,6 +216,12 @@ static struct drm_driver driver = { .dumb_map_offset = ast_dumb_mmap_offset, .dumb_destroy = drm_gem_dumb_destroy, + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, }; static int __init ast_init(void) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 9833a1b..c3b2567 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -29,6 +29,7 @@ #define __AST_DRV_H__ #include <drm/drm_fb_helper.h> +#include <drm/drm_atomic.h> #include <drm/ttm/ttm_bo_api.h> #include <drm/ttm/ttm_bo_driver.h> diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index 953fc8a..e219ab6 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c @@ -101,6 +101,12 @@ static struct drm_driver driver = { .dumb_create = cirrus_dumb_create, .dumb_map_offset = cirrus_dumb_mmap_offset, .dumb_destroy = drm_gem_dumb_destroy, + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, }; static struct pci_driver cirrus_pci_driver = { diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h index 117d3ec..f929bc8 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.h +++ b/drivers/gpu/drm/cirrus/cirrus_drv.h @@ -14,6 +14,7 @@ #include <video/vga.h> #include <drm/drm_fb_helper.h> +#include <drm/drm_atomic.h> #include <drm/ttm/ttm_bo_api.h> #include <drm/ttm/ttm_bo_driver.h> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c new file mode 100644 index 0000000..c3e267a --- /dev/null +++ b/drivers/gpu/drm/drm_atomic.c @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2013 Red Hat + * Author: Rob Clark <robdclark@xxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <drm/drmP.h> +#include <drm/drm_atomic.h> + +/** + * drm_atomic_begin - start a sequence of atomic updates + * @dev: DRM device + * @flags: the modifier flags that userspace has requested + * + * Begin a sequence of atomic property sets. Returns a driver + * private state object that is passed back into the various + * object's set_property() fxns, and into the remainder of the + * atomic funcs. The state object should accumulate the changes + * from one o more set_property()'s. At the end, the state can + * be checked, and optionally committed. + * + * RETURNS + * a driver private state object, which is passed back in to + * the various other atomic fxns, or error (such as -EBUSY if + * there is still a pending async update) + */ +void *drm_atomic_begin(struct drm_device *dev, uint32_t flags) +{ + struct drm_atomic_state *state; + int sz; + void *ptr; + + sz = sizeof(*state); + + ptr = kzalloc(sz, GFP_KERNEL); + + state = ptr; + ptr = &state[1]; + + kref_init(&state->refcount); + state->dev = dev; + state->flags = flags; + return state; +} +EXPORT_SYMBOL(drm_atomic_begin); + +/** + * drm_atomic_set_event - set a pending event on mode object + * @dev: DRM device + * @state: the driver private state object + * @obj: the object to set the event on + * @event: the event to send back + * + * Set pending event for an update on the specified object. The + * event is to be sent back to userspace after the update completes. + */ +int drm_atomic_set_event(struct drm_device *dev, + void *state, struct drm_mode_object *obj, + struct drm_pending_vblank_event *event) +{ + return -EINVAL; /* for now */ +} +EXPORT_SYMBOL(drm_atomic_set_event); + +/** + * drm_atomic_check - validate state object + * @dev: DRM device + * @state: the driver private state object + * + * Check the state object to see if the requested state is + * physically possible. + * + * RETURNS + * Zero for success or -errno + */ +int drm_atomic_check(struct drm_device *dev, void *state) +{ + return 0; /* for now */ +} +EXPORT_SYMBOL(drm_atomic_check); + +/** + * drm_atomic_commit - commit state + * @dev: DRM device + * @state: the driver private state object + * + * Commit the state. This will only be called if atomic_check() + * succeeds. + * + * RETURNS + * Zero for success or -errno + */ +int drm_atomic_commit(struct drm_device *dev, void *state) +{ + return 0; /* for now */ +} +EXPORT_SYMBOL(drm_atomic_commit); + +/** + * drm_atomic_end - conclude the atomic update + * @dev: DRM device + * @state: the driver private state object + * + * Release resources associated with the state object. + */ +void drm_atomic_end(struct drm_device *dev, void *state) +{ + drm_atomic_state_unreference(state); +} +EXPORT_SYMBOL(drm_atomic_end); + +void _drm_atomic_state_free(struct kref *kref) +{ + struct drm_atomic_state *state = + container_of(kref, struct drm_atomic_state, refcount); + kfree(state); +} +EXPORT_SYMBOL(_drm_atomic_state_free); + + +const struct drm_atomic_funcs drm_atomic_funcs = { +}; +EXPORT_SYMBOL(drm_atomic_funcs); diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 5504c4d..f96ca7f 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -3573,20 +3573,21 @@ int drm_mode_connector_property_set_ioctl(struct drm_device *dev, return drm_mode_obj_set_property_ioctl(dev, &obj_set_prop, file_priv); } -static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj, - struct drm_property *property, - uint64_t value) +static int drm_mode_connector_set_obj_prop(struct drm_connector *connector, + void *state, struct drm_property *property, + uint64_t value, void *blob_data) { int ret = -EINVAL; - struct drm_connector *connector = obj_to_connector(obj); /* Do DPMS ourselves */ if (property == connector->dev->mode_config.dpms_property) { if (connector->funcs->dpms) (*connector->funcs->dpms)(connector, (int)value); ret = 0; - } else if (connector->funcs->set_property) - ret = connector->funcs->set_property(connector, property, value); + } else if (connector->funcs->set_property) { + ret = connector->funcs->set_property(connector, state, + property, value, blob_data); + } /* store the property value if successful */ if (!ret) @@ -3594,36 +3595,90 @@ static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj, return ret; } -static int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj, - struct drm_property *property, - uint64_t value) +static int drm_mode_crtc_set_obj_prop(struct drm_crtc *crtc, + void *state, struct drm_property *property, + uint64_t value, void *blob_data) { int ret = -EINVAL; - struct drm_crtc *crtc = obj_to_crtc(obj); if (crtc->funcs->set_property) - ret = crtc->funcs->set_property(crtc, property, value); + ret = crtc->funcs->set_property(crtc, state, property, + value, blob_data); if (!ret) - drm_object_property_set_value(obj, property, value); + drm_object_property_set_value(&crtc->base, property, value); return ret; } -static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj, - struct drm_property *property, - uint64_t value) +static int drm_mode_plane_set_obj_prop(struct drm_plane *plane, + void *state, struct drm_property *property, + uint64_t value, void *blob_data) { int ret = -EINVAL; - struct drm_plane *plane = obj_to_plane(obj); if (plane->funcs->set_property) - ret = plane->funcs->set_property(plane, property, value); + ret = plane->funcs->set_property(plane, state, property, + value, blob_data); if (!ret) - drm_object_property_set_value(obj, property, value); + drm_object_property_set_value(&plane->base, property, value); return ret; } +static int drm_mode_set_obj_prop(struct drm_device *dev, + struct drm_mode_object *obj, void *state, + struct drm_property *property, uint64_t value, void *blob_data) +{ + if (drm_property_change_is_valid(property, value)) { + switch (obj->type) { + case DRM_MODE_OBJECT_CONNECTOR: + return drm_mode_connector_set_obj_prop(obj_to_connector(obj), + state, property, value, blob_data); + case DRM_MODE_OBJECT_CRTC: + return drm_mode_crtc_set_obj_prop(obj_to_crtc(obj), + state, property, value, blob_data); + case DRM_MODE_OBJECT_PLANE: + return drm_mode_plane_set_obj_prop(obj_to_plane(obj), + state, property, value, blob_data); + } + } + + return -EINVAL; +} + +/* call with mode_config mutex held */ +static int drm_mode_set_obj_prop_id(struct drm_device *dev, void *state, + uint32_t obj_id, uint32_t obj_type, + uint32_t prop_id, uint64_t value, void *blob_data) +{ + struct drm_mode_object *arg_obj; + struct drm_mode_object *prop_obj; + struct drm_property *property; + int i; + + arg_obj = drm_mode_object_find(dev, obj_id, obj_type); + if (!arg_obj) + return -ENOENT; + if (!arg_obj->properties) + return -EINVAL; + + for (i = 0; i < arg_obj->properties->count; i++) + if (arg_obj->properties->ids[i] == prop_id) + break; + + if (i == arg_obj->properties->count) + return -EINVAL; + + prop_obj = drm_mode_object_find(dev, prop_id, + DRM_MODE_OBJECT_PROPERTY); + if (!prop_obj) + return -ENOENT; + property = obj_to_property(prop_obj); + + return drm_mode_set_obj_prop(dev, arg_obj, state, property, + value, blob_data); +} + int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -3684,57 +3739,35 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_mode_obj_set_property *arg = data; - struct drm_mode_object *arg_obj; - struct drm_mode_object *prop_obj; - struct drm_property *property; + void *state; int ret = -EINVAL; - int i; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; drm_modeset_lock_all(dev); - arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type); - if (!arg_obj) { - ret = -ENOENT; - goto out; + state = dev->driver->atomic_begin(dev, 0); + if (IS_ERR(state)) { + ret = PTR_ERR(state); + goto out_unlock; } - if (!arg_obj->properties) - goto out; - - for (i = 0; i < arg_obj->properties->count; i++) - if (arg_obj->properties->ids[i] == arg->prop_id) - break; - if (i == arg_obj->properties->count) + ret = drm_mode_set_obj_prop_id(dev, state, + arg->obj_id, arg->obj_type, + arg->prop_id, arg->value, NULL); + if (ret) goto out; - prop_obj = drm_mode_object_find(dev, arg->prop_id, - DRM_MODE_OBJECT_PROPERTY); - if (!prop_obj) { - ret = -ENOENT; - goto out; - } - property = obj_to_property(prop_obj); - - if (!drm_property_change_is_valid(property, arg->value)) + ret = dev->driver->atomic_check(dev, state); + if (ret) goto out; - switch (arg_obj->type) { - case DRM_MODE_OBJECT_CONNECTOR: - ret = drm_mode_connector_set_obj_prop(arg_obj, property, - arg->value); - break; - case DRM_MODE_OBJECT_CRTC: - ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value); - break; - case DRM_MODE_OBJECT_PLANE: - ret = drm_mode_plane_set_obj_prop(arg_obj, property, arg->value); - break; - } + ret = dev->driver->atomic_commit(dev, state); out: + dev->driver->atomic_end(dev, state); +out_unlock: drm_modeset_unlock_all(dev); return ret; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 507abd5..2b2777e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -254,8 +254,10 @@ static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) } static int exynos_drm_crtc_set_property(struct drm_crtc *crtc, + void *state, struct drm_property *property, - uint64_t val) + uint64_t val, + void *blob_data) { struct drm_device *dev = crtc->dev; struct exynos_drm_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 215131a..92ab3d0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -13,6 +13,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_atomic.h> #include <linux/anon_inodes.h> @@ -303,6 +304,12 @@ static struct drm_driver exynos_drm_driver = { .dumb_create = exynos_drm_gem_dumb_create, .dumb_map_offset = exynos_drm_gem_dumb_map_offset, .dumb_destroy = drm_gem_dumb_destroy, + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_export = exynos_dmabuf_prime_export, diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 7943dd3..9172fa9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -217,8 +217,10 @@ static void exynos_plane_destroy(struct drm_plane *plane) } static int exynos_plane_set_property(struct drm_plane *plane, + void *state, struct drm_property *property, - uint64_t val) + uint64_t val, + void *blob_data) { struct drm_device *dev = plane->dev; struct exynos_plane *exynos_plane = to_exynos_plane(plane); diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c index 661af49..d9c612f9 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_crt.c +++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c @@ -212,8 +212,10 @@ static int cdv_intel_crt_get_modes(struct drm_connector *connector) } static int cdv_intel_crt_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t value) + uint64_t value, + void *blob_data) { return 0; } diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c index 0490ce3..6e7c4da 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_dp.c +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c @@ -1645,8 +1645,10 @@ cdv_intel_dp_detect_audio(struct drm_connector *connector) static int cdv_intel_dp_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t val) + uint64_t val, + void *blob_data) { struct drm_psb_private *dev_priv = connector->dev->dev_private; struct gma_encoder *encoder = gma_attached_encoder(connector); diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c index 1c0d723..74e5de1 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c +++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c @@ -157,8 +157,10 @@ static enum drm_connector_status cdv_hdmi_detect( } static int cdv_hdmi_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t value) + uint64_t value, + void *blob_data) { struct drm_encoder *encoder = connector->encoder; diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c index 20e08e6..97d76c1 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c @@ -452,8 +452,10 @@ static void cdv_intel_lvds_destroy(struct drm_connector *connector) } static int cdv_intel_lvds_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t value) + uint64_t value, + void *blob_data) { struct drm_encoder *encoder = connector->encoder; diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c index 860a4ee..76dadee 100644 --- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c +++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c @@ -243,8 +243,10 @@ mdfld_dsi_connector_detect(struct drm_connector *connector, bool force) } static int mdfld_dsi_connector_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t value) + uint64_t value, + void *blob_data) { struct drm_encoder *encoder = connector->encoder; diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index 1199180..66db23b 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -676,6 +676,13 @@ static struct drm_driver driver = { .preclose = psb_driver_preclose, .postclose = psb_driver_close, + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, + .gem_free_object = psb_gem_free_object, .gem_vm_ops = &psb_gem_vm_ops, .dumb_create = psb_gem_dumb_create, diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 5ad6a03..540dc24 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -25,6 +25,7 @@ #include <drm/drmP.h> #include <drm/drm_global.h> #include <drm/gma_drm.h> +#include <drm/drm_atomic.h> #include "psb_reg.h" #include "psb_intel_drv.h" #include "gma_display.h" diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h index dc2c8eb..837c953 100644 --- a/drivers/gpu/drm/gma500/psb_intel_drv.h +++ b/drivers/gpu/drm/gma500/psb_intel_drv.h @@ -256,8 +256,10 @@ extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, extern int psb_intel_lvds_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode); extern int psb_intel_lvds_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t value); + uint64_t value, + void *blob_data); extern void psb_intel_lvds_destroy(struct drm_connector *connector); extern const struct drm_encoder_funcs psb_intel_lvds_enc_funcs; diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c index 32342f6..e3a3923 100644 --- a/drivers/gpu/drm/gma500/psb_intel_lvds.c +++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c @@ -569,8 +569,10 @@ void psb_intel_lvds_destroy(struct drm_connector *connector) } int psb_intel_lvds_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t value) + uint64_t value, + void *blob_data) { struct drm_encoder *encoder = connector->encoder; diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index 07d3a9e..5ff83dc 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c @@ -1705,8 +1705,10 @@ static bool psb_intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) static int psb_intel_sdvo_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t val) + uint64_t val, + void *blob_data) { struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2d05d7c..49fe576 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -951,6 +951,14 @@ static struct drm_driver driver = { .dumb_create = i915_gem_dumb_create, .dumb_map_offset = i915_gem_mmap_gtt, .dumb_destroy = drm_gem_dumb_destroy, + + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, + .ioctls = i915_ioctls, .fops = &i915_driver_fops, .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 9864aa1..b28c74f9 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -700,8 +700,10 @@ static int intel_crt_get_modes(struct drm_connector *connector) } static int intel_crt_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t value) + uint64_t value, + void *blob_data) { return 0; } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f47807b..b17078b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3308,8 +3308,10 @@ intel_dp_detect_audio(struct drm_connector *connector) static int intel_dp_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t val) + uint64_t val, + void *blob_data) { struct drm_i915_private *dev_priv = connector->dev->dev_private; struct intel_connector *intel_connector = to_intel_connector(connector); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a4ffc02..11c9d0f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -31,6 +31,7 @@ #include "i915_drv.h" #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_atomic.h> #include <drm/drm_fb_helper.h> #include <drm/drm_dp_helper.h> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 98d68ab..6644e3f 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -980,8 +980,10 @@ intel_hdmi_detect_audio(struct drm_connector *connector) static int intel_hdmi_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t val) + uint64_t val, + void *blob_data) { struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct intel_digital_port *intel_dig_port = diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index fecff3c..ce7d4fd 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -493,8 +493,10 @@ static void intel_lvds_destroy(struct drm_connector *connector) } static int intel_lvds_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t value) + uint64_t value, + void *blob_data) { struct intel_connector *intel_connector = to_intel_connector(connector); struct drm_device *dev = connector->dev; diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 825853d..876e350 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2052,8 +2052,10 @@ static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) static int intel_sdvo_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t val) + uint64_t val, + void *blob_data) { struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index b64fc1c..8cf519a 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1446,8 +1446,9 @@ intel_tv_destroy(struct drm_connector *connector) static int -intel_tv_set_property(struct drm_connector *connector, struct drm_property *property, - uint64_t val) +intel_tv_set_property(struct drm_connector *connector, void *state, + struct drm_property *property, + uint64_t val, void *blob_data) { struct drm_device *dev = connector->dev; struct intel_tv *intel_tv = intel_attached_tv(connector); diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index f15ea3c..0425bdd 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -103,6 +103,13 @@ static struct drm_driver driver = { .dumb_create = mgag200_dumb_create, .dumb_map_offset = mgag200_dumb_mmap_offset, .dumb_destroy = drm_gem_dumb_destroy, + + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, }; static struct pci_driver mgag200_pci_driver = { diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index cf11ee6..c4d1600 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -16,6 +16,7 @@ #include <video/vga.h> #include <drm/drm_fb_helper.h> +#include <drm/drm_atomic.h> #include <drm/ttm/ttm_bo_api.h> #include <drm/ttm/ttm_bo_driver.h> #include <drm/ttm/ttm_placement.h> diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index f96497b..c697fe4 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -467,8 +467,8 @@ static int mdp4_crtc_page_flip(struct drm_crtc *crtc, return msm_gem_queue_inactive_cb(obj, &mdp4_crtc->pageflip_cb); } -static int mdp4_crtc_set_property(struct drm_crtc *crtc, - struct drm_property *property, uint64_t val) +static int mdp4_crtc_set_property(struct drm_crtc *crtc, void *state, + struct drm_property *property, uint64_t val, void *blob_data) { // XXX return -EINVAL; diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c index afa9c67..599490c 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c @@ -84,8 +84,8 @@ void mdp4_plane_install_properties(struct drm_plane *plane, // XXX } -int mdp4_plane_set_property(struct drm_plane *plane, - struct drm_property *property, uint64_t val) +int mdp4_plane_set_property(struct drm_plane *plane, void *state, + struct drm_property *property, uint64_t val, void *blob_data) { // XXX return -EINVAL; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index f200048..4087fb0 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -385,8 +385,8 @@ static int mdp5_crtc_page_flip(struct drm_crtc *crtc, return msm_gem_queue_inactive_cb(obj, &mdp5_crtc->pageflip_cb); } -static int mdp5_crtc_set_property(struct drm_crtc *crtc, - struct drm_property *property, uint64_t val) +static int mdp5_crtc_set_property(struct drm_crtc *crtc, void *state, + struct drm_property *property, uint64_t val, void *blob_data) { // XXX return -EINVAL; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 651baac..fd951e1 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -99,8 +99,8 @@ void mdp5_plane_install_properties(struct drm_plane *plane, // XXX } -int mdp5_plane_set_property(struct drm_plane *plane, - struct drm_property *property, uint64_t val) +int mdp5_plane_set_property(struct drm_plane *plane, void *state, + struct drm_property *property, uint64_t val, void *blob_data) { // XXX return -EINVAL; diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index f9de156..e0a0172 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -815,6 +815,12 @@ static struct drm_driver msm_driver = { .gem_prime_import_sg_table = msm_gem_prime_import_sg_table, .gem_prime_vmap = msm_gem_prime_vmap, .gem_prime_vunmap = msm_gem_prime_vunmap, + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, #ifdef CONFIG_DEBUG_FS .debugfs_init = msm_debugfs_init, .debugfs_cleanup = msm_debugfs_cleanup, diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 9d10ee0..afc990e 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -50,6 +50,7 @@ static inline struct device *msm_iommu_get_ctx(const char *ctx_name) #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_fb_helper.h> +#include <drm/drm_atomic.h> #include <drm/msm_drm.h> struct msm_kms; diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c index 0b4f35d..fe0d94a 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c +++ b/drivers/gpu/drm/nouveau/dispnv04/overlay.c @@ -220,9 +220,9 @@ nv10_set_params(struct nouveau_plane *plane) } static int -nv_set_property(struct drm_plane *plane, - struct drm_property *property, - uint64_t value) +nv_set_property(struct drm_plane *plane, void *state, + struct drm_property *property, + uint64_t value, void *blob_data) { struct nouveau_plane *nv_plane = (struct nouveau_plane *)plane; diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 1674882..36499e1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -447,7 +447,8 @@ nouveau_connector_force(struct drm_connector *connector) static int nouveau_connector_set_property(struct drm_connector *connector, - struct drm_property *property, uint64_t value) + void *state, struct drm_property *property, + uint64_t value, void *blob_data) { struct nouveau_display *disp = nouveau_display(connector->dev); struct nouveau_connector *nv_connector = nouveau_connector(connector); diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 89c484d..c74856a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -833,6 +833,13 @@ driver = { .dumb_map_offset = nouveau_display_dumb_map_offset, .dumb_destroy = drm_gem_dumb_destroy, + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, + .name = DRIVER_NAME, .desc = DRIVER_DESC, #ifdef GIT_REVISION diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h index 23ca7a5..6a1f00d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -29,6 +29,7 @@ #include <subdev/vm.h> #include <drmP.h> +#include <drm/drm_atomic.h> #include <drm/nouveau_drm.h> #include <drm/ttm/ttm_bo_api.h> diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 2015715..846d509 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -362,8 +362,8 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, return 0; } -static int omap_crtc_set_property(struct drm_crtc *crtc, - struct drm_property *property, uint64_t val) +static int omap_crtc_set_property(struct drm_crtc *crtc, void *state, + struct drm_property *property, uint64_t val, void *blob_data) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); struct omap_drm_private *priv = crtc->dev->dev_private; @@ -373,7 +373,8 @@ static int omap_crtc_set_property(struct drm_crtc *crtc, !!(val & ((1LL << DRM_ROTATE_90) | (1LL << DRM_ROTATE_270))); } - return omap_plane_set_property(omap_crtc->plane, property, val); + return omap_plane_set_property(omap_crtc->plane, state, + property, val, blob_data); } static const struct drm_crtc_funcs omap_crtc_funcs = { diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index bf39fcc..5e056e2 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -645,6 +645,12 @@ static struct drm_driver omap_drm_driver = { .dumb_create = omap_gem_dumb_create, .dumb_map_offset = omap_gem_dumb_map_offset, .dumb_destroy = drm_gem_dumb_destroy, + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, .ioctls = ioctls, .num_ioctls = DRM_OMAP_NUM_IOCTLS, .fops = &omapdriver_fops, diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index 428b2981..818631f 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -25,6 +25,7 @@ #include <linux/types.h> #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_atomic.h> #include <drm/omap_drm.h> #include <linux/platform_data/omap_drm.h> @@ -176,8 +177,8 @@ int omap_plane_mode_set(struct drm_plane *plane, void (*fxn)(void *), void *arg); void omap_plane_install_properties(struct drm_plane *plane, struct drm_mode_object *obj); -int omap_plane_set_property(struct drm_plane *plane, - struct drm_property *property, uint64_t val); +int omap_plane_set_property(struct drm_plane *plane, void *state, + struct drm_property *property, uint64_t val, void *blob_data); struct drm_encoder *omap_encoder_init(struct drm_device *dev, struct omap_dss_device *dssdev); diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index d4179b2..534b067 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -327,8 +327,8 @@ void omap_plane_install_properties(struct drm_plane *plane, drm_object_attach_property(obj, prop, 0); } -int omap_plane_set_property(struct drm_plane *plane, - struct drm_property *property, uint64_t val) +int omap_plane_set_property(struct drm_plane *plane, void *state, + struct drm_property *property, uint64_t val, void *blob_data) { struct omap_plane *omap_plane = to_omap_plane(plane); struct omap_drm_private *priv = plane->dev->dev_private; diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 24b6112..2975707 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -821,8 +821,10 @@ static enum drm_connector_status qxl_conn_detect( } static int qxl_conn_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t value) + uint64_t value, + void *blob_data) { DRM_DEBUG("\n"); return 0; diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index fee8748..250581d 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -34,6 +34,7 @@ #include "drmP.h" #include "drm/drm.h" #include "drm_crtc_helper.h" +#include "drm_atomic.h" #include "qxl_drv.h" #include "qxl_object.h" @@ -221,6 +222,14 @@ static struct drm_driver qxl_driver = { .dumb_create = qxl_mode_dumb_create, .dumb_map_offset = qxl_mode_dumb_mmap, .dumb_destroy = drm_gem_dumb_destroy, + + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, + #if defined(CONFIG_DEBUG_FS) .debugfs_init = qxl_debugfs_init, .debugfs_cleanup = qxl_debugfs_takedown, diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 33b482b..054f721 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -359,8 +359,9 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn } } -static int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property, - uint64_t val) +static int radeon_connector_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, + uint64_t val, void *blob_data) { struct drm_device *dev = connector->dev; struct radeon_device *rdev = dev->dev_private; @@ -682,8 +683,10 @@ static void radeon_connector_destroy(struct drm_connector *connector) } static int radeon_lvds_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t value) + uint64_t value, + void *blob_data) { struct drm_device *dev = connector->dev; struct radeon_encoder *radeon_encoder; diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 4392b7c..30ceeca 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -34,6 +34,7 @@ #include "radeon_drv.h" #include <drm/drm_pciids.h> +#include <drm/drm_atomic.h> #include <linux/console.h> #include <linux/module.h> #include <linux/pm_runtime.h> @@ -554,6 +555,14 @@ static struct drm_driver kms_driver = { .dumb_create = radeon_mode_dumb_create, .dumb_map_offset = radeon_mode_dumb_mmap, .dumb_destroy = drm_gem_dumb_destroy, + + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, + .fops = &radeon_driver_kms_fops, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index 792fd1d..3f642a8 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -21,6 +21,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_atomic.h> #include <drm/drm_fb_cma_helper.h> #include <drm/drm_gem_cma_helper.h> @@ -175,6 +176,12 @@ static struct drm_driver rcar_du_driver = { .dumb_create = rcar_du_dumb_create, .dumb_map_offset = drm_gem_cma_dumb_map_offset, .dumb_destroy = drm_gem_dumb_destroy, + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, .fops = &rcar_du_fops, .name = "rcar-du", .desc = "Renesas R-Car Display Unit", diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index 27f1531..29080ee 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c @@ -397,8 +397,10 @@ done: } static int rcar_du_plane_set_property(struct drm_plane *plane, + void *state, struct drm_property *property, - uint64_t value) + uint64_t value, + void *blob_data) { struct rcar_du_plane *rplane = to_rcar_plane(plane); struct rcar_du_group *rgrp = rplane->group; diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c index c839c9c..f4b3f80 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c @@ -21,6 +21,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_atomic.h> #include <drm/drm_gem_cma_helper.h> #include "shmob_drm_crtc.h" @@ -285,6 +286,12 @@ static struct drm_driver shmob_drm_driver = { .dumb_create = drm_gem_cma_dumb_create, .dumb_map_offset = drm_gem_cma_dumb_map_offset, .dumb_destroy = drm_gem_dumb_destroy, + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, .fops = &shmob_drm_fops, .name = "shmob-drm", .desc = "Renesas SH Mobile DRM", diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 171a820..eb239d2 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -519,6 +519,12 @@ static struct drm_driver tilcdc_driver = { .dumb_create = drm_gem_cma_dumb_create, .dumb_map_offset = drm_gem_cma_dumb_map_offset, .dumb_destroy = drm_gem_dumb_destroy, + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, #ifdef CONFIG_DEBUG_FS .debugfs_init = tilcdc_debugfs_init, .debugfs_cleanup = tilcdc_debugfs_cleanup, diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h index 0938036..1280a65 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h @@ -31,6 +31,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_atomic.h> #include <drm/drm_gem_cma_helper.h> #include <drm/drm_fb_cma_helper.h> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave.c b/drivers/gpu/drm/tilcdc/tilcdc_slave.c index 595068b..48bcc26 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_slave.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_slave.c @@ -206,7 +206,8 @@ static struct drm_encoder *slave_connector_best_encoder( } static int slave_connector_set_property(struct drm_connector *connector, - struct drm_property *property, uint64_t value) + void *state, struct drm_property *property, + uint64_t value, void *blob_data) { struct drm_encoder *encoder = to_slave_connector(connector)->encoder; return get_slave_funcs(encoder)->set_property(encoder, diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c index b44d548..cd0c01a 100644 --- a/drivers/gpu/drm/udl/udl_connector.c +++ b/drivers/gpu/drm/udl/udl_connector.c @@ -115,9 +115,9 @@ udl_best_single_encoder(struct drm_connector *connector) return encoder; } -static int udl_connector_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t val) +static int udl_connector_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, + uint64_t val, void *blob_data) { return 0; } diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 3ddd6cd..52ade41 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -9,6 +9,7 @@ #include <linux/module.h> #include <drm/drm_usb.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_atomic.h> #include "udl_drv.h" static struct drm_driver driver; @@ -88,6 +89,13 @@ static struct drm_driver driver = { .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_import = udl_gem_prime_import, + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, + .name = DRIVER_NAME, .desc = DRIVER_DESC, .date = DRIVER_DATE, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 0083cbf..6643ff3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -1349,6 +1349,13 @@ static struct drm_driver driver = { .prime_fd_to_handle = vmw_prime_fd_to_handle, .prime_handle_to_fd = vmw_prime_handle_to_fd, + .atomic_begin = drm_atomic_begin, + .atomic_set_event = drm_atomic_set_event, + .atomic_check = drm_atomic_check, + .atomic_commit = drm_atomic_commit, + .atomic_end = drm_atomic_end, + .atomic_funcs = &drm_atomic_funcs, + .fops = &vmwgfx_driver_fops, .name = VMWGFX_DRIVER_NAME, .desc = VMWGFX_DRIVER_DESC, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 9e4be17..df8f0e6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -30,6 +30,7 @@ #include "vmwgfx_reg.h" #include <drm/drmP.h> +#include <drm/drm_atomic.h> #include <drm/vmwgfx_drm.h> #include <drm/drm_hashtab.h> #include <linux/suspend.h> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 8a65041..53bbcbe 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -2009,8 +2009,10 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, } int vmw_du_connector_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t val) + uint64_t val, + void *blob_data) { return 0; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index 8d038c3..e259d6c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -141,8 +141,10 @@ vmw_du_connector_detect(struct drm_connector *connector, bool force); int vmw_du_connector_fill_modes(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); int vmw_du_connector_set_property(struct drm_connector *connector, + void *state, struct drm_property *property, - uint64_t val); + uint64_t val, + void *blob_data); /* diff --git a/include/drm/drmP.h b/include/drm/drmP.h index f103d69..b4058f5 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -987,6 +987,83 @@ struct drm_driver { struct drm_device *dev, uint32_t handle); + /* + * Atomic functions: + */ + + /** + * atomic_begin - start a sequence of atomic updates + * @dev: DRM device + * @flags: the modifier flags that userspace has requested + * + * Begin a sequence of atomic property sets. Returns a driver + * private state object that is passed back into the various + * object's set_property() fxns, and into the remainder of the + * atomic funcs. The state object should accumulate the changes + * from one o more set_property()'s. At the end, the state can + * be checked, and optionally committed. + * + * RETURNS + * a driver private state object, which is passed back in to + * the various other atomic fxns, or error (such as -EBUSY if + * there is still a pending async update) + */ + void *(*atomic_begin)(struct drm_device *dev, uint32_t flags); + + /** + * atomic_set_event - set a pending event on mode object + * @dev: DRM device + * @state: the driver private state object + * @obj: the object to set the event on + * @event: the event to send back + * + * Set pending event for an update on the specified object. The + * event is to be sent back to userspace after the update completes. + */ + int (*atomic_set_event)(struct drm_device *dev, + void *state, struct drm_mode_object *obj, + struct drm_pending_vblank_event *event); + + /** + * atomic_check - validate state object + * @dev: DRM device + * @state: the driver private state object + * + * Check the state object to see if the requested state is + * physically possible. + * + * RETURNS + * Zero for success or -errno + */ + int (*atomic_check)(struct drm_device *dev, void *state); + + /** + * atomic_commit - commit state + * @dev: DRM device + * @state: the driver private state object + * + * Commit the state. This will only be called if atomic_check() + * succeeds. + * + * RETURNS + * Zero for success or -errno + */ + int (*atomic_commit)(struct drm_device *dev, void *state); + + /** + * atomic_end - conclude the atomic update + * @dev: DRM device + * @state: the driver private state object + + * Release resources associated with the state object. + */ + void (*atomic_end)(struct drm_device *dev, void *state); + + /** + * Helpers used by drm-atomic-helpers + */ + const void *atomic_funcs; + /* Driver private ops for this object */ const struct vm_operations_struct *gem_vm_ops; diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h new file mode 100644 index 0000000..afeefe3 --- /dev/null +++ b/include/drm/drm_atomic.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2013 Red Hat + * Author: Rob Clark <robdclark@xxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DRM_ATOMIC_HELPER_H_ +#define DRM_ATOMIC_HELPER_H_ + +/** + * DOC: atomic state helpers + * + * Base helper atomic state and functions. Drivers are free to either + * use these as-is, extend them, or completely replace them, in order + * to implement the atomic KMS API. + * + * A naive driver, with no special constraints or hw support for atomic + * updates may simply add the following to their driver struct: + * + * .atomic_begin = drm_atomic_begin, + * .atomic_set_event = drm_atomic_set_event, + * .atomic_check = drm_atomic_check, + * .atomic_commit = drm_atomic_commit, + * .atomic_end = drm_atomic_end, + * .atomics = &drm_atomic_funcs, + * + * In addition, if you're plane/crtc doesn't already have it's own custom + * properties, then add to your plane/crtc_funcs: + * + * .set_property = drm_atomic_{plane,crtc}_set_property, + * + * Unlike the crtc helpers, it is intended that the atomic helpers can be + * used piecemeal by the drivers, either using all or overriding parts as + * needed. + * + * A driver which can have (for example) conflicting modes across multiple + * crtcs (for example, bandwidth limitations or clock/pll configuration + * restrictions), can simply wrap drm_atomic_check() with their own + * driver specific .atomic_check() function. + * + * A driver which can support true atomic updates can wrap + * drm_atomic_commit(). + * + * A driver with custom properties should override the appropriate get_state(), + * check_state(), and commit_state() functions in .atomics if it uses + * the drm-atomic-helpers. Otherwise it is free to use &drm_atomic_funcs + * as-is. + */ + +/** + * struct drm_atomic_funcs - helper funcs used by the atomic helpers + */ +struct drm_atomic_funcs { + int dummy; /* for now */ +}; + +const extern struct drm_atomic_funcs drm_atomic_funcs; + +void *drm_atomic_begin(struct drm_device *dev, uint32_t flags); +int drm_atomic_set_event(struct drm_device *dev, + void *state, struct drm_mode_object *obj, + struct drm_pending_vblank_event *event); +int drm_atomic_check(struct drm_device *dev, void *state); +int drm_atomic_commit(struct drm_device *dev, void *state); +void drm_atomic_end(struct drm_device *dev, void *state); + +/** + * struct drm_atomic_state - the state object used by atomic helpers + */ +struct drm_atomic_state { + struct kref refcount; + struct drm_device *dev; + uint32_t flags; +}; + +static inline void +drm_atomic_state_reference(struct drm_atomic_state *state) +{ + kref_get(&state->refcount); +} + +static inline void +drm_atomic_state_unreference(struct drm_atomic_state *state) +{ + void _drm_atomic_state_free(struct kref *kref); + kref_put(&state->refcount, _drm_atomic_state_free); +} + +#endif /* DRM_ATOMIC_HELPER_H_ */ diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 826e373..e75cee6 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -378,8 +378,9 @@ struct drm_crtc_funcs { struct drm_pending_vblank_event *event, uint32_t flags); - int (*set_property)(struct drm_crtc *crtc, - struct drm_property *property, uint64_t val); + int (*set_property)(struct drm_crtc *crtc, void *state, + struct drm_property *property, uint64_t val, + void *blob_data); }; /** @@ -489,8 +490,8 @@ struct drm_connector_funcs { enum drm_connector_status (*detect)(struct drm_connector *connector, bool force); int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); - int (*set_property)(struct drm_connector *connector, struct drm_property *property, - uint64_t val); + int (*set_property)(struct drm_connector *connector, void *state, + struct drm_property *property, uint64_t val, void *blob_data); void (*destroy)(struct drm_connector *connector); void (*force)(struct drm_connector *connector); }; @@ -661,8 +662,9 @@ struct drm_plane_funcs { int (*disable_plane)(struct drm_plane *plane); void (*destroy)(struct drm_plane *plane); - int (*set_property)(struct drm_plane *plane, - struct drm_property *property, uint64_t val); + int (*set_property)(struct drm_plane *plane, void *state, + struct drm_property *property, uint64_t val, + void *blob_data); }; enum drm_plane_type { -- 1.8.5.3 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel