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

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

File Facts

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

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)
			wrtm = VI6_WPF_OUTFMT_WRTM_BT601;
		else if (ycbcr_enc == V4L2_YCBCR_ENC_601 &&
			 quantization == V4L2_QUANTIZATION_FULL_RANGE)
			wrtm = VI6_WPF_OUTFMT_WRTM_BT601_EXT;
		else if (ycbcr_enc == V4L2_YCBCR_ENC_709 &&
			 quantization == V4L2_QUANTIZATION_LIM_RANGE)
			wrtm = VI6_WPF_OUTFMT_WRTM_BT709;
		else
			wrtm = VI6_WPF_OUTFMT_WRTM_BT709_EXT;

		outfmt |= VI6_WPF_OUTFMT_CSC | wrtm;
	}

	wpf->outfmt = outfmt;

	vsp1_dl_body_write(dlb, VI6_DPR_WPF_FPORCH(index),
			   VI6_DPR_WPF_FPORCH_FP_WPFN);

	/*
	 * Sources. If the pipeline has a single input and BRx 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 VSPX configure the enabled sources as masters.
	 */
	for (i = 0; i < vsp1->info->rpf_count; ++i) {
		struct vsp1_rwpf *input = pipe->inputs[i];

		if (!input)
			continue;

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

	if (pipe->brx)
		srcrpf |= pipe->brx->type == VSP1_ENTITY_BRU
			? VI6_WPF_SRCRPF_VIRACT_MST
			: VI6_WPF_SRCRPF_VIRACT2_MST;

	vsp1_wpf_write(wpf, dlb, VI6_WPF_SRCRPF, srcrpf);

	/* Enable interrupts. */
	vsp1_dl_body_write(dlb, VI6_WPF_IRQ_STA(index), 0);
	vsp1_dl_body_write(dlb, VI6_WPF_IRQ_ENB(index),
			   VI6_WPF_IRQ_ENB_DFEE);

	if (pipe->iif)
		return;

	/*
	 * Configure writeback for display pipelines (the wpf writeback flag is
	 * never set for memory-to-memory pipelines). Start by adding a chained
	 * display list to disable writeback after a single frame, and process
	 * to enable writeback. If the display list allocation fails don't
	 * enable writeback as we wouldn't be able to safely disable it,
	 * resulting in possible memory corruption.
	 */
	if (wpf->writeback) {
		ret = wpf_configure_writeback_chain(wpf, dl);
		if (ret < 0)
			wpf->writeback = false;
	}

	vsp1_dl_body_write(dlb, VI6_WPF_WRBCK_CTRL(index),
			   wpf->writeback ? VI6_WPF_WRBCK_CTRL_WBMD : 0);
}

static void wpf_configure_frame(struct vsp1_entity *entity,
				struct vsp1_pipeline *pipe,
				struct vsp1_dl_list *dl,
				struct vsp1_dl_body *dlb)
{
	const unsigned int mask = BIT(WPF_CTRL_VFLIP)
				| BIT(WPF_CTRL_HFLIP);
	struct vsp1_rwpf *wpf = to_rwpf(&entity->subdev);
	u32 outfmt;

	scoped_guard(spinlock_irqsave, &wpf->flip.lock) {
		wpf->flip.active = (wpf->flip.active & ~mask)

Annotation

Implementation Notes