drivers/media/platform/ti/davinci/vpif_display.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/ti/davinci/vpif_display.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/ti/davinci/vpif_display.c
Extension
.c
Size
38069 bytes
Lines
1403
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret < 0) {
			vpif_err("can't set clock\n");
			goto err;
		}
	}

	/* set the parameters and addresses */
	ret = vpif_set_video_params(vpif, ch->channel_id + 2);
	if (ret < 0)
		goto err;

	ycmux_mode = ret;
	vpif_config_addr(ch, ret);
	/* Get the next frame from the buffer queue */
	common->next_frm = common->cur_frm =
			    list_entry(common->dma_queue.next,
				       struct vpif_disp_buffer, list);

	list_del(&common->cur_frm->list);
	spin_unlock_irqrestore(&common->irqlock, flags);

	addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb.vb2_buf, 0);
	common->set_addr((addr + common->ytop_off),
			    (addr + common->ybtm_off),
			    (addr + common->ctop_off),
			    (addr + common->cbtm_off));

	/*
	 * Set interrupt for both the fields in VPIF
	 * Register enable channel in VPIF register
	 */
	channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
	if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
		channel2_intr_assert();
		channel2_intr_enable(1);
		enable_channel2(1);
		if (vpif_config_data->chan_config[VPIF_CHANNEL2_VIDEO].clip_en)
			channel2_clipping_enable(1);
	}

	if (VPIF_CHANNEL3_VIDEO == ch->channel_id || ycmux_mode == 2) {
		channel3_intr_assert();
		channel3_intr_enable(1);
		enable_channel3(1);
		if (vpif_config_data->chan_config[VPIF_CHANNEL3_VIDEO].clip_en)
			channel3_clipping_enable(1);
	}

	return 0;

err:
	list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
		list_del(&buf->list);
		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
	}
	spin_unlock_irqrestore(&common->irqlock, flags);

	return ret;
}

/**
 * vpif_stop_streaming : Stop the DMA engine
 * @vq: ptr to vb2_queue
 *
 * This callback stops the DMA engine and any remaining buffers
 * in the DMA queue are released.
 */
static void vpif_stop_streaming(struct vb2_queue *vq)
{
	struct channel_obj *ch = vb2_get_drv_priv(vq);
	struct common_obj *common;
	unsigned long flags;

	common = &ch->common[VPIF_VIDEO_INDEX];

	/* Disable channel */
	if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
		enable_channel2(0);
		channel2_intr_enable(0);
	}
	if (VPIF_CHANNEL3_VIDEO == ch->channel_id || ycmux_mode == 2) {
		enable_channel3(0);
		channel3_intr_enable(0);
	}

	/* release all active buffers */
	spin_lock_irqsave(&common->irqlock, flags);
	if (common->cur_frm == common->next_frm) {
		vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
				VB2_BUF_STATE_ERROR);

Annotation

Implementation Notes