Skip to content
Snippets Groups Projects
Select Git revision
1 result Searching

gem.c

Blame
  • gem.c 16.57 KiB
    // SPDX-License-Identifier: GPL-2.0-only
    /*
     * NVIDIA Tegra DRM GEM helper functions
     *
     * Copyright (C) 2012 Sascha Hauer, Pengutronix
     * Copyright (C) 2013-2015 NVIDIA CORPORATION, All rights reserved.
     *
     * Based on the GEM/CMA helpers
     *
     * Copyright (c) 2011 Samsung Electronics Co., Ltd.
     */
    
    #include <linux/dma-buf.h>
    #include <linux/iommu.h>
    #include <linux/module.h>
    
    #include <drm/drm_drv.h>
    #include <drm/drm_prime.h>
    #include <drm/tegra_drm.h>
    
    #include "drm.h"
    #include "gem.h"
    
    MODULE_IMPORT_NS(DMA_BUF);
    
    static unsigned int sg_dma_count_chunks(struct scatterlist *sgl, unsigned int nents)
    {
    	dma_addr_t next = ~(dma_addr_t)0;
    	unsigned int count = 0, i;
    	struct scatterlist *s;
    
    	for_each_sg(sgl, s, nents, i) {
    		/* sg_dma_address(s) is only valid for entries that have sg_dma_len(s) != 0. */
    		if (!sg_dma_len(s))
    			continue;
    
    		if (sg_dma_address(s) != next) {
    			next = sg_dma_address(s) + sg_dma_len(s);
    			count++;
    		}
    	}
    
    	return count;
    }
    
    static inline unsigned int sgt_dma_count_chunks(struct sg_table *sgt)
    {
    	return sg_dma_count_chunks(sgt->sgl, sgt->nents);
    }
    
    static void tegra_bo_put(struct host1x_bo *bo)
    {
    	struct tegra_bo *obj = host1x_to_tegra_bo(bo);
    
    	drm_gem_object_put(&obj->gem);
    }
    
    static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
    					      enum dma_data_direction direction)
    {
    	struct tegra_bo *obj = host1x_to_tegra_bo(bo);
    	struct drm_gem_object *gem = &obj->gem;
    	struct host1x_bo_mapping *map;
    	int err;
    
    	map = kzalloc(sizeof(*map), GFP_KERNEL);
    	if (!map)
    		return ERR_PTR(-ENOMEM);
    
    	kref_init(&map->ref);