Exemplo n.º 1
0
static int rcar_du_crtc_page_flip(struct drm_crtc *crtc,
				  struct drm_framebuffer *fb,
				  struct drm_pending_vblank_event *event,
				  uint32_t page_flip_flags)
{
	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
	struct drm_device *dev = rcrtc->crtc.dev;
	unsigned long flags;

	spin_lock_irqsave(&dev->event_lock, flags);
	if (rcrtc->event != NULL) {
		spin_unlock_irqrestore(&dev->event_lock, flags);
		return -EBUSY;
	}
	spin_unlock_irqrestore(&dev->event_lock, flags);

	crtc->fb = fb;
	rcar_du_crtc_update_base(rcrtc);

	if (event) {
		event->pipe = rcrtc->index;
		drm_vblank_get(dev, rcrtc->index);
		spin_lock_irqsave(&dev->event_lock, flags);
		rcrtc->event = event;
		spin_unlock_irqrestore(&dev->event_lock, flags);
	}

	return 0;
}
Exemplo n.º 2
0
static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
				      struct drm_framebuffer *fb,
				      struct drm_pending_vblank_event *event)
{
	struct drm_device *dev = crtc->dev;
	struct exynos_drm_private *dev_priv = dev->dev_private;
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
	struct drm_framebuffer *old_fb = crtc->fb;
	int ret = -EINVAL;

	DRM_DEBUG_KMS("%s\n", __FILE__);

	/* when the page flip is requested, crtc's dpms should be on */
	if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
		DRM_ERROR("failed page flip request.\n");
		return -EINVAL;
	}

	mutex_lock(&dev->struct_mutex);

	if (event) {
		/*
		 * the pipe from user always is 0 so we can set pipe number
		 * of current owner to event.
		 */
		event->pipe = exynos_crtc->pipe;

		ret = drm_vblank_get(dev, exynos_crtc->pipe);
		if (ret) {
			DRM_DEBUG("failed to acquire vblank counter\n");

			goto out;
		}

		spin_lock_irq(&dev->event_lock);
		list_add_tail(&event->base.link,
				&dev_priv->pageflip_event_list);
		atomic_set(&exynos_crtc->pending_flip, 1);
		spin_unlock_irq(&dev->event_lock);

		crtc->fb = fb;
		ret = exynos_drm_crtc_mode_set_base(crtc, crtc->x, crtc->y,
						    NULL);
		if (ret) {
			crtc->fb = old_fb;

			spin_lock_irq(&dev->event_lock);
			drm_vblank_put(dev, exynos_crtc->pipe);
			list_del(&event->base.link);
			spin_unlock_irq(&dev->event_lock);

			goto out;
		}
	}
out:
	mutex_unlock(&dev->struct_mutex);
	return ret;
}
Exemplo n.º 3
0
void MRSTLFBEnableVSyncInterrupt(MRSTLFB_DEVINFO * psDevinfo)
{
#if defined(MRST_USING_INTERRUPTS)
	if( drm_vblank_get( psDevinfo->psDrmDevice , psDevinfo->ui32MainPipe ) )
	{
		DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX	"Couldn't get vsync enabled"));
	}
#endif
}
static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
                                     struct drm_framebuffer *fb,
                                     struct drm_pending_vblank_event *event)
{
    struct drm_device *dev = crtc->dev;
    struct exynos_drm_private *dev_priv = dev->dev_private;
    struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
    struct drm_framebuffer *old_fb = crtc->fb;
    int ret = -EINVAL;

    DRM_DEBUG_KMS("%s\n", __FILE__);

    mutex_lock(&dev->struct_mutex);

