On Wed, Aug 12, 2015 at 05:00:31PM +0200, Thierry Reding wrote:
From: Thierry Reding treding@nvidia.com
Name all references to the pipe number (CRTC index) consistently to make it easier to distinguish which is a pipe number and which is a pointer to struct drm_crtc.
While at it also make all references to the pipe number unsigned because there is no longer any reason why it should ever be negative.
Signed-off-by: Thierry Reding treding@nvidia.com
There's 2 "int crtc" and one "int pipe" (without the unsigned) left after this patch. Can you please do a follow-up? Applied this meanwhile. -Daniel
drivers/gpu/drm/drm_irq.c | 316 +++++++++++++++++++++++----------------------- include/drm/drmP.h | 32 ++--- 2 files changed, 175 insertions(+), 173 deletions(-)
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index a957b9618e85..f42459b2862d 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -43,8 +43,8 @@ #include <linux/export.h>
/* Access macro for slots in vblank timestamp ringbuffer. */ -#define vblanktimestamp(dev, crtc, count) \
- ((dev)->vblank[crtc].time[(count) % DRM_VBLANKTIME_RBSIZE])
+#define vblanktimestamp(dev, pipe, count) \
- ((dev)->vblank[pipe].time[(count) % DRM_VBLANKTIME_RBSIZE])
/* Retry timestamp calculation up to 3 times to satisfy
- drm_timestamp_precision before giving up.
@@ -57,7 +57,7 @@ #define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
static bool -drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, +drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, struct timeval *tvblank, unsigned flags);
static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ @@ -107,7 +107,7 @@ static void store_vblank(struct drm_device *dev, int crtc, /**
- drm_update_vblank_count - update the master vblank counter
- @dev: DRM device
- @crtc: counter to update
- @pipe: counter to update
- Call back into the driver to update the appropriate vblank counter
- (specified by @crtc). Deal with wraparound, if it occurred, and
@@ -120,9 +120,9 @@ static void store_vblank(struct drm_device *dev, int crtc,
- Note: caller must hold dev->vbl_lock since this reads & writes
- device vblank fields.
*/ -static void drm_update_vblank_count(struct drm_device *dev, int crtc) +static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe) {
- struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
- struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; u32 cur_vblank, diff; bool rc; struct timeval t_vblank;
@@ -140,21 +140,21 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) * corresponding vblank timestamp. */ do {
cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0);
- } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc));
cur_vblank = dev->driver->get_vblank_counter(dev, pipe);
rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, 0);
} while (cur_vblank != dev->driver->get_vblank_counter(dev, pipe));
/* Deal with counter wrap */ diff = cur_vblank - vblank->last; if (cur_vblank < vblank->last) { diff += dev->max_vblank_count + 1;
DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
crtc, vblank->last, cur_vblank, diff);
DRM_DEBUG("last_vblank[%u]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
}pipe, vblank->last, cur_vblank, diff);
- DRM_DEBUG("updating vblank count on crtc %d, missed %d\n",
crtc, diff);
DRM_DEBUG("updating vblank count on crtc %u, missed %d\n",
pipe, diff);
if (diff == 0) return;
@@ -167,7 +167,7 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) if (!rc) t_vblank = (struct timeval) {0, 0};
- store_vblank(dev, crtc, diff, &t_vblank);
- store_vblank(dev, pipe, diff, &t_vblank);
}
/* @@ -176,9 +176,9 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc)
- are preserved, even if there are any spurious vblank irq's after
- disable.
*/ -static void vblank_disable_and_save(struct drm_device *dev, int crtc) +static void vblank_disable_and_save(struct drm_device *dev, unsigned int pipe) {
- struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
- struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; unsigned long irqflags; u32 vblcount; s64 diff_ns;
@@ -206,8 +206,8 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) * vblank interrupt is disabled. */ if (!vblank->enabled &&
drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0)) {
drm_update_vblank_count(dev, crtc);
drm_get_last_vbltimestamp(dev, pipe, &tvblank, 0)) {
spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); return; }drm_update_vblank_count(dev, pipe);
@@ -218,7 +218,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) * hardware potentially runtime suspended. */ if (vblank->enabled) {
dev->driver->disable_vblank(dev, crtc);
vblank->enabled = false; }dev->driver->disable_vblank(dev, pipe);
@@ -235,9 +235,9 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) * delayed gpu counter increment. */ do {
vblank->last = dev->driver->get_vblank_counter(dev, crtc);
vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0);
- } while (vblank->last != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblrc);
vblank->last = dev->driver->get_vblank_counter(dev, pipe);
vblrc = drm_get_last_vbltimestamp(dev, pipe, &tvblank, 0);
} while (vblank->last != dev->driver->get_vblank_counter(dev, pipe) && (--count) && vblrc);
if (!count) vblrc = 0;
@@ -247,7 +247,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) */ vblcount = vblank->count; diff_ns = timeval_to_ns(&tvblank) -
timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount));
timeval_to_ns(&vblanktimestamp(dev, pipe, vblcount));
/* If there is at least 1 msec difference between the last stored
- timestamp and tvblank, then we are currently executing our
@@ -262,7 +262,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) * hope for the best. */ if (vblrc && (abs64(diff_ns) > 1000000))
store_vblank(dev, crtc, 1, &tvblank);
store_vblank(dev, pipe, 1, &tvblank);
spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
} @@ -271,16 +271,16 @@ static void vblank_disable_fn(unsigned long arg) { struct drm_vblank_crtc *vblank = (void *)arg; struct drm_device *dev = vblank->dev;
- unsigned int pipe = vblank->pipe; unsigned long irqflags;
int crtc = vblank->crtc;
if (!dev->vblank_disable_allowed) return;
spin_lock_irqsave(&dev->vbl_lock, irqflags); if (atomic_read(&vblank->refcount) == 0 && vblank->enabled) {
DRM_DEBUG("disabling vblank on crtc %d\n", crtc);
vblank_disable_and_save(dev, crtc);
DRM_DEBUG("disabling vblank on crtc %u\n", pipe);
} spin_unlock_irqrestore(&dev->vbl_lock, irqflags);vblank_disable_and_save(dev, pipe);
} @@ -293,14 +293,14 @@ static void vblank_disable_fn(unsigned long arg) */ void drm_vblank_cleanup(struct drm_device *dev) {
- int crtc;
unsigned int pipe;
/* Bail if the driver didn't call drm_vblank_init() */ if (dev->num_crtcs == 0) return;
- for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
for (pipe = 0; pipe < dev->num_crtcs; pipe++) {
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
WARN_ON(vblank->enabled && drm_core_check_feature(dev, DRIVER_MODESET));
@@ -316,17 +316,18 @@ EXPORT_SYMBOL(drm_vblank_cleanup);
/**
- drm_vblank_init - initialize vblank support
- @dev: drm_device
- @num_crtcs: number of crtcs supported by @dev
- @dev: DRM device
*/
- @num_crtcs: number of CRTCs supported by @dev
- This function initializes vblank support for @num_crtcs display pipelines.
- Returns:
- Zero on success or a negative error code on failure.
-int drm_vblank_init(struct drm_device *dev, int num_crtcs) +int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs) {
- int i, ret = -ENOMEM;
int ret = -ENOMEM;
unsigned int i;
spin_lock_init(&dev->vbl_lock); spin_lock_init(&dev->vblank_time_lock);
@@ -341,7 +342,7 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) struct drm_vblank_crtc *vblank = &dev->vblank[i];
vblank->dev = dev;
vblank->crtc = i;
init_waitqueue_head(&vblank->queue); setup_timer(&vblank->disable_timer, vblank_disable_fn, (unsigned long)vblank);vblank->pipe = i;
@@ -624,17 +625,17 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc, if (mode->flags & DRM_MODE_FLAG_INTERLACE) framedur_ns /= 2; } else
DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n",
DRM_ERROR("crtc %u: Can't calculate constants, dotclock = 0!\n", crtc->base.id);
crtc->pixeldur_ns = pixeldur_ns; crtc->linedur_ns = linedur_ns; crtc->framedur_ns = framedur_ns;
- DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
- DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n", crtc->base.id, mode->crtc_htotal, mode->crtc_vtotal, mode->crtc_vdisplay);
- DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n",
- DRM_DEBUG("crtc %u: clock %d kHz framedur %d linedur %d, pixeldur %d\n", crtc->base.id, dotclock, framedur_ns, linedur_ns, pixeldur_ns);
} @@ -643,7 +644,7 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); /**
- drm_calc_vbltimestamp_from_scanoutpos - precise vblank timestamp helper
- @dev: DRM device
- @crtc: Which CRTC's vblank timestamp to retrieve
- @pipe: index of CRTC whose vblank timestamp to retrieve
- @max_error: Desired maximum allowable error in timestamps (nanosecs)
On return contains true maximum error of timestamp
- @vblank_time: Pointer to struct timeval which should receive the timestamp
@@ -686,7 +687,8 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
- DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval.
*/ -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, +int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags,
@@ -700,8 +702,8 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; bool invbl;
- if (crtc < 0 || crtc >= dev->num_crtcs) {
DRM_ERROR("Invalid crtc %d\n", crtc);
- if (pipe >= dev->num_crtcs) {
return -EINVAL; }DRM_ERROR("Invalid crtc %u\n", pipe);
@@ -720,7 +722,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, * Happens during initial modesetting of a crtc. */ if (framedur_ns == 0) {
DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc);
return -EAGAIN; }DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe);
@@ -736,13 +738,13 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, * Get vertical and horizontal scanout position vpos, hpos, * and bounding timestamps stime, etime, pre/post query. */
vbl_status = dev->driver->get_scanout_position(dev, crtc, flags, &vpos,
vbl_status = dev->driver->get_scanout_position(dev, pipe, flags, &vpos, &hpos, &stime, &etime);
/* Return as no-op if scanout query unsupported or failed. */ if (!(vbl_status & DRM_SCANOUTPOS_VALID)) {
DRM_DEBUG("crtc %d : scanoutpos query failed [%d].\n",
crtc, vbl_status);
DRM_DEBUG("crtc %u : scanoutpos query failed [%d].\n",
}pipe, vbl_status); return -EIO;
@@ -756,8 +758,8 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
/* Noisy system timing? */ if (i == DRM_TIMESTAMP_MAXRETRIES) {
DRM_DEBUG("crtc %d: Noisy timestamp %d us > %d us [%d reps].\n",
crtc, duration_ns/1000, *max_error/1000, i);
DRM_DEBUG("crtc %u: Noisy timestamp %d us > %d us [%d reps].\n",
pipe, duration_ns/1000, *max_error/1000, i);
}
/* Return upper bound of timestamp precision error. */
@@ -790,8 +792,8 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, etime = ktime_sub_ns(etime, delta_ns); *vblank_time = ktime_to_timeval(etime);
- DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n",
crtc, (int)vbl_status, hpos, vpos,
- DRM_DEBUG("crtc %u : v %d p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n",
(long)tv_etime.tv_sec, (long)tv_etime.tv_usec, (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, duration_ns/1000, i);pipe, (int)vbl_status, hpos, vpos,
@@ -816,7 +818,7 @@ static struct timeval get_drm_timestamp(void)
- drm_get_last_vbltimestamp - retrieve raw timestamp for the most recent
vblank interval
- @dev: DRM device
- @crtc: which CRTC's vblank timestamp to retrieve
- @pipe: index of CRTC whose vblank timestamp to retrieve
- @tvblank: Pointer to target struct timeval which should receive the timestamp
- @flags: Flags to pass to driver:
0 = Default,
@@ -833,7 +835,7 @@ static struct timeval get_drm_timestamp(void)
- True if timestamp is considered to be very precise, false otherwise.
*/ static bool -drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, +drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, struct timeval *tvblank, unsigned flags) { int ret; @@ -843,7 +845,7 @@ drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
/* Query driver if possible and precision timestamping enabled. */ if (dev->driver->get_vblank_timestamp && (max_error > 0)) {
ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error,
if (ret > 0) return true;ret = dev->driver->get_vblank_timestamp(dev, pipe, &max_error, tvblank, flags);
@@ -860,7 +862,7 @@ drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, /**
- drm_vblank_count - retrieve "cooked" vblank counter value
- @dev: DRM device
- @crtc: which counter to retrieve
- @pipe: index of CRTC for which to retrieve the counter
- Fetches the "cooked" vblank count value that represents the number of
- vblank events since the system was booted, including lost events due to
@@ -871,11 +873,11 @@ drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
- Returns:
- The software vblank counter.
*/ -u32 drm_vblank_count(struct drm_device *dev, int crtc) +u32 drm_vblank_count(struct drm_device *dev, int pipe) {
- struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
- struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
- if (WARN_ON(crtc >= dev->num_crtcs))
- if (WARN_ON(pipe >= dev->num_crtcs)) return 0; return vblank->count;
} @@ -901,11 +903,10 @@ u32 drm_crtc_vblank_count(struct drm_crtc *crtc) EXPORT_SYMBOL(drm_crtc_vblank_count);
/**
- drm_vblank_count_and_time - retrieve "cooked" vblank counter value
- and the system timestamp corresponding to that vblank counter value.
- drm_vblank_count_and_time - retrieve "cooked" vblank counter value and the
system timestamp corresponding to that vblank counter value.
- @dev: DRM device
- @crtc: which counter to retrieve
- @pipe: index of CRTC whose counter to retrieve
- @vblanktime: Pointer to struct timeval to receive the vblank timestamp.
- Fetches the "cooked" vblank count value that represents the number of
@@ -913,13 +914,13 @@ EXPORT_SYMBOL(drm_crtc_vblank_count);
- modesetting activity. Returns corresponding system timestamp of the time
- of the vblank interval that corresponds to the current vblank counter value.
*/ -u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, +u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe, struct timeval *vblanktime) {
- struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
- struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; u32 cur_vblank;
- if (WARN_ON(crtc >= dev->num_crtcs))
if (WARN_ON(pipe >= dev->num_crtcs)) return 0;
/*
@@ -930,7 +931,7 @@ u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, do { cur_vblank = vblank->count; smp_rmb();
*vblanktime = vblanktimestamp(dev, crtc, cur_vblank);
smp_rmb(); } while (cur_vblank != vblank->count);*vblanktime = vblanktimestamp(dev, pipe, cur_vblank);
@@ -957,7 +958,7 @@ static void send_vblank_event(struct drm_device *dev, /**
- drm_send_vblank_event - helper to send vblank event after pageflip
- @dev: DRM device
- @crtc: CRTC in question
- @pipe: CRTC index
- @e: the event to send
- Updates sequence # and timestamp on event, and sends it to userspace.
@@ -965,20 +966,20 @@ static void send_vblank_event(struct drm_device *dev,
- This is the legacy version of drm_crtc_send_vblank_event().
*/ -void drm_send_vblank_event(struct drm_device *dev, int crtc,
struct drm_pending_vblank_event *e)
+void drm_send_vblank_event(struct drm_device *dev, unsigned int pipe,
struct drm_pending_vblank_event *e)
{ struct timeval now; unsigned int seq;
if (dev->num_crtcs > 0) {
seq = drm_vblank_count_and_time(dev, crtc, &now);
seq = drm_vblank_count_and_time(dev, pipe, &now);
} else { seq = 0;
now = get_drm_timestamp(); }
- e->pipe = crtc;
- e->pipe = pipe; send_vblank_event(dev, e, seq, &now);
} EXPORT_SYMBOL(drm_send_vblank_event); @@ -1003,11 +1004,11 @@ EXPORT_SYMBOL(drm_crtc_send_vblank_event); /**
- drm_vblank_enable - enable the vblank interrupt on a CRTC
- @dev: DRM device
- @crtc: CRTC in question
*/
- @pipe: CRTC index
-static int drm_vblank_enable(struct drm_device *dev, int crtc) +static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe) {
- struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; int ret = 0;
assert_spin_locked(&dev->vbl_lock);
@@ -1022,13 +1023,13 @@ static int drm_vblank_enable(struct drm_device *dev, int crtc) * timestamps. Filtercode in drm_handle_vblank() will * prevent double-accounting of same vblank interval. */
ret = dev->driver->enable_vblank(dev, crtc);
DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
ret = dev->driver->enable_vblank(dev, pipe);
if (ret) atomic_dec(&vblank->refcount); else { vblank->enabled = true;DRM_DEBUG("enabling vblank on crtc %u, ret: %d\n", pipe, ret);
drm_update_vblank_count(dev, crtc);
} }drm_update_vblank_count(dev, pipe);
@@ -1040,7 +1041,7 @@ static int drm_vblank_enable(struct drm_device *dev, int crtc) /**
- drm_vblank_get - get a reference count on vblank events
- @dev: DRM device
- @crtc: which CRTC to own
- @pipe: index of CRTC to own
- Acquire a reference count on vblank events to avoid having them disabled
- while in use.
@@ -1050,22 +1051,22 @@ static int drm_vblank_enable(struct drm_device *dev, int crtc)
- Returns:
- Zero on success, nonzero on failure.
*/ -int drm_vblank_get(struct drm_device *dev, int crtc) +int drm_vblank_get(struct drm_device *dev, unsigned int pipe) {
- struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; unsigned long irqflags; int ret = 0;
if (!dev->num_crtcs) return -EINVAL;
- if (WARN_ON(crtc >= dev->num_crtcs))
if (WARN_ON(pipe >= dev->num_crtcs)) return -EINVAL;
spin_lock_irqsave(&dev->vbl_lock, irqflags); /* Going from 0->1 means we have to enable interrupts again */ if (atomic_add_return(1, &vblank->refcount) == 1) {
ret = drm_vblank_enable(dev, crtc);
} else { if (!vblank->enabled) { atomic_dec(&vblank->refcount);ret = drm_vblank_enable(dev, pipe);
@@ -1097,20 +1098,20 @@ int drm_crtc_vblank_get(struct drm_crtc *crtc) EXPORT_SYMBOL(drm_crtc_vblank_get);
/**
- drm_vblank_put - give up ownership of vblank events
- drm_vblank_put - release ownership of vblank events
- @dev: DRM device
- @crtc: which counter to give up
*/
- @pipe: index of CRTC to release
- Release ownership of a given vblank counter, turning off interrupts
- if possible. Disable interrupts after drm_vblank_offdelay milliseconds.
- This is the legacy version of drm_crtc_vblank_put().
-void drm_vblank_put(struct drm_device *dev, int crtc) +void drm_vblank_put(struct drm_device *dev, unsigned int pipe) {
- struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
- struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
- if (WARN_ON(crtc >= dev->num_crtcs))
if (WARN_ON(pipe >= dev->num_crtcs)) return;
if (WARN_ON(atomic_read(&vblank->refcount) == 0))
@@ -1147,33 +1148,34 @@ EXPORT_SYMBOL(drm_crtc_vblank_put); /**
- drm_wait_one_vblank - wait for one vblank
- @dev: DRM device
- @crtc: crtc index
*/
- @pipe: CRTC index
- This waits for one vblank to pass on @crtc, using the irq driver interfaces.
- It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
- due to lack of driver support or because the crtc is off.
-void drm_wait_one_vblank(struct drm_device *dev, int crtc) +void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe) {
- struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; int ret; u32 last;
- if (WARN_ON(crtc >= dev->num_crtcs))
- if (WARN_ON(pipe >= dev->num_crtcs)) return;
- ret = drm_vblank_get(dev, crtc);
- if (WARN(ret, "vblank not available on crtc %i, ret=%i\n", crtc, ret))
- ret = drm_vblank_get(dev, pipe);
- if (WARN(ret, "vblank not available on crtc %i, ret=%i\n", pipe, ret)) return;
- last = drm_vblank_count(dev, crtc);
- last = drm_vblank_count(dev, pipe);
- ret = wait_event_timeout(dev->vblank[crtc].queue,
last != drm_vblank_count(dev, crtc),
- ret = wait_event_timeout(vblank->queue,
last != drm_vblank_count(dev, pipe), msecs_to_jiffies(100));
- WARN(ret == 0, "vblank wait timed out on crtc %i\n", crtc);
- WARN(ret == 0, "vblank wait timed out on crtc %i\n", pipe);
- drm_vblank_put(dev, crtc);
- drm_vblank_put(dev, pipe);
} EXPORT_SYMBOL(drm_wait_one_vblank);
@@ -1194,7 +1196,7 @@ EXPORT_SYMBOL(drm_crtc_wait_one_vblank); /**
- drm_vblank_off - disable vblank events on a CRTC
- @dev: DRM device
- @crtc: CRTC in question
- @pipe: CRTC index
- Drivers can use this function to shut down the vblank interrupt handling when
- disabling a crtc. This function ensures that the latest vblank frame count is
@@ -1205,21 +1207,21 @@ EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
- This is the legacy version of drm_crtc_vblank_off().
*/ -void drm_vblank_off(struct drm_device *dev, int crtc) +void drm_vblank_off(struct drm_device *dev, unsigned int pipe) {
- struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
- struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; struct drm_pending_vblank_event *e, *t; struct timeval now; unsigned long irqflags; unsigned int seq;
- if (WARN_ON(crtc >= dev->num_crtcs))
if (WARN_ON(pipe >= dev->num_crtcs)) return;
spin_lock_irqsave(&dev->event_lock, irqflags);
spin_lock(&dev->vbl_lock);
- vblank_disable_and_save(dev, crtc);
vblank_disable_and_save(dev, pipe); wake_up(&vblank->queue);
/*
@@ -1233,16 +1235,16 @@ void drm_vblank_off(struct drm_device *dev, int crtc) spin_unlock(&dev->vbl_lock);
/* Send any queued vblank events, lest the natives grow disquiet */
- seq = drm_vblank_count_and_time(dev, crtc, &now);
seq = drm_vblank_count_and_time(dev, pipe, &now);
list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
if (e->pipe != crtc)
DRM_DEBUG("Sending premature vblank event on disable: \ wanted %d, current %d\n", e->event.sequence, seq); list_del(&e->base.link);if (e->pipe != pipe) continue;
drm_vblank_put(dev, e->pipe);
send_vblank_event(dev, e, seq, &now); } spin_unlock_irqrestore(&dev->event_lock, irqflags);drm_vblank_put(dev, pipe);
@@ -1303,7 +1305,7 @@ EXPORT_SYMBOL(drm_crtc_vblank_reset); /**
- drm_vblank_on - enable vblank events on a CRTC
- @dev: DRM device
- @crtc: CRTC in question
- @pipe: CRTC index
- This functions restores the vblank interrupt state captured with
- drm_vblank_off() again. Note that calls to drm_vblank_on() and
@@ -1312,12 +1314,12 @@ EXPORT_SYMBOL(drm_crtc_vblank_reset);
- This is the legacy version of drm_crtc_vblank_on().
*/ -void drm_vblank_on(struct drm_device *dev, int crtc) +void drm_vblank_on(struct drm_device *dev, unsigned int pipe) {
- struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
- struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; unsigned long irqflags;
- if (WARN_ON(crtc >= dev->num_crtcs))
if (WARN_ON(pipe >= dev->num_crtcs)) return;
spin_lock_irqsave(&dev->vbl_lock, irqflags);
@@ -1335,7 +1337,7 @@ void drm_vblank_on(struct drm_device *dev, int crtc) * vblank counter value before and after a modeset */ vblank->last =
(dev->driver->get_vblank_counter(dev, crtc) - 1) &
dev->max_vblank_count; /*(dev->driver->get_vblank_counter(dev, pipe) - 1) &
- re-enable interrupts if there are users left, or the
@@ -1343,7 +1345,7 @@ void drm_vblank_on(struct drm_device *dev, int crtc) */ if (atomic_read(&vblank->refcount) != 0 || (!dev->vblank_disable_immediate && drm_vblank_offdelay == 0))
WARN_ON(drm_vblank_enable(dev, crtc));
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);WARN_ON(drm_vblank_enable(dev, pipe));
} EXPORT_SYMBOL(drm_vblank_on); @@ -1368,7 +1370,7 @@ EXPORT_SYMBOL(drm_crtc_vblank_on); /**
- drm_vblank_pre_modeset - account for vblanks across mode sets
- @dev: DRM device
- @crtc: CRTC in question
- @pipe: CRTC index
- Account for vblank events across mode setting events, which will likely
- reset the hardware frame counter.
@@ -1388,15 +1390,15 @@ EXPORT_SYMBOL(drm_crtc_vblank_on);
- Drivers must call drm_vblank_post_modeset() when re-enabling the same crtc
- again.
*/ -void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) +void drm_vblank_pre_modeset(struct drm_device *dev, unsigned int pipe) {
- struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
/* vblank is not initialized (IRQ not installed ?), or has been freed */ if (!dev->num_crtcs) return;
- if (WARN_ON(crtc >= dev->num_crtcs))
if (WARN_ON(pipe >= dev->num_crtcs)) return;
/*
@@ -1408,7 +1410,7 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) */ if (!vblank->inmodeset) { vblank->inmodeset = 0x1;
if (drm_vblank_get(dev, crtc) == 0)
}if (drm_vblank_get(dev, pipe) == 0) vblank->inmodeset |= 0x2;
} @@ -1417,21 +1419,21 @@ EXPORT_SYMBOL(drm_vblank_pre_modeset); /**
- drm_vblank_post_modeset - undo drm_vblank_pre_modeset changes
- @dev: DRM device
- @crtc: CRTC in question
*/
- @pipe: CRTC index
- This function again drops the temporary vblank reference acquired in
- drm_vblank_pre_modeset.
-void drm_vblank_post_modeset(struct drm_device *dev, int crtc) +void drm_vblank_post_modeset(struct drm_device *dev, unsigned int pipe) {
- struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; unsigned long irqflags;
/* vblank is not initialized (IRQ not installed ?), or has been freed */ if (!dev->num_crtcs) return;
- if (WARN_ON(crtc >= dev->num_crtcs))
if (WARN_ON(pipe >= dev->num_crtcs)) return;
if (vblank->inmodeset) {
@@ -1440,7 +1442,7 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc) spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
if (vblank->inmodeset & 0x2)
drm_vblank_put(dev, crtc);
drm_vblank_put(dev, pipe);
vblank->inmodeset = 0; }
@@ -1462,7 +1464,7 @@ int drm_modeset_ctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_modeset_ctl *modeset = data;
- unsigned int crtc;
unsigned int pipe;
/* If drm_vblank_init() hasn't been called yet, just no-op */ if (!dev->num_crtcs)
@@ -1472,16 +1474,16 @@ int drm_modeset_ctl(struct drm_device *dev, void *data, if (drm_core_check_feature(dev, DRIVER_MODESET)) return 0;
- crtc = modeset->crtc;
- if (crtc >= dev->num_crtcs)
pipe = modeset->crtc;
if (pipe >= dev->num_crtcs) return -EINVAL;
switch (modeset->cmd) { case _DRM_PRE_MODESET:
drm_vblank_pre_modeset(dev, crtc);
break; case _DRM_POST_MODESET:drm_vblank_pre_modeset(dev, pipe);
drm_vblank_post_modeset(dev, crtc);
break; default: return -EINVAL;drm_vblank_post_modeset(dev, pipe);
@@ -1490,7 +1492,7 @@ int drm_modeset_ctl(struct drm_device *dev, void *data, return 0; }
-static int drm_queue_vblank_event(struct drm_device *dev, int pipe, +static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe, union drm_wait_vblank *vblwait, struct drm_file *file_priv) { @@ -1544,7 +1546,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, vblwait->reply.sequence = vblwait->request.sequence; }
- DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n",
DRM_DEBUG("event on vblank count %d, current %d, crtc %u\n", vblwait->request.sequence, seq, pipe);
trace_drm_vblank_event_queued(current->pid, pipe,
@@ -1593,7 +1595,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_vblank_crtc *vblank; union drm_wait_vblank *vblwait = data; int ret;
- unsigned int flags, seq, crtc, high_crtc;
unsigned int flags, seq, pipe, high_pipe;
if (!dev->irq_enabled) return -EINVAL;
@@ -1612,22 +1614,22 @@ int drm_wait_vblank(struct drm_device *dev, void *data, }
flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
- high_crtc = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK);
- if (high_crtc)
crtc = high_crtc >> _DRM_VBLANK_HIGH_CRTC_SHIFT;
- high_pipe = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK);
- if (high_pipe)
elsepipe = high_pipe >> _DRM_VBLANK_HIGH_CRTC_SHIFT;
crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
- if (crtc >= dev->num_crtcs)
pipe = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
- if (pipe >= dev->num_crtcs) return -EINVAL;
- vblank = &dev->vblank[crtc];
- vblank = &dev->vblank[pipe];
- ret = drm_vblank_get(dev, crtc);
- ret = drm_vblank_get(dev, pipe); if (ret) { DRM_DEBUG("failed to acquire vblank counter, %d\n", ret); return ret; }
- seq = drm_vblank_count(dev, crtc);
seq = drm_vblank_count(dev, pipe);
switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { case _DRM_VBLANK_RELATIVE:
@@ -1644,7 +1646,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, /* must hold on to the vblank ref until the event fires * drm_vblank_put will be called asynchronously */
return drm_queue_vblank_event(dev, crtc, vblwait, file_priv);
return drm_queue_vblank_event(dev, pipe, vblwait, file_priv);
}
if ((flags & _DRM_VBLANK_NEXTONMISS) &&
@@ -1652,11 +1654,11 @@ int drm_wait_vblank(struct drm_device *dev, void *data, vblwait->request.sequence = seq + 1; }
- DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
vblwait->request.sequence, crtc);
- DRM_DEBUG("waiting on vblank count %d, crtc %u\n",
vblank->last_wait = vblwait->request.sequence; DRM_WAIT_ON(ret, vblank->queue, 3 * HZ,vblwait->request.sequence, pipe);
(((drm_vblank_count(dev, crtc) -
(((drm_vblank_count(dev, pipe) - vblwait->request.sequence) <= (1 << 23)) || !vblank->enabled || !dev->irq_enabled));
@@ -1664,7 +1666,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, if (ret != -EINTR) { struct timeval now;
vblwait->reply.sequence = drm_vblank_count_and_time(dev, crtc, &now);
vblwait->reply.tval_sec = now.tv_sec; vblwait->reply.tval_usec = now.tv_usec;vblwait->reply.sequence = drm_vblank_count_and_time(dev, pipe, &now);
@@ -1675,11 +1677,11 @@ int drm_wait_vblank(struct drm_device *dev, void *data, }
done:
- drm_vblank_put(dev, crtc);
- drm_vblank_put(dev, pipe); return ret;
}
-static void drm_handle_vblank_events(struct drm_device *dev, int crtc) +static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe) { struct drm_pending_vblank_event *e, *t; struct timeval now; @@ -1687,10 +1689,10 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc)
assert_spin_locked(&dev->event_lock);
- seq = drm_vblank_count_and_time(dev, crtc, &now);
seq = drm_vblank_count_and_time(dev, pipe, &now);
list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
if (e->pipe != crtc)
if ((seq - e->event.sequence) > (1<<23)) continue;if (e->pipe != pipe) continue;
@@ -1699,26 +1701,26 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc) e->event.sequence, seq);
list_del(&e->base.link);
drm_vblank_put(dev, e->pipe);
send_vblank_event(dev, e, seq, &now); }drm_vblank_put(dev, pipe);
- trace_drm_vblank_event(crtc, seq);
- trace_drm_vblank_event(pipe, seq);
}
/**
- drm_handle_vblank - handle a vblank event
- @dev: DRM device
- @crtc: where this event occurred
*/
- @pipe: index of CRTC where this event occurred
- Drivers should call this routine in their vblank interrupt handlers to
- update the vblank counter and send any signals that may be pending.
- This is the legacy version of drm_crtc_handle_vblank().
-bool drm_handle_vblank(struct drm_device *dev, int crtc) +bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe) {
- struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
- struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; u32 vblcount; s64 diff_ns; struct timeval tvblank;
@@ -1727,7 +1729,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) if (WARN_ON_ONCE(!dev->num_crtcs)) return false;
- if (WARN_ON(crtc >= dev->num_crtcs))
if (WARN_ON(pipe >= dev->num_crtcs)) return false;
spin_lock_irqsave(&dev->event_lock, irqflags);
@@ -1751,11 +1753,11 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
/* Get current timestamp and count. */ vblcount = vblank->count;
- drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ);
drm_get_last_vbltimestamp(dev, pipe, &tvblank, DRM_CALLED_FROM_VBLIRQ);
/* Compute time difference to timestamp of last vblank */ diff_ns = timeval_to_ns(&tvblank) -
timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount));
timeval_to_ns(&vblanktimestamp(dev, pipe, vblcount));
/* Update vblank timestamp and count if at least
- DRM_REDUNDANT_VBLIRQ_THRESH_NS nanoseconds
@@ -1767,15 +1769,15 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) * ignore those for accounting. */ if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS)
store_vblank(dev, crtc, 1, &tvblank);
elsestore_vblank(dev, pipe, 1, &tvblank);
DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n",
crtc, (int) diff_ns);
DRM_DEBUG("crtc %u: Redundant vblirq ignored. diff_ns = %d\n",
pipe, (int) diff_ns);
spin_unlock(&dev->vblank_time_lock);
wake_up(&vblank->queue);
- drm_handle_vblank_events(dev, crtc);
drm_handle_vblank_events(dev, pipe);
spin_unlock_irqrestore(&dev->event_lock, irqflags);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 5908848d86b3..020afa343dff 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -681,7 +681,7 @@ struct drm_minor {
struct drm_pending_vblank_event { struct drm_pending_event base;
- int pipe;
- unsigned int pipe; struct drm_event_vblank event;
};
@@ -700,7 +700,7 @@ struct drm_vblank_crtc { /* for wraparound handling */ u32 last_wait; /* Last vblank seqno waited per CRTC */ unsigned int inmodeset; /* Display driver is setting mode */
- int crtc; /* crtc index */
- unsigned int pipe; /* crtc index */ bool enabled; /* so we don't call enable more than once per disable */
}; @@ -920,34 +920,34 @@ void drm_clflush_virt_range(void *addr, unsigned long length); extern int drm_irq_install(struct drm_device *dev, int irq); extern int drm_irq_uninstall(struct drm_device *dev);
-extern int drm_vblank_init(struct drm_device *dev, int num_crtcs); +extern int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs); extern int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *filp); -extern u32 drm_vblank_count(struct drm_device *dev, int crtc); +extern u32 drm_vblank_count(struct drm_device *dev, int pipe); extern u32 drm_crtc_vblank_count(struct drm_crtc *crtc); -extern u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, +extern u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe, struct timeval *vblanktime); -extern void drm_send_vblank_event(struct drm_device *dev, int crtc,
struct drm_pending_vblank_event *e);
+extern void drm_send_vblank_event(struct drm_device *dev, unsigned int pipe,
struct drm_pending_vblank_event *e);
extern void drm_crtc_send_vblank_event(struct drm_crtc *crtc, struct drm_pending_vblank_event *e); -extern bool drm_handle_vblank(struct drm_device *dev, int crtc); +extern bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe); extern bool drm_crtc_handle_vblank(struct drm_crtc *crtc); -extern int drm_vblank_get(struct drm_device *dev, int crtc); -extern void drm_vblank_put(struct drm_device *dev, int crtc); +extern int drm_vblank_get(struct drm_device *dev, unsigned int pipe); +extern void drm_vblank_put(struct drm_device *dev, unsigned int pipe); extern int drm_crtc_vblank_get(struct drm_crtc *crtc); extern void drm_crtc_vblank_put(struct drm_crtc *crtc); -extern void drm_wait_one_vblank(struct drm_device *dev, int crtc); +extern void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe); extern void drm_crtc_wait_one_vblank(struct drm_crtc *crtc); -extern void drm_vblank_off(struct drm_device *dev, int crtc); -extern void drm_vblank_on(struct drm_device *dev, int crtc); +extern void drm_vblank_off(struct drm_device *dev, unsigned int pipe); +extern void drm_vblank_on(struct drm_device *dev, unsigned int pipe); extern void drm_crtc_vblank_off(struct drm_crtc *crtc); extern void drm_crtc_vblank_reset(struct drm_crtc *crtc); extern void drm_crtc_vblank_on(struct drm_crtc *crtc); extern void drm_vblank_cleanup(struct drm_device *dev);
extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
int crtc, int *max_error,
unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags, const struct drm_crtc *refcrtc,
@@ -968,8 +968,8 @@ static inline wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc }
/* Modesetting support */ -extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); -extern void drm_vblank_post_modeset(struct drm_device *dev, int crtc); +extern void drm_vblank_pre_modeset(struct drm_device *dev, unsigned int pipe); +extern void drm_vblank_post_modeset(struct drm_device *dev, unsigned int pipe);
/* Stub support (drm_stub.h) */
extern struct drm_master *drm_master_get(struct drm_master *master);
2.4.5