drivers/gpu/drm/logicvc/logicvc_layer.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/logicvc/logicvc_layer.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/logicvc/logicvc_layer.c
Extension
.c
Size
16258 bytes
Lines
631
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 (ret) {
			drm_err(drm_dev, "No viable setup for buffer found.\n");
			return ret;
		}
	}

	min_scale = DRM_PLANE_NO_SCALING;
	max_scale = DRM_PLANE_NO_SCALING;

	can_position = (drm_plane->type == DRM_PLANE_TYPE_OVERLAY &&
			layer->index != (logicvc->config.layers_count - 1) &&
			logicvc->config.layers_configurable);

	ret = drm_atomic_helper_check_plane_state(new_state, crtc_state,
						  min_scale, max_scale,
						  can_position, true);
	if (ret) {
		drm_err(drm_dev, "Invalid plane state\n\n");
		return ret;
	}

	return 0;
}

static void logicvc_plane_atomic_update(struct drm_plane *drm_plane,
					struct drm_atomic_commit *state)
{
	struct logicvc_layer *layer = logicvc_layer(drm_plane);
	struct logicvc_drm *logicvc = logicvc_drm(drm_plane->dev);
	struct drm_device *drm_dev = &logicvc->drm_dev;
	struct drm_plane_state *new_state =
		drm_atomic_get_new_plane_state(state, drm_plane);
	struct drm_crtc *drm_crtc = &logicvc->crtc->drm_crtc;
	struct drm_display_mode *mode = &drm_crtc->state->adjusted_mode;
	struct drm_framebuffer *fb = new_state->fb;
	struct logicvc_layer_buffer_setup setup = {};
	u32 index = layer->index;
	u32 reg;

	/* Layer dimensions */

	regmap_write(logicvc->regmap, LOGICVC_LAYER_WIDTH_REG(index),
		     new_state->crtc_w - 1);
	regmap_write(logicvc->regmap, LOGICVC_LAYER_HEIGHT_REG(index),
		     new_state->crtc_h - 1);

	if (logicvc->caps->layer_address) {
		phys_addr_t fb_addr = drm_fb_dma_get_gem_addr(fb, new_state, 0);

		regmap_write(logicvc->regmap, LOGICVC_LAYER_ADDRESS_REG(index),
			     fb_addr);
	} else {
		/* Rely on offsets to configure the address. */

		logicvc_layer_buffer_find_setup(logicvc, layer, new_state,
						&setup);

		/* Layer memory offsets */

		regmap_write(logicvc->regmap, LOGICVC_BUFFER_SEL_REG,
			     LOGICVC_BUFFER_SEL_VALUE(index, setup.buffer_sel));
		regmap_write(logicvc->regmap, LOGICVC_LAYER_HOFFSET_REG(index),
			     setup.hoffset);
		regmap_write(logicvc->regmap, LOGICVC_LAYER_VOFFSET_REG(index),
			     setup.voffset);
	}

	/* Layer position */

	regmap_write(logicvc->regmap, LOGICVC_LAYER_HPOSITION_REG(index),
		     mode->hdisplay - 1 - new_state->crtc_x);

	/* Vertical position must be set last to sync layer register changes. */
	regmap_write(logicvc->regmap, LOGICVC_LAYER_VPOSITION_REG(index),
		     mode->vdisplay - 1 - new_state->crtc_y);

	/* Layer alpha */

	if (layer->config.alpha_mode == LOGICVC_LAYER_ALPHA_LAYER) {
		u32 alpha_bits;
		u32 alpha_max;
		u32 alpha;

		switch (layer->config.depth) {
		case 8:
			alpha_bits = 3;
			break;
		case 16:
			if (layer->config.colorspace ==
			    LOGICVC_LAYER_COLORSPACE_YUV)

Annotation

Implementation Notes