    if (event) {
        /*
         * the pipe from user always is 0 so we can set pipe number
         * of current owner to event.
         */
        event->pipe = exynos_crtc->pipe;

        ret = drm_vblank_get(dev, exynos_crtc->pipe);
        if (ret) {
            DRM_DEBUG("failed to acquire vblank counter\n");
            list_del(&event->base.link);

            goto out;
        }

        list_add_tail(&event->base.link,
                      &dev_priv->pageflip_event_list);

        crtc->fb = fb;
        ret = exynos_drm_crtc_update(crtc);
        if (ret) {
            crtc->fb = old_fb;
            drm_vblank_put(dev, exynos_crtc->pipe);
            list_del(&event->base.link);

            goto out;
        }

        /*
         * the values related to a buffer of the drm framebuffer
         * to be applied should be set at here. because these values
         * first, are set to shadow registers and then to
         * real registers at vsync front porch period.
         */
        exynos_drm_crtc_apply(crtc);
    }
out:
    mutex_unlock(&dev->struct_mutex);
    return ret;
}
static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
				      struct drm_framebuffer *fb,
				      struct drm_pending_vblank_event *event)
{
	struct drm_device *dev = crtc->dev;
	struct exynos_drm_private *dev_priv = dev->dev_private;
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
	struct drm_framebuffer *old_fb = crtc->fb;
	int ret = -EINVAL;

	DRM_DEBUG_KMS("%s\n", __FILE__);

	mutex_lock(&dev->struct_mutex);

	if (event) {
		/*
                                                             
                               
   */
		event->pipe = exynos_crtc->pipe;

		ret = drm_vblank_get(dev, exynos_crtc->pipe);
		if (ret) {
			DRM_DEBUG("failed to acquire vblank counter\n");
			list_del(&event->base.link);

			goto out;
		}

		list_add_tail(&event->base.link,
				&dev_priv->pageflip_event_list);

		crtc->fb = fb;
		ret = exynos_drm_crtc_update(crtc);
		if (ret) {
			crtc->fb = old_fb;
			drm_vblank_put(dev, exynos_crtc->pipe);
			list_del(&event->base.link);

			goto out;
		}

		/*
                                                          
                                                              
                                                   
                                                
   */
		exynos_drm_crtc_apply(crtc);
	}
out:
	mutex_unlock(&dev->struct_mutex);
	return ret;
}
Exemplo n.º 6
0
void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
                              struct armada_vbl_event *evt)
{
    unsigned long flags;

    spin_lock_irqsave(&dcrtc->irq_lock, flags);
    if (list_empty(&evt->node)) {
        list_add_tail(&evt->node, &dcrtc->vbl_list);

        drm_vblank_get(dcrtc->crtc.dev, dcrtc->num);
    }
    spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
}
Exemplo n.º 7
0
int
drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
	struct timeval		 now;
	union drm_wait_vblank	*vblwait = data;
	int			 ret, flags, crtc, seq;

	if (!dev->irq_enabled || dev->vblank == NULL ||
	    vblwait->request.type & _DRM_VBLANK_SIGNAL)
		return (EINVAL);

	flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
	crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;

	if (crtc >= dev->vblank->vb_num)
		return (EINVAL);

	if ((ret = drm_vblank_get(dev, crtc)) != 0)
		return (ret);
	seq = drm_vblank_count(dev, crtc);

	if (vblwait->request.type & _DRM_VBLANK_RELATIVE) {
		vblwait->request.sequence += seq;
		vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
	}

	flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
	if ((flags & _DRM_VBLANK_NEXTONMISS) &&
	    (seq - vblwait->request.sequence) <= (1<<23)) {
		vblwait->request.sequence = seq + 1;
	}

	if (flags & _DRM_VBLANK_EVENT)
		return (drm_queue_vblank_event(dev, crtc, vblwait, file_priv));

	DPRINTF("%s: %d waiting on %d, current %d\n", __func__, crtc,
	     vblwait->request.sequence, drm_vblank_count(dev, crtc));
	DRM_WAIT_ON(ret, &dev->vblank->vb_crtcs[crtc], &dev->vblank->vb_lock,
	    3 * hz, "drmvblq", ((drm_vblank_count(dev, crtc) -
	    vblwait->request.sequence) <= (1 << 23)) || dev->irq_enabled == 0);

	microtime(&now);
	vblwait->reply.tval_sec = now.tv_sec;
	vblwait->reply.tval_usec = now.tv_usec;
	vblwait->reply.sequence = drm_vblank_count(dev, crtc);
	DPRINTF("%s: %d done waiting, seq = %d\n", __func__, crtc,
	    vblwait->reply.sequence);

	drm_vblank_put(dev, crtc);
	return (ret);
}
Exemplo n.º 8
0
int
drm_modeset_ctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
	struct drm_modeset_ctl	*modeset = data;
	struct drm_vblank	*vbl;
	int			 crtc, ret = 0;

	/* not initialised yet, just noop */
	if (dev->vblank == NULL)
		return (0);

	crtc = modeset->crtc;
	if (crtc >= dev->vblank->vb_num || crtc < 0)
		return (EINVAL);

	vbl = &dev->vblank->vb_crtcs[crtc];

	/*
	 * If interrupts are enabled/disabled between calls to this ioctl then
	 * it can get nasty. So just grab a reference so that the interrupts
	 * keep going through the modeset
	 */
	switch (modeset->cmd) {
	case _DRM_PRE_MODESET:
		DPRINTF("%s: pre modeset on %d\n", __func__, crtc);
		if (vbl->vbl_inmodeset == 0) {
			mtx_enter(&dev->vblank->vb_lock);
			vbl->vbl_inmodeset = 0x1;
			mtx_leave(&dev->vblank->vb_lock);
			if (drm_vblank_get(dev, crtc) == 0)
				vbl->vbl_inmodeset |= 0x2;
		}
		break;
	case _DRM_POST_MODESET:
		DPRINTF("%s: post modeset on %d\n", __func__, crtc);
		if (vbl->vbl_inmodeset) {
			if (vbl->vbl_inmodeset & 0x2)
				drm_vblank_put(dev, crtc);
			vbl->vbl_inmodeset = 0;
		}
		break;
	default:
		ret = EINVAL;
		break;
	}

	return (ret);
}
Exemplo n.º 9
0
static int vigs_crtc_page_flip(struct drm_crtc *crtc,
                               struct drm_framebuffer *fb,
                               struct drm_pending_vblank_event *event)
{
    unsigned long flags;
    struct vigs_device *vigs_dev = crtc->dev->dev_private;
    struct drm_framebuffer *old_fb = crtc->fb;
    int ret = -EINVAL;

