drivers/gpu/drm/ast/ast_mode.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/ast/ast_mode.c
Extension
.c
Size
32616 bytes
Lines
1079
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

drm_atomic_for_each_plane_damage(&iter, &damage) {
			ast_handle_damage(ast_plane, shadow_plane_state->data, fb, &damage,
					  &shadow_plane_state->fmtcnv_state);
		}

		drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
	}

	/*
	 * Some BMCs stop scanning out the video signal after the driver
	 * reprogrammed the offset. This stalls display output for several
	 * seconds and makes the display unusable. Therefore only update
	 * the offset if it changes.
	 */
	if (!old_fb || old_fb->pitches[0] != fb->pitches[0])
		ast_set_offset_reg(ast, fb);
}

static void ast_primary_plane_helper_atomic_enable(struct drm_plane *plane,
						   struct drm_atomic_commit *state)
{
	struct ast_device *ast = to_ast_device(plane->dev);
	struct ast_plane *ast_plane = to_ast_plane(plane);

	/*
	 * Some BMCs stop scanning out the video signal after the driver
	 * reprogrammed the scanout address. This stalls display
	 * output for several seconds and makes the display unusable.
	 * Therefore only reprogram the address after enabling the plane.
	 */
	ast_set_start_address_crt1(ast, (u32)ast_plane->offset);
}

static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
						    struct drm_atomic_commit *state)
{
	/*
	 * Keep this empty function to avoid calling
	 * atomic_update when disabling the plane.
	 */
}

static int ast_primary_plane_helper_get_scanout_buffer(struct drm_plane *plane,
						       struct drm_scanout_buffer *sb)
{
	struct ast_plane *ast_plane = to_ast_plane(plane);

	if (plane->state && plane->state->fb) {
		sb->format = plane->state->fb->format;
		sb->width = plane->state->fb->width;
		sb->height = plane->state->fb->height;
		sb->pitch[0] = plane->state->fb->pitches[0];
		iosys_map_set_vaddr_iomem(&sb->map[0], ast_plane_vaddr(ast_plane));
		return 0;
	}
	return -ENODEV;
}

static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = {
	DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
	.atomic_check = ast_primary_plane_helper_atomic_check,
	.atomic_update = ast_primary_plane_helper_atomic_update,
	.atomic_enable = ast_primary_plane_helper_atomic_enable,
	.atomic_disable = ast_primary_plane_helper_atomic_disable,
	.get_scanout_buffer = ast_primary_plane_helper_get_scanout_buffer,
};

static const struct drm_plane_funcs ast_primary_plane_funcs = {
	.update_plane = drm_atomic_helper_update_plane,
	.disable_plane = drm_atomic_helper_disable_plane,
	.destroy = drm_plane_cleanup,
	DRM_GEM_SHADOW_PLANE_FUNCS,
};

static int ast_primary_plane_init(struct ast_device *ast)
{
	struct drm_device *dev = &ast->base;
	struct ast_plane *ast_primary_plane = &ast->primary_plane;
	struct drm_plane *primary_plane = &ast_primary_plane->base;
	u64 offset = ast_fb_vram_offset();
	unsigned long size = ast_fb_vram_size(ast);
	int ret;

	ret = ast_plane_init(dev, ast_primary_plane, offset, size,
			     0x01, &ast_primary_plane_funcs,
			     ast_primary_plane_formats, ARRAY_SIZE(ast_primary_plane_formats),
			     NULL, DRM_PLANE_TYPE_PRIMARY);
	if (ret) {
		drm_err(dev, "ast_plane_init() failed: %d\n", ret);
		return ret;

Annotation

Implementation Notes