Skip to content

Commit 0fc6766

Browse files
committed
[WIP]drivers: video: Implement buffer management with RTIO backend
- Application side nearly unchanged, except a call to video_release_buf() after finishing with the full buffer to queue it back to sqe. RTIO is opaque to application. - Driver just needs to hold an io_q and deal a bit with the buffer from sqe in isr. No need to implement rtio_iodev_api's submit() - The video subsystem does everything needed for buffer management. Signed-off-by: Phi Bang Nguyen <[email protected]> Co-developed-by: Josuah Demangeon <[email protected]>
1 parent 3052778 commit 0fc6766

File tree

7 files changed

+146
-170
lines changed

7 files changed

+146
-170
lines changed

drivers/video/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#
99
menuconfig VIDEO
1010
bool "Video drivers"
11+
imply RTIO
1112
help
1213
Enable support for the VIDEO.
1314

drivers/video/video_common.c

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
#include <zephyr/drivers/video-controls.h>
1414
#include <zephyr/kernel.h>
1515
#include <zephyr/logging/log.h>
16+
#include <zephyr/rtio/rtio.h>
1617
#include <zephyr/sys/byteorder.h>
1718
#include <zephyr/sys/util.h>
1819

1920
#include "video_common.h"
21+
#include "video_device.h"
2022

2123
LOG_MODULE_REGISTER(video_common, CONFIG_VIDEO_LOG_LEVEL);
2224

@@ -131,14 +133,15 @@ int video_request_buffers(uint8_t count, size_t size, enum video_buf_type type,
131133
return 0;
132134
}
133135

136+
RTIO_DEFINE(rtio, CONFIG_VIDEO_BUFFER_POOL_NUM_MAX, CONFIG_VIDEO_BUFFER_POOL_NUM_MAX);
137+
134138
int video_enqueue(const struct device *dev, struct video_buffer *buf)
135139
{
136140
int ret;
137-
const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
138141

139142
__ASSERT_NO_MSG(dev != NULL);
140143

141-
api = (const struct video_driver_api *)dev->api;
144+
const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
142145
if (api->enqueue == NULL) {
143146
return -ENOSYS;
144147
}
@@ -162,11 +165,65 @@ int video_enqueue(const struct device *dev, struct video_buffer *buf)
162165
return ret;
163166
}
164167

165-
video_buf[buf->index].state = VIDEO_BUF_STATE_QUEUED;
168+
/* RTIO submission */
169+
struct rtio_iodev *ri = video_find_iodev(dev);
170+
struct rtio_sqe *sqe = rtio_sqe_acquire(&rtio);
171+
172+
__ASSERT_NO_MSG(ri != NULL);
173+
__ASSERT_NO_MSG(sqe != NULL);
174+
175+
rtio_sqe_prep_read(sqe, ri, RTIO_PRIO_NORM, video_buf[index].buffer,
176+
video_buf[index].size, &video_buf[index]);
177+
178+
sqe->flags |= RTIO_SQE_MULTISHOT;
179+
180+
/* Do not wait for complete */
181+
rtio_submit(&rtio, 0);
182+
183+
video_buf[index].state = VIDEO_BUF_STATE_QUEUED;
184+
185+
return 0;
186+
}
187+
188+
int video_dequeue(struct video_buffer **buf)
189+
{
190+
struct rtio_cqe *cqe = rtio_cqe_consume_block(&rtio);
191+
*buf = cqe->userdata;
192+
193+
if (cqe->result < 0) {
194+
LOG_ERR("I/O operation failed");
195+
return cqe->result;
196+
}
166197

167198
return 0;
168199
}
169200

