1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
From 5df9bc3b2a3d86bcc8504896cc87d7fcb5aea3a4 Mon Sep 17 00:00:00 2001
From: Andrey Konovalov <andrey.konovalov@linaro.org>
Date: Mon, 11 Mar 2024 15:15:07 +0100
Subject: [PATCH 03/21] libcamera: dma_heaps: extend DmaHeap class to support
system heap
Add an argument to the constructor to specify dma heaps type(s)
to use. Can be DmaHeapFlag::Cma and/or DmaHeapFlag::System.
By default DmaHeapFlag::Cma is used. If both DmaHeapFlag::Cma and
DmaHeapFlag::System are set, CMA heap is tried first.
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
include/libcamera/internal/dma_heaps.h | 12 ++++-
src/libcamera/dma_heaps.cpp | 67 ++++++++++++++++++++------
2 files changed, 63 insertions(+), 16 deletions(-)
diff --git a/include/libcamera/internal/dma_heaps.h b/include/libcamera/internal/dma_heaps.h
index cff8f140..80bf29e7 100644
--- a/include/libcamera/internal/dma_heaps.h
+++ b/include/libcamera/internal/dma_heaps.h
@@ -9,6 +9,7 @@
#include <stddef.h>
+#include <libcamera/base/flags.h>
#include <libcamera/base/unique_fd.h>
namespace libcamera {
@@ -16,7 +17,14 @@ namespace libcamera {
class DmaHeap
{
public:
- DmaHeap();
+ enum class DmaHeapFlag {
+ Cma = 1 << 0,
+ System = 1 << 1,
+ };
+
+ using DmaHeapFlags = Flags<DmaHeapFlag>;
+
+ DmaHeap(DmaHeapFlags flags = DmaHeapFlag::Cma);
~DmaHeap();
bool isValid() const { return dmaHeapHandle_.isValid(); }
UniqueFD alloc(const char *name, std::size_t size);
@@ -25,4 +33,6 @@ private:
UniqueFD dmaHeapHandle_;
};
+LIBCAMERA_FLAGS_ENABLE_OPERATORS(DmaHeap::DmaHeapFlag)
+
} /* namespace libcamera */
diff --git a/src/libcamera/dma_heaps.cpp b/src/libcamera/dma_heaps.cpp
index 38ef175a..d0e33ce6 100644
--- a/src/libcamera/dma_heaps.cpp
+++ b/src/libcamera/dma_heaps.cpp
@@ -19,9 +19,11 @@
/**
* \file dma_heaps.cpp
- * \brief CMA dma-heap allocator
+ * \brief dma-heap allocator
*/
+namespace libcamera {
+
/*
* /dev/dma_heap/linux,cma is the dma-heap allocator, which allows dmaheap-cma
* to only have to worry about importing.
@@ -29,42 +31,77 @@
* Annoyingly, should the cma heap size be specified on the kernel command line
* instead of DT, the heap gets named "reserved" instead.
*/
-static constexpr std::array<const char *, 2> heapNames = {
- "/dev/dma_heap/linux,cma",
- "/dev/dma_heap/reserved"
+
+/**
+ * \struct DmaHeapInfo
+ * \brief Tells what type of dma-heap the dma-heap represented by the device node name is
+ * \var DmaHeapInfo::flag
+ * \brief The type of the dma-heap
+ * \var DmaHeapInfo::name
+ * \brief The dma-heap's device node name
+ */
+struct DmaHeapInfo {
+ DmaHeap::DmaHeapFlag flag;
+ const char *name;
};
-namespace libcamera {
+static constexpr std::array<DmaHeapInfo, 3> heapInfos = {
+ { /* CMA heap names first */
+ { DmaHeap::DmaHeapFlag::Cma, "/dev/dma_heap/linux,cma" },
+ { DmaHeap::DmaHeapFlag::Cma, "/dev/dma_heap/reserved" },
+ { DmaHeap::DmaHeapFlag::System, "/dev/dma_heap/system" } }
+};
LOG_DEFINE_CATEGORY(DmaHeap)
/**
* \class DmaHeap
- * \brief Helper class for CMA dma-heap allocations
+ * \brief Helper class for dma-heap allocations
*/
/**
- * \brief Construct a DmaHeap that owns a CMA dma-heap file descriptor
+ * \enum DmaHeap::DmaHeapFlag
+ * \brief Type of the dma-heap
+ * \var DmaHeap::Cma
+ * \brief Allocate from a CMA dma-heap
+ * \var DmaHeap::System
+ * \brief Allocate from the system dma-heap
+ */
+
+/**
+ * \typedef DmaHeap::DmaHeapFlags
+ * \brief A bitwise combination of DmaHeap::DmaHeapFlag values
+ */
+
+/**
+ * \brief Construct a DmaHeap that owns a CMA or system dma-heap file descriptor
+ * \param [in] flags The type(s) of the dma-heap(s) to allocate from
*
- * Goes through the internal list of possible names of the CMA dma-heap devices
- * until a CMA dma-heap device is successfully opened. If it fails to open any
- * dma-heap device, an invalid DmaHeap object is constructed. A valid DmaHeap
- * object owns a wrapped dma-heap file descriptor.
+ * By default \a flags are set to DmaHeap::DmaHeapFlag::Cma. The constructor goes
+ * through the internal list of possible names of the CMA and system dma-heap devices
+ * until the dma-heap device of the requested type is successfully opened. If more
+ * than one dma-heap type is specified in flags the CMA heap is tried first. If it
+ * fails to open any dma-heap device an invalid DmaHeap object is constructed.
+ * A valid DmaHeap object owns a wrapped dma-heap file descriptor.
*
* Please check the new DmaHeap object with \ref DmaHeap::isValid before using it.
*/
-DmaHeap::DmaHeap()
+DmaHeap::DmaHeap(DmaHeapFlags flags)
{
- for (const char *name : heapNames) {
- int ret = ::open(name, O_RDWR | O_CLOEXEC, 0);
+ for (const auto &info : heapInfos) {
+ if (!(flags & info.flag))
+ continue;
+
+ int ret = ::open(info.name, O_RDWR | O_CLOEXEC, 0);
if (ret < 0) {
ret = errno;
LOG(DmaHeap, Debug)
- << "Failed to open " << name << ": "
+ << "Failed to open " << info.name << ": "
<< strerror(ret);
continue;
}
+ LOG(DmaHeap, Debug) << "Using " << info.name;
dmaHeapHandle_ = UniqueFD(ret);
break;
}
--
2.43.2
|