aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap4_ion.c
blob: 423f571f7339530b318f5e910dba27b600d26e8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * ION Initialization for OMAP4.
 *
 * Copyright (C) 2011 Texas Instruments
 *
 * Author: Dan Murphy <dmurphy@ti.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/ion.h>
#include <linux/memblock.h>
#include <linux/omap_ion.h>
#include <linux/platform_device.h>

#include <mach/omap4_ion.h>

static struct ion_platform_data omap4_ion_data = {
	.nr = 5,
	.heaps = {
		{
			.type = ION_HEAP_TYPE_CARVEOUT,
			.id = OMAP_ION_HEAP_SECURE_INPUT,
			.name = "secure_input",
			.base = PHYS_ADDR_SMC_MEM,
			.size = -1,
		},
		{	.type = OMAP_ION_HEAP_TYPE_TILER,
			.id = OMAP_ION_HEAP_TILER,
			.name = "tiler",
			.base = PHYS_ADDR_DUCATI_MEM,
			.size = -1,
		},
		{
			.type = OMAP_ION_HEAP_TYPE_TILER,
			.id = OMAP_ION_HEAP_NONSECURE_TILER,
			.name = "nonsecure_tiler",
			.base = 0,	/* append before prior */
			.size = -1,
		},
		{
			.type = ION_HEAP_TYPE_SYSTEM,
			.id = OMAP_ION_HEAP_SYSTEM,
			.name = "system",
		},
		{
			.type = OMAP_ION_HEAP_TYPE_TILER_RESERVATION,
			.id = OMAP_ION_HEAP_TILER_RESERVATION,
			.name = "tiler_reservation",
		},
	},
};

static struct omap_ion_platform_data omap4_ion_pdata = {
	.ion = &omap4_ion_data,
	.tiler2d_size = OMAP4_ION_HEAP_TILER_SIZE,
	.nonsecure_tiler2d_size = OMAP4_ION_HEAP_NONSECURE_TILER_SIZE,
};

static struct platform_device omap4_ion_device = {
	.name = "ion-omap4",
	.id = -1,
	.dev = {
		.platform_data = &omap4_ion_data,
	},
};

struct omap_ion_platform_data *get_omap_ion_platform_data(void)
{
	return &omap4_ion_pdata;
}

void __init omap4_register_ion(void)
{
	platform_device_register(&omap4_ion_device);
}

void __init omap_ion_init(void)
{
	int i;
	int ret;
	u32 nonsecure = omap4_ion_pdata.nonsecure_tiler2d_size;

	for (i = 0; i < omap4_ion_data.nr; i++) {
		struct ion_platform_heap *h = &omap4_ion_data.heaps[i];
		bool backward = 0 > (s32) h->size;

		if (backward)
			h->size = -h->size;
		if (h->base == 0)
			/* continue after/before previous heap */
			h->base = h[-1].base + (backward ? 0 : h[-1].size);

		switch (h->id) {
		case OMAP_ION_HEAP_SECURE_INPUT:
			h->size = OMAP4_ION_HEAP_SECURE_INPUT_SIZE;
			break;
		case OMAP_ION_HEAP_NONSECURE_TILER:
			h->size = nonsecure;
			break;
		case OMAP_ION_HEAP_TILER:
			/* total TILER carveouts must be aligned to 2M */
			h->size = ALIGN(omap4_ion_pdata.tiler2d_size +
					nonsecure, SZ_2M) - nonsecure;
			break;
		default:
			break;
		}

		if (backward)
			h->base -= h->size;
		pr_info("%s: id=%u [%lx-%lx] size=%x\n", __func__, h->id,
					h->base, h->base + h->size, h->size);
	}

	for (i = 0; i < omap4_ion_data.nr; i++)
		if (omap4_ion_data.heaps[i].type == ION_HEAP_TYPE_CARVEOUT ||
		    omap4_ion_data.heaps[i].type == OMAP_ION_HEAP_TYPE_TILER) {
			ret = memblock_remove(omap4_ion_data.heaps[i].base,
					      omap4_ion_data.heaps[i].size);
			if (ret)
				pr_err("memblock remove of %x@%lx failed\n",
				       omap4_ion_data.heaps[i].size,
				       omap4_ion_data.heaps[i].base);
		}
}