drivers/media/platform/renesas/vsp1/vsp1_rpf.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/renesas/vsp1/vsp1_rpf.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/renesas/vsp1/vsp1_rpf.c
Extension
.c
Size
13464 bytes
Lines
458
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

struct vsp1_extcmd_auto_fld_body {
	u32 top_y0;
	u32 bottom_y0;
	u32 top_c0;
	u32 bottom_c0;
	u32 top_c1;
	u32 bottom_c1;
	u32 reserved0;
	u32 reserved1;
} __packed;

/* -----------------------------------------------------------------------------
 * Device Access
 */

static inline void vsp1_rpf_write(struct vsp1_rwpf *rpf,
				  struct vsp1_dl_body *dlb, u32 reg, u32 data)
{
	vsp1_dl_body_write(dlb, reg + rpf->entity.index * VI6_RPF_OFFSET,
			       data);
}

/* -----------------------------------------------------------------------------
 * VSP1 Entity Operations
 */

static void rpf_configure_stream(struct vsp1_entity *entity,
				 struct v4l2_subdev_state *state,
				 struct vsp1_pipeline *pipe,
				 struct vsp1_dl_list *dl,
				 struct vsp1_dl_body *dlb)
{
	struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
	const struct vsp1_format_info *fmtinfo = rpf->fmtinfo;
	const struct v4l2_pix_format_mplane *format = &rpf->format;
	const struct v4l2_mbus_framefmt *source_format;
	const struct v4l2_mbus_framefmt *sink_format;
	unsigned int left = 0;
	unsigned int top = 0;
	u32 pstride;
	u32 infmt;

	/* Stride */
	pstride = format->plane_fmt[0].bytesperline
		<< VI6_RPF_SRCM_PSTRIDE_Y_SHIFT;
	if (format->num_planes > 1)
		pstride |= format->plane_fmt[1].bytesperline
			<< VI6_RPF_SRCM_PSTRIDE_C_SHIFT;

	/*
	 * pstride has both STRIDE_Y and STRIDE_C, but multiplying the whole
	 * of pstride by 2 is conveniently OK here as we are multiplying both
	 * values.
	 */
	if (pipe->interlaced)
		pstride *= 2;

	vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_PSTRIDE, pstride);

	/* Format */
	sink_format = v4l2_subdev_state_get_format(state, RWPF_PAD_SINK);
	source_format = v4l2_subdev_state_get_format(state, RWPF_PAD_SOURCE);

	infmt = (pipe->iif ? 0 : VI6_RPF_INFMT_CIPM)
	      | (fmtinfo->hwfmt << VI6_RPF_INFMT_RDFMT_SHIFT);

	if (fmtinfo->swap_yc)
		infmt |= VI6_RPF_INFMT_SPYCS;
	if (fmtinfo->swap_uv)
		infmt |= VI6_RPF_INFMT_SPUVS;

	if (sink_format->code != source_format->code) {
		u16 ycbcr_enc;
		u16 quantization;
		u32 rdtm;

		if (sink_format->code == MEDIA_BUS_FMT_AYUV8_1X32) {
			ycbcr_enc = sink_format->ycbcr_enc;
			quantization = sink_format->quantization;
		} else {
			ycbcr_enc = source_format->ycbcr_enc;
			quantization = source_format->quantization;
		}

		if (ycbcr_enc == V4L2_YCBCR_ENC_601 &&
		    quantization == V4L2_QUANTIZATION_LIM_RANGE)
			rdtm = VI6_RPF_INFMT_RDTM_BT601;
		else if (ycbcr_enc == V4L2_YCBCR_ENC_601 &&
			 quantization == V4L2_QUANTIZATION_FULL_RANGE)
			rdtm = VI6_RPF_INFMT_RDTM_BT601_EXT;

Annotation

Implementation Notes