summaryrefslogtreecommitdiff
path: root/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
diff options
context:
space:
mode:
authorNaushir Patuck <naush@raspberrypi.com>2020-07-15 10:39:11 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-07-17 16:36:28 +0300
commit3e7aa49344ad5233f644703559898572b57f9613 (patch)
tree579857871a6bff875f06579b5faf3910c24c90ce /src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
parent3c02a808e8934a0c2d875d5585403ce0a09d7c93 (diff)
libcamera: pipeline: ipa: raspberrypi: Use dma heap allocs for LS tables
Remove use of vcsm allocations and replace with dma heap allocations. The pipeline handler now passes the fd of the allocation over to the IPA instead of the raw pointer. Also use libcamera::FileDescriptor for fd lifetime management. This commit must be built alongside the accompanying BCM2835 ISP kernel driver changes at https://github.com/raspberrypi/linux/pull/3715. Otherwise a mismatch will cause undefined behavior. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/libcamera/pipeline/raspberrypi/dma_heaps.cpp')
-rw-r--r--src/libcamera/pipeline/raspberrypi/dma_heaps.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp b/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
new file mode 100644
index 00000000..6769c046
--- /dev/null
+++ b/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2020, Raspberry Pi (Trading) Limited
+ *
+ * dma_heaps.h - Helper class for dma-heap allocations.
+ */
+
+#include "dma_heaps.h"
+
+#include <fcntl.h>
+#include <linux/dma-buf.h>
+#include <linux/dma-heap.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include "libcamera/internal/log.h"
+
+/*
+ * /dev/dma-heap/linux,cma is the dma-heap allocator, which allows dmaheap-cma
+ * to only have to worry about importing.
+ *
+ * Annoyingly, should the cma heap size be specified on the kernel command line
+ * instead of DT, the heap gets named "reserved" instead.
+ */
+#define DMA_HEAP_CMA_NAME "/dev/dma_heap/linux,cma"
+#define DMA_HEAP_CMA_ALT_NAME "/dev/dma_heap/reserved"
+
+namespace libcamera {
+
+LOG_DECLARE_CATEGORY(RPI)
+
+namespace RPi {
+
+DmaHeap::DmaHeap()
+{
+ dmaHeapHandle_ = ::open(DMA_HEAP_CMA_NAME, O_RDWR, 0);
+ if (dmaHeapHandle_ == -1) {
+ dmaHeapHandle_ = ::open(DMA_HEAP_CMA_ALT_NAME, O_RDWR, 0);
+ if (dmaHeapHandle_ == -1) {
+ LOG(RPI, Error) << "Could not open dmaHeap device";
+ }
+ }
+}
+
+DmaHeap::~DmaHeap()
+{
+ if (dmaHeapHandle_)
+ ::close(dmaHeapHandle_);
+}
+
+FileDescriptor DmaHeap::alloc(const char *name, std::size_t size)
+{
+ int ret;
+
+ if (!name)
+ return FileDescriptor();
+
+ struct dma_heap_allocation_data alloc = {};
+
+ alloc.len = size;
+ alloc.fd_flags = O_CLOEXEC | O_RDWR;
+
+ ret = ::ioctl(dmaHeapHandle_, DMA_HEAP_IOCTL_ALLOC, &alloc);
+
+ if (ret < 0) {
+ LOG(RPI, Error) << "dmaHeap allocation failure for "
+ << name;
+ return FileDescriptor();
+ }
+
+ ret = ::ioctl(alloc.fd, DMA_BUF_SET_NAME, name);
+ if (ret < 0) {
+ LOG(RPI, Error) << "dmaHeap naming failure for "
+ << name;
+ ::close(alloc.fd);
+ return FileDescriptor();
+ }
+
+ return FileDescriptor(std::move(alloc.fd));
+}
+
+} /* namespace RPi */
+
+} /* namespace libcamera */