drivers/gpu/drm/i915/display/intel_fbdev.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/display/intel_fbdev.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_fbdev.c
Extension
.c
Size
15755 bytes
Lines
569
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 intel_fbdev {
	struct intel_framebuffer *fb;
	struct i915_vma *vma;
};

static struct intel_fbdev *to_intel_fbdev(struct drm_fb_helper *fb_helper)
{
	struct intel_display *display = to_intel_display(fb_helper->client.dev);

	return display->fbdev.fbdev;
}

static struct intel_frontbuffer *to_frontbuffer(struct intel_fbdev *ifbdev)
{
	return ifbdev->fb->frontbuffer;
}

static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev)
{
	intel_frontbuffer_invalidate(to_frontbuffer(ifbdev), ORIGIN_CPU);
}

FB_GEN_DEFAULT_DEFERRED_IOMEM_OPS(intel_fbdev,
				  drm_fb_helper_damage_range,
				  drm_fb_helper_damage_area)

static int intel_fbdev_set_par(struct fb_info *info)
{
	struct intel_fbdev *ifbdev = to_intel_fbdev(info->par);
	int ret;

	ret = drm_fb_helper_set_par(info);
	if (ret == 0)
		intel_fbdev_invalidate(ifbdev);

	return ret;
}

static int intel_fbdev_blank(int blank, struct fb_info *info)
{
	struct intel_fbdev *ifbdev = to_intel_fbdev(info->par);
	int ret;

	ret = drm_fb_helper_blank(blank, info);
	if (ret == 0)
		intel_fbdev_invalidate(ifbdev);

	return ret;
}

static int intel_fbdev_pan_display(struct fb_var_screeninfo *var,
				   struct fb_info *info)
{
	struct intel_fbdev *ifbdev = to_intel_fbdev(info->par);
	int ret;

	ret = drm_fb_helper_pan_display(var, info);
	if (ret == 0)
		intel_fbdev_invalidate(ifbdev);

	return ret;
}

static int intel_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
	struct drm_fb_helper *fb_helper = info->par;
	struct drm_gem_object *obj = drm_gem_fb_get_obj(fb_helper->fb, 0);

	return intel_bo_fb_mmap(obj, vma);
}

static void intel_fbdev_fb_destroy(struct fb_info *info)
{
	struct drm_fb_helper *fb_helper = info->par;
	struct intel_display *display = to_intel_display(fb_helper->client.dev);
	struct intel_fbdev *ifbdev = to_intel_fbdev(fb_helper);

	drm_fb_helper_fini(fb_helper);

	/*
	 * We rely on the object-free to release the VMA pinning for
	 * the info->screen_base mmaping. Leaking the VMA is simpler than
	 * trying to rectify all the possible error paths leading here.
	 */
	intel_parent_fb_pin_ggtt_unpin(display, ifbdev->vma, -1);
	drm_framebuffer_remove(fb_helper->fb);

	drm_client_release(&fb_helper->client);
}

Annotation

Implementation Notes