Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6084 → Rev 6088

/drivers/video/drm/drm_irq.c
370,8 → 370,8
vblank->dev = dev;
vblank->pipe = i;
init_waitqueue_head(&vblank->queue);
// setup_timer(&vblank->disable_timer, vblank_disable_fn,
// (unsigned long)vblank);
setup_timer(&vblank->disable_timer, vblank_disable_fn,
(unsigned long)vblank);
}
 
DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
829,7 → 829,141
return cur_vblank;
}
EXPORT_SYMBOL(drm_vblank_count_and_time);
 
/**
* drm_crtc_vblank_count_and_time - retrieve "cooked" vblank counter value
* and the system timestamp corresponding to that vblank counter value
* @crtc: which counter to retrieve
* @vblanktime: Pointer to struct timeval to receive the vblank timestamp.
*
* Fetches the "cooked" vblank count value that represents the number of
* vblank events since the system was booted, including lost events due to
* modesetting activity. Returns corresponding system timestamp of the time
* of the vblank interval that corresponds to the current vblank counter value.
*
* This is the native KMS version of drm_vblank_count_and_time().
*/
u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc,
struct timeval *vblanktime)
{
return drm_vblank_count_and_time(crtc->dev, drm_crtc_index(crtc),
vblanktime);
}
EXPORT_SYMBOL(drm_crtc_vblank_count_and_time);
 
static void send_vblank_event(struct drm_device *dev,
struct drm_pending_vblank_event *e,
unsigned long seq, struct timeval *now)
{
assert_spin_locked(&dev->event_lock);
 
e->event.sequence = seq;
e->event.tv_sec = now->tv_sec;
e->event.tv_usec = now->tv_usec;
 
list_add_tail(&e->base.link,
&e->base.file_priv->event_list);
wake_up_interruptible(&e->base.file_priv->event_wait);
}
 
/**
* drm_arm_vblank_event - arm vblank event after pageflip
* @dev: DRM device
* @pipe: CRTC index
* @e: the event to prepare to send
*
* A lot of drivers need to generate vblank events for the very next vblank
* interrupt. For example when the page flip interrupt happens when the page
* flip gets armed, but not when it actually executes within the next vblank
* period. This helper function implements exactly the required vblank arming
* behaviour.
*
* Caller must hold event lock. Caller must also hold a vblank reference for
* the event @e, which will be dropped when the next vblank arrives.
*
* This is the legacy version of drm_crtc_arm_vblank_event().
*/
void drm_arm_vblank_event(struct drm_device *dev, unsigned int pipe,
struct drm_pending_vblank_event *e)
{
assert_spin_locked(&dev->event_lock);
 
e->pipe = pipe;
e->event.sequence = drm_vblank_count(dev, pipe);
list_add_tail(&e->base.link, &dev->vblank_event_list);
}
EXPORT_SYMBOL(drm_arm_vblank_event);
 
/**
* drm_crtc_arm_vblank_event - arm vblank event after pageflip
* @crtc: the source CRTC of the vblank event
* @e: the event to send
*
* A lot of drivers need to generate vblank events for the very next vblank
* interrupt. For example when the page flip interrupt happens when the page
* flip gets armed, but not when it actually executes within the next vblank
* period. This helper function implements exactly the required vblank arming
* behaviour.
*
* Caller must hold event lock. Caller must also hold a vblank reference for
* the event @e, which will be dropped when the next vblank arrives.
*
* This is the native KMS version of drm_arm_vblank_event().
*/
void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
struct drm_pending_vblank_event *e)
{
drm_arm_vblank_event(crtc->dev, drm_crtc_index(crtc), e);
}
EXPORT_SYMBOL(drm_crtc_arm_vblank_event);
 
/**
* drm_send_vblank_event - helper to send vblank event after pageflip
* @dev: DRM device
* @pipe: CRTC index
* @e: the event to send
*
* Updates sequence # and timestamp on event, and sends it to userspace.
* Caller must hold event lock.
*
* This is the legacy version of drm_crtc_send_vblank_event().
*/
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, pipe, &now);
} else {
seq = 0;
 
now = get_drm_timestamp();
}
e->pipe = pipe;
send_vblank_event(dev, e, seq, &now);
}
EXPORT_SYMBOL(drm_send_vblank_event);
 
/**
* drm_crtc_send_vblank_event - helper to send vblank event after pageflip
* @crtc: the source CRTC of the vblank event
* @e: the event to send
*
* Updates sequence # and timestamp on event, and sends it to userspace.
* Caller must hold event lock.
*
* This is the native KMS version of drm_send_vblank_event().
*/
void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
struct drm_pending_vblank_event *e)
{
drm_send_vblank_event(crtc->dev, drm_crtc_index(crtc), e);
}
EXPORT_SYMBOL(drm_crtc_send_vblank_event);
 
