summaryrefslogtreecommitdiff
path: root/drivers/media/video/cx18
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx18')
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c5
-rw-r--r--drivers/media/video/cx18/cx18-streams.c26
-rw-r--r--drivers/media/video/cx18/cx18-streams.h3
3 files changed, 33 insertions, 1 deletions
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index f231dd09c720..0ac0e2c993a5 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -223,8 +223,11 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
s->name, mdl->bytesused);
- if (s->type != CX18_ENC_STREAM_TYPE_TS)
+ if (s->type != CX18_ENC_STREAM_TYPE_TS) {
cx18_enqueue(s, mdl, &s->q_full);
+ if (s->type == CX18_ENC_STREAM_TYPE_IDX)
+ cx18_stream_rotate_idx_mdls(cx);
+ }
else {
cx18_mdl_send_to_dvb(s, mdl);
cx18_enqueue(s, mdl, &s->q_free);
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 9755f4416e96..680e7da5e5e4 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -463,6 +463,32 @@ static void cx18_vbi_setup(struct cx18_stream *s)
cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
}
+void cx18_stream_rotate_idx_mdls(struct cx18 *cx)
+{
+ struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
+ struct cx18_mdl *mdl;
+
+ if (!cx18_stream_enabled(s))
+ return;
+
+ /* Return if the firmware is not running low on MDLs */
+ if ((atomic_read(&s->q_free.depth) + atomic_read(&s->q_busy.depth)) >=
+ CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN)
+ return;
+
+ /* Return if there are no MDLs to rotate back to the firmware */
+ if (atomic_read(&s->q_full.depth) < 2)
+ return;
+
+ /*
+ * Take the oldest IDX MDL still holding data, and discard its index
+ * entries by scheduling the MDL to go back to the firmware
+ */
+ mdl = cx18_dequeue(s, &s->q_full);
+ if (mdl != NULL)
+ cx18_enqueue(s, mdl, &s->q_free);
+}
+
static
struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
struct cx18_mdl *mdl)
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 7b36225c4abe..0bff0fa29763 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -28,6 +28,9 @@ int cx18_streams_setup(struct cx18 *cx);
int cx18_streams_register(struct cx18 *cx);
void cx18_streams_cleanup(struct cx18 *cx, int unregister);
+#define CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN (3)
+void cx18_stream_rotate_idx_mdls(struct cx18 *cx);
+
static inline bool cx18_stream_enabled(struct cx18_stream *s)
{
return s->video_dev || s->dvb.enabled ||