Ejemplo n.º 1
0
/*!
 * Shut down the voutera
 *
 * @param vout      structure vout_data *
 *
 * @return status  0 Success
 */
static int mxc_v4l2out_streamoff(vout_data * vout)
{
	int i, retval = 0;
	unsigned long lock_flag = 0;

	if (!vout)
		return -EINVAL;

	if (vout->state == STATE_STREAM_OFF) {
		return 0;
	}

	spin_lock_irqsave(&g_lock, lock_flag);

	del_timer(&vout->output_timer);
	pp_enable(0);		/* Disable PP */

	if (vout->state == STATE_STREAM_ON) {
		vout->state = STATE_STREAM_STOPPING;
	}

	spin_unlock_irqrestore(&g_lock, lock_flag);

	vout->ready_q.head = vout->ready_q.tail = 0;
	vout->done_q.head = vout->done_q.tail = 0;
	for (i = 0; i < vout->buffer_cnt; i++) {
		vout->v4l2_bufs[i].flags = 0;
		vout->v4l2_bufs[i].timestamp.tv_sec = 0;
		vout->v4l2_bufs[i].timestamp.tv_usec = 0;
	}

	vout->state = STATE_STREAM_OFF;

	if (vout->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY) {
		struct fb_gwinfo gwinfo;

		/* Disable graphic window */
		gwinfo.enabled = 0;
		mx2_gw_set(&gwinfo);
	}
#ifdef CONFIG_VIDEO_MXC_OUTPUT_FBSYNC
	if (vout->tear_protection == TEARING_PROTECTION_ACTIVE) {
		g_output_fb = -1;
		g_fb_enabled = 0;
		g_pp_ready = 0;
		fb_unregister_client(&fb_event_notifier);
		mx2fb_unregister_client(&mx2fb_event_notifier);
	}
#endif

	mxc_free_buffers(vout->display_bufs, vout->display_bufs_vaddr,
			 2, vout->sdc_fg_buf_size);

	return retval;
}
Ejemplo n.º 2
0
/*!
 * @brief Enable graphic window.
 * @param info	framebuffer information pointer
 */
static void _enable_graphic_window(struct fb_info *info)
{
	struct fb_var_screeninfo *var = &info->var;

	g_gwinfo.enabled = 1;

	g_gwinfo.base = (var->yoffset * var->xres_virtual + var->xoffset);
	g_gwinfo.base *= (var->bits_per_pixel) / 8;
	g_gwinfo.base += info->fix.smem_start;

	g_gwinfo.xres = var->xres;
	g_gwinfo.yres = var->yres;
	g_gwinfo.xres_virtual = var->xres_virtual;

	mx2_gw_set(&g_gwinfo);
}
Ejemplo n.º 3
0
irqreturn_t mxc_v4l2out_pp_in_irq_handler(int irq, void *dev_id)
{
	int last_buf;
	int index;
	unsigned long timeout;
	unsigned long lock_flags;
	vout_data *vout = dev_id;

	spin_lock_irqsave(&g_lock, lock_flags);

	g_irq_cnt++;

	if ((vout->state == STATE_STREAM_OFF)
	    || (vout->state == STATE_STREAM_STOPPING)) {
		spin_unlock_irqrestore(&g_lock, lock_flags);
		return IRQ_HANDLED;
	}

	if (vout->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY) {
		struct fb_gwinfo gwinfo;

		gwinfo.enabled = 1;
		gwinfo.alpha_value = 255;
		gwinfo.ck_enabled = 0;
		gwinfo.xpos = vout->crop_current.left;
		gwinfo.ypos = vout->crop_current.top;
		gwinfo.base = (unsigned long)vout->display_bufs[pp_num_last()];
		gwinfo.xres = vout->crop_current.width;
		gwinfo.yres = vout->crop_current.height;
		gwinfo.xres_virtual = vout->crop_current.width;
		gwinfo.vs_reversed = 0;

		mx2_gw_set(&gwinfo);
	}

	/* Process previous buffer */
	last_buf = vout->ipu_buf[0];
	pr_debug("last_buf %d g_irq_cnt %d\n", last_buf, g_irq_cnt);
	if (last_buf != -1) {
		g_buf_output_cnt++;
		vout->v4l2_bufs[last_buf].flags = V4L2_BUF_FLAG_DONE;
		queue_buf(&vout->done_q, last_buf);
		vout->ipu_buf[0] = -1;
		wake_up_interruptible(&vout->v4l_bufq);
	}

	/* Setup timer for next buffer, when stream has been paused */
	if ((vout->state == STATE_STREAM_PAUSED)
	    && ((index = peek_next_buf(&vout->ready_q)) != -1)) {
		pr_debug("next index %d\n", index);
		/* if timestamp is 0, then default to 30fps */
		if ((vout->v4l2_bufs[index].timestamp.tv_sec == 0)
		    && (vout->v4l2_bufs[index].timestamp.tv_usec == 0))
			timeout =
			    vout->start_jiffies + vout->frame_count * HZ / 30;
		else
			timeout =
			    get_jiffies(&vout->v4l2_bufs[index].timestamp);

		if (jiffies >= timeout) {
			pr_debug("warning: timer timeout already expired.\n");
		}

		vout->state = STATE_STREAM_ON;

		if (mod_timer(&vout->output_timer, timeout))
			pr_debug("warning: timer was already set\n");

		pr_debug("timer handler next schedule: %lu\n", timeout);
	}

	spin_unlock_irqrestore(&g_lock, lock_flags);

	return IRQ_HANDLED;
}