aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7164/saa7164-encoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/saa7164/saa7164-encoder.c')
-rw-r--r--drivers/media/video/saa7164/saa7164-encoder.c245
1 files changed, 144 insertions, 101 deletions
diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c
index 08b62e41c46..0859448bae0 100644
--- a/drivers/media/video/saa7164/saa7164-encoder.c
+++ b/drivers/media/video/saa7164/saa7164-encoder.c
@@ -76,15 +76,131 @@ static void saa7164_encoder_configure(struct saa7164_port *port)
76 saa7164_api_set_audio_std(port); 76 saa7164_api_set_audio_std(port);
77} 77}
78 78
79/* One time configuration at registration time */ 79static int saa7164_encoder_buffers_dealloc(struct saa7164_port *port)
80static int saa7164_encoder_initialize(struct saa7164_port *port) 80{
81 struct list_head *c, *n, *p, *q, *l, *v;
82 struct saa7164_dev *dev = port->dev;
83 struct saa7164_buffer *buf;
84 struct saa7164_user_buffer *ubuf;
85
86 /* Remove any allocated buffers */
87 mutex_lock(&port->dmaqueue_lock);
88
89 dprintk(DBGLVL_ENC, "%s(port=%d) dmaqueue\n", __func__, port->nr);
90 list_for_each_safe(c, n, &port->dmaqueue.list) {
91 buf = list_entry(c, struct saa7164_buffer, list);
92 list_del(c);
93 saa7164_buffer_dealloc(buf);
94 }
95
96 dprintk(DBGLVL_ENC, "%s(port=%d) used\n", __func__, port->nr);
97 list_for_each_safe(p, q, &port->list_buf_used.list) {
98 ubuf = list_entry(p, struct saa7164_user_buffer, list);
99 list_del(p);
100 saa7164_buffer_dealloc_user(ubuf);
101 }
102
103 dprintk(DBGLVL_ENC, "%s(port=%d) free\n", __func__, port->nr);
104 list_for_each_safe(l, v, &port->list_buf_free.list) {
105 ubuf = list_entry(l, struct saa7164_user_buffer, list);
106 list_del(l);
107 saa7164_buffer_dealloc_user(ubuf);
108 }
109
110 mutex_unlock(&port->dmaqueue_lock);
111 dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr);
112
113 return 0;
114}
115
116/* Dynamic buffer switch at encoder start time */
117static int saa7164_encoder_buffers_alloc(struct saa7164_port *port)
81{ 118{
82 struct saa7164_dev *dev = port->dev; 119 struct saa7164_dev *dev = port->dev;
120 struct saa7164_buffer *buf;
121 struct saa7164_user_buffer *ubuf;
122 tmHWStreamParameters_t *params = &port->hw_streamingparams;
123 int result = -ENODEV, i;
124 int len = 0;
83 125
84 dprintk(DBGLVL_ENC, "%s()\n", __func__); 126 dprintk(DBGLVL_ENC, "%s()\n", __func__);
85 127
86 saa7164_encoder_configure(port); 128 if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {
129 dprintk(DBGLVL_ENC, "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_PS\n", __func__);
130 params->samplesperline = 128;
131 params->numberoflines = 256;
132 params->pitch = 128;
133 params->numpagetables = 2 +
134 ((SAA7164_PS_NUMBER_OF_LINES * 128) / PAGE_SIZE);
135 } else
136 if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) {
137 dprintk(DBGLVL_ENC, "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_TS\n", __func__);
138 params->samplesperline = 188;
139 params->numberoflines = 312;
140 params->pitch = 188;
141 params->numpagetables = 2 +
142 ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE);
143 } else
144 BUG();
145
146 /* Init and establish defaults */
147 params->bitspersample = 8;
148 params->linethreshold = 0;
149 params->pagetablelistvirt = 0;
150 params->pagetablelistphys = 0;
151 params->numpagetableentries = port->hwcfg.buffercount;
152
153 /* Allocate the PCI resources, buffers (hard) */
154 for (i = 0; i < port->hwcfg.buffercount; i++) {
155 buf = saa7164_buffer_alloc(port,
156 params->numberoflines *
157 params->pitch);
158
159 if (!buf) {
160 printk(KERN_ERR "%s() failed "
161 "(errno = %d), unable to allocate buffer\n",
162 __func__, result);
163 result = -ENOMEM;
164 goto failed;
165 } else {
166
167 mutex_lock(&port->dmaqueue_lock);
168 list_add_tail(&buf->list, &port->dmaqueue.list);
169 mutex_unlock(&port->dmaqueue_lock);
170
171 }
172 }
173
174 /* Allocate some kenrel kernel buffers for copying
175 * to userpsace.
176 */
177 len = params->numberoflines * params->pitch;
178
179 if (encoder_buffers < 16)
180 encoder_buffers = 16;
181 if (encoder_buffers > 512)
182 encoder_buffers = 512;
183
184 for (i = 0; i < encoder_buffers; i++) {
185
186 ubuf = saa7164_buffer_alloc_user(dev, len);
187 if (ubuf) {
188 mutex_lock(&port->dmaqueue_lock);
189 list_add_tail(&ubuf->list, &port->list_buf_free.list);
190 mutex_unlock(&port->dmaqueue_lock);
191 }
192
193 }
194
195 result = 0;
87 196
197failed:
198 return result;
199}
200
201static int saa7164_encoder_initialize(struct saa7164_port *port)
202{
203 saa7164_encoder_configure(port);
88 return 0; 204 return 0;
89} 205}
90 206
@@ -835,6 +951,7 @@ static int saa7164_encoder_stop_streaming(struct saa7164_port *port)
835 dprintk(DBGLVL_ENC, "%s(port=%d) Hardware stopped\n", __func__, 951 dprintk(DBGLVL_ENC, "%s(port=%d) Hardware stopped\n", __func__,
836 port->nr); 952 port->nr);
837 953
954 /* Reset the state of any allocated buffer resources */
838 mutex_lock(&port->dmaqueue_lock); 955 mutex_lock(&port->dmaqueue_lock);
839 956
840 /* Reset the hard and soft buffer state */ 957 /* Reset the hard and soft buffer state */
@@ -851,6 +968,10 @@ static int saa7164_encoder_stop_streaming(struct saa7164_port *port)
851 } 968 }
852 969
853 mutex_unlock(&port->dmaqueue_lock); 970 mutex_unlock(&port->dmaqueue_lock);
971
972 /* Free any allocated resources */
973 saa7164_encoder_buffers_dealloc(port);
974
854 dprintk(DBGLVL_ENC, "%s(port=%d) Released\n", __func__, port->nr); 975 dprintk(DBGLVL_ENC, "%s(port=%d) Released\n", __func__, port->nr);
855 976
856 return ret; 977 return ret;
@@ -863,10 +984,19 @@ static int saa7164_encoder_start_streaming(struct saa7164_port *port)
863 984
864 dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr); 985 dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr);
865 986
987 port->done_first_interrupt = 0;
988
989 /* allocate all of the PCIe DMA buffer resources on the fly,
990 * allowing switching between TS and PS payloads without
991 * requiring a complete driver reload.
992 */
993 saa7164_encoder_buffers_alloc(port);
994
866 /* Configure the encoder with any cache values */ 995 /* Configure the encoder with any cache values */
867 saa7164_api_set_encoder(port); 996 saa7164_api_set_encoder(port);
868 saa7164_api_get_encoder(port); 997 saa7164_api_get_encoder(port);
869 998
999 /* Place the empty buffers on the hardware */
870 saa7164_buffer_cfg_port(port); 1000 saa7164_buffer_cfg_port(port);
871 1001
872 /* Acquire the hardware */ 1002 /* Acquire the hardware */
@@ -1005,27 +1135,29 @@ static int fops_release(struct file *file)
1005 1135
1006struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port) 1136struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port)
1007{ 1137{
1008 struct saa7164_user_buffer *buf = 0; 1138 struct saa7164_user_buffer *ubuf = 0;
1009 struct saa7164_dev *dev = port->dev; 1139 struct saa7164_dev *dev = port->dev;
1010 u32 crc; 1140 u32 crc;
1011 1141
1012 mutex_lock(&port->dmaqueue_lock); 1142 mutex_lock(&port->dmaqueue_lock);
1013 if (!list_empty(&port->list_buf_used.list)) { 1143 if (!list_empty(&port->list_buf_used.list)) {
1014 buf = list_first_entry(&port->list_buf_used.list, 1144 ubuf = list_first_entry(&port->list_buf_used.list,
1015 struct saa7164_user_buffer, list); 1145 struct saa7164_user_buffer, list);
1016 1146
1017 crc = crc32(0, buf->data, buf->actual_size); 1147 if (crc_checking) {
1018 if (crc != buf->crc) { 1148 crc = crc32(0, ubuf->data, ubuf->actual_size);
1019 printk(KERN_ERR "%s() buf %p crc became invalid, was 0x%x became 0x%x\n", __func__, 1149 if (crc != ubuf->crc) {
1020 buf, buf->crc, crc); 1150 printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__,
1151 ubuf, ubuf->crc, crc);
1152 }
1021 } 1153 }
1022 1154
1023 } 1155 }
1024 mutex_unlock(&port->dmaqueue_lock); 1156 mutex_unlock(&port->dmaqueue_lock);
1025 1157
1026 dprintk(DBGLVL_ENC, "%s() returns %p\n", __func__, buf); 1158 dprintk(DBGLVL_ENC, "%s() returns %p\n", __func__, ubuf);
1027 1159
1028 return buf; 1160 return ubuf;
1029} 1161}
1030 1162
1031static ssize_t fops_read(struct file *file, char __user *buffer, 1163static ssize_t fops_read(struct file *file, char __user *buffer,
@@ -1292,10 +1424,7 @@ static struct video_device *saa7164_encoder_alloc(
1292int saa7164_encoder_register(struct saa7164_port *port) 1424int saa7164_encoder_register(struct saa7164_port *port)
1293{ 1425{
1294 struct saa7164_dev *dev = port->dev; 1426 struct saa7164_dev *dev = port->dev;
1295 struct saa7164_buffer *buf; 1427 int result = -ENODEV;
1296 struct saa7164_user_buffer *ubuf;
1297 int result = -ENODEV, i;
1298 int len = 0;
1299 1428
1300 dprintk(DBGLVL_ENC, "%s()\n", __func__); 1429 dprintk(DBGLVL_ENC, "%s()\n", __func__);
1301 1430
@@ -1311,64 +1440,6 @@ int saa7164_encoder_register(struct saa7164_port *port)
1311 goto failed; 1440 goto failed;
1312 } 1441 }
1313 1442
1314 /* Init and establish defaults */
1315 /* TODO: Check the umber of lines for PS */
1316 port->hw_streamingparams.bitspersample = 8;
1317 port->hw_streamingparams.samplesperline = 128;
1318 port->hw_streamingparams.numberoflines = 256;
1319
1320 port->hw_streamingparams.pitch = 128;
1321 port->hw_streamingparams.linethreshold = 0;
1322 port->hw_streamingparams.pagetablelistvirt = 0;
1323 port->hw_streamingparams.pagetablelistphys = 0;
1324 port->hw_streamingparams.numpagetables = 2 +
1325 ((SAA7164_PS_NUMBER_OF_LINES * 128) / PAGE_SIZE);
1326
1327 port->hw_streamingparams.numpagetableentries = port->hwcfg.buffercount;
1328
1329 /* Allocate the PCI resources, buffers (hard) */
1330 for (i = 0; i < port->hwcfg.buffercount; i++) {
1331 buf = saa7164_buffer_alloc(port,
1332 port->hw_streamingparams.numberoflines *
1333 port->hw_streamingparams.pitch);
1334
1335 if (!buf) {
1336 printk(KERN_ERR "%s() failed "
1337 "(errno = %d), unable to allocate buffer\n",
1338 __func__, result);
1339 result = -ENOMEM;
1340 goto failed;
1341 } else {
1342
1343 mutex_lock(&port->dmaqueue_lock);
1344 list_add_tail(&buf->list, &port->dmaqueue.list);
1345 mutex_unlock(&port->dmaqueue_lock);
1346
1347 }
1348 }
1349
1350 /* Allocate some kenrel kernel buffers for copying
1351 * to userpsace.
1352 */
1353 len = port->hw_streamingparams.numberoflines *
1354 port->hw_streamingparams.pitch;
1355
1356 if (encoder_buffers < 16)
1357 encoder_buffers = 16;
1358 if (encoder_buffers > 512)
1359 encoder_buffers = 512;
1360
1361 for (i = 0; i < encoder_buffers; i++) {
1362
1363 ubuf = saa7164_buffer_alloc_user(dev, len);
1364 if (ubuf) {
1365 mutex_lock(&port->dmaqueue_lock);
1366 list_add_tail(&ubuf->list, &port->list_buf_free.list);
1367 mutex_unlock(&port->dmaqueue_lock);
1368 }
1369
1370 }
1371
1372 /* Establish encoder defaults here */ 1443 /* Establish encoder defaults here */
1373 /* Set default TV standard */ 1444 /* Set default TV standard */
1374 port->encodernorm = saa7164_tvnorms[0]; 1445 port->encodernorm = saa7164_tvnorms[0];
@@ -1446,9 +1517,6 @@ failed:
1446void saa7164_encoder_unregister(struct saa7164_port *port) 1517void saa7164_encoder_unregister(struct saa7164_port *port)
1447{ 1518{
1448 struct saa7164_dev *dev = port->dev; 1519 struct saa7164_dev *dev = port->dev;
1449 struct saa7164_buffer *buf;
1450 struct saa7164_user_buffer *ubuf;
1451 struct list_head *c, *n, *p, *q, *l, *v;
1452 1520
1453 dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr); 1521 dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr);
1454 1522
@@ -1464,31 +1532,6 @@ void saa7164_encoder_unregister(struct saa7164_port *port)
1464 port->v4l_device = NULL; 1532 port->v4l_device = NULL;
1465 } 1533 }
1466 1534
1467 /* Remove any allocated buffers */
1468 mutex_lock(&port->dmaqueue_lock);
1469
1470 dprintk(DBGLVL_ENC, "%s(port=%d) dmaqueue\n", __func__, port->nr);
1471 list_for_each_safe(c, n, &port->dmaqueue.list) {
1472 buf = list_entry(c, struct saa7164_buffer, list);
1473 list_del(c);
1474 saa7164_buffer_dealloc(buf);
1475 }
1476
1477 dprintk(DBGLVL_ENC, "%s(port=%d) used\n", __func__, port->nr);
1478 list_for_each_safe(p, q, &port->list_buf_used.list) {
1479 ubuf = list_entry(p, struct saa7164_user_buffer, list);
1480 list_del(p);
1481 saa7164_buffer_dealloc_user(ubuf);
1482 }
1483
1484 dprintk(DBGLVL_ENC, "%s(port=%d) free\n", __func__, port->nr);
1485 list_for_each_safe(l, v, &port->list_buf_free.list) {
1486 ubuf = list_entry(l, struct saa7164_user_buffer, list);
1487 list_del(l);
1488 saa7164_buffer_dealloc_user(ubuf);
1489 }
1490
1491 mutex_unlock(&port->dmaqueue_lock);
1492 dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr); 1535 dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr);
1493} 1536}
1494 1537