PageRenderTime 12ms CodeModel.GetById 0ms app.highlight 10ms RepoModel.GetById 0ms app.codeStats 0ms

/arch/arm/mach-msm/board-msm8x60-vcm.c

https://bitbucket.org/sammyz/iscream_thunderc-2.6.35-rebase
C | 173 lines | 130 code | 22 blank | 21 comment | 10 complexity | 27d691fd08c20e6071009177cbd44b9d MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
  2 *
  3 * This program is free software; you can redistribute it and/or modify
  4 * it under the terms of the GNU General Public License version 2 and
  5 * only version 2 as published by the Free Software Foundation.
  6 *
  7 * This program is distributed in the hope that it will be useful,
  8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 10 * GNU General Public License for more details.
 11 *
 12 * You should have received a copy of the GNU General Public License
 13 * along with this program; if not, write to the Free Software
 14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 15 * 02110-1301, USA.
 16 */
 17
 18#include <linux/kernel.h>
 19#include <linux/bootmem.h>
 20
 21#include <linux/vcm.h>
 22#include <linux/vcm_alloc.h>
 23
 24#define MSM_SMI_BASE           0x38000000
 25#define MSM_SMI_SIZE           0x04000000
 26
 27#define SMI_16M	0
 28#define SMI_1M	1
 29#define SMI_64K	2
 30#define SMI_4K	3
 31#define EBI_16M 4
 32#define EBI_1M  5
 33#define EBI_64K 6
 34#define EBI_4K	7
 35
 36static void free_ebi_pools(void);
 37
 38static struct physmem_region memory[] = {
 39	{	/* SMI 16M */
 40		.addr = MSM_SMI_BASE,
 41		.size = SZ_16M,
 42		.chunk_size = SZ_16M
 43	},
 44	{	/* SMI 1M */
 45		.addr = MSM_SMI_BASE + SZ_16M,
 46		.size = SZ_8M,
 47		.chunk_size = SZ_1M
 48	},
 49	{	/* SMI 64K */
 50		.addr = MSM_SMI_BASE + SZ_16M + SZ_8M,
 51		.size = SZ_4M,
 52		.chunk_size = SZ_64K
 53	},
 54	{	/* SMI 4K */
 55		.addr = MSM_SMI_BASE + SZ_16M + SZ_8M + SZ_4M,
 56		.size = SZ_4M,
 57		.chunk_size = SZ_4K
 58	},
 59
 60	{	/* EBI 16M */
 61		.addr = 0,
 62		.size = SZ_16M,
 63		.chunk_size = SZ_16M
 64	},
 65	{	/* EBI 1M */
 66		.addr = 0,
 67		.size = SZ_8M,
 68		.chunk_size = SZ_1M
 69	},
 70	{	/* EBI 64K */
 71		.addr = 0,
 72		.size = SZ_4M,
 73		.chunk_size = SZ_64K
 74	},
 75	{	/* EBI 4K */
 76		.addr = 0,
 77		.size = SZ_4M,
 78		.chunk_size = SZ_4K
 79	}
 80};
 81
 82
 83/* The pool priority MUST be in descending order of size */
 84static struct vcm_memtype_map mt_map[] __initdata = {
 85	{
 86		/* MEMTYPE_0 */
 87		.pool_id = {SMI_16M, SMI_1M, SMI_64K, SMI_4K},
 88		.num_pools = 4,
 89	},
 90	{
 91		/* MEMTYPE_1 */
 92		.pool_id = {SMI_16M, SMI_1M, SMI_64K, EBI_4K},
 93		.num_pools = 4,
 94	},
 95	{	/* MEMTYPE_2 */
 96		.pool_id = {EBI_16M, EBI_1M, EBI_64K, EBI_4K},
 97		.num_pools = 4,
 98	},
 99	{
100		/* MEMTYPE_3 */
101		.pool_id = {SMI_16M, SMI_1M, EBI_1M, SMI_64K, EBI_64K, EBI_4K},
102		.num_pools = 6,
103	}
104};
105
106static int __init msm8x60_vcm_init(void)
107{
108	int ret, i;
109	void *ebi_chunk;
110
111
112	for (i = 0; i < ARRAY_SIZE(memory); i++) {
113		if (memory[i].addr == 0) {
114			ebi_chunk = __alloc_bootmem(memory[i].size,
115							    memory[i].size, 0);
116			if (!ebi_chunk) {
117				pr_err("Could not allocate VCM-managed physical"
118				       " memory\n");
119				ret = -ENOMEM;
120				goto fail;
121			}
122			memory[i].addr = __pa(ebi_chunk);
123		}
124	}
125
126	ret = vcm_sys_init(memory, ARRAY_SIZE(memory),
127			   mt_map, ARRAY_SIZE(mt_map),
128			   (void *)MSM_SMI_BASE + MSM_SMI_SIZE - SZ_8M, SZ_8M);
129
130	if (ret != 0) {
131		pr_err("vcm_sys_init() ret %i\n", ret);
132		goto fail;
133	}
134
135	return 0;
136fail:
137	free_ebi_pools();
138	return ret;
139};
140
141static void free_ebi_pools(void)
142{
143	int i;
144	phys_addr_t r;
145	for (i = 0; i < ARRAY_SIZE(memory); i++) {
146		r = memory[i].addr;
147		if (r > MSM_SMI_BASE + MSM_SMI_SIZE)
148			free_bootmem((unsigned long)__va(r), memory[i].size);
149	}
150}
151
152
153/* Useful for testing, and if VCM is ever unloaded */
154static void __exit msm8x60_vcm_exit(void)
155{
156	int ret;
157
158	ret = vcm_sys_destroy();
159	if (ret != 0) {
160		pr_err("vcm_sys_destroy() ret %i\n", ret);
161		goto fail;
162	}
163	free_ebi_pools();
164fail:
165	return;
166}
167
168
169subsys_initcall(msm8x60_vcm_init);
170module_exit(msm8x60_vcm_exit);
171
172MODULE_LICENSE("GPL v2");
173MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");