drivers/gpu/drm/v3d/v3d_bo.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/v3d/v3d_bo.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/v3d/v3d_bo.c
Extension
.c
Size
7302 bytes
Lines
307
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

// SPDX-License-Identifier: GPL-2.0+
/* Copyright (C) 2015-2018 Broadcom */

/**
 * DOC: V3D GEM BO management support
 *
 * Compared to VC4 (V3D 2.x), V3D 3.3 introduces an MMU between the
 * GPU and the bus, allowing us to use shmem objects for our storage
 * instead of CMA.
 *
 * Physically contiguous objects may still be imported to V3D, but the
 * driver doesn't allocate physically contiguous objects on its own.
 * Display engines requiring physically contiguous allocations should
 * look into Mesa's "renderonly" support (as used by the Mesa pl111
 * driver) for an example of how to integrate with V3D.
 */

#include <linux/dma-buf.h>
#include <linux/vmalloc.h>

#include <drm/drm_print.h>

#include "v3d_drv.h"
#include "uapi/drm/v3d_drm.h"

static enum drm_gem_object_status v3d_gem_status(struct drm_gem_object *obj)
{
	struct v3d_bo *bo = to_v3d_bo(obj);
	enum drm_gem_object_status res = 0;

	if (bo->base.pages)
		res |= DRM_GEM_OBJECT_RESIDENT;

	return res;
}

/* Called DRM core on the last userspace/kernel unreference of the
 * BO.
 */
void v3d_free_object(struct drm_gem_object *obj)
{
	struct v3d_dev *v3d = to_v3d_dev(obj->dev);
	struct v3d_bo *bo = to_v3d_bo(obj);

	if (bo->vaddr)
		v3d_put_bo_vaddr(bo);

	v3d_mmu_remove_ptes(bo);

	mutex_lock(&v3d->bo_lock);
	v3d->bo_stats.num_allocated--;
	v3d->bo_stats.pages_allocated -= obj->size >> V3D_MMU_PAGE_SHIFT;
	mutex_unlock(&v3d->bo_lock);

	spin_lock(&v3d->mm_lock);
	drm_mm_remove_node(&bo->node);
	spin_unlock(&v3d->mm_lock);

	/* GPU execution may have dirtied any pages in the BO. */
	bo->base.pages_mark_dirty_on_put = true;

	drm_gem_shmem_free(&bo->base);
}

static const struct drm_gem_object_funcs v3d_gem_funcs = {
	.free = v3d_free_object,
	.print_info = drm_gem_shmem_object_print_info,
	.pin = drm_gem_shmem_object_pin,
	.unpin = drm_gem_shmem_object_unpin,
	.get_sg_table = drm_gem_shmem_object_get_sg_table,
	.vmap = drm_gem_shmem_object_vmap,
	.vunmap = drm_gem_shmem_object_vunmap,
	.mmap = drm_gem_shmem_object_mmap,
	.status = v3d_gem_status,
	.vm_ops = &drm_gem_shmem_vm_ops,
};

/* gem_create_object function for allocating a BO struct and doing
 * early setup.
 */
struct drm_gem_object *v3d_create_object(struct drm_device *dev, size_t size)
{
	struct v3d_bo *bo;
	struct drm_gem_object *obj;

	if (size == 0)
		return ERR_PTR(-EINVAL);

	bo = kzalloc_obj(*bo);
	if (!bo)

Annotation

Implementation Notes