    mutex_lock(&vigs_dev->drm_dev->struct_mutex);

    if (event) {
        event->pipe = 0;

        ret = drm_vblank_get(vigs_dev->drm_dev, 0);

        if (ret != 0) {
            DRM_ERROR("failed to acquire vblank counter\n");
            goto out;
        }

        spin_lock_irqsave(&vigs_dev->drm_dev->event_lock, flags);
        list_add_tail(&event->base.link,
                      &vigs_dev->pageflip_event_list);
        spin_unlock_irqrestore(&vigs_dev->drm_dev->event_lock, flags);

        crtc->fb = fb;
        ret = vigs_crtc_update(crtc, old_fb);
        if (ret != 0) {
            crtc->fb = old_fb;
            spin_lock_irqsave(&vigs_dev->drm_dev->event_lock, flags);
            if (atomic_read(&vigs_dev->drm_dev->vblank_refcount[0]) > 0) {
                /*
                 * Only do this if event wasn't already processed.
                 */
                drm_vblank_put(vigs_dev->drm_dev, 0);
                list_del(&event->base.link);
            }
            spin_unlock_irqrestore(&vigs_dev->drm_dev->event_lock, flags);
            goto out;
        }
    }

out:
    mutex_unlock(&vigs_dev->drm_dev->struct_mutex);

    return ret;
}
Exemplo n.º 10
0
static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
				      struct drm_framebuffer *fb,
				      struct drm_pending_vblank_event *event)
{
	struct drm_device *dev = crtc->dev;
	struct exynos_drm_private *dev_priv = dev->dev_private;
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
	struct drm_framebuffer *old_fb = crtc->fb;
	int ret = -EINVAL;

	DRM_DEBUG_KMS("%s\n", __FILE__);

	mutex_lock(&dev->struct_mutex);

