aboutsummaryrefslogtreecommitdiffstats
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-driver.c49
-rw-r--r--drivers/media/video/cx18/cx18-driver.h7
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c5
-rw-r--r--drivers/media/video/cx18/cx18-queue.c6
-rw-r--r--drivers/media/video/cx18/cx18-streams.c26
5 files changed, 71 insertions, 22 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index ba4c3ceffbb3..87a735f1ee9e 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -211,7 +211,9 @@ MODULE_PARM_DESC(enc_yuv_buffers,
211 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS)); 211 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
212MODULE_PARM_DESC(enc_yuv_bufsize, 212MODULE_PARM_DESC(enc_yuv_bufsize,
213 "Size of an encoder YUV buffer (kB)\n" 213 "Size of an encoder YUV buffer (kB)\n"
214 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFSIZE)); 214 "\t\t\tAllowed values are multiples of 33.75 kB rounded up\n"
215 "\t\t\t(multiples of size required for 32 screen lines)\n"
216 "\t\t\tDefault: 102");
215MODULE_PARM_DESC(enc_yuv_bufs, 217MODULE_PARM_DESC(enc_yuv_bufs,
216 "Number of encoder YUV buffers\n" 218 "Number of encoder YUV buffers\n"
217 "\t\t\tDefault is computed from other enc_yuv_* parameters"); 219 "\t\t\tDefault is computed from other enc_yuv_* parameters");
@@ -499,10 +501,27 @@ static void cx18_process_options(struct cx18 *cx)
499 continue; 501 continue;
500 } 502 }
501 /* 503 /*
504 * YUV is a special case where the stream_buf_size needs to be
505 * an integral multiple of 33.75 kB (storage for 32 screens
506 * lines to maintain alignment in case of lost buffers
507 */
508 if (i == CX18_ENC_STREAM_TYPE_YUV) {
509 cx->stream_buf_size[i] *= 1024;
510 cx->stream_buf_size[i] -=
511 (cx->stream_buf_size[i] % CX18_UNIT_ENC_YUV_BUFSIZE);
512
513 if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE)
514 cx->stream_buf_size[i] =
515 CX18_UNIT_ENC_YUV_BUFSIZE;
516 }
517 /*
518 * YUV is a special case where the stream_buf_size is
519 * now in bytes.
502 * VBI is a special case where the stream_buf_size is fixed 520 * VBI is a special case where the stream_buf_size is fixed
503 * and already in bytes 521 * and already in bytes
504 */ 522 */
505 if (i == CX18_ENC_STREAM_TYPE_VBI) { 523 if (i == CX18_ENC_STREAM_TYPE_VBI ||
524 i == CX18_ENC_STREAM_TYPE_YUV) {
506 if (cx->stream_buffers[i] < 0) { 525 if (cx->stream_buffers[i] < 0) {
507 cx->stream_buffers[i] = 526 cx->stream_buffers[i] =
508 cx->options.megabytes[i] * 1024 * 1024 527 cx->options.megabytes[i] * 1024 * 1024
@@ -513,18 +532,24 @@ static void cx18_process_options(struct cx18 *cx)
513 cx->stream_buffers[i] 532 cx->stream_buffers[i]
514 * cx->stream_buf_size[i]/(1024 * 1024); 533 * cx->stream_buf_size[i]/(1024 * 1024);
515 } 534 }
516 continue;
517 }
518 /* All other streams have stream_buf_size in kB at this point */
519 if (cx->stream_buffers[i] < 0) {
520 cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
521 / cx->stream_buf_size[i];
522 } else { 535 } else {
523 /* N.B. This might round down to 0 */ 536 /* All other streams have stream_buf_size in kB here */
524 cx->options.megabytes[i] = 537 if (cx->stream_buffers[i] < 0) {
525 cx->stream_buffers[i] * cx->stream_buf_size[i] / 1024; 538 cx->stream_buffers[i] =
539 cx->options.megabytes[i] * 1024
540 / cx->stream_buf_size[i];
541 } else {
542 /* N.B. This might round down to 0 */
543 cx->options.megabytes[i] =
544 cx->stream_buffers[i]
545 * cx->stream_buf_size[i] / 1024;
546 }
547 /* convert from kB to bytes */
548 cx->stream_buf_size[i] *= 1024;
526 } 549 }
527 cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */ 550 CX18_DEBUG_INFO("Stream type %d options: %d MB, %d buffers, "
551 "%d bytes\n", i, cx->options.megabytes[i],
552 cx->stream_buffers[i], cx->stream_buf_size[i]);
528 } 553 }
529 554
530 cx->options.cardtype = cardtype[cx->instance]; 555 cx->options.cardtype = cardtype[cx->instance];
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index bed8bcc65411..5c78b014dbc0 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -120,11 +120,16 @@
120/* Maximum firmware DMA buffers per stream */ 120/* Maximum firmware DMA buffers per stream */
121#define CX18_MAX_FW_MDLS_PER_STREAM 63 121#define CX18_MAX_FW_MDLS_PER_STREAM 63
122 122
123/* YUV buffer sizes in bytes to ensure integer # of frames per buffer */
124#define CX18_UNIT_ENC_YUV_BUFSIZE (720 * 32 * 3 / 2) /* bytes */
125#define CX18_625_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 576/32)
126#define CX18_525_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 480/32)
127
123/* DMA buffer, default size in kB allocated */ 128/* DMA buffer, default size in kB allocated */
124#define CX18_DEFAULT_ENC_TS_BUFSIZE 32 129#define CX18_DEFAULT_ENC_TS_BUFSIZE 32
125#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32 130#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32
126#define CX18_DEFAULT_ENC_IDX_BUFSIZE 32 131#define CX18_DEFAULT_ENC_IDX_BUFSIZE 32
127#define CX18_DEFAULT_ENC_YUV_BUFSIZE 128 132#define CX18_DEFAULT_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1)
128/* Default VBI bufsize based on standards supported by card tuner for now */ 133/* Default VBI bufsize based on standards supported by card tuner for now */
129#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4 134#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4
130 135
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 54a6fd3f7af5..71ad2d1b4c2c 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -362,9 +362,10 @@ int cx18_dvb_register(struct cx18_stream *stream)
362 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx); 362 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
363 363
364 CX18_INFO("DVB Frontend registered\n"); 364 CX18_INFO("DVB Frontend registered\n");
365 CX18_INFO("Registered DVB adapter%d for %s (%d x %d kB)\n", 365 CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n",
366 stream->dvb.dvb_adapter.num, stream->name, 366 stream->dvb.dvb_adapter.num, stream->name,
367 stream->buffers, stream->buf_size/1024); 367 stream->buffers, stream->buf_size/1024,
368 (stream->buf_size * 100 / 1024) % 100);
368 369
369 mutex_init(&dvb->feedlock); 370 mutex_init(&dvb->feedlock);
370 dvb->enabled = 1; 371 dvb->enabled = 1;
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index c1a49ecf9d98..98cbf001f8da 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -348,9 +348,11 @@ int cx18_stream_alloc(struct cx18_stream *s)
348 if (s->buffers == 0) 348 if (s->buffers == 0)
349 return 0; 349 return 0;
350 350
351 CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers (%dkB total)\n", 351 CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers "
352 "(%d.%02d kB total)\n",
352 s->name, s->buffers, s->buf_size, 353 s->name, s->buffers, s->buf_size,
353 s->buffers * s->buf_size / 1024); 354 s->buffers * s->buf_size / 1024,
355 (s->buffers * s->buf_size * 100 / 1024) % 100);
354 356
355 if (((char __iomem *)&cx->scb->cpu_mdl[cx->free_mdl_idx + s->buffers] - 357 if (((char __iomem *)&cx->scb->cpu_mdl[cx->free_mdl_idx + s->buffers] -
356 (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) { 358 (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) {
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 9f8adda6f261..7755937fc521 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -262,9 +262,11 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
262 262
263 switch (vfl_type) { 263 switch (vfl_type) {
264 case VFL_TYPE_GRABBER: 264 case VFL_TYPE_GRABBER:
265 CX18_INFO("Registered device video%d for %s (%d x %d kB)\n", 265 CX18_INFO("Registered device video%d for %s "
266 "(%d x %d.%02d kB)\n",
266 num, s->name, cx->stream_buffers[type], 267 num, s->name, cx->stream_buffers[type],
267 cx->stream_buf_size[type]/1024); 268 cx->stream_buf_size[type] / 1024,
269 (cx->stream_buf_size[type] * 100 / 1024) % 100);
268 break; 270 break;
269 271
270 case VFL_TYPE_RADIO: 272 case VFL_TYPE_RADIO:
@@ -501,9 +503,23 @@ static void cx18_stream_configure_mdls(struct cx18_stream *s)
501{ 503{
502 cx18_unload_queues(s); 504 cx18_unload_queues(s);
503 505
504 /* For now */ 506 switch (s->type) {
505 s->bufs_per_mdl = 1; 507 case CX18_ENC_STREAM_TYPE_YUV:
506 s->mdl_size = s->buf_size * s->bufs_per_mdl; 508 /*
509 * Height should be a multiple of 32 lines.
510 * Set the MDL size to the exact size needed for one frame.
511 * Use enough buffers per MDL to cover the MDL size
512 */
513 s->mdl_size = 720 * s->cx->params.height * 3 / 2;
514 s->bufs_per_mdl = s->mdl_size / s->buf_size;
515 if (s->mdl_size % s->buf_size)
516 s->bufs_per_mdl++;
517 break;
518 default:
519 s->bufs_per_mdl = 1;
520 s->mdl_size = s->buf_size * s->bufs_per_mdl;
521 break;
522 }
507 523
508 cx18_load_queues(s); 524 cx18_load_queues(s);
509} 525}