/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

  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. #include <linux/kernel.h>
  18. #include <linux/bootmem.h>
  19. #include <linux/vcm.h>
  20. #include <linux/vcm_alloc.h>
  21. #define MSM_SMI_BASE 0x38000000
  22. #define MSM_SMI_SIZE 0x04000000
  23. #define SMI_16M 0
  24. #define SMI_1M 1
  25. #define SMI_64K 2
  26. #define SMI_4K 3
  27. #define EBI_16M 4
  28. #define EBI_1M 5
  29. #define EBI_64K 6
  30. #define EBI_4K 7
  31. static void free_ebi_pools(void);
  32. static struct physmem_region memory[] = {
  33. { /* SMI 16M */
  34. .addr = MSM_SMI_BASE,
  35. .size = SZ_16M,
  36. .chunk_size = SZ_16M
  37. },
  38. { /* SMI 1M */
  39. .addr = MSM_SMI_BASE + SZ_16M,
  40. .size = SZ_8M,
  41. .chunk_size = SZ_1M
  42. },
  43. { /* SMI 64K */
  44. .addr = MSM_SMI_BASE + SZ_16M + SZ_8M,
  45. .size = SZ_4M,
  46. .chunk_size = SZ_64K
  47. },
  48. { /* SMI 4K */
  49. .addr = MSM_SMI_BASE + SZ_16M + SZ_8M + SZ_4M,
  50. .size = SZ_4M,
  51. .chunk_size = SZ_4K
  52. },
  53. { /* EBI 16M */
  54. .addr = 0,
  55. .size = SZ_16M,
  56. .chunk_size = SZ_16M
  57. },
  58. { /* EBI 1M */
  59. .addr = 0,
  60. .size = SZ_8M,
  61. .chunk_size = SZ_1M
  62. },
  63. { /* EBI 64K */
  64. .addr = 0,
  65. .size = SZ_4M,
  66. .chunk_size = SZ_64K
  67. },
  68. { /* EBI 4K */
  69. .addr = 0,
  70. .size = SZ_4M,
  71. .chunk_size = SZ_4K
  72. }
  73. };
  74. /* The pool priority MUST be in descending order of size */
  75. static struct vcm_memtype_map mt_map[] __initdata = {
  76. {
  77. /* MEMTYPE_0 */
  78. .pool_id = {SMI_16M, SMI_1M, SMI_64K, SMI_4K},
  79. .num_pools = 4,
  80. },
  81. {
  82. /* MEMTYPE_1 */
  83. .pool_id = {SMI_16M, SMI_1M, SMI_64K, EBI_4K},
  84. .num_pools = 4,
  85. },
  86. { /* MEMTYPE_2 */
  87. .pool_id = {EBI_16M, EBI_1M, EBI_64K, EBI_4K},
  88. .num_pools = 4,
  89. },
  90. {
  91. /* MEMTYPE_3 */
  92. .pool_id = {SMI_16M, SMI_1M, EBI_1M, SMI_64K, EBI_64K, EBI_4K},
  93. .num_pools = 6,
  94. }
  95. };
  96. static int __init msm8x60_vcm_init(void)
  97. {
  98. int ret, i;
  99. void *ebi_chunk;
  100. for (i = 0; i < ARRAY_SIZE(memory); i++) {
  101. if (memory[i].addr == 0) {
  102. ebi_chunk = __alloc_bootmem(memory[i].size,
  103. memory[i].size, 0);
  104. if (!ebi_chunk) {
  105. pr_err("Could not allocate VCM-managed physical"
  106. " memory\n");
  107. ret = -ENOMEM;
  108. goto fail;
  109. }
  110. memory[i].addr = __pa(ebi_chunk);
  111. }
  112. }
  113. ret = vcm_sys_init(memory, ARRAY_SIZE(memory),
  114. mt_map, ARRAY_SIZE(mt_map),
  115. (void *)MSM_SMI_BASE + MSM_SMI_SIZE - SZ_8M, SZ_8M);
  116. if (ret != 0) {
  117. pr_err("vcm_sys_init() ret %i\n", ret);
  118. goto fail;
  119. }
  120. return 0;
  121. fail:
  122. free_ebi_pools();
  123. return ret;
  124. };
  125. static void free_ebi_pools(void)
  126. {
  127. int i;
  128. phys_addr_t r;
  129. for (i = 0; i < ARRAY_SIZE(memory); i++) {
  130. r = memory[i].addr;
  131. if (r > MSM_SMI_BASE + MSM_SMI_SIZE)
  132. free_bootmem((unsigned long)__va(r), memory[i].size);
  133. }
  134. }
  135. /* Useful for testing, and if VCM is ever unloaded */
  136. static void __exit msm8x60_vcm_exit(void)
  137. {
  138. int ret;
  139. ret = vcm_sys_destroy();
  140. if (ret != 0) {
  141. pr_err("vcm_sys_destroy() ret %i\n", ret);
  142. goto fail;
  143. }
  144. free_ebi_pools();
  145. fail:
  146. return;
  147. }
  148. subsys_initcall(msm8x60_vcm_init);
  149. module_exit(msm8x60_vcm_exit);
  150. MODULE_LICENSE("GPL v2");
  151. MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");