Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7b34af76 authored by Laura Abbott's avatar Laura Abbott Committed by Stephen Boyd
Browse files

msm: kgsl: Switch to using the dmabuf APIs



The dmabuf APIs are now fully supported upstream. Since Ion
is now a dmabuf exporter, there is no need to call those APIs
directly. Switch to calling the dmabuf APIs to generate
scattergather lists for mapping to be more compatible.

Change-Id: Ie393e74bba080cba8a10e60908af7932729e6da6
Signed-off-by: default avatarLaura Abbott <lauraa@codeaurora.org>
parent a27fad38
Loading
Loading
Loading
Loading
+55 −24
Original line number Diff line number Diff line
@@ -18,13 +18,12 @@
#include <linux/uaccess.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>

#include <linux/dma-buf.h>
#include <linux/vmalloc.h>
#include <linux/pm_runtime.h>
#include <linux/rbtree.h>
#include <linux/ashmem.h>
#include <linux/major.h>
#include <linux/msm_ion.h>
#include <linux/io.h>
#include <mach/socinfo.h>
#include <linux/mman.h>
@@ -52,7 +51,11 @@ module_param_named(mmutype, ksgl_mmu_type, charp, 0);
MODULE_PARM_DESC(ksgl_mmu_type,
"Type of MMU to be used for graphics. Valid values are 'iommu' or 'gpummu' or 'nommu'");

static struct ion_client *kgsl_ion_client;
struct kgsl_dma_buf_meta {
	struct dma_buf_attachment *attach;
	struct dma_buf *dmabuf;
	struct sg_table *table;
};

/**
 * kgsl_trace_issueibcmds() - Call trace_issueibcmds by proxy
@@ -187,6 +190,14 @@ kgsl_mem_entry_create(void)
	return entry;
}

static void kgsl_destroy_ion(struct kgsl_dma_buf_meta *meta)
{
	dma_buf_unmap_attachment(meta->attach, meta->table, DMA_FROM_DEVICE);
	dma_buf_detach(meta->dmabuf, meta->attach);
	dma_buf_put(meta->dmabuf);
	kfree(meta);
}

void
kgsl_mem_entry_destroy(struct kref *kref)
{
@@ -216,7 +227,7 @@ kgsl_mem_entry_destroy(struct kref *kref)
			fput(entry->priv_data);
		break;
	case KGSL_MEM_ENTRY_ION:
		ion_free(kgsl_ion_client, entry->priv_data);
		kgsl_destroy_ion(entry->priv_data);
		break;
	}

@@ -1825,38 +1836,55 @@ static int kgsl_setup_ashmem(struct kgsl_mem_entry *entry,
#endif

static int kgsl_setup_ion(struct kgsl_mem_entry *entry,
		struct kgsl_pagetable *pagetable, void *data)
		struct kgsl_pagetable *pagetable, void *data,
		struct kgsl_device *device)
{
	struct ion_handle *handle;
	struct scatterlist *s;
	struct sg_table *sg_table;
	struct kgsl_map_user_mem *param = data;
	int fd = param->fd;
	struct dma_buf *dmabuf;
	struct dma_buf_attachment *attach;
	struct kgsl_dma_buf_meta *meta;
	int ret;

	if (!param->len)
		return -EINVAL;

	if (IS_ERR_OR_NULL(kgsl_ion_client))
		return -ENODEV;
	meta = kzalloc(sizeof(*meta), GFP_KERNEL);
	if (!meta)
		return -ENOMEM;

	handle = ion_import_dma_buf(kgsl_ion_client, fd);
	if (IS_ERR(handle))
		return PTR_ERR(handle);
	else if (!handle)
		return -EINVAL;
	dmabuf = dma_buf_get(fd);
	if (IS_ERR_OR_NULL(dmabuf)) {
		ret = PTR_ERR(dmabuf);
		goto err1;
	}

	attach = dma_buf_attach(dmabuf, device->dev);
	if (IS_ERR_OR_NULL(attach)) {
		ret = PTR_ERR(attach);
		goto err2;
	}

	meta->dmabuf = dmabuf;
	meta->attach = attach;

	entry->memtype = KGSL_MEM_ENTRY_ION;
	entry->priv_data = handle;
	entry->priv_data = meta;
	entry->memdesc.pagetable = pagetable;
	entry->memdesc.size = 0;
	/* USE_CPU_MAP is not impemented for ION. */
	entry->memdesc.flags &= ~KGSL_MEMFLAGS_USE_CPU_MAP;

	sg_table = ion_sg_table(kgsl_ion_client, handle);
	sg_table = dma_buf_map_attachment(attach, DMA_TO_DEVICE);

	if (IS_ERR_OR_NULL(sg_table))
		goto err;
	if (IS_ERR_OR_NULL(sg_table)) {
		ret = PTR_ERR(sg_table);
		goto err3;
	}

	meta->table = sg_table;
	entry->memdesc.sg = sg_table->sgl;

	/* Calculate the size of the memdesc from the sglist */
@@ -1871,9 +1899,13 @@ static int kgsl_setup_ion(struct kgsl_mem_entry *entry,
	entry->memdesc.size = PAGE_ALIGN(entry->memdesc.size);

	return 0;
err:
	ion_free(kgsl_ion_client, handle);
	return -ENOMEM;
err3:
	dma_buf_detach(dmabuf, attach);
err2:
	dma_buf_put(dmabuf);
err1:
	kfree(meta);
	return ret;
}

static long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv,
@@ -1961,7 +1993,8 @@ static long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv,
		entry->memtype = KGSL_MEM_ENTRY_ASHMEM;
		break;
	case KGSL_USER_MEM_TYPE_ION:
		result = kgsl_setup_ion(entry, private->pagetable, data);
		result = kgsl_setup_ion(entry, private->pagetable, data,
					dev_priv->device);
		break;
	default:
		KGSL_CORE_ERR("Invalid memory type: %x\n", memtype);
@@ -2008,7 +2041,7 @@ error_put_file_ptr:
			fput(entry->priv_data);
		break;
	case KGSL_MEM_ENTRY_ION:
		ion_free(kgsl_ion_client, entry->priv_data);
		kgsl_destroy_ion(entry->priv_data);
		break;
	default:
		break;
@@ -3022,8 +3055,6 @@ int kgsl_device_platform_probe(struct kgsl_device *device)
	if (status)
		goto error;

	kgsl_ion_client = msm_ion_client_create(UINT_MAX, KGSL_NAME);

	/* Get starting physical address of device registers */
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
					   device->iomemname);