Пример #1
0
static int
dt3155_start_acq(struct dt3155_priv *pd)
{
	struct vb2_buffer *vb = pd->curr_buf;
	dma_addr_t dma_addr;

	dma_addr = vb2_dma_contig_plane_paddr(vb, 0);
	iowrite32(dma_addr, pd->regs + EVEN_DMA_START);
	iowrite32(dma_addr + img_width, pd->regs + ODD_DMA_START);
	iowrite32(img_width, pd->regs + EVEN_DMA_STRIDE);
	iowrite32(img_width, pd->regs + ODD_DMA_STRIDE);
	/* enable interrupts, clear all irq flags */
	iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START |
			FLD_END_EVEN | FLD_END_ODD, pd->regs + INT_CSR);
	iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN |
		  FLD_DN_ODD | FLD_DN_EVEN | CAP_CONT_EVEN | CAP_CONT_ODD,
							pd->regs + CSR1);
	wait_i2c_reg(pd->regs);
	write_i2c_reg(pd->regs, CONFIG, pd->config);
	write_i2c_reg(pd->regs, EVEN_CSR, CSR_ERROR | CSR_DONE);
	write_i2c_reg(pd->regs, ODD_CSR, CSR_ERROR | CSR_DONE);

	/*  start the board  */
	write_i2c_reg(pd->regs, CSR2, pd->csr2 | BUSY_EVEN | BUSY_ODD);
	return 0; /* success  */
}
Пример #2
0
static int __at91sam9x5_video_buf_in_use(struct at91sam9x5_video_priv *priv,
		struct at91sam9x5_video_bufinfo *bi,
		size_t heoaddr_offset, unsigned planeno)
{
	if (planeno >= 0) {
		u32 heoaddr = at91sam9x5_video_read32(priv, heoaddr_offset);
		dma_addr_t plane_paddr =
			vb2_dma_contig_plane_paddr(bi->vb, planeno);

		if (heoaddr - plane_paddr <= bi->plane_size[planeno])
			return 1;
	}

	return 0;
}
Пример #3
0
static int mx3_videobuf_prepare(struct vb2_buffer *vb)
{
	struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	struct mx3_camera_dev *mx3_cam = ici->priv;
	struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
	struct scatterlist *sg;
	struct mx3_camera_buffer *buf;
	size_t new_size;
	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
						icd->current_fmt->host_fmt);

	if (bytes_per_line < 0)
		return bytes_per_line;

	buf = to_mx3_vb(vb);
	sg = &buf->sg;

	new_size = bytes_per_line * icd->user_height;

	if (vb2_plane_size(vb, 0) < new_size) {
		dev_err(icd->dev.parent, "Buffer too small (%lu < %zu)\n",
			vb2_plane_size(vb, 0), new_size);
		return -ENOBUFS;
	}

	if (buf->state == CSI_BUF_NEEDS_INIT) {
		sg_dma_address(sg)	= vb2_dma_contig_plane_paddr(vb, 0);
		sg_dma_len(sg)		= new_size;

		buf->txd = ichan->dma_chan.device->device_prep_slave_sg(
			&ichan->dma_chan, sg, 1, DMA_FROM_DEVICE,
			DMA_PREP_INTERRUPT);
		if (!buf->txd)
			return -EIO;

		buf->txd->callback_param	= buf->txd;
		buf->txd->callback		= mx3_cam_dma_done;

		buf->state = CSI_BUF_PREPARED;
	}

	vb2_set_plane_payload(vb, 0, new_size);

	return 0;
}
/* The color format (colplanes, memplanes) must be already configured. */
int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
		      struct fimc_frame *frame, struct fimc_addr *paddr)
{
	int ret = 0;
	u32 pix_size;

	if (vb == NULL || frame == NULL)
		return -EINVAL;

	pix_size = frame->width * frame->height;

	dbg("memplanes= %d, colplanes= %d, pix_size= %d",
		frame->fmt->memplanes, frame->fmt->colplanes, pix_size);

	paddr->y = vb2_dma_contig_plane_paddr(vb, 0);

