drivers/gpu/drm/loongson/lsdc_plane.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/loongson/lsdc_plane.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/loongson/lsdc_plane.c
Extension
.c
Size
22215 bytes
Lines
795
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

switch (new_state->crtc_w) {
		case 64:
			cursor_size = CURSOR_SIZE_64X64;
			break;
		case 32:
			cursor_size = CURSOR_SIZE_32X32;
			break;
		default:
			cursor_size = CURSOR_SIZE_32X32;
			break;
		}

		ops->update_position(cursor, new_state->crtc_x, new_state->crtc_y);

		ops->update_cfg(cursor, cursor_size, CURSOR_FORMAT_ARGB8888);

		if (!old_fb || old_fb != new_fb)
			ops->update_bo_addr(cursor, lsdc_fb_base_addr(new_fb));
	}
}

/* ls7a1000 cursor plane helpers */

static int ls7a1000_cursor_plane_atomic_check(struct drm_plane *plane,
					      struct drm_atomic_commit *state)
{
	struct drm_plane_state *new_plane_state;
	struct drm_crtc_state *new_crtc_state;
	struct drm_crtc *crtc;

	new_plane_state = drm_atomic_get_new_plane_state(state, plane);

	crtc = new_plane_state->crtc;
	if (!crtc) {
		drm_dbg(plane->dev, "%s is not bind to a crtc\n", plane->name);
		return 0;
	}

	if (new_plane_state->crtc_w != 32 || new_plane_state->crtc_h != 32) {
		drm_dbg(plane->dev, "unsupported cursor size: %ux%u\n",
			new_plane_state->crtc_w, new_plane_state->crtc_h);
		return -EINVAL;
	}

	new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);

	return drm_atomic_helper_check_plane_state(new_plane_state,
						   new_crtc_state,
						   DRM_PLANE_NO_SCALING,
						   DRM_PLANE_NO_SCALING,
						   true, true);
}

static void ls7a1000_cursor_plane_atomic_update(struct drm_plane *plane,
						struct drm_atomic_commit *state)
{
	struct lsdc_cursor *cursor = to_lsdc_cursor(plane);
	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
	struct drm_framebuffer *new_fb = new_plane_state->fb;
	struct drm_framebuffer *old_fb = old_plane_state->fb;
	const struct lsdc_cursor_plane_ops *ops = cursor->ops;
	u64 addr = lsdc_fb_base_addr(new_fb);

	if (!new_plane_state->visible)
		return;

	ops->update_position(cursor, new_plane_state->crtc_x, new_plane_state->crtc_y);

	if (!old_fb || old_fb != new_fb)
		ops->update_bo_addr(cursor, addr);

	ops->update_cfg(cursor, CURSOR_SIZE_32X32, CURSOR_FORMAT_ARGB8888);
}

static void ls7a1000_cursor_plane_atomic_disable(struct drm_plane *plane,
						 struct drm_atomic_commit *state)
{
	struct lsdc_cursor *cursor = to_lsdc_cursor(plane);
	const struct lsdc_cursor_plane_ops *ops = cursor->ops;

	ops->update_cfg(cursor, CURSOR_SIZE_32X32, CURSOR_FORMAT_DISABLE);
}

static const struct drm_plane_helper_funcs ls7a1000_cursor_plane_helper_funcs = {
	.prepare_fb = lsdc_plane_prepare_fb,
	.cleanup_fb = lsdc_plane_cleanup_fb,
	.atomic_check = ls7a1000_cursor_plane_atomic_check,
	.atomic_update = ls7a1000_cursor_plane_atomic_update,
	.atomic_disable = ls7a1000_cursor_plane_atomic_disable,

Annotation

Implementation Notes