mtk_meminfo.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include <asm/page.h>
  2. #include <asm/setup.h>
  3. #include <linux/module.h>
  4. #include <linux/of_fdt.h>
  5. #include <mt-plat/mtk_memcfg.h>
  6. #include <mt-plat/mtk_meminfo.h>
  7. #ifdef CONFIG_OF
  8. /* return the actual physical DRAM size */
  9. static u64 kernel_mem_sz;
  10. static u64 phone_dram_sz; /* original phone DRAM size */
  11. static int dt_scan_memory(unsigned long node, const char *uname,
  12. int depth, void *data)
  13. {
  14. const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
  15. int i;
  16. const __be32 *reg, *endp;
  17. int l;
  18. struct dram_info *dram_info;
  19. /* We are scanning "memory" nodes only */
  20. if (type == NULL) {
  21. /*
  22. * The longtrail doesn't have a device_type on the
  23. * /memory node, so look for the node called /memory@0.
  24. */
  25. if (depth != 1 || strcmp(uname, "memory@0") != 0)
  26. return 0;
  27. } else if (strcmp(type, "memory") != 0) {
  28. return 0;
  29. }
  30. /*
  31. * Use kernel_mem_sz if phone_dram_sz is not available (workaround)
  32. * Projects use device tree should have orig_dram_info entry in their
  33. * device tree.
  34. * After the porting is done, kernel_mem_sz will be removed.
  35. */
  36. reg = of_get_flat_dt_prop(node, "reg", &l);
  37. if (reg == NULL)
  38. return 0;
  39. endp = reg + (l / sizeof(__be32));
  40. while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
  41. u64 base, size;
  42. base = dt_mem_next_cell(dt_root_addr_cells, &reg);
  43. size = dt_mem_next_cell(dt_root_size_cells, &reg);
  44. if (size == 0)
  45. continue;
  46. kernel_mem_sz += size;
  47. }
  48. /* orig_dram_info */
  49. dram_info = (struct dram_info *)of_get_flat_dt_prop(node,
  50. "orig_dram_info", NULL);
  51. if (dram_info) {
  52. for (i = 0; i < dram_info->rank_num; i++)
  53. phone_dram_sz += dram_info->rank_info[i].size;
  54. }
  55. return node;
  56. }
  57. static int __init init_get_max_DRAM_size(void)
  58. {
  59. if (!phone_dram_sz && !kernel_mem_sz) {
  60. if (of_scan_flat_dt(dt_scan_memory, NULL)) {
  61. pr_alert("init_get_max_DRAM_size done. phone_dram_sz: 0x%llx, kernel_mem_sz: 0x%llx\n",
  62. (unsigned long long)phone_dram_sz,
  63. (unsigned long long)kernel_mem_sz);
  64. } else {
  65. pr_err("init_get_max_DRAM_size fail\n");
  66. BUG();
  67. }
  68. }
  69. return 0;
  70. }
  71. phys_addr_t get_max_DRAM_size(void)
  72. {
  73. if (!phone_dram_sz && !kernel_mem_sz)
  74. init_get_max_DRAM_size();
  75. return phone_dram_sz ?
  76. (phys_addr_t)phone_dram_sz : (phys_addr_t)kernel_mem_sz;
  77. }
  78. early_initcall(init_get_max_DRAM_size);
  79. #else
  80. phys_addr_t get_max_DRAM_size(void)
  81. {
  82. return mtk_get_max_DRAM_size();
  83. }
  84. #endif /* end of CONFIG_OF */
  85. EXPORT_SYMBOL(get_max_DRAM_size);
  86. /*
  87. * Return the DRAM size used by Linux kernel.
  88. * In current stage, use phone DRAM size directly
  89. */
  90. phys_addr_t get_memory_size(void)
  91. {
  92. return get_max_DRAM_size();
  93. }
  94. EXPORT_SYMBOL(get_memory_size);
  95. phys_addr_t get_phys_offset(void)
  96. {
  97. return PHYS_OFFSET;
  98. }
  99. EXPORT_SYMBOL(get_phys_offset);