drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
Extension
.c
Size
9776 bytes
Lines
329
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

struct shmob_drm_plane {
	struct drm_plane base;
	unsigned int index;
};

struct shmob_drm_plane_state {
	struct drm_plane_state base;

	const struct shmob_drm_format_info *format;
	u32 dma[2];
};

static inline struct shmob_drm_plane *to_shmob_plane(struct drm_plane *plane)
{
	return container_of(plane, struct shmob_drm_plane, base);
}

static inline struct shmob_drm_plane_state *to_shmob_plane_state(struct drm_plane_state *state)
{
	return container_of(state, struct shmob_drm_plane_state, base);
}

static void shmob_drm_plane_compute_base(struct shmob_drm_plane_state *sstate)
{
	struct drm_framebuffer *fb = sstate->base.fb;
	unsigned int x = sstate->base.src_x >> 16;
	unsigned int y = sstate->base.src_y >> 16;
	struct drm_gem_dma_object *gem;
	unsigned int bpp;

	bpp = shmob_drm_format_is_yuv(sstate->format) ? 8 : sstate->format->bpp;
	gem = drm_fb_dma_get_gem_obj(fb, 0);
	sstate->dma[0] = gem->dma_addr + fb->offsets[0]
		       + y * fb->pitches[0] + x * bpp / 8;

	if (shmob_drm_format_is_yuv(sstate->format)) {
		bpp = sstate->format->bpp - 8;
		gem = drm_fb_dma_get_gem_obj(fb, 1);
		sstate->dma[1] = gem->dma_addr + fb->offsets[1]
			       + y / (bpp == 4 ? 2 : 1) * fb->pitches[1]
			       + x * (bpp == 16 ? 2 : 1);
	}
}

static void shmob_drm_primary_plane_setup(struct shmob_drm_plane *splane,
					  struct drm_plane_state *state)
{
	struct shmob_drm_plane_state *sstate = to_shmob_plane_state(state);
	struct shmob_drm_device *sdev = to_shmob_device(splane->base.dev);
	struct drm_framebuffer *fb = state->fb;

	/* TODO: Handle YUV colorspaces. Hardcode REC709 for now. */
	lcdc_write(sdev, LDDFR, sstate->format->lddfr | LDDFR_CF1);
	lcdc_write(sdev, LDMLSR, fb->pitches[0]);

	/* Word and long word swap. */
	lcdc_write(sdev, LDDDSR, sstate->format->ldddsr);

	lcdc_write_mirror(sdev, LDSA1R, sstate->dma[0]);
	if (shmob_drm_format_is_yuv(sstate->format))
		lcdc_write_mirror(sdev, LDSA2R, sstate->dma[1]);

	lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS);
}

static void shmob_drm_overlay_plane_setup(struct shmob_drm_plane *splane,
					  struct drm_plane_state *state)
{
	struct shmob_drm_plane_state *sstate = to_shmob_plane_state(state);
	struct shmob_drm_device *sdev = to_shmob_device(splane->base.dev);
	struct drm_framebuffer *fb = state->fb;
	u32 format;

	/* TODO: Support ROP3 mode */
	format = LDBBSIFR_EN | ((state->alpha >> 8) << LDBBSIFR_LAY_SHIFT) |
		 sstate->format->ldbbsifr;

#define plane_reg_dump(sdev, splane, reg) \
	dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \
		splane->index, #reg, \
		lcdc_read(sdev, reg(splane->index)), \
		lcdc_read(sdev, reg(splane->index) + LCDC_SIDE_B_OFFSET))

	plane_reg_dump(sdev, splane, LDBnBSIFR);
	plane_reg_dump(sdev, splane, LDBnBSSZR);
	plane_reg_dump(sdev, splane, LDBnBLOCR);
	plane_reg_dump(sdev, splane, LDBnBSMWR);
	plane_reg_dump(sdev, splane, LDBnBSAYR);
	plane_reg_dump(sdev, splane, LDBnBSACR);

Annotation

Implementation Notes