dma_util.c 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. #include "dma_util.h"
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <sys/ioctl.h>
  7. #include <linux/dma-heap.h>
  8. int dma_heap_alloc(const char *heap_name, size_t size, int *fd) {
  9. /* Try the requested heap first, then fall back to cma then to
  10. * system-uncached so existing callers (decoder "cma", detector
  11. * "reserved") keep working. Callers that must have a <4G buffer (output
  12. * fds and the composer mirror) pass "system-uncached-dma32", whose pages
  13. * are guaranteed below 4G. The plain system-uncached heap can hand out
  14. * pages above 4G, which the RGA driver refuses to import. */
  15. const char *tries[3];
  16. int n = 0;
  17. if (heap_name && heap_name[0]) tries[n++] = heap_name;
  18. if (n == 0 || strcmp(tries[0], "cma") != 0) tries[n++] = "cma";
  19. if (n == 0 || strcmp(tries[0], "system-uncached") != 0) tries[n++] = "system-uncached";
  20. for (int t = 0; t < n; t++) {
  21. char path[64];
  22. snprintf(path, sizeof(path), "/dev/dma_heap/%s", tries[t]);
  23. int heap_fd = open(path, O_RDWR | O_CLOEXEC);
  24. if (heap_fd < 0) continue;
  25. struct dma_heap_allocation_data data = {
  26. .len = size,
  27. .fd_flags = O_RDWR | O_CLOEXEC,
  28. };
  29. int ret = ioctl(heap_fd, DMA_HEAP_IOCTL_ALLOC, &data);
  30. close(heap_fd);
  31. if (ret < 0) continue;
  32. *fd = (int)data.fd;
  33. return 0;
  34. }
  35. return -1;
  36. }