drivers/gpu/drm/loongson/lsdc_gem.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/loongson/lsdc_gem.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/loongson/lsdc_gem.c
Extension
.c
Size
6207 bytes
Lines
276
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) 2023 Loongson Technology Corporation Limited
 */

#include <linux/dma-buf.h>

#include <drm/drm_debugfs.h>
#include <drm/drm_dumb_buffers.h>
#include <drm/drm_file.h>
#include <drm/drm_gem.h>
#include <drm/drm_prime.h>
#include <drm/drm_print.h>

#include "lsdc_drv.h"
#include "lsdc_gem.h"
#include "lsdc_ttm.h"

static int lsdc_gem_prime_pin(struct drm_gem_object *obj)
{
	struct lsdc_bo *lbo = gem_to_lsdc_bo(obj);
	int ret;

	dma_resv_assert_held(obj->resv);

	ret = lsdc_bo_pin(lbo, LSDC_GEM_DOMAIN_GTT, NULL);
	if (likely(ret == 0))
		lbo->sharing_count++;

	return ret;
}

static void lsdc_gem_prime_unpin(struct drm_gem_object *obj)
{
	struct lsdc_bo *lbo = gem_to_lsdc_bo(obj);

	dma_resv_assert_held(obj->resv);

	lsdc_bo_unpin(lbo);
	if (lbo->sharing_count)
		lbo->sharing_count--;
}

static struct sg_table *lsdc_gem_prime_get_sg_table(struct drm_gem_object *obj)
{
	struct ttm_buffer_object *tbo = to_ttm_bo(obj);
	struct ttm_tt *tt = tbo->ttm;

	if (!tt) {
		drm_err(obj->dev, "sharing a buffer without backing memory\n");
		return ERR_PTR(-ENOMEM);
	}

	return drm_prime_pages_to_sg(obj->dev, tt->pages, tt->num_pages);
}

static void lsdc_gem_object_free(struct drm_gem_object *obj)
{
	struct ttm_buffer_object *tbo = to_ttm_bo(obj);

	if (tbo)
		ttm_bo_fini(tbo);
}

static int lsdc_gem_object_vmap(struct drm_gem_object *obj, struct iosys_map *map)
{
	struct ttm_buffer_object *tbo = to_ttm_bo(obj);
	struct lsdc_bo *lbo = to_lsdc_bo(tbo);
	int ret;

	if (lbo->vmap_count > 0) {
		++lbo->vmap_count;
		goto out;
	}

	ret = lsdc_bo_pin(lbo, 0, NULL);
	if (unlikely(ret)) {
		drm_err(obj->dev, "pin %p for vmap failed\n", lbo);
		return ret;
	}

	ret = ttm_bo_vmap(tbo, &lbo->map);
	if (ret) {
		drm_err(obj->dev, "ttm bo vmap failed\n");
		lsdc_bo_unpin(lbo);
		return ret;
	}

	lbo->vmap_count = 1;

Annotation

Implementation Notes