aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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)
223 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n", 223 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
224 s->name, mdl->bytesused); 224 s->name, mdl->bytesused);
225 225
226 if (s->type != CX18_ENC_STREAM_TYPE_TS) 226 if (s->type != CX18_ENC_STREAM_TYPE_TS) {
227 cx18_enqueue(s, mdl, &s->q_full); 227 cx18_enqueue(s, mdl, &s->q_full);
228 if (s->type == CX18_ENC_STREAM_TYPE_IDX)
229 cx18_stream_rotate_idx_mdls(cx);
230 }
228 else { 231 else {
229 cx18_mdl_send_to_dvb(s, mdl); 232 cx18_mdl_send_to_dvb(s, mdl);
230 cx18_enqueue(s, mdl, &s->q_free); 233 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)
463 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); 463 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
464} 464}
465 465
466void cx18_stream_rotate_idx_mdls(struct cx18 *cx)
467{
468 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
469 struct cx18_mdl *mdl;
470
471 if (!cx18_stream_enabled(s))
472 return;
473
474 /* Return if the firmware is not running low on MDLs */
475 if ((atomic_read(&s->q_free.depth) + atomic_read(&s->q_busy.depth)) >=
476 CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN)
477 return;
478
479 /* Return if there are no MDLs to rotate back to the firmware */
480 if (atomic_read(&s->q_full.depth) < 2)
481 return;
482
483 /*
484 * Take the oldest IDX MDL still holding data, and discard its index
485 * entries by scheduling the MDL to go back to the firmware
486 */
487 mdl = cx18_dequeue(s, &s->q_full);
488 if (mdl != NULL)
489 cx18_enqueue(s, mdl, &s->q_free);
490}
491
466static 492static
467struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s, 493struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
468 struct cx18_mdl *mdl) 494 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);
28int cx18_streams_register(struct cx18 *cx); 28int cx18_streams_register(struct cx18 *cx);
29void cx18_streams_cleanup(struct cx18 *cx, int unregister); 29void cx18_streams_cleanup(struct cx18 *cx, int unregister);
30 30
31#define CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN (3)
32void cx18_stream_rotate_idx_mdls(struct cx18 *cx);
33
31static inline bool cx18_stream_enabled(struct cx18_stream *s) 34static inline bool cx18_stream_enabled(struct cx18_stream *s)
32{ 35{
33 return s->video_dev || s->dvb.enabled || 36 return s->video_dev || s->dvb.enabled ||