Пример #1
0
static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
{
	struct vsp1_rwpf *wpf = to_rwpf(subdev);
	struct vsp1_device *vsp1 = wpf->entity.vsp1;

	if (enable)
		return 0;

	/* Write to registers directly when stopping the stream as there will be
	 * no pipeline run to apply the display list.
	 */
	vsp1_write(vsp1, VI6_WPF_IRQ_ENB(wpf->entity.index), 0);
	vsp1_write(vsp1, wpf->entity.index * VI6_WPF_OFFSET +
		   VI6_WPF_SRCRPF, 0);

	return 0;
}
Пример #2
0
static inline void vsp1_uds_write(struct vsp1_uds *uds, u32 reg, u32 data)
{
	vsp1_write(uds->entity.vsp1,
		   reg + uds->entity.index * VI6_UDS_OFFSET, data);
}
Пример #3
0
static inline void vsp1_sru_write(struct vsp1_sru *sru, u32 reg, u32 data)
{
	vsp1_write(sru->entity.vsp1, reg, data);
}
Пример #4
0
static inline void vsp1_rpf_write(struct vsp1_rwpf *rpf, u32 reg, u32 data)
{
	vsp1_write(rpf->entity.vsp1,
		   reg + rpf->entity.index * VI6_RPF_OFFSET, data);
}
Пример #5
0
static inline void vsp1_lut_write(struct vsp1_lut *lut, u32 reg, u32 data)
{
    vsp1_write(lut->entity.vsp1, reg, data);
}
Пример #6
0
static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
{
	struct vsp1_pipeline *pipe = to_vsp1_pipeline(&subdev->entity);
	struct vsp1_rwpf *wpf = to_rwpf(subdev);
	struct vsp1_device *vsp1 = wpf->entity.vsp1;
	const struct v4l2_rect *crop = &wpf->crop;
	unsigned int i;
	u32 srcrpf = 0;
	u32 outfmt = 0;
	int ret;

	ret = vsp1_entity_set_streaming(&wpf->entity, enable);
	if (ret < 0)
		return ret;

	if (!enable) {
		vsp1_write(vsp1, VI6_WPF_IRQ_ENB(wpf->entity.index), 0);
		vsp1_wpf_write(wpf, VI6_WPF_SRCRPF, 0);
		return 0;
	}

	/* Sources. If the pipeline has a single input and BRU is not used,
	 * configure it as the master layer. Otherwise configure all
	 * inputs as sub-layers and select the virtual RPF as the master
	 * layer.
	 */
	for (i = 0; i < pipe->num_inputs; ++i) {
		struct vsp1_rwpf *input = pipe->inputs[i];

		srcrpf |= (!pipe->bru && pipe->num_inputs == 1)
			? VI6_WPF_SRCRPF_RPF_ACT_MST(input->entity.index)
			: VI6_WPF_SRCRPF_RPF_ACT_SUB(input->entity.index);
	}

	if (pipe->bru || pipe->num_inputs > 1)
		srcrpf |= VI6_WPF_SRCRPF_VIRACT_MST;

	vsp1_wpf_write(wpf, VI6_WPF_SRCRPF, srcrpf);

	/* Destination stride. */
	if (!pipe->lif) {
		struct v4l2_pix_format_mplane *format = &wpf->video.format;

		vsp1_wpf_write(wpf, VI6_WPF_DSTM_STRIDE_Y,
			       format->plane_fmt[0].bytesperline);
		if (format->num_planes > 1)
			vsp1_wpf_write(wpf, VI6_WPF_DSTM_STRIDE_C,
				       format->plane_fmt[1].bytesperline);
	}

	vsp1_wpf_write(wpf, VI6_WPF_HSZCLIP, VI6_WPF_SZCLIP_EN |
		       (crop->left << VI6_WPF_SZCLIP_OFST_SHIFT) |
		       (crop->width << VI6_WPF_SZCLIP_SIZE_SHIFT));
	vsp1_wpf_write(wpf, VI6_WPF_VSZCLIP, VI6_WPF_SZCLIP_EN |
		       (crop->top << VI6_WPF_SZCLIP_OFST_SHIFT) |
		       (crop->height << VI6_WPF_SZCLIP_SIZE_SHIFT));

	/* Format */
	if (!pipe->lif) {
		const struct vsp1_format_info *fmtinfo = wpf->video.fmtinfo;

		outfmt = fmtinfo->hwfmt << VI6_WPF_OUTFMT_WRFMT_SHIFT;

		if (fmtinfo->alpha)
			outfmt |= VI6_WPF_OUTFMT_PXA;
		if (fmtinfo->swap_yc)
			outfmt |= VI6_WPF_OUTFMT_SPYCS;
		if (fmtinfo->swap_uv)
			outfmt |= VI6_WPF_OUTFMT_SPUVS;

		vsp1_wpf_write(wpf, VI6_WPF_DSWAP, fmtinfo->swap);
	}

	if (wpf->entity.formats[RWPF_PAD_SINK].code !=
	    wpf->entity.formats[RWPF_PAD_SOURCE].code)
		outfmt |= VI6_WPF_OUTFMT_CSC;

	/* Take the control handler lock to ensure that the PDV value won't be
	 * changed behind our back by a set control operation.
	 */
	mutex_lock(wpf->ctrls.lock);
	outfmt |= vsp1_wpf_read(wpf, VI6_WPF_OUTFMT) & VI6_WPF_OUTFMT_PDV_MASK;
	vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, outfmt);
	mutex_unlock(wpf->ctrls.lock);

	vsp1_write(vsp1, VI6_DPR_WPF_FPORCH(wpf->entity.index),
		   VI6_DPR_WPF_FPORCH_FP_WPFN);

	vsp1_write(vsp1, VI6_WPF_WRBCK_CTRL, 0);

	/* Enable interrupts */
	vsp1_write(vsp1, VI6_WPF_IRQ_STA(wpf->entity.index), 0);
	vsp1_write(vsp1, VI6_WPF_IRQ_ENB(wpf->entity.index),
		   VI6_WFP_IRQ_ENB_FREE);

	return 0;
}
Пример #7
0
static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
{
	struct vsp1_rwpf *wpf = to_rwpf(subdev);
	struct vsp1_pipeline *pipe =
		to_vsp1_pipeline(&wpf->entity.subdev.entity);
	struct vsp1_device *vsp1 = wpf->entity.vsp1;
	const struct v4l2_rect *crop = &wpf->crop;
	unsigned int i;
	u32 srcrpf = 0;
	u32 outfmt = 0;

	if (!enable) {
		vsp1_write(vsp1, VI6_WPF_IRQ_ENB(wpf->entity.index), 0);
		return 0;
	}

	/* Sources. If the pipeline has a single input configure it as the
	 * master layer. Otherwise configure all inputs as sub-layers and
	 * select the virtual RPF as the master layer.
	 */
	for (i = 0; i < pipe->num_inputs; ++i) {
		struct vsp1_rwpf *input = pipe->inputs[i];

		srcrpf |= pipe->num_inputs == 1
			? VI6_WPF_SRCRPF_RPF_ACT_MST(input->entity.index)
			: VI6_WPF_SRCRPF_RPF_ACT_SUB(input->entity.index);
	}

	if (pipe->num_inputs > 1)
		srcrpf |= VI6_WPF_SRCRPF_VIRACT_MST;

	vsp1_wpf_write(wpf, VI6_WPF_SRCRPF, srcrpf);

	/* Destination stride. */
	if (!pipe->lif) {
		struct v4l2_pix_format_mplane *format = &wpf->video.format;

		vsp1_wpf_write(wpf, VI6_WPF_DSTM_STRIDE_Y,
			       format->plane_fmt[0].bytesperline);
		if (format->num_planes > 1)
			vsp1_wpf_write(wpf, VI6_WPF_DSTM_STRIDE_C,
				       format->plane_fmt[1].bytesperline);
	}

	vsp1_wpf_write(wpf, VI6_WPF_HSZCLIP, VI6_WPF_SZCLIP_EN |
		       (crop->left << VI6_WPF_SZCLIP_OFST_SHIFT) |
		       (crop->width << VI6_WPF_SZCLIP_SIZE_SHIFT));
	vsp1_wpf_write(wpf, VI6_WPF_VSZCLIP, VI6_WPF_SZCLIP_EN |
		       (crop->top << VI6_WPF_SZCLIP_OFST_SHIFT) |
		       (crop->height << VI6_WPF_SZCLIP_SIZE_SHIFT));

	/* Format */
	if (!pipe->lif) {
		const struct vsp1_format_info *fmtinfo = wpf->video.fmtinfo;

		outfmt = fmtinfo->hwfmt << VI6_WPF_OUTFMT_WRFMT_SHIFT;

		if (fmtinfo->swap_yc)
			outfmt |= VI6_WPF_OUTFMT_SPYCS;
		if (fmtinfo->swap_uv)
			outfmt |= VI6_WPF_OUTFMT_SPUVS;

		vsp1_wpf_write(wpf, VI6_WPF_DSWAP, fmtinfo->swap);
	}

	if (wpf->entity.formats[RWPF_PAD_SINK].code !=
	    wpf->entity.formats[RWPF_PAD_SOURCE].code)
		outfmt |= VI6_WPF_OUTFMT_CSC;

	vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, outfmt);

	vsp1_write(vsp1, VI6_DPR_WPF_FPORCH(wpf->entity.index),
		   VI6_DPR_WPF_FPORCH_FP_WPFN);

	vsp1_write(vsp1, VI6_WPF_WRBCK_CTRL, 0);

	/* Enable interrupts */
	vsp1_write(vsp1, VI6_WPF_IRQ_STA(wpf->entity.index), 0);
	vsp1_write(vsp1, VI6_WPF_IRQ_ENB(wpf->entity.index),
		   VI6_WFP_IRQ_ENB_FREE);

	return 0;
}
Пример #8
0
static inline void vsp1_lif_write(struct vsp1_lif *lif, u32 reg, u32 data)
{
	vsp1_write(lif->entity.vsp1, reg, data);
}
Пример #9
0
static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
{
	struct vsp1_rwpf *wpf = to_rwpf(subdev);
	struct vsp1_pipeline *pipe =
		to_vsp1_pipeline(&wpf->entity.subdev.entity);
	struct vsp1_device *vsp1 = wpf->entity.vsp1;
	const struct v4l2_mbus_framefmt *format =
		&wpf->entity.formats[RWPF_PAD_SOURCE];
	unsigned int i;
	u32 srcrpf = 0;
	u32 outfmt = 0;

	if (!enable) {
		vsp1_write(vsp1, VI6_WPF_IRQ_ENB(wpf->entity.index), 0);
		return 0;
	}

	/* Sources */
	for (i = 0; i < pipe->num_inputs; ++i) {
		struct vsp1_rwpf *input = pipe->inputs[i];

		srcrpf |= VI6_WPF_SRCRPF_RPF_ACT_MST(input->entity.index);
	}

	vsp1_wpf_write(wpf, VI6_WPF_SRCRPF, srcrpf);

	/* Destination stride. Cropping isn't supported yet. */
	if (!pipe->lif) {
		struct v4l2_pix_format_mplane *format = &wpf->video.format;

		vsp1_wpf_write(wpf, VI6_WPF_DSTM_STRIDE_Y,
			       format->plane_fmt[0].bytesperline);
		if (format->num_planes > 1)
			vsp1_wpf_write(wpf, VI6_WPF_DSTM_STRIDE_C,
				       format->plane_fmt[1].bytesperline);
	}

	vsp1_wpf_write(wpf, VI6_WPF_HSZCLIP,
		       format->width << VI6_WPF_SZCLIP_SIZE_SHIFT);
	vsp1_wpf_write(wpf, VI6_WPF_VSZCLIP,
		       format->height << VI6_WPF_SZCLIP_SIZE_SHIFT);

	/* Format */
	if (!pipe->lif) {
		const struct vsp1_format_info *fmtinfo = wpf->video.fmtinfo;

		outfmt = fmtinfo->hwfmt << VI6_WPF_OUTFMT_WRFMT_SHIFT;

		if (fmtinfo->swap_yc)
			outfmt |= VI6_WPF_OUTFMT_SPYCS;
		if (fmtinfo->swap_uv)
			outfmt |= VI6_WPF_OUTFMT_SPUVS;

		vsp1_wpf_write(wpf, VI6_WPF_DSWAP, fmtinfo->swap);
	}

	if (wpf->entity.formats[RWPF_PAD_SINK].code !=
	    wpf->entity.formats[RWPF_PAD_SOURCE].code)
		outfmt |= VI6_WPF_OUTFMT_CSC;

	vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, outfmt);

	vsp1_write(vsp1, VI6_DPR_WPF_FPORCH(wpf->entity.index),
		   VI6_DPR_WPF_FPORCH_FP_WPFN);

	vsp1_write(vsp1, VI6_WPF_WRBCK_CTRL, 0);

	/* Enable interrupts */
	vsp1_write(vsp1, VI6_WPF_IRQ_STA(wpf->entity.index), 0);
	vsp1_write(vsp1, VI6_WPF_IRQ_ENB(wpf->entity.index),
		   VI6_WFP_IRQ_ENB_FREE);

	return 0;
}
Пример #10
0
static inline void vsp1_hsit_write(struct vsp1_hsit *hsit, u32 reg, u32 data)
{
	vsp1_write(hsit->entity.vsp1, reg, data);
}