/**
* drm_vblank_enable - enable the vblank interrupt on a CRTC
* @dev: DRM device
* @pipe: CRTC index
952,11 → 1086,8
if (atomic_dec_and_test(&vblank->refcount)) {
if (drm_vblank_offdelay == 0)
return;
else if (dev->vblank_disable_immediate || drm_vblank_offdelay < 0)
else
vblank_disable_fn((unsigned long)vblank);
else
mod_timer(&vblank->disable_timer,
jiffies + ((drm_vblank_offdelay * HZ)/1000));
}
}
EXPORT_SYMBOL(drm_vblank_put);
987,24 → 1118,26
*/
void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
{
#if 0
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
int ret;
u32 last;
 
ret = drm_vblank_get(dev, crtc);
if (WARN(ret, "vblank not available on crtc %i, ret=%i\n", crtc, ret))
if (WARN_ON(pipe >= dev->num_crtcs))
return;
 
last = drm_vblank_count(dev, crtc);
ret = drm_vblank_get(dev, pipe);
if (WARN(ret, "vblank not available on crtc %i, ret=%i\n", pipe, ret))
return;
 
ret = wait_event_timeout(dev->vblank[crtc].queue,
last != drm_vblank_count(dev, crtc),
last = drm_vblank_count(dev, pipe);
 
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);
#endif
drm_vblank_put(dev, pipe);
}
EXPORT_SYMBOL(drm_wait_one_vblank);
 
1044,8 → 1177,40
unsigned long irqflags;
unsigned int seq;
 
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, pipe);
wake_up(&vblank->queue);
 
/*
* Prevent subsequent drm_vblank_get() from re-enabling
* the vblank interrupt by bumping the refcount.
*/
if (!vblank->inmodeset) {
atomic_inc(&vblank->refcount);
vblank->inmodeset = 1;
}
spin_unlock(&dev->vbl_lock);
 
/* Send any queued vblank events, lest the natives grow disquiet */
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 != pipe)
continue;
DRM_DEBUG("Sending premature vblank event on disable: "
"wanted %d, current %d\n",
e->event.sequence, seq);
list_del(&e->base.link);
drm_vblank_put(dev, pipe);
send_vblank_event(dev, e, seq, &now);
}
spin_unlock_irqrestore(&dev->event_lock, irqflags);
}
EXPORT_SYMBOL(drm_vblank_off);
 
/**
1116,8 → 1281,6
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
unsigned long irqflags;
 
dbgprintf("%s pipe %d dev->num_crtcs %d\n", pipe,dev->num_crtcs);\
 
if (WARN_ON(pipe >= dev->num_crtcs))
return;
 
1240,7 → 1403,116
}
EXPORT_SYMBOL(drm_vblank_post_modeset);
 
static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe)
{
struct drm_pending_vblank_event *e, *t;
struct timeval now;
unsigned int seq;
 
assert_spin_locked(&dev->event_lock);
 
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 != pipe)
continue;
if ((seq - e->event.sequence) > (1<<23))
continue;
 
DRM_DEBUG("vblank event on %d, current %d\n",
e->event.sequence, seq);
 
list_del(&e->base.link);
drm_vblank_put(dev, pipe);
send_vblank_event(dev, e, seq, &now);
}
 
}
 
/**
* drm_handle_vblank - handle a vblank event
* @dev: DRM device
* @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, unsigned int pipe)
{
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
unsigned long irqflags;
 
if (WARN_ON_ONCE(!dev->num_crtcs))
return false;
 
if (WARN_ON(pipe >= dev->num_crtcs))
return false;
 
spin_lock_irqsave(&dev->event_lock, irqflags);
 
/* Need timestamp lock to prevent concurrent execution with
* vblank enable/disable, as this would cause inconsistent
* or corrupted timestamps and vblank counts.
*/
spin_lock(&dev->vblank_time_lock);
 
/* Vblank irq handling disabled. Nothing to do. */
if (!vblank->enabled) {
spin_unlock(&dev->vblank_time_lock);
spin_unlock_irqrestore(&dev->event_lock, irqflags);
return false;
}
 
drm_update_vblank_count(dev, pipe, DRM_CALLED_FROM_VBLIRQ);
 
spin_unlock(&dev->vblank_time_lock);
 
wake_up(&vblank->queue);
drm_handle_vblank_events(dev, pipe);
 
spin_unlock_irqrestore(&dev->event_lock, irqflags);
 
return true;
}
EXPORT_SYMBOL(drm_handle_vblank);
 
/**
* drm_crtc_handle_vblank - handle a vblank event
* @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 native KMS version of drm_handle_vblank().
*
* Returns:
* True if the event was successfully handled, false on failure.
*/
bool drm_crtc_handle_vblank(struct drm_crtc *crtc)
{
return drm_handle_vblank(crtc->dev, drm_crtc_index(crtc));
}
EXPORT_SYMBOL(drm_crtc_handle_vblank);
 
/**
* drm_vblank_no_hw_counter - "No hw counter" implementation of .get_vblank_counter()
* @dev: DRM device
* @pipe: CRTC for which to read the counter
*
* Drivers can plug this into the .get_vblank_counter() function if
* there is no useable hardware frame counter available.
*
* Returns:
* 0
*/
u32 drm_vblank_no_hw_counter(struct drm_device *dev, unsigned int pipe)
{
return 0;
}
EXPORT_SYMBOL(drm_vblank_no_hw_counter);
 
u64 div64_u64(u64 dividend, u64 divisor)
{
u32 high, d;