You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'drm-misc-next-2017-06-02' of git://anongit.freedesktop.org/git/drm-misc into drm-next
Core Changes: - Stop proliferation of drm_vblank_cleanup by adding to the docs and deleting boilerplate (Daniel) - Roll out and use mode_valid hooks across crtc/encoder/bridge (Jose) - Add drm_vblank.[hc] to isolate vblank code from optional irq helpers (Daniel) Driver Changes: - Replace drm_for_each_connector with drm_for_each_connector_iter (Gustavo) - A couple misc driver fixes Cc: Gustavo Padovan <gustavo.padovan@collabora.com> Cc: Jose Abreu <Jose.Abreu@synopsys.com> Cc: Daniel Vetter <daniel.vetter@intel.com> * tag 'drm-misc-next-2017-06-02' of git://anongit.freedesktop.org/git/drm-misc: (34 commits) drm/vc4: Mark the device as active when enabling runtime PM. drm: remove writeq/readq function definitions drm/atmel-hlcdc: Use crtc->mode_valid() callback drm/exynos: Drop drm_vblank_cleanup drm/hdlcd|mali: Drop drm_vblank_cleanup drm/doc: Polish irq helper documentation drm: Extract drm_vblank.[hc] drm/vc4: Fix comment in vc4_drv.h drm/pl111: fix warnings without CONFIG_ARM_AMBA drm/atomic: Consitfy mode parameter to drm_atomic_set_mode_for_crtc() drm/arcgpu: Drop drm_vblank_cleanup drm/atmel: Drop drm_vblank_cleanup drm/imx: Drop drm_vblank_cleanup drm/meson: Drop drm_vblank_cleanup drm/stm: Drop drm_vblank_cleanup drm/sun4i: Drop drm_vblank_cleanup drm: better document how to send out the crtc disable event drm: Use vsnprintf extension %ph drm/doc: move printf helpers out of drmP.h drm/pl111: select DRM_PANEL ...
This commit is contained in:
+10
-23
@@ -80,6 +80,9 @@
|
||||
#include <drm/drm_debugfs.h>
|
||||
#include <drm/drm_ioctl.h>
|
||||
#include <drm/drm_sysfs.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
#include <drm/drm_irq.h>
|
||||
|
||||
|
||||
struct module;
|
||||
|
||||
@@ -292,23 +295,6 @@ struct pci_controller;
|
||||
/* Format strings and argument splitters to simplify printing
|
||||
* various "complex" objects
|
||||
*/
|
||||
#define DRM_MODE_FMT "%d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x"
|
||||
#define DRM_MODE_ARG(m) \
|
||||
(m)->base.id, (m)->name, (m)->vrefresh, (m)->clock, \
|
||||
(m)->hdisplay, (m)->hsync_start, (m)->hsync_end, (m)->htotal, \
|
||||
(m)->vdisplay, (m)->vsync_start, (m)->vsync_end, (m)->vtotal, \
|
||||
(m)->type, (m)->flags
|
||||
|
||||
#define DRM_RECT_FMT "%dx%d%+d%+d"
|
||||
#define DRM_RECT_ARG(r) drm_rect_width(r), drm_rect_height(r), (r)->x1, (r)->y1
|
||||
|
||||
/* for rect's in fixed-point format: */
|
||||
#define DRM_RECT_FP_FMT "%d.%06ux%d.%06u%+d.%06u%+d.%06u"
|
||||
#define DRM_RECT_FP_ARG(r) \
|
||||
drm_rect_width(r) >> 16, ((drm_rect_width(r) & 0xffff) * 15625) >> 10, \
|
||||
drm_rect_height(r) >> 16, ((drm_rect_height(r) & 0xffff) * 15625) >> 10, \
|
||||
(r)->x1 >> 16, (((r)->x1 & 0xffff) * 15625) >> 10, \
|
||||
(r)->y1 >> 16, (((r)->y1 & 0xffff) * 15625) >> 10
|
||||
|
||||
/*@}*/
|
||||
|
||||
@@ -391,8 +377,13 @@ struct drm_device {
|
||||
int last_context; /**< Last current context */
|
||||
/*@} */
|
||||
|
||||
/** \name VBLANK IRQ support */
|
||||
/*@{ */
|
||||
/**
|
||||
* @irq_enabled:
|
||||
*
|
||||
* Indicates that interrupt handling is enabled, specifically vblank
|
||||
* handling. Drivers which don't use drm_irq_install() need to set this
|
||||
* to true manually.
|
||||
*/
|
||||
bool irq_enabled;
|
||||
int irq;
|
||||
|
||||
@@ -429,8 +420,6 @@ struct drm_device {
|
||||
struct pci_controller *hose;
|
||||
#endif
|
||||
|
||||
struct virtio_device *virtdev;
|
||||
|
||||
struct drm_sg_mem *sg; /**< Scatter gather memory */
|
||||
unsigned int num_crtcs; /**< Number of CRTCs on this device */
|
||||
|
||||
@@ -466,8 +455,6 @@ static inline bool drm_drv_uses_atomic_modeset(struct drm_device *dev)
|
||||
return dev->mode_config.funcs->atomic_commit != NULL;
|
||||
}
|
||||
|
||||
#include <drm/drm_irq.h>
|
||||
|
||||
#define DRM_SWITCH_POWER_ON 0
|
||||
#define DRM_SWITCH_POWER_OFF 1
|
||||
#define DRM_SWITCH_POWER_CHANGING 2
|
||||
|
||||
@@ -520,7 +520,7 @@ __drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
|
||||
|
||||
int __must_check
|
||||
drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
|
||||
struct drm_display_mode *mode);
|
||||
const struct drm_display_mode *mode);
|
||||
int __must_check
|
||||
drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
|
||||
struct drm_property_blob *blob);
|
||||
|
||||
@@ -253,6 +253,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
|
||||
bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
|
||||
const struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_mode *mode);
|
||||
void drm_bridge_disable(struct drm_bridge *bridge);
|
||||
void drm_bridge_post_disable(struct drm_bridge *bridge);
|
||||
void drm_bridge_mode_set(struct drm_bridge *bridge,
|
||||
|
||||
@@ -1009,21 +1009,6 @@ struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
|
||||
void drm_mode_put_tile_group(struct drm_device *dev,
|
||||
struct drm_tile_group *tg);
|
||||
|
||||
/**
|
||||
* drm_for_each_connector - iterate over all connectors
|
||||
* @connector: the loop cursor
|
||||
* @dev: the DRM device
|
||||
*
|
||||
* Iterate over all connectors of @dev.
|
||||
*
|
||||
* WARNING:
|
||||
*
|
||||
* This iterator is not safe against hotadd/removal of connectors and is
|
||||
* deprecated. Use drm_for_each_connector_iter() instead.
|
||||
*/
|
||||
#define drm_for_each_connector(connector, dev) \
|
||||
list_for_each_entry(connector, &(dev)->mode_config.connector_list, head)
|
||||
|
||||
/**
|
||||
* struct drm_connector_list_iter - connector_list iterator
|
||||
*
|
||||
|
||||
@@ -214,7 +214,9 @@ struct drm_crtc_state {
|
||||
* atomic commit. In that case the event can be send out any time
|
||||
* after the hardware has stopped scanning out the current
|
||||
* framebuffers. It should contain the timestamp and counter for the
|
||||
* last vblank before the display pipeline was shut off.
|
||||
* last vblank before the display pipeline was shut off. The simplest
|
||||
* way to achieve that is calling drm_crtc_send_vblank_event()
|
||||
* somewhen after drm_crtc_vblank_off() has been called.
|
||||
*
|
||||
* - For a CRTC which is enabled at the end of the commit (even when it
|
||||
* undergoes an full modeset) the vblank timestamp and counter must
|
||||
|
||||
+31
-2
@@ -327,11 +327,40 @@ struct drm_driver {
|
||||
struct timeval *vblank_time,
|
||||
bool in_vblank_irq);
|
||||
|
||||
/* these have to be filled in */
|
||||
|
||||
/**
|
||||
* @irq_handler:
|
||||
*
|
||||
* Interrupt handler called when using drm_irq_install(). Not used by
|
||||
* drivers which implement their own interrupt handling.
|
||||
*/
|
||||
irqreturn_t(*irq_handler) (int irq, void *arg);
|
||||
|
||||
/**
|
||||
* @irq_preinstall:
|
||||
*
|
||||
* Optional callback used by drm_irq_install() which is called before
|
||||
* the interrupt handler is registered. This should be used to clear out
|
||||
* any pending interrupts (from e.g. firmware based drives) and reset
|
||||
* the interrupt handling registers.
|
||||
*/
|
||||
void (*irq_preinstall) (struct drm_device *dev);
|
||||
|
||||
/**
|
||||
* @irq_postinstall:
|
||||
*
|
||||
* Optional callback used by drm_irq_install() which is called after
|
||||
* the interrupt handler is registered. This should be used to enable
|
||||
* interrupt generation in the hardware.
|
||||
*/
|
||||
int (*irq_postinstall) (struct drm_device *dev);
|
||||
|
||||
/**
|
||||
* @irq_uninstall:
|
||||
*
|
||||
* Optional callback used by drm_irq_uninstall() which is called before
|
||||
* the interrupt handler is unregistered. This should be used to disable
|
||||
* interrupt generation in the hardware.
|
||||
*/
|
||||
void (*irq_uninstall) (struct drm_device *dev);
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
struct dma_fence;
|
||||
struct drm_file;
|
||||
struct drm_device;
|
||||
struct device;
|
||||
|
||||
/*
|
||||
* FIXME: Not sure we want to have drm_minor here in the end, but to avoid
|
||||
|
||||
+1
-157
@@ -24,165 +24,9 @@
|
||||
#ifndef _DRM_IRQ_H_
|
||||
#define _DRM_IRQ_H_
|
||||
|
||||
#include <linux/seqlock.h>
|
||||
|
||||
/**
|
||||
* struct drm_pending_vblank_event - pending vblank event tracking
|
||||
*/
|
||||
struct drm_pending_vblank_event {
|
||||
/**
|
||||
* @base: Base structure for tracking pending DRM events.
|
||||
*/
|
||||
struct drm_pending_event base;
|
||||
/**
|
||||
* @pipe: drm_crtc_index() of the &drm_crtc this event is for.
|
||||
*/
|
||||
unsigned int pipe;
|
||||
/**
|
||||
* @event: Actual event which will be sent to userspace.
|
||||
*/
|
||||
struct drm_event_vblank event;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_vblank_crtc - vblank tracking for a CRTC
|
||||
*
|
||||
* This structure tracks the vblank state for one CRTC.
|
||||
*
|
||||
* Note that for historical reasons - the vblank handling code is still shared
|
||||
* with legacy/non-kms drivers - this is a free-standing structure not directly
|
||||
* connected to &struct drm_crtc. But all public interface functions are taking
|
||||
* a &struct drm_crtc to hide this implementation detail.
|
||||
*/
|
||||
struct drm_vblank_crtc {
|
||||
/**
|
||||
* @dev: Pointer to the &drm_device.
|
||||
*/
|
||||
struct drm_device *dev;
|
||||
/**
|
||||
* @queue: Wait queue for vblank waiters.
|
||||
*/
|
||||
wait_queue_head_t queue; /**< VBLANK wait queue */
|
||||
/**
|
||||
* @disable_timer: Disable timer for the delayed vblank disabling
|
||||
* hysteresis logic. Vblank disabling is controlled through the
|
||||
* drm_vblank_offdelay module option and the setting of the
|
||||
* &drm_device.max_vblank_count value.
|
||||
*/
|
||||
struct timer_list disable_timer;
|
||||
|
||||
/**
|
||||
* @seqlock: Protect vblank count and time.
|
||||
*/
|
||||
seqlock_t seqlock; /* protects vblank count and time */
|
||||
|
||||
/**
|
||||
* @count: Current software vblank counter.
|
||||
*/
|
||||
u32 count;
|
||||
/**
|
||||
* @time: Vblank timestamp corresponding to @count.
|
||||
*/
|
||||
struct timeval time;
|
||||
|
||||
/**
|
||||
* @refcount: Number of users/waiters of the vblank interrupt. Only when
|
||||
* this refcount reaches 0 can the hardware interrupt be disabled using
|
||||
* @disable_timer.
|
||||
*/
|
||||
atomic_t refcount; /* number of users of vblank interruptsper crtc */
|
||||
/**
|
||||
* @last: Protected by &drm_device.vbl_lock, used for wraparound handling.
|
||||
*/
|
||||
u32 last;
|
||||
/**
|
||||
* @inmodeset: Tracks whether the vblank is disabled due to a modeset.
|
||||
* For legacy driver bit 2 additionally tracks whether an additional
|
||||
* temporary vblank reference has been acquired to paper over the
|
||||
* hardware counter resetting/jumping. KMS drivers should instead just
|
||||
* call drm_crtc_vblank_off() and drm_crtc_vblank_on(), which explicitly
|
||||
* save and restore the vblank count.
|
||||
*/
|
||||
unsigned int inmodeset; /* Display driver is setting mode */
|
||||
/**
|
||||
* @pipe: drm_crtc_index() of the &drm_crtc corresponding to this
|
||||
* structure.
|
||||
*/
|
||||
unsigned int pipe;
|
||||
/**
|
||||
* @framedur_ns: Frame/Field duration in ns, used by
|
||||
* drm_calc_vbltimestamp_from_scanoutpos() and computed by
|
||||
* drm_calc_timestamping_constants().
|
||||
*/
|
||||
int framedur_ns;
|
||||
/**
|
||||
* @linedur_ns: Line duration in ns, used by
|
||||
* drm_calc_vbltimestamp_from_scanoutpos() and computed by
|
||||
* drm_calc_timestamping_constants().
|
||||
*/
|
||||
int linedur_ns;
|
||||
|
||||
/**
|
||||
* @hwmode:
|
||||
*
|
||||
* Cache of the current hardware display mode. Only valid when @enabled
|
||||
* is set. This is used by helpers like
|
||||
* drm_calc_vbltimestamp_from_scanoutpos(). We can't just access the
|
||||
* hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode,
|
||||
* because that one is really hard to get from interrupt context.
|
||||
*/
|
||||
struct drm_display_mode hwmode;
|
||||
|
||||
/**
|
||||
* @enabled: Tracks the enabling state of the corresponding &drm_crtc to
|
||||
* avoid double-disabling and hence corrupting saved state. Needed by
|
||||
* drivers not using atomic KMS, since those might go through their CRTC
|
||||
* disabling functions multiple times.
|
||||
*/
|
||||
bool enabled;
|
||||
};
|
||||
struct drm_device;
|
||||
|
||||
int drm_irq_install(struct drm_device *dev, int irq);
|
||||
int drm_irq_uninstall(struct drm_device *dev);
|
||||
|
||||
int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs);
|
||||
u32 drm_crtc_vblank_count(struct drm_crtc *crtc);
|
||||
u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc,
|
||||
struct timeval *vblanktime);
|
||||
void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
|
||||
struct drm_pending_vblank_event *e);
|
||||
void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
|
||||
struct drm_pending_vblank_event *e);
|
||||
bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe);
|
||||
bool drm_crtc_handle_vblank(struct drm_crtc *crtc);
|
||||
int drm_crtc_vblank_get(struct drm_crtc *crtc);
|
||||
void drm_crtc_vblank_put(struct drm_crtc *crtc);
|
||||
void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe);
|
||||
void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
|
||||
void drm_crtc_vblank_off(struct drm_crtc *crtc);
|
||||
void drm_crtc_vblank_reset(struct drm_crtc *crtc);
|
||||
void drm_crtc_vblank_on(struct drm_crtc *crtc);
|
||||
void drm_vblank_cleanup(struct drm_device *dev);
|
||||
u32 drm_accurate_vblank_count(struct drm_crtc *crtc);
|
||||
|
||||
bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
|
||||
unsigned int pipe, int *max_error,
|
||||
struct timeval *vblank_time,
|
||||
bool in_vblank_irq);
|
||||
void drm_calc_timestamping_constants(struct drm_crtc *crtc,
|
||||
const struct drm_display_mode *mode);
|
||||
|
||||
/**
|
||||
* drm_crtc_vblank_waitqueue - get vblank waitqueue for the CRTC
|
||||
* @crtc: which CRTC's vblank waitqueue to retrieve
|
||||
*
|
||||
* This function returns a pointer to the vblank waitqueue for the CRTC.
|
||||
* Drivers can use this to implement vblank waits using wait_event() and related
|
||||
* functions.
|
||||
*/
|
||||
static inline wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc)
|
||||
{
|
||||
return &crtc->dev->vblank[drm_crtc_index(crtc)].queue;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -197,6 +197,8 @@ enum drm_mode_status {
|
||||
* there's the hardware timings, which are corrected for interlacing,
|
||||
* double-clocking and similar things. They are provided as a convenience, and
|
||||
* can be appropriately computed using drm_mode_set_crtcinfo().
|
||||
*
|
||||
* For printing you can use %DRM_MODE_FMT and DRM_MODE_ARG().
|
||||
*/
|
||||
struct drm_display_mode {
|
||||
/**
|
||||
@@ -407,6 +409,21 @@ struct drm_display_mode {
|
||||
enum hdmi_picture_aspect picture_aspect_ratio;
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_MODE_FMT - printf string for &struct drm_display_mode
|
||||
*/
|
||||
#define DRM_MODE_FMT "%d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x"
|
||||
|
||||
/**
|
||||
* DRM_MODE_ARG - printf arguments for &struct drm_display_mode
|
||||
* @m: display mode
|
||||
*/
|
||||
#define DRM_MODE_ARG(m) \
|
||||
(m)->base.id, (m)->name, (m)->vrefresh, (m)->clock, \
|
||||
(m)->hdisplay, (m)->hsync_start, (m)->hsync_end, (m)->htotal, \
|
||||
(m)->vdisplay, (m)->vsync_start, (m)->vsync_end, (m)->vtotal, \
|
||||
(m)->type, (m)->flags
|
||||
|
||||
#define obj_to_mode(x) container_of(x, struct drm_display_mode, base)
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,19 +6,7 @@
|
||||
#include <linux/interrupt.h> /* For task queue support */
|
||||
#include <linux/sched/signal.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#ifndef readq
|
||||
static inline u64 readq(void __iomem *reg)
|
||||
{
|
||||
return ((u64) readl(reg)) | (((u64) readl(reg + 4UL)) << 32);
|
||||
}
|
||||
|
||||
static inline void writeq(u64 val, void __iomem *reg)
|
||||
{
|
||||
writel(val & 0xffffffff, reg);
|
||||
writel(val >> 32, reg + 0x4UL);
|
||||
}
|
||||
#endif
|
||||
#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
|
||||
/** Current process ID */
|
||||
#define DRM_CURRENTPID task_pid_nr(current)
|
||||
|
||||
@@ -59,6 +59,8 @@ struct drm_device;
|
||||
struct drm_gem_object;
|
||||
struct drm_file;
|
||||
|
||||
struct device;
|
||||
|
||||
struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
|
||||
struct drm_gem_object *obj,
|
||||
int flags);
|
||||
|
||||
@@ -42,6 +42,33 @@ struct drm_rect {
|
||||
int x1, y1, x2, y2;
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_RECT_FMT - printf string for &struct drm_rect
|
||||
*/
|
||||
#define DRM_RECT_FMT "%dx%d%+d%+d"
|
||||
/**
|
||||
* DRM_RECT_ARG - printf arguments for &struct drm_rect
|
||||
* @r: rectangle struct
|
||||
*/
|
||||
#define DRM_RECT_ARG(r) drm_rect_width(r), drm_rect_height(r), (r)->x1, (r)->y1
|
||||
|
||||
/**
|
||||
* DRM_RECT_FP_FMT - printf string for &struct drm_rect in 16.16 fixed point
|
||||
*/
|
||||
#define DRM_RECT_FP_FMT "%d.%06ux%d.%06u%+d.%06u%+d.%06u"
|
||||
/**
|
||||
* DRM_RECT_FP_ARG - printf arguments for &struct drm_rect in 16.16 fixed point
|
||||
* @r: rectangle struct
|
||||
*
|
||||
* This is useful for e.g. printing plane source rectangles, which are in 16.16
|
||||
* fixed point.
|
||||
*/
|
||||
#define DRM_RECT_FP_ARG(r) \
|
||||
drm_rect_width(r) >> 16, ((drm_rect_width(r) & 0xffff) * 15625) >> 10, \
|
||||
drm_rect_height(r) >> 16, ((drm_rect_height(r) & 0xffff) * 15625) >> 10, \
|
||||
(r)->x1 >> 16, (((r)->x1 & 0xffff) * 15625) >> 10, \
|
||||
(r)->y1 >> 16, (((r)->y1 & 0xffff) * 15625) >> 10
|
||||
|
||||
/**
|
||||
* drm_rect_adjust_size - adjust the size of the rectangle
|
||||
* @r: rectangle to be adjusted
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright 2016 Intel Corp.
|
||||
*
|
||||
* 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
|
||||
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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.
|
||||
*/
|
||||
|
||||
#ifndef _DRM_VBLANK_H_
|
||||
#define _DRM_VBLANK_H_
|
||||
|
||||
#include <linux/seqlock.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/poll.h>
|
||||
|
||||
#include <drm/drm_file.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <uapi/drm/drm.h>
|
||||
|
||||
struct drm_device;
|
||||
struct drm_crtc;
|
||||
|
||||
/**
|
||||
* struct drm_pending_vblank_event - pending vblank event tracking
|
||||
*/
|
||||
struct drm_pending_vblank_event {
|
||||
/**
|
||||
* @base: Base structure for tracking pending DRM events.
|
||||
*/
|
||||
struct drm_pending_event base;
|
||||
/**
|
||||
* @pipe: drm_crtc_index() of the &drm_crtc this event is for.
|
||||
*/
|
||||
unsigned int pipe;
|
||||
/**
|
||||
* @event: Actual event which will be sent to userspace.
|
||||
*/
|
||||
struct drm_event_vblank event;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_vblank_crtc - vblank tracking for a CRTC
|
||||
*
|
||||
* This structure tracks the vblank state for one CRTC.
|
||||
*
|
||||
* Note that for historical reasons - the vblank handling code is still shared
|
||||
* with legacy/non-kms drivers - this is a free-standing structure not directly
|
||||
* connected to &struct drm_crtc. But all public interface functions are taking
|
||||
* a &struct drm_crtc to hide this implementation detail.
|
||||
*/
|
||||
struct drm_vblank_crtc {
|
||||
/**
|
||||
* @dev: Pointer to the &drm_device.
|
||||
*/
|
||||
struct drm_device *dev;
|
||||
/**
|
||||
* @queue: Wait queue for vblank waiters.
|
||||
*/
|
||||
wait_queue_head_t queue; /**< VBLANK wait queue */
|
||||
/**
|
||||
* @disable_timer: Disable timer for the delayed vblank disabling
|
||||
* hysteresis logic. Vblank disabling is controlled through the
|
||||
* drm_vblank_offdelay module option and the setting of the
|
||||
* &drm_device.max_vblank_count value.
|
||||
*/
|
||||
struct timer_list disable_timer;
|
||||
|
||||
/**
|
||||
* @seqlock: Protect vblank count and time.
|
||||
*/
|
||||
seqlock_t seqlock; /* protects vblank count and time */
|
||||
|
||||
/**
|
||||
* @count: Current software vblank counter.
|
||||
*/
|
||||
u32 count;
|
||||
/**
|
||||
* @time: Vblank timestamp corresponding to @count.
|
||||
*/
|
||||
struct timeval time;
|
||||
|
||||
/**
|
||||
* @refcount: Number of users/waiters of the vblank interrupt. Only when
|
||||
* this refcount reaches 0 can the hardware interrupt be disabled using
|
||||
* @disable_timer.
|
||||
*/
|
||||
atomic_t refcount; /* number of users of vblank interruptsper crtc */
|
||||
/**
|
||||
* @last: Protected by &drm_device.vbl_lock, used for wraparound handling.
|
||||
*/
|
||||
u32 last;
|
||||
/**
|
||||
* @inmodeset: Tracks whether the vblank is disabled due to a modeset.
|
||||
* For legacy driver bit 2 additionally tracks whether an additional
|
||||
* temporary vblank reference has been acquired to paper over the
|
||||
* hardware counter resetting/jumping. KMS drivers should instead just
|
||||
* call drm_crtc_vblank_off() and drm_crtc_vblank_on(), which explicitly
|
||||
* save and restore the vblank count.
|
||||
*/
|
||||
unsigned int inmodeset; /* Display driver is setting mode */
|
||||
/**
|
||||
* @pipe: drm_crtc_index() of the &drm_crtc corresponding to this
|
||||
* structure.
|
||||
*/
|
||||
unsigned int pipe;
|
||||
/**
|
||||
* @framedur_ns: Frame/Field duration in ns, used by
|
||||
* drm_calc_vbltimestamp_from_scanoutpos() and computed by
|
||||
* drm_calc_timestamping_constants().
|
||||
*/
|
||||
int framedur_ns;
|
||||
/**
|
||||
* @linedur_ns: Line duration in ns, used by
|
||||
* drm_calc_vbltimestamp_from_scanoutpos() and computed by
|
||||
* drm_calc_timestamping_constants().
|
||||
*/
|
||||
int linedur_ns;
|
||||
|
||||
/**
|
||||
* @hwmode:
|
||||
*
|
||||
* Cache of the current hardware display mode. Only valid when @enabled
|
||||
* is set. This is used by helpers like
|
||||
* drm_calc_vbltimestamp_from_scanoutpos(). We can't just access the
|
||||
* hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode,
|
||||
* because that one is really hard to get from interrupt context.
|
||||
*/
|
||||
struct drm_display_mode hwmode;
|
||||
|
||||
/**
|
||||
* @enabled: Tracks the enabling state of the corresponding &drm_crtc to
|
||||
* avoid double-disabling and hence corrupting saved state. Needed by
|
||||
* drivers not using atomic KMS, since those might go through their CRTC
|
||||
* disabling functions multiple times.
|
||||
*/
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs);
|
||||
u32 drm_crtc_vblank_count(struct drm_crtc *crtc);
|
||||
u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc,
|
||||
struct timeval *vblanktime);
|
||||
void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
|
||||
struct drm_pending_vblank_event *e);
|
||||
void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
|
||||
struct drm_pending_vblank_event *e);
|
||||
bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe);
|
||||
bool drm_crtc_handle_vblank(struct drm_crtc *crtc);
|
||||
int drm_crtc_vblank_get(struct drm_crtc *crtc);
|
||||
void drm_crtc_vblank_put(struct drm_crtc *crtc);
|
||||
void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe);
|
||||
void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
|
||||
void drm_crtc_vblank_off(struct drm_crtc *crtc);
|
||||
void drm_crtc_vblank_reset(struct drm_crtc *crtc);
|
||||
void drm_crtc_vblank_on(struct drm_crtc *crtc);
|
||||
void drm_vblank_cleanup(struct drm_device *dev);
|
||||
u32 drm_accurate_vblank_count(struct drm_crtc *crtc);
|
||||
|
||||
bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
|
||||
unsigned int pipe, int *max_error,
|
||||
struct timeval *vblank_time,
|
||||
bool in_vblank_irq);
|
||||
void drm_calc_timestamping_constants(struct drm_crtc *crtc,
|
||||
const struct drm_display_mode *mode);
|
||||
wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc);
|
||||
#endif
|
||||
Reference in New Issue
Block a user