201+
void video_release_buf()
202+
{
203+
/* Buffer will be re-queued thanks to RTIO_SQE_MULTISHOT */
204+
rtio_cqe_release(&rtio, rtio_cqe_consume_block(&rtio));
205+
}
206+
207+
struct video_buffer *video_get_buf_sqe(struct mpsc *io_q)
208+
{
209+
struct mpsc_node *node = mpsc_pop(io_q);
210+
if (node == NULL) {
211+
return NULL;
212+
}
213+
214+
struct rtio_iodev_sqe *iodev_sqe = CONTAINER_OF(node, struct rtio_iodev_sqe, q);
215+
struct rtio_sqe *sqe = &iodev_sqe->sqe;
216+
217+
if (sqe->op != RTIO_OP_RX) {
218+
LOG_ERR("Invalid operation %d of length %u for submission %p", sqe->op,
219+
sqe->rx.buf_len, (void *)iodev_sqe);
220+
rtio_iodev_sqe_err(iodev_sqe, -EINVAL);
221+
return NULL;
222+
}
223+
224+
return sqe->userdata;
225+
}
226+
170227
int video_format_caps_index(const struct video_format_cap *fmts, const struct video_format *fmt,
171228
size_t *idx)
172229
{

drivers/video/video_device.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7+
#include <zephyr/rtio/rtio.h>
8+
79
#include "video_device.h"
810

911
struct video_device *video_find_vdev(const struct device *dev)
@@ -20,3 +22,32 @@ struct video_device *video_find_vdev(const struct device *dev)
2022

2123
return NULL;
2224
}
25+
26+
struct rtio_iodev *video_find_iodev(const struct device *dev)
27+
{
28+
struct video_interface *vi;
29+
30+
if (!dev) {
31+
return NULL;
32+
}
33+
34+
STRUCT_SECTION_FOREACH(rtio_iodev, ri) {
35+
vi = ri->data;
36+
if (vi->dev == dev) {
37+
return ri;
38+
}
39+
}
40+
41+
return NULL;
42+
}
43+
44+
static void video_iodev_submit(struct rtio_iodev_sqe *iodev_sqe)
45+
{
46+
struct video_interface *vi = iodev_sqe->sqe.iodev->data;
47+
48+
mpsc_push(vi->io_q, &iodev_sqe->q);
49+
}
50+
51+
const struct rtio_iodev_api _video_iodev_api = {
52+
.submit = video_iodev_submit,
53+
};

drivers/video/video_device.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define ZEPHYR_INCLUDE_DRIVERS_VIDEO_VIDEO_DEVICE_H_
99

1010
#include <zephyr/device.h>
11+
#include <zephyr/rtio/rtio.h>
1112
#include <zephyr/sys/dlist.h>
1213

1314
struct video_device {
@@ -18,20 +19,28 @@ struct video_device {
1819

1920
struct video_interface {
2021
const struct device *dev;
22+
struct mpsc *io_q;
2123
};
2224

25+
extern const struct rtio_iodev_api _video_iodev_api;
26+
2327
#define VIDEO_DEVICE_DEFINE(name, device, source) \
2428
static STRUCT_SECTION_ITERABLE(video_device, name) = { \
2529
.dev = device, \
2630
.src_dev = source, \
2731
.ctrls = SYS_DLIST_STATIC_INIT(&name.ctrls), \
2832
}
2933

30-
#define VIDEO_INTERFACE_DEFINE(name, device) \
31-
static STRUCT_SECTION_ITERABLE(video_interface, name) = { \
34+
#define VIDEO_INTERFACE_DEFINE(name, device, io_queue) \
35+
static STRUCT_SECTION_ITERABLE(video_interface, name) = { \
3236
.dev = device, \
33-
}
37+
.io_q = io_queue, \
38+
}; \
39+
RTIO_IODEV_DEFINE(name##_iodev, &_video_iodev_api, &name)
3440

3541
struct video_device *video_find_vdev(const struct device *dev);
42+
struct rtio_iodev *video_find_iodev(const struct device *dev);
43+
44+
struct video_buffer *video_get_buf_sqe(struct mpsc *io_q);
3645

3746
#endif /* ZEPHYR_INCLUDE_DRIVERS_VIDEO_VIDEO_DEVICE_H_ */

0 commit comments

Comments
 (0)