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