drivers/gpu/drm/kmb/kmb_plane.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/kmb/kmb_plane.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/kmb/kmb_plane.c
Extension
.c
Size
18347 bytes
Lines
642
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 (pixel_blend_mode) {
		case DRM_MODE_BLEND_PIXEL_NONE:
			break;
		case DRM_MODE_BLEND_PREMULTI:
			*val |= LCD_LAYER_ALPHA_EMBED | LCD_LAYER_ALPHA_PREMULT;
			break;
		case DRM_MODE_BLEND_COVERAGE:
			*val |= LCD_LAYER_ALPHA_EMBED;
			break;
		default:
			DRM_DEBUG("Missing pixel blend mode case (%s == %ld)\n",
				  __stringify(pixel_blend_mode),
				  (long)pixel_blend_mode);
			break;
		}
	}

	if (plane_alpha == DRM_BLEND_ALPHA_OPAQUE && !has_alpha) {
		*val &= LCD_LAYER_ALPHA_DISABLED;
		return;
	}

	kmb_write_lcd(kmb, LCD_LAYERn_ALPHA(plane_id), plane_alpha);
}

static void kmb_plane_atomic_update(struct drm_plane *plane,
				    struct drm_atomic_commit *state)
{
	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 *fb;
	struct kmb_drm_private *kmb;
	unsigned int width;
	unsigned int height;
	unsigned int dma_len;
	struct kmb_plane *kmb_plane;
	unsigned int dma_cfg;
	unsigned int ctrl = 0, val = 0, out_format = 0;
	unsigned int src_w, src_h, crtc_x, crtc_y;
	unsigned char plane_id;
	int num_planes;
	static dma_addr_t addr[MAX_SUB_PLANES];
	struct disp_cfg *init_disp_cfg;

	if (!plane || !new_plane_state || !old_plane_state)
		return;

	fb = new_plane_state->fb;
	if (!fb)
		return;

	num_planes = fb->format->num_planes;
	kmb_plane = to_kmb_plane(plane);

	kmb = to_kmb(plane->dev);
	plane_id = kmb_plane->id;

	spin_lock_irq(&kmb->irq_lock);
	if (kmb->kmb_under_flow || kmb->kmb_flush_done) {
		spin_unlock_irq(&kmb->irq_lock);
		drm_dbg(&kmb->drm, "plane_update:underflow!!!! returning");
		return;
	}
	spin_unlock_irq(&kmb->irq_lock);

	init_disp_cfg = &kmb->init_disp_cfg[plane_id];
	src_w = new_plane_state->src_w >> 16;
	src_h = new_plane_state->src_h >> 16;
	crtc_x = new_plane_state->crtc_x;
	crtc_y = new_plane_state->crtc_y;

	drm_dbg(&kmb->drm,
		"src_w=%d src_h=%d, fb->format->format=0x%x fb->flags=0x%x\n",
		  src_w, src_h, fb->format->format, fb->flags);

	width = fb->width;
	height = fb->height;
	dma_len = (width * height * fb->format->cpp[0]);
	drm_dbg(&kmb->drm, "dma_len=%d ", dma_len);
	kmb_write_lcd(kmb, LCD_LAYERn_DMA_LEN(plane_id), dma_len);
	kmb_write_lcd(kmb, LCD_LAYERn_DMA_LEN_SHADOW(plane_id), dma_len);
	kmb_write_lcd(kmb, LCD_LAYERn_DMA_LINE_VSTRIDE(plane_id),
		      fb->pitches[0]);
	kmb_write_lcd(kmb, LCD_LAYERn_DMA_LINE_WIDTH(plane_id),
		      (width * fb->format->cpp[0]));

	addr[Y_PLANE] = drm_fb_dma_get_gem_addr(fb, new_plane_state, 0);
	kmb_write_lcd(kmb, LCD_LAYERn_DMA_START_ADDR(plane_id),

Annotation

Implementation Notes