rpf->location.left = dst->left;
rpf->location.top = dst->top;
- /* Set the memory buffer address. */
+ /* Set the memory buffer address but don't apply the values to the
+ * hardware as the crop offsets haven't been computed yet.
+ */
memory.num_planes = fmtinfo->planes;
memory.addr[0] = mem[0];
memory.addr[1] = mem[1];
+ memory.addr[2] = 0;
- rpf->ops->set_memory(rpf, &memory);
+ vsp1_rwpf_set_memory(rpf, &memory, false);
spin_lock_irqsave(&pipe->irqlock, flags);
pstride = format->plane_fmt[0].bytesperline
<< VI6_RPF_SRCM_PSTRIDE_Y_SHIFT;
- vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_Y,
- rpf->buf_addr[0] + rpf->offsets[0]);
-
if (format->num_planes > 1) {
rpf->offsets[1] = crop->top * format->plane_fmt[1].bytesperline
+ crop->left * fmtinfo->bpp[1] / 8;
pstride |= format->plane_fmt[1].bytesperline
<< VI6_RPF_SRCM_PSTRIDE_C_SHIFT;
-
- vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C0,
- rpf->buf_addr[1] + rpf->offsets[1]);
-
- if (format->num_planes > 2)
- vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C1,
- rpf->buf_addr[2] + rpf->offsets[1]);
+ } else {
+ rpf->offsets[1] = 0;
}
vsp1_rpf_write(rpf, VI6_RPF_SRCM_PSTRIDE, pstride);
+ /* Now that the offsets have been computed program the DMA addresses. */
+ rpf->ops->set_memory(rpf);
+
/* Format */
infmt = VI6_RPF_INFMT_CIPM
| (fmtinfo->hwfmt << VI6_RPF_INFMT_RDFMT_SHIFT);
* Video Device Operations
*/
-static void rpf_set_memory(struct vsp1_rwpf *rpf, struct vsp1_rwpf_memory *mem)
+static void rpf_set_memory(struct vsp1_rwpf *rpf)
{
- unsigned int i;
-
- for (i = 0; i < 3; ++i)
- rpf->buf_addr[i] = mem->addr[i];
-
- if (!vsp1_entity_is_streaming(&rpf->entity))
- return;
-
vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_Y,
- mem->addr[0] + rpf->offsets[0]);
- if (mem->num_planes > 1)
- vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C0,
- mem->addr[1] + rpf->offsets[1]);
- if (mem->num_planes > 2)
- vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C1,
- mem->addr[2] + rpf->offsets[1]);
+ rpf->buf_addr[0] + rpf->offsets[0]);
+ vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C0,
+ rpf->buf_addr[1] + rpf->offsets[1]);
+ vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C1,
+ rpf->buf_addr[2] + rpf->offsets[1]);
}
static const struct vsp1_rwpf_operations rpf_vdev_ops = {
return rwpf->ctrls.error;
}
+
+/* -----------------------------------------------------------------------------
+ * Buffers
+ */
+
+/**
+ * vsp1_rwpf_set_memory - Configure DMA addresses for a [RW]PF
+ * @rwpf: the [RW]PF instance
+ * @mem: DMA memory addresses
+ * @apply: whether to apply the configuration to the hardware
+ *
+ * This function stores the DMA addresses for all planes in the rwpf instance
+ * and optionally applies the configuration to hardware registers if the apply
+ * argument is set to true.
+ */
+void vsp1_rwpf_set_memory(struct vsp1_rwpf *rwpf, struct vsp1_rwpf_memory *mem,
+ bool apply)
+{
+ unsigned int i;
+
+ for (i = 0; i < 3; ++i)
+ rwpf->buf_addr[i] = mem->addr[i];
+
+ if (apply)
+ rwpf->ops->set_memory(rwpf);
+}
unsigned int length[3];
};
+/**
+ * struct vsp1_rwpf_operations - RPF and WPF operations
+ * @set_memory: Setup memory buffer access. This operation applies the settings
+ * stored in the rwpf buf_addr field to the hardware.
+ */
struct vsp1_rwpf_operations {
- void (*set_memory)(struct vsp1_rwpf *rwpf,
- struct vsp1_rwpf_memory *mem);
+ void (*set_memory)(struct vsp1_rwpf *rwpf);
};
struct vsp1_rwpf {
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_selection *sel);
+void vsp1_rwpf_set_memory(struct vsp1_rwpf *rwpf, struct vsp1_rwpf_memory *mem,
+ bool apply);
+
#endif /* __VSP1_RWPF_H__ */
spin_lock_irqsave(&pipe->irqlock, flags);
- video->rwpf->ops->set_memory(video->rwpf, &buf->mem);
+ vsp1_rwpf_set_memory(video->rwpf, &buf->mem, true);
pipe->buffers_ready |= 1 << video->pipe_index;
spin_unlock_irqrestore(&pipe->irqlock, flags);
return -EINVAL;
}
+ for ( ; i < 3; ++i) {
+ buf->mem.addr[i] = 0;
+ buf->mem.length[i] = 0;
+ }
+
return 0;
}
spin_lock_irqsave(&pipe->irqlock, flags);
- video->rwpf->ops->set_memory(video->rwpf, &buf->mem);
+ vsp1_rwpf_set_memory(video->rwpf, &buf->mem, true);
pipe->buffers_ready |= 1 << video->pipe_index;
if (vb2_is_streaming(&video->queue) &&
* Video Device Operations
*/
-static void wpf_set_memory(struct vsp1_rwpf *wpf, struct vsp1_rwpf_memory *mem)
+static void wpf_set_memory(struct vsp1_rwpf *wpf)
{
- vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_Y, mem->addr[0]);
- if (mem->num_planes > 1)
- vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_C0, mem->addr[1]);
- if (mem->num_planes > 2)
- vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_C1, mem->addr[2]);
+ vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_Y, wpf->buf_addr[0]);
+ vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_C0, wpf->buf_addr[1]);
+ vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_C1, wpf->buf_addr[2]);
}
static const struct vsp1_rwpf_operations wpf_vdev_ops = {