On 01/20/2015 05:57 AM, Matt Roper wrote:
Add the top-level atomic entrypoints for check/commit. These won't get called yet; we still need to either enable the atomic ioctl or switch to using the non-transitional atomic helpers for legacy operations. Signed-off-by: Matt Roper <matthew.d.roper@xxxxxxxxx> --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/intel_atomic.c | 161 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 2 + drivers/gpu/drm/i915/intel_drv.h | 7 ++ 4 files changed, 171 insertions(+) create mode 100644 drivers/gpu/drm/i915/intel_atomic.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 16e3dc3..c7e2ab5 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -66,6 +66,7 @@ i915-y += dvo_ch7017.o \ dvo_ns2501.o \ dvo_sil164.o \ dvo_tfp410.o \ + intel_atomic.o \ intel_atomic_plane.o \ intel_crt.o \ intel_ddi.o \ diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c new file mode 100644 index 0000000..1542005 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -0,0 +1,161 @@ +/* + * Copyright © 2015 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * DOC: atomic modeset support + * + * The functions here implement the state management and hardware programming + * dispatch required by the atomic modeset infrastructure. + * See intel_atomic_plane.c for the plane-specific atomic functionality. + */ + +#include <drm/drmP.h> +#include <drm/drm_atomic.h> +#include <drm/drm_atomic_helper.h> +#include <drm/drm_plane_helper.h> +#include "intel_drv.h" + + +/** + * intel_atomic_check - validate state object + * @dev: drm device + * @state: state to validate + */ +int intel_atomic_check(struct drm_device *dev, + struct drm_atomic_state *state) +{ + int nplanes = dev->mode_config.num_total_plane; + int ncrtcs = dev->mode_config.num_crtc; + int nconnectors = dev->mode_config.num_connector; + int crtc_mask = 0; + int ret; + int i; + bool not_nuclear = false; + + /* Figure out what crtcs are involved */ + for (i = 0; i < nplanes; i++) { + struct drm_plane *plane = state->planes[i]; + if (!plane) + continue; + crtc_mask |= plane->possible_crtcs;
This would compute the wrong mask for older gens, where the planes are not mapped to one specific pipe. But we don't support planes at all in that case, so I guess this is fine.
+ } + + /* + * FIXME: At the moment, we only support "nuclear pageflip" on a + * single CRTC. Cross-crtc updates will be added later. + */ + if (hweight32(crtc_mask) > 1) { + DRM_DEBUG_KMS("i915 only support atomic plane operations on a single CRTC at the moment\n"); + return -EINVAL; + } + + /* + * FIXME: We only handle planes for now; make sure there are no CRTC's + * or connectors involved. + */ + state->allow_modeset = false; + for (i = 0; i < ncrtcs; i++) + not_nuclear |= (state->crtcs[i] && + drm_crtc_mask(state->crtcs[i]) != crtc_mask); + for (i = 0; i < nconnectors; i++) + not_nuclear |= (state->connectors[i] != NULL);
I think "if (condition) not_nuclear = true;" would be more clear here. Ander
+ + if (not_nuclear) { + DRM_DEBUG_KMS("i915 only supports atomic plane operations at the moment\n"); + return -EINVAL; + } + + ret = drm_atomic_helper_check_planes(dev, state); + if (ret) + return ret; + + return ret; +} + + +/** + * intel_atomic_commit - commit validated state object + * @dev: DRM device + * @state: the top-level driver state object + * @async: asynchronous commit + * + * This function commits a top-level state object that has been validated + * with drm_atomic_helper_check(). + * + * FIXME: Atomic modeset support for i915 is not yet complete. At the moment + * we can only handle plane-related operations and do not yet support + * asynchronous commit. + * + * RETURNS + * Zero for success or -errno. + */ +int intel_atomic_commit(struct drm_device *dev, + struct drm_atomic_state *state, + bool async) +{ + int ret; + int i; + + if (async) { + DRM_DEBUG_KMS("i915 does not yet support async commit\n"); + return -EINVAL; + } + + ret = drm_atomic_helper_prepare_planes(dev, state); + if (ret) + return ret; + + /* Point of no return */ + + /* + * FIXME: The proper sequence here will eventually be: + * + * drm_atomic_helper_swap_state(dev, state) + * drm_atomic_helper_commit_pre_planes(dev, state); + * drm_atomic_helper_commit_planes(dev, state); + * drm_atomic_helper_commit_post_planes(dev, state); + * drm_atomic_helper_wait_for_vblanks(dev, state); + * drm_atomic_helper_cleanup_planes(dev, state); + * drm_atomic_state_free(state); + * + * once we have full atomic modeset. For now, just manually update + * plane states to avoid clobbering good states with dummy states + * while nuclear pageflipping. + */ + for (i = 0; i < dev->mode_config.num_total_plane; i++) { + struct drm_plane *plane = state->planes[i]; + + if (!plane) + continue; + + plane->state->state = state; + swap(state->plane_states[i], plane->state); + plane->state->state = NULL; + } + drm_atomic_helper_commit_planes(dev, state); + drm_atomic_helper_wait_for_vblanks(dev, state); + drm_atomic_helper_cleanup_planes(dev, state); + drm_atomic_state_free(state); + + return 0; +} diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 50ae3b1..0e18879 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12681,6 +12681,8 @@ static inline void intel_fbdev_output_poll_changed(struct drm_device *dev) static const struct drm_mode_config_funcs intel_mode_funcs = { .fb_create = intel_user_framebuffer_create, .output_poll_changed = intel_fbdev_output_poll_changed, + .atomic_check = intel_atomic_check, + .atomic_commit = intel_atomic_commit, }; /* Set up chip specific display functions */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 2d9e9a4..503e2f2 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1261,6 +1261,13 @@ void intel_pre_disable_primary(struct drm_crtc *crtc); void intel_tv_init(struct drm_device *dev); /* intel_atomic.c */ +int intel_atomic_check(struct drm_device *dev, + struct drm_atomic_state *state); +int intel_atomic_commit(struct drm_device *dev, + struct drm_atomic_state *state, + bool async); + +/* intel_atomic_plane.c */ struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane); void intel_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state);
_______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx