drivers/gpu/drm/ast/ast_cursor.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/ast/ast_cursor.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/ast/ast_cursor.c
Extension
.c
Size
10907 bytes
Lines
361
Domain
Driver Families
Bucket
drivers/gpu
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 (one_pixel_copy) {
			const u16 *src16 = (const u16 *)src;

			csum += *src16;
			src += SZ_2;
		}
		src += trailing_bytes;
	}

	return csum;
}

static void ast_set_cursor_image(struct ast_device *ast, const u8 *src,
				 unsigned int width, unsigned int height)
{
	u8 __iomem *dst = ast_plane_vaddr(&ast->cursor_plane.base);
	u32 csum = ast_cursor_calculate_checksum(src, width, height);

	/* write pixel data */
#if defined(__BIG_ENDIAN)
	unsigned int i;

	for (i = 0; i < AST_HWC_SIZE; i += 2)
		writew(swab16(*(const __u16 *)&src[i]), &dst[i]);
#else
	memcpy_toio(dst, src, AST_HWC_SIZE);
#endif

	/* write checksum + signature */
	dst += AST_HWC_SIZE;
	writel(csum, dst);
	writel(width, dst + AST_HWC_SIGNATURE_SizeX);
	writel(height, dst + AST_HWC_SIGNATURE_SizeY);
	writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTX);
	writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY);
}

static void ast_set_cursor_base(struct ast_device *ast, u64 address)
{
	u8 addr0 = (address >> 3) & 0xff;
	u8 addr1 = (address >> 11) & 0xff;
	u8 addr2 = (address >> 19) & 0xff;

	ast_set_index_reg(ast, AST_IO_VGACRI, 0xc8, addr0);
	ast_set_index_reg(ast, AST_IO_VGACRI, 0xc9, addr1);
	ast_set_index_reg(ast, AST_IO_VGACRI, 0xca, addr2);
}

static void ast_set_cursor_location(struct ast_device *ast, u16 x, u16 y,
				    u8 x_offset, u8 y_offset)
{
	u8 x0 = (x & 0x00ff);
	u8 x1 = (x & 0x0f00) >> 8;
	u8 y0 = (y & 0x00ff);
	u8 y1 = (y & 0x0700) >> 8;

	ast_set_index_reg(ast, AST_IO_VGACRI, 0xc2, x_offset);
	ast_set_index_reg(ast, AST_IO_VGACRI, 0xc3, y_offset);
	ast_set_index_reg(ast, AST_IO_VGACRI, 0xc4, x0);
	ast_set_index_reg(ast, AST_IO_VGACRI, 0xc5, x1);
	ast_set_index_reg(ast, AST_IO_VGACRI, 0xc6, y0);
	ast_set_index_reg(ast, AST_IO_VGACRI, 0xc7, y1);
}

static void ast_set_cursor_enabled(struct ast_device *ast, bool enabled)
{
	static const u8 mask = (u8)~(AST_IO_VGACRCB_HWC_16BPP |
				     AST_IO_VGACRCB_HWC_ENABLED);

	u8 vgacrcb = AST_IO_VGACRCB_HWC_16BPP;

	if (enabled)
		vgacrcb |= AST_IO_VGACRCB_HWC_ENABLED;

	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xcb, mask, vgacrcb);
}

/*
 * Cursor plane
 */

static const uint32_t ast_cursor_plane_formats[] = {
	DRM_FORMAT_ARGB4444,
	DRM_FORMAT_ARGB8888,
};

static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane,
						struct drm_atomic_commit *state)
{
	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);

Annotation

Implementation Notes