	if (event) {
		/*
		 * the pipe from user always is 0 so we can set pipe number
		 * of current owner to event.
		 */
		event->pipe = exynos_crtc->pipe;

		ret = drm_vblank_get(dev, exynos_crtc->pipe);
		if (ret) {
			DRM_DEBUG("failed to acquire vblank counter\n");
			list_del(&event->base.link);

			goto out;
		}

		list_add_tail(&event->base.link,
				&dev_priv->pageflip_event_list);

		crtc->fb = fb;
		ret = exynos_drm_crtc_mode_set_base(crtc, crtc->x, crtc->y,
						    NULL);
		if (ret) {
			crtc->fb = old_fb;
			drm_vblank_put(dev, exynos_crtc->pipe);
			list_del(&event->base.link);

			goto out;
		}
	}
out:
	mutex_unlock(&dev->struct_mutex);
	return ret;
}
Exemplo n.º 11
0
/**
 * drm_vblank_pre_modeset - account for vblanks across mode sets
 * @dev: DRM device
 * @crtc: CRTC in question
 *
 * Account for vblank events across mode setting events, which will likely
 * reset the hardware frame counter.
 */
void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
{
	/* vblank is not initialized (IRQ not installed ?) */
	if (!dev->num_crtcs)
		return;
	/*
	 * To avoid all the problems that might happen if interrupts
	 * were enabled/disabled around or between these calls, we just
	 * have the kernel take a reference on the CRTC (just once though
	 * to avoid corrupting the count if multiple, mismatch calls occur),
	 * so that interrupts remain enabled in the interim.
	 */
	if (!dev->vblank_inmodeset[crtc]) {
		dev->vblank_inmodeset[crtc] = 0x1;
		if (drm_vblank_get(dev, crtc) == 0)
			dev->vblank_inmodeset[crtc] |= 0x2;
	}
}
Exemplo n.º 12
0
static int xylon_drm_crtc_page_flip(struct drm_crtc *base_crtc,
				    struct drm_framebuffer *fb,
				    struct drm_pending_vblank_event *event,
				    u32 page_flip_flags)
{
	struct drm_device *dev = base_crtc->dev;
	struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&dev->event_lock, flags);
	if (crtc->event != NULL) {
		spin_unlock_irqrestore(&dev->event_lock, flags);
		return -EBUSY;
	}
	spin_unlock_irqrestore(&dev->event_lock, flags);

	ret = xylon_drm_plane_fb_set(base_crtc->primary, fb,
				     0, 0,
				     base_crtc->hwmode.hdisplay,
				     base_crtc->hwmode.vdisplay,
				     base_crtc->x, base_crtc->y,
				     base_crtc->hwmode.hdisplay,
				     base_crtc->hwmode.vdisplay);
	if (ret) {
		DRM_ERROR("failed mode set plane\n");
		return ret;
	}

	xylon_drm_plane_commit(base_crtc->primary);

	base_crtc->primary->fb = fb;

	if (event) {
		event->pipe = 0;
		drm_vblank_get(dev, 0);
		spin_lock_irqsave(&dev->event_lock, flags);
		crtc->event = event;
		spin_unlock_irqrestore(&dev->event_lock, flags);
	}

	return 0;
}
Exemplo n.º 13
0
/* page flip functions */
static int xilinx_drm_crtc_page_flip(struct drm_crtc *base_crtc,
				     struct drm_framebuffer *fb,
				     struct drm_pending_vblank_event *event,
				     uint32_t page_flip_flags)
{
	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
	struct drm_device *drm = base_crtc->dev;
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&drm->event_lock, flags);
	if (crtc->event != NULL) {
		spin_unlock_irqrestore(&drm->event_lock, flags);
		return -EBUSY;
	}
	spin_unlock_irqrestore(&drm->event_lock, flags);

	/* configure a plane */
	ret = _xilinx_drm_crtc_mode_set_base(base_crtc, fb,
					     base_crtc->x, base_crtc->y);
	if (ret) {
		DRM_ERROR("failed to mode set a plane\n");
		return ret;
	}

	base_crtc->fb = fb;

	if (event) {
		event->pipe = 0;
		drm_vblank_get(drm, 0);
		spin_lock_irqsave(&drm->event_lock, flags);
		crtc->event = event;
		spin_unlock_irqrestore(&drm->event_lock, flags);
	}

	return 0;
}