of_reserved_mem.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Device tree based initialization code for reserved memory.
  3. *
  4. * Copyright (c) 2013 Samsung Electronics Co., Ltd.
  5. * http://www.samsung.com
  6. * Author: Marek Szyprowski <m.szyprowski@samsung.com>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of the
  11. * License or (at your optional) any later version of the license.
  12. */
  13. #include <linux/memblock.h>
  14. #include <linux/err.h>
  15. #include <linux/of.h>
  16. #include <linux/of_fdt.h>
  17. #include <linux/of_platform.h>
  18. #include <linux/mm.h>
  19. #include <linux/sizes.h>
  20. #include <linux/mm_types.h>
  21. #include <linux/dma-contiguous.h>
  22. #include <linux/dma-mapping.h>
  23. #include <linux/of_reserved_mem.h>
  24. #define MAX_RESERVED_REGIONS 16
  25. struct reserved_mem {
  26. phys_addr_t base;
  27. unsigned long size;
  28. struct cma *cma;
  29. char name[32];
  30. };
  31. static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
  32. static int reserved_mem_count;
  33. static int __init fdt_scan_reserved_mem(unsigned long node, const char *uname,
  34. int depth, void *data)
  35. {
  36. struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
  37. phys_addr_t base, size;
  38. int is_cma, is_reserved;
  39. unsigned long len;
  40. const char *status;
  41. __be32 *prop;
  42. is_cma = IS_ENABLED(CONFIG_DMA_CMA) &&
  43. of_flat_dt_is_compatible(node, "linux,contiguous-memory-region");
  44. is_reserved = of_flat_dt_is_compatible(node, "reserved-memory-region");
  45. if (!is_reserved && !is_cma) {
  46. /* ignore node and scan next one */
  47. return 0;
  48. }
  49. status = of_get_flat_dt_prop(node, "status", &len);
  50. if (status && strcmp(status, "okay") != 0) {
  51. /* ignore disabled node nad scan next one */
  52. return 0;
  53. }
  54. prop = of_get_flat_dt_prop(node, "reg", &len);
  55. if (!prop || (len < (dt_root_size_cells + dt_root_addr_cells) *
  56. sizeof(__be32))) {
  57. pr_err("Reserved mem: node %s, incorrect \"reg\" property\n",
  58. uname);
  59. /* ignore node and scan next one */
  60. return 0;
  61. }
  62. base = dt_mem_next_cell(dt_root_addr_cells, &prop);
  63. size = dt_mem_next_cell(dt_root_size_cells, &prop);
  64. if (!size) {
  65. /* ignore node and scan next one */
  66. return 0;
  67. }
  68. pr_info("Reserved mem: found %s, memory base %lx, size %ld MiB\n",
  69. uname, (unsigned long)base, (unsigned long)size / SZ_1M);
  70. if (reserved_mem_count == ARRAY_SIZE(reserved_mem))
  71. return -ENOSPC;
  72. rmem->base = base;
  73. rmem->size = size;
  74. strlcpy(rmem->name, uname, sizeof(rmem->name));
  75. if (is_cma) {
  76. struct cma *cma;
  77. if (dma_contiguous_reserve_area(size, base, 0, &cma) == 0) {
  78. rmem->cma = cma;
  79. reserved_mem_count++;
  80. if (of_get_flat_dt_prop(node,
  81. "linux,default-contiguous-region",
  82. NULL))
  83. dma_contiguous_set_default(cma);
  84. }
  85. } else if (is_reserved) {
  86. if (memblock_remove(base, size) == 0)
  87. reserved_mem_count++;
  88. else
  89. pr_err("Failed to reserve memory for %s\n", uname);
  90. }
  91. return 0;
  92. }
  93. static struct reserved_mem *get_dma_memory_region(struct device *dev)
  94. {
  95. struct device_node *node;
  96. const char *name;
  97. int i;
  98. node = of_parse_phandle(dev->of_node, "memory-region", 0);
  99. if (!node)
  100. return NULL;
  101. name = kbasename(node->full_name);
  102. for (i = 0; i < reserved_mem_count; i++)
  103. if (strcmp(name, reserved_mem[i].name) == 0)
  104. return &reserved_mem[i];
  105. return NULL;
  106. }
  107. /**
  108. * of_reserved_mem_device_init() - assign reserved memory region to given device
  109. *
  110. * This function assign memory region pointed by "memory-region" device tree
  111. * property to the given device.
  112. */
  113. void of_reserved_mem_device_init(struct device *dev)
  114. {
  115. struct reserved_mem *region = get_dma_memory_region(dev);
  116. if (!region)
  117. return;
  118. if (region->cma) {
  119. dev_set_cma_area(dev, region->cma);
  120. pr_info("Assigned CMA %s to %s device\n", region->name,
  121. dev_name(dev));
  122. } else {
  123. if (dma_declare_coherent_memory(dev, region->base, region->base,
  124. region->size, DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) != 0)
  125. pr_info("Declared reserved memory %s to %s device\n",
  126. region->name, dev_name(dev));
  127. }
  128. }
  129. /**
  130. * of_reserved_mem_device_release() - release reserved memory device structures
  131. *
  132. * This function releases structures allocated for memory region handling for
  133. * the given device.
  134. */
  135. void of_reserved_mem_device_release(struct device *dev)
  136. {
  137. struct reserved_mem *region = get_dma_memory_region(dev);
  138. if (!region && !region->cma)
  139. dma_release_declared_memory(dev);
  140. }
  141. /**
  142. * early_init_dt_scan_reserved_mem() - create reserved memory regions
  143. *
  144. * This function grabs memory from early allocator for device exclusive use
  145. * defined in device tree structures. It should be called by arch specific code
  146. * once the early allocator (memblock) has been activated and all other
  147. * subsystems have already allocated/reserved memory.
  148. */
  149. void __init early_init_dt_scan_reserved_mem(void)
  150. {
  151. of_scan_flat_dt_by_path("/memory/reserved-memory",
  152. fdt_scan_reserved_mem, NULL);
  153. }