img_mem_ocm.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*!
  2. *****************************************************************************
  3. *
  4. * @File img_mem_ocm.c
  5. * ---------------------------------------------------------------------------
  6. *
  7. * Copyright (c) Imagination Technologies Ltd.
  8. *
  9. * The contents of this file are subject to the MIT license as set out below.
  10. *
  11. * Permission is hereby granted, free of charge, to any person obtaining a
  12. * copy of this software and associated documentation files (the "Software"),
  13. * to deal in the Software without restriction, including without limitation
  14. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  15. * and/or sell copies of the Software, and to permit persons to whom the
  16. * Software is furnished to do so, subject to the following conditions:
  17. *
  18. * The above copyright notice and this permission notice shall be included in
  19. * all copies or substantial portions of the Software.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  22. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  23. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  24. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  25. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  26. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  27. * THE SOFTWARE.
  28. *
  29. * Alternatively, the contents of this file may be used under the terms of the
  30. * GNU General Public License Version 2 ("GPL")in which case the provisions of
  31. * GPL are applicable instead of those above.
  32. *
  33. * If you wish to allow use of your version of this file only under the terms
  34. * of GPL, and not to allow others to use your version of this file under the
  35. * terms of the MIT license, indicate your decision by deleting the provisions
  36. * above and replace them with the notice and other provisions required by GPL
  37. * as set out in the file called "GPLHEADER" included in this distribution. If
  38. * you do not delete the provisions above, a recipient may use your version of
  39. * this file under the terms of either the MIT license or GPL.
  40. *
  41. * This License is also included in this distribution in the file called
  42. * "MIT_COPYING".
  43. *
  44. *****************************************************************************/
  45. #include <linux/version.h>
  46. #include <linux/module.h>
  47. #include <linux/device.h>
  48. #include <linux/slab.h>
  49. #include <img_mem_man.h>
  50. #include "img_mem_man_priv.h"
  51. static int trace_physical_pages;
  52. struct buffer_data {
  53. uint64_t *addrs; /* array of physical addresses, upcast to 64-bit */
  54. enum img_mem_attr mattr; /* memory attributes */
  55. };
  56. static int ocm_heap_alloc(struct device *device, struct heap *heap,
  57. size_t size, enum img_mem_attr attr,
  58. struct buffer *buffer)
  59. {
  60. struct buffer_data *buffer_data;
  61. phys_addr_t phys_addr;
  62. size_t pages, page;
  63. pr_debug("%s:%d buffer %d (0x%p)\n", __func__, __LINE__,
  64. buffer->id, buffer);
  65. if (size > heap->options.ocm.size) {
  66. pr_err("%s requested size bigger than ocm size !\n",
  67. __func__);
  68. return -EINVAL;
  69. }
  70. buffer_data = kzalloc(sizeof(struct buffer_data), GFP_KERNEL);
  71. if (!buffer_data)
  72. return -ENOMEM;
  73. pages = size / PAGE_SIZE;
  74. buffer_data->addrs = kmalloc_array(pages, sizeof(uint64_t), GFP_KERNEL);
  75. if (!buffer_data->addrs) {
  76. kfree(buffer_data);
  77. return -ENOMEM;
  78. }
  79. buffer_data->mattr = attr;
  80. phys_addr = heap->options.ocm.phys;
  81. page = 0;
  82. while (page < pages) {
  83. if (trace_physical_pages)
  84. pr_info("%s phys %llx\n",
  85. __func__, (unsigned long long)phys_addr);
  86. buffer_data->addrs[page++] = phys_addr;
  87. phys_addr += PAGE_SIZE;
  88. };
  89. buffer->priv = buffer_data;
  90. pr_debug("%s buffer %d phys %#llx size %zu attrs %x\n", __func__,
  91. buffer->id,
  92. (unsigned long long)buffer_data->addrs[0],
  93. size,
  94. attr);
  95. return 0;
  96. }
  97. static void ocm_heap_free(struct heap *heap, struct buffer *buffer)
  98. {
  99. struct buffer_data *buffer_data = buffer->priv;
  100. pr_debug("%s:%d buffer %d (0x%p)\n", __func__, __LINE__,
  101. buffer->id, buffer);
  102. kfree(buffer_data->addrs);
  103. kfree(buffer_data);
  104. }
  105. static int ocm_heap_get_page_array(struct heap *heap,
  106. struct buffer *buffer,
  107. uint64_t **addrs)
  108. {
  109. struct buffer_data *buffer_data = buffer->priv;
  110. *addrs = buffer_data->addrs;
  111. return 0;
  112. }
  113. static void ocm_heap_destroy(struct heap *heap)
  114. {
  115. pr_debug("%s:%d\n", __func__, __LINE__);
  116. }
  117. static struct heap_ops ocm_heap_ops = {
  118. .alloc = ocm_heap_alloc,
  119. .import = NULL,
  120. .free = ocm_heap_free,
  121. .map_um = NULL,
  122. .unmap_um = NULL,
  123. .map_km = NULL,
  124. .unmap_km = NULL,
  125. .get_sg_table = NULL,
  126. .get_page_array = ocm_heap_get_page_array,
  127. .sync_cpu_to_dev = NULL,
  128. .sync_dev_to_cpu = NULL,
  129. .set_offset = NULL,
  130. .destroy = ocm_heap_destroy,
  131. };
  132. int img_mem_ocm_init(const struct heap_config *heap_cfg, struct heap *heap)
  133. {
  134. pr_debug("%s phys:%#llx size:%zu attrs:%#x\n", __func__,
  135. (unsigned long long)heap->options.ocm.phys,
  136. heap->options.ocm.size, heap->options.ocm.hattr);
  137. heap->ops = &ocm_heap_ops;
  138. heap->priv = NULL;
  139. return 0;
  140. }
  141. /*
  142. * coding style for emacs
  143. *
  144. * Local variables:
  145. * indent-tabs-mode: t
  146. * tab-width: 8
  147. * c-basic-offset: 8
  148. * End:
  149. */