drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
Extension
.c
Size
29183 bytes
Lines
1127
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 rzg2l_cru_buffer {
	struct vb2_v4l2_buffer vb;
	struct list_head list;
};

#define to_buf_list(vb2_buffer) \
	(&container_of(vb2_buffer, struct rzg2l_cru_buffer, vb)->list)

/*
 * The CRU hardware cycles over its slots when transferring frames. All drivers
 * structure that contains programming data for the slots, such as the memory
 * destination addresses have to be iterated as they were circular buffers.
 *
 * Provide here utilities to iterate over slots and the associated data.
 */
static inline unsigned int rzg2l_cru_slot_next(struct rzg2l_cru_dev *cru,
					       unsigned int slot)
{
	return (slot + 1) % cru->num_buf;
}

/* Start cycling on cru slots from the one after 'start'. */
#define for_each_cru_slot_from(cru, slot, start)			\
	for ((slot) = rzg2l_cru_slot_next((cru), (start));			\
	     (slot) != (start); (slot) = rzg2l_cru_slot_next((cru), (slot)))

/* -----------------------------------------------------------------------------
 * DMA operations
 */
static void __rzg2l_cru_write(struct rzg2l_cru_dev *cru, u32 offset, u32 value)
{
	const u16 *regs = cru->info->regs;

	/*
	 * CRUnCTRL is a first register on all CRU supported SoCs so validate
	 * rest of the registers have valid offset being set in cru->info->regs.
	 */
	if (WARN_ON(offset >= RZG2L_CRU_MAX_REG) ||
	    WARN_ON(offset != CRUnCTRL && regs[offset] == 0))
		return;

	iowrite32(value, cru->base + regs[offset]);
}

static u32 __rzg2l_cru_read(struct rzg2l_cru_dev *cru, u32 offset)
{
	const u16 *regs = cru->info->regs;

	/*
	 * CRUnCTRL is a first register on all CRU supported SoCs so validate
	 * rest of the registers have valid offset being set in cru->info->regs.
	 */
	if (WARN_ON(offset >= RZG2L_CRU_MAX_REG) ||
	    WARN_ON(offset != CRUnCTRL && regs[offset] == 0))
		return 0;

	return ioread32(cru->base + regs[offset]);
}

static __always_inline void
__rzg2l_cru_write_constant(struct rzg2l_cru_dev *cru, u32 offset, u32 value)
{
	const u16 *regs = cru->info->regs;

	BUILD_BUG_ON(offset >= RZG2L_CRU_MAX_REG);

	iowrite32(value, cru->base + regs[offset]);
}

static __always_inline u32
__rzg2l_cru_read_constant(struct rzg2l_cru_dev *cru, u32 offset)
{
	const u16 *regs = cru->info->regs;

	BUILD_BUG_ON(offset >= RZG2L_CRU_MAX_REG);

	return ioread32(cru->base + regs[offset]);
}

#define rzg2l_cru_write(cru, offset, value) \
	(__builtin_constant_p(offset) ? \
	 __rzg2l_cru_write_constant(cru, offset, value) : \
	 __rzg2l_cru_write(cru, offset, value))

#define rzg2l_cru_read(cru, offset) \
	(__builtin_constant_p(offset) ? \
	 __rzg2l_cru_read_constant(cru, offset) : \
	 __rzg2l_cru_read(cru, offset))

static void rzg2l_cru_return_buffers(struct rzg2l_cru_dev *cru,

Annotation

Implementation Notes