drivers/video/fbdev/core/fb_copyarea.h

Source file repositories/reference/linux-study-clean/drivers/video/fbdev/core/fb_copyarea.h

File Facts

System
Linux kernel
Corpus path
drivers/video/fbdev/core/fb_copyarea.h
Extension
.h
Size
11689 bytes
Lines
406
Domain
Driver Families
Bucket
drivers/video
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

while (offset + 4 <= end) {
			fb_copy_offset(offset + 0, dst, src);
			fb_copy_offset(offset + 1, dst, src);
			fb_copy_offset(offset + 2, dst, src);
			fb_copy_offset(offset + 3, dst, src);
			offset += 4;
		}
		while (offset < end)
			fb_copy_offset(offset++, dst, src);

		/* Trailing bits */
		if (last)
			fb_copy_offset_masked(last, offset, dst, src);
	}
}

/* reverse aligned copy */
static inline void fb_copy_aligned_rev(const struct fb_address *dst,
				       const struct fb_address *src,
				       int end, struct fb_reverse reverse)
{
	unsigned long first, last;

	first = fb_pixel_mask(dst->bits, reverse);
	last = ~fb_pixel_mask(end & (BITS_PER_LONG-1), reverse);

	if (end <= BITS_PER_LONG) {
		/* Single word */
		if (last)
			first &= last;
		if (first == ~0UL)
			fb_copy_offset(0, dst, src);
		else
			fb_copy_offset_masked(first, 0, dst, src);
	} else {
		/* Multiple destination words */
		int offset = first != ~0UL;

		/* Trailing bits */
		end /= BITS_PER_LONG;

		if (last)
			fb_copy_offset_masked(last, end, dst, src);

		/* Main chunk */
		while (end >= offset + 4) {
			fb_copy_offset(end - 1, dst, src);
			fb_copy_offset(end - 2, dst, src);
			fb_copy_offset(end - 3, dst, src);
			fb_copy_offset(end - 4, dst, src);
			end -= 4;
		}
		while (end > offset)
			fb_copy_offset(--end, dst, src);

		/* Leading bits */
		if (offset)
			fb_copy_offset_masked(first, 0, dst, src);
	}
}

static inline void fb_copy_aligned(struct fb_address *dst, struct fb_address *src,
				   int width, u32 height, unsigned int bits_per_line,
				   struct fb_reverse reverse, bool rev_copy)
{
	if (rev_copy)
		while (height--) {
			fb_copy_aligned_rev(dst, src, width + dst->bits, reverse);
			fb_address_backward(dst, bits_per_line);
			fb_address_backward(src, bits_per_line);
		}
	else
		while (height--) {
			fb_copy_aligned_fwd(dst, src, width + dst->bits, reverse);
			fb_address_forward(dst, bits_per_line);
			fb_address_forward(src, bits_per_line);
		}
}

static __always_inline void fb_copy_fwd(const struct fb_address *dst,
					const struct fb_address *src, int width,
					unsigned long (*reorder)(unsigned long val,
								 struct fb_reverse reverse),
					struct fb_reverse reverse)
{
	unsigned long first, last;
	unsigned long d0, d1;
	int end = dst->bits + width;
	int shift, left, right;

Annotation

Implementation Notes