/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
- /* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
- #include <linux/kernel.h>
- #include <linux/bootmem.h>
- #include <linux/vcm.h>
- #include <linux/vcm_alloc.h>
- #define MSM_SMI_BASE 0x38000000
- #define MSM_SMI_SIZE 0x04000000
- #define SMI_16M 0
- #define SMI_1M 1
- #define SMI_64K 2
- #define SMI_4K 3
- #define EBI_16M 4
- #define EBI_1M 5
- #define EBI_64K 6
- #define EBI_4K 7
- static void free_ebi_pools(void);
- static struct physmem_region memory[] = {
- { /* SMI 16M */
- .addr = MSM_SMI_BASE,
- .size = SZ_16M,
- .chunk_size = SZ_16M
- },
- { /* SMI 1M */
- .addr = MSM_SMI_BASE + SZ_16M,
- .size = SZ_8M,
- .chunk_size = SZ_1M
- },
- { /* SMI 64K */
- .addr = MSM_SMI_BASE + SZ_16M + SZ_8M,
- .size = SZ_4M,
- .chunk_size = SZ_64K
- },
- { /* SMI 4K */
- .addr = MSM_SMI_BASE + SZ_16M + SZ_8M + SZ_4M,
- .size = SZ_4M,
- .chunk_size = SZ_4K
- },
- { /* EBI 16M */
- .addr = 0,
- .size = SZ_16M,
- .chunk_size = SZ_16M
- },
- { /* EBI 1M */
- .addr = 0,
- .size = SZ_8M,
- .chunk_size = SZ_1M
- },
- { /* EBI 64K */
- .addr = 0,
- .size = SZ_4M,
- .chunk_size = SZ_64K
- },
- { /* EBI 4K */
- .addr = 0,
- .size = SZ_4M,
- .chunk_size = SZ_4K
- }
- };
- /* The pool priority MUST be in descending order of size */
- static struct vcm_memtype_map mt_map[] __initdata = {
- {
- /* MEMTYPE_0 */
- .pool_id = {SMI_16M, SMI_1M, SMI_64K, SMI_4K},
- .num_pools = 4,
- },
- {
- /* MEMTYPE_1 */
- .pool_id = {SMI_16M, SMI_1M, SMI_64K, EBI_4K},
- .num_pools = 4,
- },
- { /* MEMTYPE_2 */
- .pool_id = {EBI_16M, EBI_1M, EBI_64K, EBI_4K},
- .num_pools = 4,
- },
- {
- /* MEMTYPE_3 */
- .pool_id = {SMI_16M, SMI_1M, EBI_1M, SMI_64K, EBI_64K, EBI_4K},
- .num_pools = 6,
- }
- };
- static int __init msm8x60_vcm_init(void)
- {
- int ret, i;
- void *ebi_chunk;
- for (i = 0; i < ARRAY_SIZE(memory); i++) {
- if (memory[i].addr == 0) {
- ebi_chunk = __alloc_bootmem(memory[i].size,
- memory[i].size, 0);
- if (!ebi_chunk) {
- pr_err("Could not allocate VCM-managed physical"
- " memory\n");
- ret = -ENOMEM;
- goto fail;
- }
- memory[i].addr = __pa(ebi_chunk);
- }
- }
- ret = vcm_sys_init(memory, ARRAY_SIZE(memory),
- mt_map, ARRAY_SIZE(mt_map),
- (void *)MSM_SMI_BASE + MSM_SMI_SIZE - SZ_8M, SZ_8M);
- if (ret != 0) {
- pr_err("vcm_sys_init() ret %i\n", ret);
- goto fail;
- }
- return 0;
- fail:
- free_ebi_pools();
- return ret;
- };
- static void free_ebi_pools(void)
- {
- int i;
- phys_addr_t r;
- for (i = 0; i < ARRAY_SIZE(memory); i++) {
- r = memory[i].addr;
- if (r > MSM_SMI_BASE + MSM_SMI_SIZE)
- free_bootmem((unsigned long)__va(r), memory[i].size);
- }
- }
- /* Useful for testing, and if VCM is ever unloaded */
- static void __exit msm8x60_vcm_exit(void)
- {
- int ret;
- ret = vcm_sys_destroy();
- if (ret != 0) {
- pr_err("vcm_sys_destroy() ret %i\n", ret);
- goto fail;
- }
- free_ebi_pools();
- fail:
- return;
- }
- subsys_initcall(msm8x60_vcm_init);
- module_exit(msm8x60_vcm_exit);
- MODULE_LICENSE("GPL v2");
- MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");