drivers/gpu/drm/omapdrm/omap_fb.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/omapdrm/omap_fb.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/omapdrm/omap_fb.c
Extension
.c
Size
10972 bytes
Lines
458
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 plane {
	dma_addr_t dma_addr;
};

#define to_omap_framebuffer(x) container_of(x, struct omap_framebuffer, base)

struct omap_framebuffer {
	struct drm_framebuffer base;
	int pin_count;
	const struct drm_format_info *format;
	struct plane planes[2];
	/* lock for pinning (pin_count and planes.dma_addr) */
	struct mutex lock;
};

static int omap_framebuffer_dirty(struct drm_framebuffer *fb,
				  struct drm_file *file_priv,
				  unsigned flags, unsigned color,
				  struct drm_clip_rect *clips,
				  unsigned num_clips)
{
	struct drm_crtc *crtc;

	drm_modeset_lock_all(fb->dev);

	drm_for_each_crtc(crtc, fb->dev)
		omap_crtc_flush(crtc);

	drm_modeset_unlock_all(fb->dev);

	return 0;
}

static const struct drm_framebuffer_funcs omap_framebuffer_funcs = {
	.create_handle = drm_gem_fb_create_handle,
	.dirty = omap_framebuffer_dirty,
	.destroy = drm_gem_fb_destroy,
};

static u32 get_linear_addr(struct drm_framebuffer *fb,
		const struct drm_format_info *format, int n, int x, int y)
{
	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
	struct plane *plane = &omap_fb->planes[n];
	u32 offset;

	offset = fb->offsets[n]
	       + (x * format->cpp[n] / (n == 0 ? 1 : format->hsub))
	       + (y * fb->pitches[n] / (n == 0 ? 1 : format->vsub));

	return plane->dma_addr + offset;
}

bool omap_framebuffer_supports_rotation(struct drm_framebuffer *fb)
{
	return omap_gem_flags(fb->obj[0]) & OMAP_BO_TILED_MASK;
}

/* Note: DRM rotates counter-clockwise, TILER & DSS rotates clockwise */
static u32 drm_rotation_to_tiler(unsigned int drm_rot)
{
	u32 orient;

	switch (drm_rot & DRM_MODE_ROTATE_MASK) {
	default:
	case DRM_MODE_ROTATE_0:
		orient = 0;
		break;
	case DRM_MODE_ROTATE_90:
		orient = MASK_XY_FLIP | MASK_X_INVERT;
		break;
	case DRM_MODE_ROTATE_180:
		orient = MASK_X_INVERT | MASK_Y_INVERT;
		break;
	case DRM_MODE_ROTATE_270:
		orient = MASK_XY_FLIP | MASK_Y_INVERT;
		break;
	}

	if (drm_rot & DRM_MODE_REFLECT_X)
		orient ^= MASK_X_INVERT;

	if (drm_rot & DRM_MODE_REFLECT_Y)
		orient ^= MASK_Y_INVERT;

	return orient;
}

/* update ovl info for scanout, handles cases of multi-planar fb's, etc.
 */

Annotation

Implementation Notes