	if (frame->fmt->memplanes == 1) {
		switch (frame->fmt->colplanes) {
		case 1:
			paddr->cb = 0;
			paddr->cr = 0;
			break;
		case 2:
			/* decompose Y into Y/Cb */
			paddr->cb = (u32)(paddr->y + pix_size);
			paddr->cr = 0;
			break;
		case 3:
			paddr->cb = (u32)(paddr->y + pix_size);
			/* decompose Y into Y/Cb/Cr */
			if (S5P_FIMC_YCBCR420 == frame->fmt->color)
				paddr->cr = (u32)(paddr->cb
						+ (pix_size >> 2));
			else /* 422 */
				paddr->cr = (u32)(paddr->cb
						+ (pix_size >> 1));
			break;
		default:
			return -EINVAL;
		}
	} else {
Пример #5
0
static void at91sam9x5_video_show_buf(struct at91sam9x5_video_priv *priv,
		struct vb2_buffer *vb)
{
	dma_addr_t buffer = vb2_dma_contig_plane_paddr(vb, 0);
	void *vaddr = vb2_plane_vaddr(vb, 0);
	struct v4l2_pix_format *pix = &priv->fmt_vid_out_cur;
	/* XXX: format dependant */
	size_t offset_dmadesc = ALIGN(pix->width * pix->height +
			ALIGN(pix->width, 2) * ALIGN(pix->height, 2) / 2, 32);
	u32 *dmadesc = vaddr + offset_dmadesc;
	u32 heocher;

	if (priv->cfgstate == at91sam9x5_video_CFG_GOOD_LATCH) {
		heocher = REG_HEOCHER_UPDATEEN;
		priv->cfgstate = at91sam9x5_video_CFG_GOOD;
	} else {
		BUG_ON(priv->cfgstate != at91sam9x5_video_CFG_GOOD);
		heocher = 0;
	}

	debug("vout=%ux%u, heocher=%08x\n", pix->width, pix->height, heocher);

	dmadesc[0] = buffer + priv->y_offset;
	dmadesc[1] = REG_HEOxCTRL_DFETCH;
	dmadesc[2] = buffer + offset_dmadesc;

	if (priv->u_planeno >= 0) {
		dmadesc[3] = vb2_dma_contig_plane_paddr(vb, priv->u_planeno) +
			priv->u_offset;
		dmadesc[4] = REG_HEOxCTRL_DFETCH;
		dmadesc[5] = buffer + offset_dmadesc + 3 * 4;
	}

	if (priv->v_planeno >= 0) {
		dmadesc[6] = vb2_dma_contig_plane_paddr(vb, priv->v_planeno) +
			priv->v_offset;
		dmadesc[7] = REG_HEOxCTRL_DFETCH;
		dmadesc[8] = buffer + offset_dmadesc + 6 * 4;
	}


	debug("HEOCHSR = %08x\n", at91sam9x5_video_read32(priv, REG_HEOCHSR));
	if (likely(priv->hwstate == at91sam9x5_video_HW_RUNNING)) {

		at91sam9x5_video_write32(priv, REG_HEOHEAD, dmadesc[2]);

		if (priv->u_planeno >= 0)
			at91sam9x5_video_write32(priv,
					REG_HEOUHEAD, dmadesc[5]);

		if (priv->v_planeno >= 0)
			at91sam9x5_video_write32(priv,
					REG_HEOVHEAD, dmadesc[8]);

		at91sam9x5_video_write32(priv,
				REG_HEOCHER, heocher | REG_HEOCHER_A2QEN);

	} else {

		at91sam9x5_video_write32(priv, REG_HEOADDR, dmadesc[0]);
		at91sam9x5_video_write32(priv, REG_HEOCTRL, dmadesc[1]);
		at91sam9x5_video_write32(priv, REG_HEONEXT, dmadesc[2]);

		if (priv->u_planeno >= 0) {
			at91sam9x5_video_write32(priv,
					REG_HEOUADDR, dmadesc[3]);
			at91sam9x5_video_write32(priv,
					REG_HEOUCTRL, dmadesc[4]);
			at91sam9x5_video_write32(priv,
					REG_HEOUNEXT, dmadesc[5]);
		}

		if (priv->v_planeno >= 0) {
			at91sam9x5_video_write32(priv,
					REG_HEOVADDR, dmadesc[6]);
			at91sam9x5_video_write32(priv,
					REG_HEOVCTRL, dmadesc[7]);
			at91sam9x5_video_write32(priv,
					REG_HEOVNEXT, dmadesc[8]);
		}

		at91sam9x5_video_write32(priv, REG_HEOCHER,
				heocher | REG_HEOCHER_CHEN);

		priv->hwstate = at91sam9x5_video_HW_RUNNING;
	}

	if (priv->cur.vb && at91sam9x5_video_buf_in_use(priv, &priv->cur)) {
		if (priv->next.vb) {
			/* drop next; XXX: is this an error? */
			debug("drop %p\n", priv->next.vb);
			vb2_buffer_done(priv->next.vb, VB2_BUF_STATE_ERROR);
		}
	} else {
		if (priv->cur.vb)
			vb2_buffer_done(priv->cur.vb, VB2_BUF_STATE_DONE);

		priv->cur = priv->next;
	}
	priv->next.vb = vb;
	priv->next.u_planeno = priv->u_planeno;
	priv->next.v_planeno = priv->v_planeno;
	priv->next.plane_size[0] = priv->plane_size[0];
	priv->next.plane_size[1] = priv->plane_size[1];
	priv->next.plane_size[2] = priv->plane_size[2];
}