fman_muram.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later
  2. /*
  3. * Copyright 2008 - 2015 Freescale Semiconductor Inc.
  4. */
  5. #include "fman_muram.h"
  6. #include <linux/io.h>
  7. #include <linux/slab.h>
  8. #include <linux/genalloc.h>
  9. struct muram_info {
  10. struct gen_pool *pool;
  11. void __iomem *vbase;
  12. phys_addr_t pbase;
  13. };
  14. static unsigned long fman_muram_vbase_to_offset(struct muram_info *muram,
  15. unsigned long vaddr)
  16. {
  17. return vaddr - (unsigned long)muram->vbase;
  18. }
  19. /**
  20. * fman_muram_init
  21. * @base: Pointer to base of memory mapped FM-MURAM.
  22. * @size: Size of the FM-MURAM partition.
  23. *
  24. * Creates partition in the MURAM.
  25. * The routine returns a pointer to the MURAM partition.
  26. * This pointer must be passed as to all other FM-MURAM function calls.
  27. * No actual initialization or configuration of FM_MURAM hardware is done by
  28. * this routine.
  29. *
  30. * Return: pointer to FM-MURAM object, or NULL for Failure.
  31. */
  32. struct muram_info *fman_muram_init(phys_addr_t base, size_t size)
  33. {
  34. struct muram_info *muram;
  35. void __iomem *vaddr;
  36. int ret;
  37. muram = kzalloc_obj(*muram);
  38. if (!muram)
  39. return NULL;
  40. muram->pool = gen_pool_create(ilog2(64), -1);
  41. if (!muram->pool) {
  42. pr_err("%s(): MURAM pool create failed\n", __func__);
  43. goto muram_free;
  44. }
  45. vaddr = ioremap(base, size);
  46. if (!vaddr) {
  47. pr_err("%s(): MURAM ioremap failed\n", __func__);
  48. goto pool_destroy;
  49. }
  50. ret = gen_pool_add_virt(muram->pool, (unsigned long)vaddr,
  51. base, size, -1);
  52. if (ret < 0) {
  53. pr_err("%s(): MURAM pool add failed\n", __func__);
  54. iounmap(vaddr);
  55. goto pool_destroy;
  56. }
  57. memset_io(vaddr, 0, (int)size);
  58. muram->vbase = vaddr;
  59. muram->pbase = base;
  60. return muram;
  61. pool_destroy:
  62. gen_pool_destroy(muram->pool);
  63. muram_free:
  64. kfree(muram);
  65. return NULL;
  66. }
  67. /**
  68. * fman_muram_offset_to_vbase
  69. * @muram: FM-MURAM module pointer.
  70. * @offset: the offset of the memory block
  71. *
  72. * Gives the address of the memory region from specific offset
  73. *
  74. * Return: The address of the memory block
  75. */
  76. unsigned long fman_muram_offset_to_vbase(struct muram_info *muram,
  77. unsigned long offset)
  78. {
  79. return offset + (unsigned long)muram->vbase;
  80. }
  81. /**
  82. * fman_muram_alloc
  83. * @muram: FM-MURAM module pointer.
  84. * @size: Size of the memory to be allocated.
  85. *
  86. * Allocate some memory from FM-MURAM partition.
  87. *
  88. * Return: address of the allocated memory; NULL otherwise.
  89. */
  90. unsigned long fman_muram_alloc(struct muram_info *muram, size_t size)
  91. {
  92. unsigned long vaddr;
  93. vaddr = gen_pool_alloc(muram->pool, size);
  94. if (!vaddr)
  95. return -ENOMEM;
  96. memset_io((void __iomem *)vaddr, 0, size);
  97. return fman_muram_vbase_to_offset(muram, vaddr);
  98. }
  99. /**
  100. * fman_muram_free_mem
  101. * @muram: FM-MURAM module pointer.
  102. * @offset: offset of the memory region to be freed.
  103. * @size: size of the memory to be freed.
  104. *
  105. * Free an allocated memory from FM-MURAM partition.
  106. */
  107. void fman_muram_free_mem(struct muram_info *muram, unsigned long offset,
  108. size_t size)
  109. {
  110. unsigned long addr = fman_muram_offset_to_vbase(muram, offset);
  111. gen_pool_free(muram->pool, addr, size);
  112. }