drivers/gpu/drm/exynos/exynos5433_drm_decon.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/exynos/exynos5433_drm_decon.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/exynos/exynos5433_drm_decon.c
Extension
.c
Size
22814 bytes
Lines
882
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 decon_context {
	struct device			*dev;
	struct drm_device		*drm_dev;
	void				*dma_priv;
	struct exynos_drm_crtc		*crtc;
	struct exynos_drm_plane		planes[WINDOWS_NR];
	struct exynos_drm_plane_config	configs[WINDOWS_NR];
	void __iomem			*addr;
	struct regmap			*sysreg;
	struct clk			*clks[ARRAY_SIZE(decon_clks_name)];
	unsigned int			irq;
	unsigned int			irq_vsync;
	unsigned int			irq_lcd_sys;
	unsigned int			te_irq;
	unsigned long			out_type;
	int				first_win;
	spinlock_t			vblank_lock;
	u32				frame_id;
};

static const uint32_t decon_formats[] = {
	DRM_FORMAT_XRGB1555,
	DRM_FORMAT_RGB565,
	DRM_FORMAT_XRGB8888,
	DRM_FORMAT_ARGB8888,
};

static const enum drm_plane_type decon_win_types[WINDOWS_NR] = {
	[PRIMARY_WIN] = DRM_PLANE_TYPE_PRIMARY,
	[CURSON_WIN] = DRM_PLANE_TYPE_CURSOR,
};

static const unsigned int capabilities[WINDOWS_NR] = {
	0,
	EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
	EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
	EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
	EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
};

static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask,
				  u32 val)
{
	val = (val & mask) | (readl(ctx->addr + reg) & ~mask);
	writel(val, ctx->addr + reg);
}

static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
{
	struct decon_context *ctx = crtc->ctx;
	u32 val;

	val = VIDINTCON0_INTEN;
	if (crtc->i80_mode)
		val |= VIDINTCON0_FRAMEDONE;
	else
		val |= VIDINTCON0_INTFRMEN | VIDINTCON0_FRAMESEL_FP;

	writel(val, ctx->addr + DECON_VIDINTCON0);

	enable_irq(ctx->irq);
	if (!(ctx->out_type & I80_HW_TRG))
		enable_irq(ctx->te_irq);

	return 0;
}

static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
{
	struct decon_context *ctx = crtc->ctx;

	if (!(ctx->out_type & I80_HW_TRG))
		disable_irq_nosync(ctx->te_irq);
	disable_irq_nosync(ctx->irq);

	writel(0, ctx->addr + DECON_VIDINTCON0);
}

/* return number of starts/ends of frame transmissions since reset */
static u32 decon_get_frame_count(struct decon_context *ctx, bool end)
{
	u32 frm, pfrm, status, cnt = 2;

	/* To get consistent result repeat read until frame id is stable.
	 * Usually the loop will be executed once, in rare cases when the loop
	 * is executed at frame change time 2nd pass will be needed.
	 */
	frm = readl(ctx->addr + DECON_CRFMID);
	do {
		status = readl(ctx->addr + DECON_VIDCON1);

Annotation

Implementation Notes