| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- // SPDX-License-Identifier: MIT
- #include <drm/drm_atomic.h>
- #include <drm/drm_crtc.h>
- #include <drm/drm_managed.h>
- #include <drm/drm_modeset_helper_vtables.h>
- #include <drm/drm_print.h>
- #include <drm/drm_vblank.h>
- #include <drm/drm_vblank_helper.h>
- /**
- * DOC: overview
- *
- * The vblank helper library provides functions for supporting vertical
- * blanking in DRM drivers.
- *
- * For vblank timers, several callback implementations are available.
- * Drivers enable support for vblank timers by setting the vblank callbacks
- * in struct &drm_crtc_funcs to the helpers provided by this library. The
- * initializer macro DRM_CRTC_VBLANK_TIMER_FUNCS does this conveniently.
- * The driver further has to send the VBLANK event from its atomic_flush
- * callback and control vblank from the CRTC's atomic_enable and atomic_disable
- * callbacks. The callbacks are located in struct &drm_crtc_helper_funcs.
- * The vblank helper library provides implementations of these callbacks
- * for drivers without further requirements. The initializer macro
- * DRM_CRTC_HELPER_VBLANK_FUNCS sets them coveniently.
- *
- * Once the driver enables vblank support with drm_vblank_init(), each
- * CRTC's vblank timer fires according to the programmed display mode. By
- * default, the vblank timer invokes drm_crtc_handle_vblank(). Drivers with
- * more specific requirements can set their own handler function in
- * struct &drm_crtc_helper_funcs.handle_vblank_timeout.
- */
- /*
- * VBLANK helpers
- */
- /**
- * drm_crtc_vblank_atomic_flush -
- * Implements struct &drm_crtc_helper_funcs.atomic_flush
- * @crtc: The CRTC
- * @state: The atomic state to apply
- *
- * The helper drm_crtc_vblank_atomic_flush() implements atomic_flush of
- * struct drm_crtc_helper_funcs for CRTCs that only need to send out a
- * VBLANK event.
- *
- * See also struct &drm_crtc_helper_funcs.atomic_flush.
- */
- void drm_crtc_vblank_atomic_flush(struct drm_crtc *crtc,
- struct drm_atomic_state *state)
- {
- struct drm_device *dev = crtc->dev;
- struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
- struct drm_pending_vblank_event *event;
- spin_lock_irq(&dev->event_lock);
- event = crtc_state->event;
- crtc_state->event = NULL;
- if (event) {
- if (drm_crtc_vblank_get(crtc) == 0)
- drm_crtc_arm_vblank_event(crtc, event);
- else
- drm_crtc_send_vblank_event(crtc, event);
- }
- spin_unlock_irq(&dev->event_lock);
- }
- EXPORT_SYMBOL(drm_crtc_vblank_atomic_flush);
- /**
- * drm_crtc_vblank_atomic_enable - Implements struct &drm_crtc_helper_funcs.atomic_enable
- * @crtc: The CRTC
- * @state: The atomic state
- *
- * The helper drm_crtc_vblank_atomic_enable() implements atomic_enable
- * of struct drm_crtc_helper_funcs for CRTCs the only need to enable VBLANKs.
- *
- * See also struct &drm_crtc_helper_funcs.atomic_enable.
- */
- void drm_crtc_vblank_atomic_enable(struct drm_crtc *crtc,
- struct drm_atomic_state *state)
- {
- drm_crtc_vblank_on(crtc);
- }
- EXPORT_SYMBOL(drm_crtc_vblank_atomic_enable);
- /**
- * drm_crtc_vblank_atomic_disable - Implements struct &drm_crtc_helper_funcs.atomic_disable
- * @crtc: The CRTC
- * @state: The atomic state
- *
- * The helper drm_crtc_vblank_atomic_disable() implements atomic_disable
- * of struct drm_crtc_helper_funcs for CRTCs the only need to disable VBLANKs.
- *
- * See also struct &drm_crtc_funcs.atomic_disable.
- */
- void drm_crtc_vblank_atomic_disable(struct drm_crtc *crtc,
- struct drm_atomic_state *state)
- {
- drm_crtc_vblank_off(crtc);
- }
- EXPORT_SYMBOL(drm_crtc_vblank_atomic_disable);
- /*
- * VBLANK timer
- */
- /**
- * drm_crtc_vblank_helper_enable_vblank_timer - Implements struct &drm_crtc_funcs.enable_vblank
- * @crtc: The CRTC
- *
- * The helper drm_crtc_vblank_helper_enable_vblank_timer() implements
- * enable_vblank of struct drm_crtc_helper_funcs for CRTCs that require
- * a VBLANK timer. It sets up the timer on the first invocation. The
- * started timer expires after the current frame duration. See struct
- * &drm_vblank_crtc.framedur_ns.
- *
- * See also struct &drm_crtc_helper_funcs.enable_vblank.
- *
- * Returns:
- * 0 on success, or a negative errno code otherwise.
- */
- int drm_crtc_vblank_helper_enable_vblank_timer(struct drm_crtc *crtc)
- {
- return drm_crtc_vblank_start_timer(crtc);
- }
- EXPORT_SYMBOL(drm_crtc_vblank_helper_enable_vblank_timer);
- /**
- * drm_crtc_vblank_helper_disable_vblank_timer - Implements struct &drm_crtc_funcs.disable_vblank
- * @crtc: The CRTC
- *
- * The helper drm_crtc_vblank_helper_disable_vblank_timer() implements
- * disable_vblank of struct drm_crtc_funcs for CRTCs that require a
- * VBLANK timer.
- *
- * See also struct &drm_crtc_helper_funcs.disable_vblank.
- */
- void drm_crtc_vblank_helper_disable_vblank_timer(struct drm_crtc *crtc)
- {
- drm_crtc_vblank_cancel_timer(crtc);
- }
- EXPORT_SYMBOL(drm_crtc_vblank_helper_disable_vblank_timer);
- /**
- * drm_crtc_vblank_helper_get_vblank_timestamp_from_timer -
- * Implements struct &drm_crtc_funcs.get_vblank_timestamp
- * @crtc: The CRTC
- * @max_error: Maximum acceptable error
- * @vblank_time: Returns the next vblank timestamp
- * @in_vblank_irq: True is called from drm_crtc_handle_vblank()
- *
- * The helper drm_crtc_helper_get_vblank_timestamp_from_timer() implements
- * get_vblank_timestamp of struct drm_crtc_funcs for CRTCs that require a
- * VBLANK timer. It returns the timestamp according to the timer's expiry
- * time.
- *
- * See also struct &drm_crtc_funcs.get_vblank_timestamp.
- *
- * Returns:
- * True on success, or false otherwise.
- */
- bool drm_crtc_vblank_helper_get_vblank_timestamp_from_timer(struct drm_crtc *crtc,
- int *max_error,
- ktime_t *vblank_time,
- bool in_vblank_irq)
- {
- drm_crtc_vblank_get_vblank_timeout(crtc, vblank_time);
- return true;
- }
- EXPORT_SYMBOL(drm_crtc_vblank_helper_get_vblank_timestamp_from_timer);
|