11184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz/*
21184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz * drivers/gpu/ion/ion_dummy_driver.c
31184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz *
41184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz * Copyright (C) 2013 Linaro, Inc
51184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz *
61184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz * This software is licensed under the terms of the GNU General Public
71184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz * License version 2, as published by the Free Software Foundation, and
81184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz * may be copied, distributed, and modified under those terms.
91184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz *
101184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz * This program is distributed in the hope that it will be useful,
111184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz * but WITHOUT ANY WARRANTY; without even the implied warranty of
121184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
131184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz * GNU General Public License for more details.
141184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz *
151184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz */
161184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz
171184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz#include <linux/err.h>
181184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz#include <linux/platform_device.h>
191184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz#include <linux/slab.h>
20102f1a2a496a76f16675ee4bf13e2a5e512c447ePaul Gortmaker#include <linux/init.h>
211184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz#include <linux/bootmem.h>
221184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz#include <linux/memblock.h>
231184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz#include <linux/sizes.h>
2410f6f9c38a422451989eb4e36a14788b1799b491Chen Gang#include <linux/io.h>
251184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz#include "ion.h"
261184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz#include "ion_priv.h"
271184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz
283a915dd250097ff3c6bb67a57f6b050f805ccdc2Wei Yongjunstatic struct ion_device *idev;
293a915dd250097ff3c6bb67a57f6b050f805ccdc2Wei Yongjunstatic struct ion_heap **heaps;
301184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz
313a915dd250097ff3c6bb67a57f6b050f805ccdc2Wei Yongjunstatic void *carveout_ptr;
323a915dd250097ff3c6bb67a57f6b050f805ccdc2Wei Yongjunstatic void *chunk_ptr;
334c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz
343a915dd250097ff3c6bb67a57f6b050f805ccdc2Wei Yongjunstatic struct ion_platform_heap dummy_heaps[] = {
351184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz		{
361184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz			.id	= ION_HEAP_TYPE_SYSTEM,
371184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz			.type	= ION_HEAP_TYPE_SYSTEM,
381184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz			.name	= "system",
391184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz		},
401184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz		{
411184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz			.id	= ION_HEAP_TYPE_SYSTEM_CONTIG,
421184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz			.type	= ION_HEAP_TYPE_SYSTEM_CONTIG,
431184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz			.name	= "system contig",
441184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz		},
454c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		{
464c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz			.id	= ION_HEAP_TYPE_CARVEOUT,
474c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz			.type	= ION_HEAP_TYPE_CARVEOUT,
484c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz			.name	= "carveout",
494c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz			.size	= SZ_4M,
504c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		},
514c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		{
524c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz			.id	= ION_HEAP_TYPE_CHUNK,
534c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz			.type	= ION_HEAP_TYPE_CHUNK,
544c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz			.name	= "chunk",
554c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz			.size	= SZ_4M,
564c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz			.align	= SZ_16K,
574c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz			.priv	= (void *)(SZ_16K),
584c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		},
591184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz};
601184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz
613a915dd250097ff3c6bb67a57f6b050f805ccdc2Wei Yongjunstatic struct ion_platform_data dummy_ion_pdata = {
6218691f53bcaab1226f22b733189ec9da190bb7a2Tomas Winkler	.nr = ARRAY_SIZE(dummy_heaps),
631184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	.heaps = dummy_heaps,
641184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz};
651184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz
661184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultzstatic int __init ion_dummy_init(void)
671184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz{
681184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	int i, err;
691184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz
701184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	idev = ion_device_create(NULL);
71d320c455cb726cc0618ad9852982debc8af535b3Phong Tran	heaps = kcalloc(dummy_ion_pdata.nr, sizeof(struct ion_heap *),
721184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz			GFP_KERNEL);
731184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	if (!heaps)
74630127f36784e59e995c206c37825a36a34d346cDan Carpenter		return -ENOMEM;
751184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz
764c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz
774c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	/* Allocate a dummy carveout heap */
784c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	carveout_ptr = alloc_pages_exact(
794c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz				dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size,
804c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz				GFP_KERNEL);
814c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	if (carveout_ptr)
824c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		dummy_heaps[ION_HEAP_TYPE_CARVEOUT].base =
834c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz						virt_to_phys(carveout_ptr);
844c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	else
854c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		pr_err("ion_dummy: Could not allocate carveout\n");
864c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz
874c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	/* Allocate a dummy chunk heap */
884c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	chunk_ptr = alloc_pages_exact(
894c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz				dummy_heaps[ION_HEAP_TYPE_CHUNK].size,
904c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz				GFP_KERNEL);
914c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	if (chunk_ptr)
924c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		dummy_heaps[ION_HEAP_TYPE_CHUNK].base = virt_to_phys(chunk_ptr);
934c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	else
944c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		pr_err("ion_dummy: Could not allocate chunk\n");
954c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz
961184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	for (i = 0; i < dummy_ion_pdata.nr; i++) {
971184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz		struct ion_platform_heap *heap_data = &dummy_ion_pdata.heaps[i];
981184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz
994c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		if (heap_data->type == ION_HEAP_TYPE_CARVEOUT &&
1004c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz							!heap_data->base)
1014c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz			continue;
1024c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz
1034c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		if (heap_data->type == ION_HEAP_TYPE_CHUNK && !heap_data->base)
1044c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz			continue;
1054c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz
1061184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz		heaps[i] = ion_heap_create(heap_data);
1071184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz		if (IS_ERR_OR_NULL(heaps[i])) {
1081184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz			err = PTR_ERR(heaps[i]);
1091184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz			goto err;
1101184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz		}
1111184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz		ion_device_add_heap(idev, heaps[i]);
1121184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	}
1131184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	return 0;
1141184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultzerr:
1151184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	for (i = 0; i < dummy_ion_pdata.nr; i++) {
1161184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz		if (heaps[i])
1171184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz			ion_heap_destroy(heaps[i]);
1181184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	}
1191184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	kfree(heaps);
1201184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz
1214c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	if (carveout_ptr) {
1224c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		free_pages_exact(carveout_ptr,
1234c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz				dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size);
1244c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		carveout_ptr = NULL;
1254c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	}
1264c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	if (chunk_ptr) {
1274c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		free_pages_exact(chunk_ptr,
1284c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz				dummy_heaps[ION_HEAP_TYPE_CHUNK].size);
1294c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		chunk_ptr = NULL;
1304c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	}
1311184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	return err;
1321184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz}
133102f1a2a496a76f16675ee4bf13e2a5e512c447ePaul Gortmakerdevice_initcall(ion_dummy_init);
1341184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz
1351184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultzstatic void __exit ion_dummy_exit(void)
1361184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz{
1371184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	int i;
1381184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz
1391184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	ion_device_destroy(idev);
1401184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz
1411184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	for (i = 0; i < dummy_ion_pdata.nr; i++)
1421184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz		ion_heap_destroy(heaps[i]);
1431184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz	kfree(heaps);
1441184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz
1454c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	if (carveout_ptr) {
1464c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		free_pages_exact(carveout_ptr,
1474c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz				dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size);
1484c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		carveout_ptr = NULL;
1494c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	}
1504c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	if (chunk_ptr) {
1514c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		free_pages_exact(chunk_ptr,
1524c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz				dummy_heaps[ION_HEAP_TYPE_CHUNK].size);
1534c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz		chunk_ptr = NULL;
1544c45b1a80ee9c85aee13445b85fd55541ec26d27John Stultz	}
1551184ead84d6c1019f5c1d31a73ef3bace90fb54aJohn Stultz}
156102f1a2a496a76f16675ee4bf13e2a5e512c447ePaul Gortmaker__exitcall(ion_dummy_exit);
157