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 */ }
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; }
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 {
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]; }