]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Zoran zr36057/zr36067 PCI controller driver, for the | |
3 | * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux | |
4 | * Media Labs LML33/LML33R10. | |
5 | * | |
6 | * This part handles device access (PCI/I2C/codec/...) | |
d56410e0 | 7 | * |
1da177e4 LT |
8 | * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> |
9 | * | |
10 | * Currently maintained by: | |
11 | * Ronald Bultje <rbultje@ronald.bitfreak.net> | |
12 | * Laurent Pinchart <laurent.pinchart@skynet.be> | |
13 | * Mailinglist <mjpeg-users@lists.sf.net> | |
14 | * | |
15 | * This program is free software; you can redistribute it and/or modify | |
16 | * it under the terms of the GNU General Public License as published by | |
17 | * the Free Software Foundation; either version 2 of the License, or | |
18 | * (at your option) any later version. | |
19 | * | |
20 | * This program is distributed in the hope that it will be useful, | |
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23 | * GNU General Public License for more details. | |
24 | * | |
25 | * You should have received a copy of the GNU General Public License | |
26 | * along with this program; if not, write to the Free Software | |
27 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
28 | */ | |
29 | ||
1da177e4 LT |
30 | #include <linux/types.h> |
31 | #include <linux/kernel.h> | |
32 | #include <linux/module.h> | |
33 | #include <linux/vmalloc.h> | |
34 | #include <linux/byteorder/generic.h> | |
35 | ||
36 | #include <linux/interrupt.h> | |
37 | #include <linux/proc_fs.h> | |
38 | #include <linux/i2c.h> | |
39 | #include <linux/i2c-algo-bit.h> | |
40 | #include <linux/videodev.h> | |
41 | #include <linux/spinlock.h> | |
42 | #include <linux/sem.h> | |
43 | ||
44 | #include <linux/pci.h> | |
45 | #include <linux/video_decoder.h> | |
46 | #include <linux/video_encoder.h> | |
47 | #include <linux/delay.h> | |
48 | #include <linux/wait.h> | |
49 | ||
50 | #include <asm/io.h> | |
51 | ||
52 | #include "videocodec.h" | |
53 | #include "zoran.h" | |
54 | #include "zoran_device.h" | |
55 | ||
56 | #define IRQ_MASK ( ZR36057_ISR_GIRQ0 | \ | |
57 | ZR36057_ISR_GIRQ1 | \ | |
58 | ZR36057_ISR_JPEGRepIRQ ) | |
59 | ||
60 | extern const struct zoran_format zoran_formats[]; | |
61 | ||
62 | extern int *zr_debug; | |
63 | ||
64 | #define dprintk(num, format, args...) \ | |
65 | do { \ | |
66 | if (*zr_debug >= num) \ | |
67 | printk(format, ##args); \ | |
68 | } while (0) | |
69 | ||
70 | static int lml33dpath = 0; /* 1 will use digital path in capture | |
71 | * mode instead of analog. It can be | |
72 | * used for picture adjustments using | |
73 | * tool like xawtv while watching image | |
74 | * on TV monitor connected to the output. | |
75 | * However, due to absence of 75 Ohm | |
76 | * load on Bt819 input, there will be | |
77 | * some image imperfections */ | |
78 | ||
79 | module_param(lml33dpath, bool, 0); | |
80 | MODULE_PARM_DESC(lml33dpath, | |
81 | "Use digital path capture mode (on LML33 cards)"); | |
82 | ||
83 | static void | |
84 | zr36057_init_vfe (struct zoran *zr); | |
85 | ||
86 | /* | |
87 | * General Purpose I/O and Guest bus access | |
88 | */ | |
89 | ||
90 | /* | |
91 | * This is a bit tricky. When a board lacks a GPIO function, the corresponding | |
92 | * GPIO bit number in the card_info structure is set to 0. | |
93 | */ | |
94 | ||
95 | void | |
96 | GPIO (struct zoran *zr, | |
97 | int bit, | |
98 | unsigned int value) | |
99 | { | |
100 | u32 reg; | |
101 | u32 mask; | |
102 | ||
103 | /* Make sure the bit number is legal | |
104 | * A bit number of -1 (lacking) gives a mask of 0, | |
105 | * making it harmless */ | |
106 | mask = (1 << (24 + bit)) & 0xff000000; | |
107 | reg = btread(ZR36057_GPPGCR1) & ~mask; | |
108 | if (value) { | |
109 | reg |= mask; | |
110 | } | |
111 | btwrite(reg, ZR36057_GPPGCR1); | |
112 | udelay(1); | |
113 | } | |
114 | ||
115 | /* | |
116 | * Wait til post office is no longer busy | |
117 | */ | |
118 | ||
119 | int | |
120 | post_office_wait (struct zoran *zr) | |
121 | { | |
122 | u32 por; | |
123 | ||
124 | // while (((por = btread(ZR36057_POR)) & (ZR36057_POR_POPen | ZR36057_POR_POTime)) == ZR36057_POR_POPen) { | |
125 | while ((por = btread(ZR36057_POR)) & ZR36057_POR_POPen) { | |
126 | /* wait for something to happen */ | |
127 | } | |
128 | if ((por & ZR36057_POR_POTime) && !zr->card.gws_not_connected) { | |
129 | /* In LML33/BUZ \GWS line is not connected, so it has always timeout set */ | |
130 | dprintk(1, KERN_INFO "%s: pop timeout %08x\n", ZR_DEVNAME(zr), | |
131 | por); | |
132 | return -1; | |
133 | } | |
134 | ||
135 | return 0; | |
136 | } | |
137 | ||
138 | int | |
139 | post_office_write (struct zoran *zr, | |
140 | unsigned int guest, | |
141 | unsigned int reg, | |
142 | unsigned int value) | |
143 | { | |
144 | u32 por; | |
145 | ||
146 | por = | |
147 | ZR36057_POR_PODir | ZR36057_POR_POTime | ((guest & 7) << 20) | | |
148 | ((reg & 7) << 16) | (value & 0xFF); | |
149 | btwrite(por, ZR36057_POR); | |
150 | ||
151 | return post_office_wait(zr); | |
152 | } | |
153 | ||
154 | int | |
155 | post_office_read (struct zoran *zr, | |
156 | unsigned int guest, | |
157 | unsigned int reg) | |
158 | { | |
159 | u32 por; | |
160 | ||
161 | por = ZR36057_POR_POTime | ((guest & 7) << 20) | ((reg & 7) << 16); | |
162 | btwrite(por, ZR36057_POR); | |
163 | if (post_office_wait(zr) < 0) { | |
164 | return -1; | |
165 | } | |
166 | ||
167 | return btread(ZR36057_POR) & 0xFF; | |
168 | } | |
169 | ||
170 | /* | |
171 | * detect guests | |
172 | */ | |
173 | ||
174 | static void | |
175 | dump_guests (struct zoran *zr) | |
176 | { | |
177 | if (*zr_debug > 2) { | |
178 | int i, guest[8]; | |
179 | ||
180 | for (i = 1; i < 8; i++) { // Don't read jpeg codec here | |
181 | guest[i] = post_office_read(zr, i, 0); | |
182 | } | |
183 | ||
184 | printk(KERN_INFO "%s: Guests:", ZR_DEVNAME(zr)); | |
185 | ||
186 | for (i = 1; i < 8; i++) { | |
187 | printk(" 0x%02x", guest[i]); | |
188 | } | |
189 | printk("\n"); | |
190 | } | |
191 | } | |
192 | ||
193 | static inline unsigned long | |
194 | get_time (void) | |
195 | { | |
196 | struct timeval tv; | |
197 | ||
198 | do_gettimeofday(&tv); | |
199 | return (1000000 * tv.tv_sec + tv.tv_usec); | |
200 | } | |
201 | ||
202 | void | |
203 | detect_guest_activity (struct zoran *zr) | |
204 | { | |
205 | int timeout, i, j, res, guest[8], guest0[8], change[8][3]; | |
206 | unsigned long t0, t1; | |
207 | ||
208 | dump_guests(zr); | |
209 | printk(KERN_INFO "%s: Detecting guests activity, please wait...\n", | |
210 | ZR_DEVNAME(zr)); | |
211 | for (i = 1; i < 8; i++) { // Don't read jpeg codec here | |
212 | guest0[i] = guest[i] = post_office_read(zr, i, 0); | |
213 | } | |
214 | ||
215 | timeout = 0; | |
216 | j = 0; | |
217 | t0 = get_time(); | |
218 | while (timeout < 10000) { | |
219 | udelay(10); | |
220 | timeout++; | |
221 | for (i = 1; (i < 8) && (j < 8); i++) { | |
222 | res = post_office_read(zr, i, 0); | |
223 | if (res != guest[i]) { | |
224 | t1 = get_time(); | |
225 | change[j][0] = (t1 - t0); | |
226 | t0 = t1; | |
227 | change[j][1] = i; | |
228 | change[j][2] = res; | |
229 | j++; | |
230 | guest[i] = res; | |
231 | } | |
232 | } | |
233 | if (j >= 8) | |
234 | break; | |
235 | } | |
236 | printk(KERN_INFO "%s: Guests:", ZR_DEVNAME(zr)); | |
237 | ||
238 | for (i = 1; i < 8; i++) { | |
239 | printk(" 0x%02x", guest0[i]); | |
240 | } | |
241 | printk("\n"); | |
242 | if (j == 0) { | |
243 | printk(KERN_INFO "%s: No activity detected.\n", ZR_DEVNAME(zr)); | |
244 | return; | |
245 | } | |
246 | for (i = 0; i < j; i++) { | |
247 | printk(KERN_INFO "%s: %6d: %d => 0x%02x\n", ZR_DEVNAME(zr), | |
248 | change[i][0], change[i][1], change[i][2]); | |
249 | } | |
250 | } | |
251 | ||
252 | /* | |
253 | * JPEG Codec access | |
254 | */ | |
255 | ||
256 | void | |
257 | jpeg_codec_sleep (struct zoran *zr, | |
258 | int sleep) | |
259 | { | |
260 | GPIO(zr, zr->card.gpio[GPIO_JPEG_SLEEP], !sleep); | |
261 | if (!sleep) { | |
262 | dprintk(3, | |
263 | KERN_DEBUG | |
264 | "%s: jpeg_codec_sleep() - wake GPIO=0x%08x\n", | |
265 | ZR_DEVNAME(zr), btread(ZR36057_GPPGCR1)); | |
266 | udelay(500); | |
267 | } else { | |
268 | dprintk(3, | |
269 | KERN_DEBUG | |
270 | "%s: jpeg_codec_sleep() - sleep GPIO=0x%08x\n", | |
271 | ZR_DEVNAME(zr), btread(ZR36057_GPPGCR1)); | |
272 | udelay(2); | |
273 | } | |
274 | } | |
275 | ||
276 | int | |
277 | jpeg_codec_reset (struct zoran *zr) | |
278 | { | |
279 | /* Take the codec out of sleep */ | |
280 | jpeg_codec_sleep(zr, 0); | |
281 | ||
282 | if (zr->card.gpcs[GPCS_JPEG_RESET] != 0xff) { | |
283 | post_office_write(zr, zr->card.gpcs[GPCS_JPEG_RESET], 0, | |
284 | 0); | |
285 | udelay(2); | |
286 | } else { | |
287 | GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 0); | |
288 | udelay(2); | |
289 | GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 1); | |
290 | udelay(2); | |
291 | } | |
292 | ||
293 | return 0; | |
294 | } | |
295 | ||
296 | /* | |
297 | * Set the registers for the size we have specified. Don't bother | |
298 | * trying to understand this without the ZR36057 manual in front of | |
299 | * you [AC]. | |
300 | * | |
301 | * PS: The manual is free for download in .pdf format from | |
302 | * www.zoran.com - nicely done those folks. | |
303 | */ | |
304 | ||
305 | static void | |
306 | zr36057_adjust_vfe (struct zoran *zr, | |
307 | enum zoran_codec_mode mode) | |
308 | { | |
309 | u32 reg; | |
310 | ||
311 | switch (mode) { | |
312 | case BUZ_MODE_MOTION_DECOMPRESS: | |
313 | btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); | |
314 | reg = btread(ZR36057_VFEHCR); | |
315 | if ((reg & (1 << 10)) && zr->card.type != LML33R10) { | |
316 | reg += ((1 << 10) | 1); | |
317 | } | |
318 | btwrite(reg, ZR36057_VFEHCR); | |
319 | break; | |
320 | case BUZ_MODE_MOTION_COMPRESS: | |
321 | case BUZ_MODE_IDLE: | |
322 | default: | |
323 | if (zr->norm == VIDEO_MODE_NTSC || | |
324 | (zr->card.type == LML33R10 && | |
325 | zr->norm == VIDEO_MODE_PAL)) | |
326 | btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); | |
327 | else | |
328 | btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); | |
329 | reg = btread(ZR36057_VFEHCR); | |
330 | if (!(reg & (1 << 10)) && zr->card.type != LML33R10) { | |
331 | reg -= ((1 << 10) | 1); | |
332 | } | |
333 | btwrite(reg, ZR36057_VFEHCR); | |
334 | break; | |
335 | } | |
336 | } | |
337 | ||
338 | /* | |
339 | * set geometry | |
340 | */ | |
341 | ||
342 | static void | |
343 | zr36057_set_vfe (struct zoran *zr, | |
344 | int video_width, | |
345 | int video_height, | |
346 | const struct zoran_format *format) | |
347 | { | |
348 | struct tvnorm *tvn; | |
349 | unsigned HStart, HEnd, VStart, VEnd; | |
350 | unsigned DispMode; | |
351 | unsigned VidWinWid, VidWinHt; | |
352 | unsigned hcrop1, hcrop2, vcrop1, vcrop2; | |
353 | unsigned Wa, We, Ha, He; | |
354 | unsigned X, Y, HorDcm, VerDcm; | |
355 | u32 reg; | |
356 | unsigned mask_line_size; | |
357 | ||
358 | tvn = zr->timing; | |
359 | ||
360 | Wa = tvn->Wa; | |
361 | Ha = tvn->Ha; | |
362 | ||
363 | dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n", | |
364 | ZR_DEVNAME(zr), video_width, video_height); | |
365 | ||
366 | if (zr->norm != VIDEO_MODE_PAL && | |
367 | zr->norm != VIDEO_MODE_NTSC && | |
368 | zr->norm != VIDEO_MODE_SECAM) { | |
369 | dprintk(1, | |
370 | KERN_ERR "%s: set_vfe() - norm = %d not valid\n", | |
371 | ZR_DEVNAME(zr), zr->norm); | |
372 | return; | |
373 | } | |
374 | if (video_width < BUZ_MIN_WIDTH || | |
375 | video_height < BUZ_MIN_HEIGHT || | |
376 | video_width > Wa || video_height > Ha) { | |
377 | dprintk(1, KERN_ERR "%s: set_vfe: w=%d h=%d not valid\n", | |
378 | ZR_DEVNAME(zr), video_width, video_height); | |
379 | return; | |
380 | } | |
381 | ||
382 | /**** zr36057 ****/ | |
383 | ||
384 | /* horizontal */ | |
385 | VidWinWid = video_width; | |
386 | X = (VidWinWid * 64 + tvn->Wa - 1) / tvn->Wa; | |
387 | We = (VidWinWid * 64) / X; | |
388 | HorDcm = 64 - X; | |
389 | hcrop1 = 2 * ((tvn->Wa - We) / 4); | |
390 | hcrop2 = tvn->Wa - We - hcrop1; | |
391 | HStart = tvn->HStart ? tvn->HStart : 1; | |
392 | /* (Ronald) Original comment: | |
393 | * "| 1 Doesn't have any effect, tested on both a DC10 and a DC10+" | |
394 | * this is false. It inverses chroma values on the LML33R10 (so Cr | |
395 | * suddenly is shown as Cb and reverse, really cool effect if you | |
396 | * want to see blue faces, not useful otherwise). So don't use |1. | |
397 | * However, the DC10 has '0' as HStart, but does need |1, so we | |
398 | * use a dirty check... | |
399 | */ | |
400 | HEnd = HStart + tvn->Wa - 1; | |
401 | HStart += hcrop1; | |
402 | HEnd -= hcrop2; | |
403 | reg = ((HStart & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HStart) | |
404 | | ((HEnd & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HEnd); | |
405 | if (zr->card.vfe_pol.hsync_pol) | |
406 | reg |= ZR36057_VFEHCR_HSPol; | |
407 | btwrite(reg, ZR36057_VFEHCR); | |
408 | ||
409 | /* Vertical */ | |
410 | DispMode = !(video_height > BUZ_MAX_HEIGHT / 2); | |
411 | VidWinHt = DispMode ? video_height : video_height / 2; | |
412 | Y = (VidWinHt * 64 * 2 + tvn->Ha - 1) / tvn->Ha; | |
413 | He = (VidWinHt * 64) / Y; | |
414 | VerDcm = 64 - Y; | |
415 | vcrop1 = (tvn->Ha / 2 - He) / 2; | |
416 | vcrop2 = tvn->Ha / 2 - He - vcrop1; | |
417 | VStart = tvn->VStart; | |
418 | VEnd = VStart + tvn->Ha / 2; // - 1; FIXME SnapShot times out with -1 in 768*576 on the DC10 - LP | |
419 | VStart += vcrop1; | |
420 | VEnd -= vcrop2; | |
421 | reg = ((VStart & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VStart) | |
422 | | ((VEnd & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VEnd); | |
423 | if (zr->card.vfe_pol.vsync_pol) | |
424 | reg |= ZR36057_VFEVCR_VSPol; | |
425 | btwrite(reg, ZR36057_VFEVCR); | |
426 | ||
427 | /* scaler and pixel format */ | |
428 | reg = 0; | |
429 | reg |= (HorDcm << ZR36057_VFESPFR_HorDcm); | |
430 | reg |= (VerDcm << ZR36057_VFESPFR_VerDcm); | |
431 | reg |= (DispMode << ZR36057_VFESPFR_DispMode); | |
432 | if (format->palette != VIDEO_PALETTE_YUV422) | |
433 | reg |= ZR36057_VFESPFR_LittleEndian; | |
434 | /* RJ: I don't know, why the following has to be the opposite | |
435 | * of the corresponding ZR36060 setting, but only this way | |
436 | * we get the correct colors when uncompressing to the screen */ | |
437 | //reg |= ZR36057_VFESPFR_VCLKPol; /**/ | |
438 | /* RJ: Don't know if that is needed for NTSC also */ | |
439 | if (zr->norm != VIDEO_MODE_NTSC) | |
440 | reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang | |
441 | reg |= ZR36057_VFESPFR_TopField; | |
442 | switch (format->palette) { | |
443 | ||
444 | case VIDEO_PALETTE_YUV422: | |
445 | reg |= ZR36057_VFESPFR_YUV422; | |
446 | break; | |
447 | ||
448 | case VIDEO_PALETTE_RGB555: | |
449 | reg |= ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ErrDif; | |
450 | break; | |
451 | ||
452 | case VIDEO_PALETTE_RGB565: | |
453 | reg |= ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ErrDif; | |
454 | break; | |
455 | ||
456 | case VIDEO_PALETTE_RGB24: | |
457 | reg |= ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_Pack24; | |
458 | break; | |
459 | ||
460 | case VIDEO_PALETTE_RGB32: | |
461 | reg |= ZR36057_VFESPFR_RGB888; | |
462 | break; | |
463 | ||
464 | default: | |
465 | dprintk(1, | |
466 | KERN_INFO "%s: set_vfe() - unknown color_fmt=%x\n", | |
467 | ZR_DEVNAME(zr), format->palette); | |
468 | return; | |
469 | ||
470 | } | |
471 | if (HorDcm >= 48) { | |
472 | reg |= 3 << ZR36057_VFESPFR_HFilter; /* 5 tap filter */ | |
473 | } else if (HorDcm >= 32) { | |
474 | reg |= 2 << ZR36057_VFESPFR_HFilter; /* 4 tap filter */ | |
475 | } else if (HorDcm >= 16) { | |
476 | reg |= 1 << ZR36057_VFESPFR_HFilter; /* 3 tap filter */ | |
477 | } | |
478 | btwrite(reg, ZR36057_VFESPFR); | |
479 | ||
480 | /* display configuration */ | |
481 | reg = (16 << ZR36057_VDCR_MinPix) | |
482 | | (VidWinHt << ZR36057_VDCR_VidWinHt) | |
483 | | (VidWinWid << ZR36057_VDCR_VidWinWid); | |
484 | if (pci_pci_problems & PCIPCI_TRITON) | |
485 | // || zr->revision < 1) // Revision 1 has also Triton support | |
486 | reg &= ~ZR36057_VDCR_Triton; | |
487 | else | |
488 | reg |= ZR36057_VDCR_Triton; | |
489 | btwrite(reg, ZR36057_VDCR); | |
490 | ||
491 | /* (Ronald) don't write this if overlay_mask = NULL */ | |
492 | if (zr->overlay_mask) { | |
493 | /* Write overlay clipping mask data, but don't enable overlay clipping */ | |
d56410e0 | 494 | /* RJ: since this makes only sense on the screen, we use |
1da177e4 LT |
495 | * zr->overlay_settings.width instead of video_width */ |
496 | ||
497 | mask_line_size = (BUZ_MAX_WIDTH + 31) / 32; | |
498 | reg = virt_to_bus(zr->overlay_mask); | |
499 | btwrite(reg, ZR36057_MMTR); | |
500 | reg = virt_to_bus(zr->overlay_mask + mask_line_size); | |
501 | btwrite(reg, ZR36057_MMBR); | |
502 | reg = | |
503 | mask_line_size - (zr->overlay_settings.width + | |
504 | 31) / 32; | |
505 | if (DispMode == 0) | |
506 | reg += mask_line_size; | |
507 | reg <<= ZR36057_OCR_MaskStride; | |
508 | btwrite(reg, ZR36057_OCR); | |
509 | } | |
510 | ||
511 | zr36057_adjust_vfe(zr, zr->codec_mode); | |
512 | } | |
513 | ||
514 | /* | |
515 | * Switch overlay on or off | |
516 | */ | |
517 | ||
518 | void | |
519 | zr36057_overlay (struct zoran *zr, | |
520 | int on) | |
521 | { | |
522 | u32 reg; | |
523 | ||
524 | if (on) { | |
525 | /* do the necessary settings ... */ | |
526 | btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); /* switch it off first */ | |
527 | ||
528 | zr36057_set_vfe(zr, | |
529 | zr->overlay_settings.width, | |
530 | zr->overlay_settings.height, | |
531 | zr->overlay_settings.format); | |
532 | ||
533 | /* Start and length of each line MUST be 4-byte aligned. | |
534 | * This should be allready checked before the call to this routine. | |
535 | * All error messages are internal driver checking only! */ | |
536 | ||
537 | /* video display top and bottom registers */ | |
d6144028 | 538 | reg = (long) zr->buffer.base + |
1da177e4 LT |
539 | zr->overlay_settings.x * |
540 | ((zr->overlay_settings.format->depth + 7) / 8) + | |
541 | zr->overlay_settings.y * | |
542 | zr->buffer.bytesperline; | |
543 | btwrite(reg, ZR36057_VDTR); | |
544 | if (reg & 3) | |
545 | dprintk(1, | |
546 | KERN_ERR | |
547 | "%s: zr36057_overlay() - video_address not aligned\n", | |
548 | ZR_DEVNAME(zr)); | |
549 | if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2) | |
550 | reg += zr->buffer.bytesperline; | |
551 | btwrite(reg, ZR36057_VDBR); | |
552 | ||
553 | /* video stride, status, and frame grab register */ | |
554 | reg = zr->buffer.bytesperline - | |
555 | zr->overlay_settings.width * | |
556 | ((zr->overlay_settings.format->depth + 7) / 8); | |
557 | if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2) | |
558 | reg += zr->buffer.bytesperline; | |
559 | if (reg & 3) | |
560 | dprintk(1, | |
561 | KERN_ERR | |
562 | "%s: zr36057_overlay() - video_stride not aligned\n", | |
563 | ZR_DEVNAME(zr)); | |
564 | reg = (reg << ZR36057_VSSFGR_DispStride); | |
565 | reg |= ZR36057_VSSFGR_VidOvf; /* clear overflow status */ | |
566 | btwrite(reg, ZR36057_VSSFGR); | |
567 | ||
568 | /* Set overlay clipping */ | |
569 | if (zr->overlay_settings.clipcount > 0) | |
570 | btor(ZR36057_OCR_OvlEnable, ZR36057_OCR); | |
571 | ||
572 | /* ... and switch it on */ | |
573 | btor(ZR36057_VDCR_VidEn, ZR36057_VDCR); | |
574 | } else { | |
575 | /* Switch it off */ | |
576 | btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); | |
577 | } | |
578 | } | |
579 | ||
580 | /* | |
581 | * The overlay mask has one bit for each pixel on a scan line, | |
582 | * and the maximum window size is BUZ_MAX_WIDTH * BUZ_MAX_HEIGHT pixels. | |
583 | */ | |
584 | ||
585 | void | |
586 | write_overlay_mask (struct file *file, | |
587 | struct video_clip *vp, | |
588 | int count) | |
589 | { | |
590 | struct zoran_fh *fh = file->private_data; | |
591 | struct zoran *zr = fh->zr; | |
592 | unsigned mask_line_size = (BUZ_MAX_WIDTH + 31) / 32; | |
593 | u32 *mask; | |
594 | int x, y, width, height; | |
595 | unsigned i, j, k; | |
596 | u32 reg; | |
597 | ||
598 | /* fill mask with one bits */ | |
599 | memset(fh->overlay_mask, ~0, mask_line_size * 4 * BUZ_MAX_HEIGHT); | |
600 | reg = 0; | |
601 | ||
602 | for (i = 0; i < count; ++i) { | |
603 | /* pick up local copy of clip */ | |
604 | x = vp[i].x; | |
605 | y = vp[i].y; | |
606 | width = vp[i].width; | |
607 | height = vp[i].height; | |
608 | ||
609 | /* trim clips that extend beyond the window */ | |
610 | if (x < 0) { | |
611 | width += x; | |
612 | x = 0; | |
613 | } | |
614 | if (y < 0) { | |
615 | height += y; | |
616 | y = 0; | |
617 | } | |
618 | if (x + width > fh->overlay_settings.width) { | |
619 | width = fh->overlay_settings.width - x; | |
620 | } | |
621 | if (y + height > fh->overlay_settings.height) { | |
622 | height = fh->overlay_settings.height - y; | |
623 | } | |
624 | ||
625 | /* ignore degenerate clips */ | |
626 | if (height <= 0) { | |
627 | continue; | |
628 | } | |
629 | if (width <= 0) { | |
630 | continue; | |
631 | } | |
632 | ||
633 | /* apply clip for each scan line */ | |
634 | for (j = 0; j < height; ++j) { | |
635 | /* reset bit for each pixel */ | |
636 | /* this can be optimized later if need be */ | |
637 | mask = fh->overlay_mask + (y + j) * mask_line_size; | |
638 | for (k = 0; k < width; ++k) { | |
639 | mask[(x + k) / 32] &= | |
640 | ~((u32) 1 << (x + k) % 32); | |
641 | } | |
642 | } | |
643 | } | |
644 | } | |
645 | ||
646 | /* Enable/Disable uncompressed memory grabbing of the 36057 */ | |
647 | ||
648 | void | |
649 | zr36057_set_memgrab (struct zoran *zr, | |
650 | int mode) | |
651 | { | |
652 | if (mode) { | |
653 | if (btread(ZR36057_VSSFGR) & | |
654 | (ZR36057_VSSFGR_SnapShot | ZR36057_VSSFGR_FrameGrab)) | |
655 | dprintk(1, | |
656 | KERN_WARNING | |
657 | "%s: zr36057_set_memgrab(1) with SnapShot or FrameGrab on!?\n", | |
658 | ZR_DEVNAME(zr)); | |
659 | ||
660 | /* switch on VSync interrupts */ | |
661 | btwrite(IRQ_MASK, ZR36057_ISR); // Clear Interrupts | |
662 | btor(zr->card.vsync_int, ZR36057_ICR); // SW | |
663 | ||
664 | /* enable SnapShot */ | |
665 | btor(ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR); | |
666 | ||
667 | /* Set zr36057 video front end and enable video */ | |
668 | zr36057_set_vfe(zr, zr->v4l_settings.width, | |
669 | zr->v4l_settings.height, | |
670 | zr->v4l_settings.format); | |
671 | ||
672 | zr->v4l_memgrab_active = 1; | |
673 | } else { | |
674 | zr->v4l_memgrab_active = 0; | |
675 | ||
676 | /* switch off VSync interrupts */ | |
677 | btand(~zr->card.vsync_int, ZR36057_ICR); // SW | |
678 | ||
679 | /* reenable grabbing to screen if it was running */ | |
680 | if (zr->v4l_overlay_active) { | |
681 | zr36057_overlay(zr, 1); | |
682 | } else { | |
683 | btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); | |
684 | btand(~ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR); | |
685 | } | |
686 | } | |
687 | } | |
688 | ||
689 | int | |
690 | wait_grab_pending (struct zoran *zr) | |
691 | { | |
692 | unsigned long flags; | |
693 | ||
694 | /* wait until all pending grabs are finished */ | |
695 | ||
696 | if (!zr->v4l_memgrab_active) | |
697 | return 0; | |
698 | ||
699 | wait_event_interruptible(zr->v4l_capq, | |
700 | (zr->v4l_pend_tail == zr->v4l_pend_head)); | |
701 | if (signal_pending(current)) | |
702 | return -ERESTARTSYS; | |
703 | ||
704 | spin_lock_irqsave(&zr->spinlock, flags); | |
705 | zr36057_set_memgrab(zr, 0); | |
706 | spin_unlock_irqrestore(&zr->spinlock, flags); | |
707 | ||
708 | return 0; | |
709 | } | |
710 | ||
711 | /***************************************************************************** | |
712 | * * | |
713 | * Set up the Buz-specific MJPEG part * | |
714 | * * | |
715 | *****************************************************************************/ | |
716 | ||
717 | static inline void | |
718 | set_frame (struct zoran *zr, | |
719 | int val) | |
720 | { | |
721 | GPIO(zr, zr->card.gpio[GPIO_JPEG_FRAME], val); | |
722 | } | |
723 | ||
724 | static void | |
725 | set_videobus_dir (struct zoran *zr, | |
726 | int val) | |
727 | { | |
728 | switch (zr->card.type) { | |
729 | case LML33: | |
730 | case LML33R10: | |
731 | if (lml33dpath == 0) | |
732 | GPIO(zr, 5, val); | |
733 | else | |
734 | GPIO(zr, 5, 1); | |
735 | break; | |
736 | default: | |
737 | GPIO(zr, zr->card.gpio[GPIO_VID_DIR], | |
738 | zr->card.gpio_pol[GPIO_VID_DIR] ? !val : val); | |
739 | break; | |
740 | } | |
741 | } | |
742 | ||
743 | static void | |
744 | init_jpeg_queue (struct zoran *zr) | |
745 | { | |
746 | int i; | |
747 | ||
748 | /* re-initialize DMA ring stuff */ | |
749 | zr->jpg_que_head = 0; | |
750 | zr->jpg_dma_head = 0; | |
751 | zr->jpg_dma_tail = 0; | |
752 | zr->jpg_que_tail = 0; | |
753 | zr->jpg_seq_num = 0; | |
754 | zr->JPEG_error = 0; | |
755 | zr->num_errors = 0; | |
756 | zr->jpg_err_seq = 0; | |
757 | zr->jpg_err_shift = 0; | |
758 | zr->jpg_queued_num = 0; | |
759 | for (i = 0; i < zr->jpg_buffers.num_buffers; i++) { | |
760 | zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ | |
761 | } | |
762 | for (i = 0; i < BUZ_NUM_STAT_COM; i++) { | |
763 | zr->stat_com[i] = cpu_to_le32(1); /* mark as unavailable to zr36057 */ | |
764 | } | |
765 | } | |
766 | ||
767 | static void | |
768 | zr36057_set_jpg (struct zoran *zr, | |
769 | enum zoran_codec_mode mode) | |
770 | { | |
771 | struct tvnorm *tvn; | |
772 | u32 reg; | |
773 | ||
774 | tvn = zr->timing; | |
775 | ||
776 | /* assert P_Reset, disable code transfer, deassert Active */ | |
777 | btwrite(0, ZR36057_JPC); | |
778 | ||
779 | /* MJPEG compression mode */ | |
780 | switch (mode) { | |
781 | ||
782 | case BUZ_MODE_MOTION_COMPRESS: | |
783 | default: | |
784 | reg = ZR36057_JMC_MJPGCmpMode; | |
785 | break; | |
786 | ||
787 | case BUZ_MODE_MOTION_DECOMPRESS: | |
788 | reg = ZR36057_JMC_MJPGExpMode; | |
789 | reg |= ZR36057_JMC_SyncMstr; | |
790 | /* RJ: The following is experimental - improves the output to screen */ | |
791 | //if(zr->jpg_settings.VFIFO_FB) reg |= ZR36057_JMC_VFIFO_FB; // No, it doesn't. SM | |
792 | break; | |
793 | ||
794 | case BUZ_MODE_STILL_COMPRESS: | |
795 | reg = ZR36057_JMC_JPGCmpMode; | |
796 | break; | |
797 | ||
798 | case BUZ_MODE_STILL_DECOMPRESS: | |
799 | reg = ZR36057_JMC_JPGExpMode; | |
800 | break; | |
801 | ||
802 | } | |
803 | reg |= ZR36057_JMC_JPG; | |
804 | if (zr->jpg_settings.field_per_buff == 1) | |
805 | reg |= ZR36057_JMC_Fld_per_buff; | |
806 | btwrite(reg, ZR36057_JMC); | |
807 | ||
808 | /* vertical */ | |
809 | btor(ZR36057_VFEVCR_VSPol, ZR36057_VFEVCR); | |
810 | reg = (6 << ZR36057_VSP_VsyncSize) | | |
811 | (tvn->Ht << ZR36057_VSP_FrmTot); | |
812 | btwrite(reg, ZR36057_VSP); | |
813 | reg = ((zr->jpg_settings.img_y + tvn->VStart) << ZR36057_FVAP_NAY) | | |
814 | (zr->jpg_settings.img_height << ZR36057_FVAP_PAY); | |
815 | btwrite(reg, ZR36057_FVAP); | |
816 | ||
817 | /* horizontal */ | |
818 | if (zr->card.vfe_pol.hsync_pol) | |
819 | btor(ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR); | |
820 | else | |
d56410e0 | 821 | btand(~ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR); |
1da177e4 LT |
822 | reg = ((tvn->HSyncStart) << ZR36057_HSP_HsyncStart) | |
823 | (tvn->Wt << ZR36057_HSP_LineTot); | |
824 | btwrite(reg, ZR36057_HSP); | |
825 | reg = ((zr->jpg_settings.img_x + | |
d56410e0 | 826 | tvn->HStart + 4) << ZR36057_FHAP_NAX) | |
1da177e4 LT |
827 | (zr->jpg_settings.img_width << ZR36057_FHAP_PAX); |
828 | btwrite(reg, ZR36057_FHAP); | |
829 | ||
830 | /* field process parameters */ | |
831 | if (zr->jpg_settings.odd_even) | |
832 | reg = ZR36057_FPP_Odd_Even; | |
833 | else | |
834 | reg = 0; | |
835 | ||
836 | btwrite(reg, ZR36057_FPP); | |
837 | ||
838 | /* Set proper VCLK Polarity, else colors will be wrong during playback */ | |
839 | //btor(ZR36057_VFESPFR_VCLKPol, ZR36057_VFESPFR); | |
840 | ||
841 | /* code base address */ | |
842 | reg = virt_to_bus(zr->stat_com); | |
843 | btwrite(reg, ZR36057_JCBA); | |
844 | ||
845 | /* FIFO threshold (FIFO is 160. double words) */ | |
846 | /* NOTE: decimal values here */ | |
847 | switch (mode) { | |
848 | ||
849 | case BUZ_MODE_STILL_COMPRESS: | |
850 | case BUZ_MODE_MOTION_COMPRESS: | |
851 | if (zr->card.type != BUZ) | |
852 | reg = 140; | |
853 | else | |
854 | reg = 60; | |
855 | break; | |
856 | ||
857 | case BUZ_MODE_STILL_DECOMPRESS: | |
858 | case BUZ_MODE_MOTION_DECOMPRESS: | |
859 | reg = 20; | |
860 | break; | |
861 | ||
862 | default: | |
863 | reg = 80; | |
864 | break; | |
865 | ||
866 | } | |
867 | btwrite(reg, ZR36057_JCFT); | |
868 | zr36057_adjust_vfe(zr, mode); | |
869 | ||
870 | } | |
871 | ||
872 | void | |
873 | print_interrupts (struct zoran *zr) | |
874 | { | |
875 | int res, noerr = 0; | |
876 | ||
877 | printk(KERN_INFO "%s: interrupts received:", ZR_DEVNAME(zr)); | |
878 | if ((res = zr->field_counter) < -1 || res > 1) { | |
879 | printk(" FD:%d", res); | |
880 | } | |
881 | if ((res = zr->intr_counter_GIRQ1) != 0) { | |
882 | printk(" GIRQ1:%d", res); | |
883 | noerr++; | |
884 | } | |
885 | if ((res = zr->intr_counter_GIRQ0) != 0) { | |
886 | printk(" GIRQ0:%d", res); | |
887 | noerr++; | |
888 | } | |
889 | if ((res = zr->intr_counter_CodRepIRQ) != 0) { | |
890 | printk(" CodRepIRQ:%d", res); | |
891 | noerr++; | |
892 | } | |
893 | if ((res = zr->intr_counter_JPEGRepIRQ) != 0) { | |
894 | printk(" JPEGRepIRQ:%d", res); | |
895 | noerr++; | |
896 | } | |
897 | if (zr->JPEG_max_missed) { | |
898 | printk(" JPEG delays: max=%d min=%d", zr->JPEG_max_missed, | |
899 | zr->JPEG_min_missed); | |
900 | } | |
901 | if (zr->END_event_missed) { | |
902 | printk(" ENDs missed: %d", zr->END_event_missed); | |
903 | } | |
904 | //if (zr->jpg_queued_num) { | |
905 | printk(" queue_state=%ld/%ld/%ld/%ld", zr->jpg_que_tail, | |
906 | zr->jpg_dma_tail, zr->jpg_dma_head, zr->jpg_que_head); | |
907 | //} | |
908 | if (!noerr) { | |
909 | printk(": no interrupts detected."); | |
910 | } | |
911 | printk("\n"); | |
912 | } | |
913 | ||
914 | void | |
915 | clear_interrupt_counters (struct zoran *zr) | |
916 | { | |
917 | zr->intr_counter_GIRQ1 = 0; | |
918 | zr->intr_counter_GIRQ0 = 0; | |
919 | zr->intr_counter_CodRepIRQ = 0; | |
920 | zr->intr_counter_JPEGRepIRQ = 0; | |
921 | zr->field_counter = 0; | |
922 | zr->IRQ1_in = 0; | |
923 | zr->IRQ1_out = 0; | |
924 | zr->JPEG_in = 0; | |
925 | zr->JPEG_out = 0; | |
926 | zr->JPEG_0 = 0; | |
927 | zr->JPEG_1 = 0; | |
928 | zr->END_event_missed = 0; | |
929 | zr->JPEG_missed = 0; | |
930 | zr->JPEG_max_missed = 0; | |
931 | zr->JPEG_min_missed = 0x7fffffff; | |
932 | } | |
933 | ||
934 | static u32 | |
935 | count_reset_interrupt (struct zoran *zr) | |
936 | { | |
937 | u32 isr; | |
938 | ||
939 | if ((isr = btread(ZR36057_ISR) & 0x78000000)) { | |
940 | if (isr & ZR36057_ISR_GIRQ1) { | |
941 | btwrite(ZR36057_ISR_GIRQ1, ZR36057_ISR); | |
942 | zr->intr_counter_GIRQ1++; | |
943 | } | |
944 | if (isr & ZR36057_ISR_GIRQ0) { | |
945 | btwrite(ZR36057_ISR_GIRQ0, ZR36057_ISR); | |
946 | zr->intr_counter_GIRQ0++; | |
947 | } | |
948 | if (isr & ZR36057_ISR_CodRepIRQ) { | |
949 | btwrite(ZR36057_ISR_CodRepIRQ, ZR36057_ISR); | |
950 | zr->intr_counter_CodRepIRQ++; | |
951 | } | |
952 | if (isr & ZR36057_ISR_JPEGRepIRQ) { | |
953 | btwrite(ZR36057_ISR_JPEGRepIRQ, ZR36057_ISR); | |
954 | zr->intr_counter_JPEGRepIRQ++; | |
955 | } | |
956 | } | |
957 | return isr; | |
958 | } | |
959 | ||
960 | /* hack */ | |
961 | extern void zr36016_write (struct videocodec *codec, | |
962 | u16 reg, | |
963 | u32 val); | |
964 | ||
965 | void | |
966 | jpeg_start (struct zoran *zr) | |
967 | { | |
968 | int reg; | |
969 | ||
970 | zr->frame_num = 0; | |
971 | ||
972 | /* deassert P_reset, disable code transfer, deassert Active */ | |
973 | btwrite(ZR36057_JPC_P_Reset, ZR36057_JPC); | |
974 | /* stop flushing the internal code buffer */ | |
975 | btand(~ZR36057_MCTCR_CFlush, ZR36057_MCTCR); | |
976 | /* enable code transfer */ | |
977 | btor(ZR36057_JPC_CodTrnsEn, ZR36057_JPC); | |
978 | ||
979 | /* clear IRQs */ | |
980 | btwrite(IRQ_MASK, ZR36057_ISR); | |
981 | /* enable the JPEG IRQs */ | |
982 | btwrite(zr->card.jpeg_int | | |
983 | ZR36057_ICR_JPEGRepIRQ | | |
984 | ZR36057_ICR_IntPinEn, | |
985 | ZR36057_ICR); | |
986 | ||
987 | set_frame(zr, 0); // \FRAME | |
988 | ||
989 | /* set the JPEG codec guest ID */ | |
990 | reg = (zr->card.gpcs[1] << ZR36057_JCGI_JPEGuestID) | | |
991 | (0 << ZR36057_JCGI_JPEGuestReg); | |
992 | btwrite(reg, ZR36057_JCGI); | |
993 | ||
994 | if (zr->card.video_vfe == CODEC_TYPE_ZR36016 && | |
995 | zr->card.video_codec == CODEC_TYPE_ZR36050) { | |
996 | /* Enable processing on the ZR36016 */ | |
997 | if (zr->vfe) | |
998 | zr36016_write(zr->vfe, 0, 1); | |
999 | ||
1000 | /* load the address of the GO register in the ZR36050 latch */ | |
1001 | post_office_write(zr, 0, 0, 0); | |
1002 | } | |
1003 | ||
1004 | /* assert Active */ | |
1005 | btor(ZR36057_JPC_Active, ZR36057_JPC); | |
1006 | ||
1007 | /* enable the Go generation */ | |
1008 | btor(ZR36057_JMC_Go_en, ZR36057_JMC); | |
1009 | udelay(30); | |
1010 | ||
1011 | set_frame(zr, 1); // /FRAME | |
1012 | ||
1013 | dprintk(3, KERN_DEBUG "%s: jpeg_start\n", ZR_DEVNAME(zr)); | |
1014 | } | |
1015 | ||
1016 | void | |
1017 | zr36057_enable_jpg (struct zoran *zr, | |
1018 | enum zoran_codec_mode mode) | |
1019 | { | |
1020 | static int zero = 0; | |
1021 | static int one = 1; | |
1022 | struct vfe_settings cap; | |
1023 | int field_size = | |
1024 | zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff; | |
1025 | ||
1026 | zr->codec_mode = mode; | |
1027 | ||
1028 | cap.x = zr->jpg_settings.img_x; | |
1029 | cap.y = zr->jpg_settings.img_y; | |
1030 | cap.width = zr->jpg_settings.img_width; | |
1031 | cap.height = zr->jpg_settings.img_height; | |
1032 | cap.decimation = | |
1033 | zr->jpg_settings.HorDcm | (zr->jpg_settings.VerDcm << 8); | |
1034 | cap.quality = zr->jpg_settings.jpg_comp.quality; | |
1035 | ||
1036 | switch (mode) { | |
1037 | ||
1038 | case BUZ_MODE_MOTION_COMPRESS: { | |
1039 | struct jpeg_app_marker app; | |
1040 | struct jpeg_com_marker com; | |
1041 | ||
1042 | /* In motion compress mode, the decoder output must be enabled, and | |
1043 | * the video bus direction set to input. | |
1044 | */ | |
1045 | set_videobus_dir(zr, 0); | |
1046 | decoder_command(zr, DECODER_ENABLE_OUTPUT, &one); | |
1047 | encoder_command(zr, ENCODER_SET_INPUT, &zero); | |
1048 | ||
1049 | /* Take the JPEG codec and the VFE out of sleep */ | |
1050 | jpeg_codec_sleep(zr, 0); | |
1051 | ||
1052 | /* set JPEG app/com marker */ | |
1053 | app.appn = zr->jpg_settings.jpg_comp.APPn; | |
1054 | app.len = zr->jpg_settings.jpg_comp.APP_len; | |
1055 | memcpy(app.data, zr->jpg_settings.jpg_comp.APP_data, 60); | |
1056 | zr->codec->control(zr->codec, CODEC_S_JPEG_APP_DATA, | |
1057 | sizeof(struct jpeg_app_marker), &app); | |
1058 | ||
1059 | com.len = zr->jpg_settings.jpg_comp.COM_len; | |
1060 | memcpy(com.data, zr->jpg_settings.jpg_comp.COM_data, 60); | |
1061 | zr->codec->control(zr->codec, CODEC_S_JPEG_COM_DATA, | |
1062 | sizeof(struct jpeg_com_marker), &com); | |
1063 | ||
1064 | /* Setup the JPEG codec */ | |
1065 | zr->codec->control(zr->codec, CODEC_S_JPEG_TDS_BYTE, | |
1066 | sizeof(int), &field_size); | |
1067 | zr->codec->set_video(zr->codec, zr->timing, &cap, | |
1068 | &zr->card.vfe_pol); | |
1069 | zr->codec->set_mode(zr->codec, CODEC_DO_COMPRESSION); | |
1070 | ||
1071 | /* Setup the VFE */ | |
1072 | if (zr->vfe) { | |
1073 | zr->vfe->control(zr->vfe, CODEC_S_JPEG_TDS_BYTE, | |
1074 | sizeof(int), &field_size); | |
1075 | zr->vfe->set_video(zr->vfe, zr->timing, &cap, | |
1076 | &zr->card.vfe_pol); | |
1077 | zr->vfe->set_mode(zr->vfe, CODEC_DO_COMPRESSION); | |
1078 | } | |
1079 | ||
1080 | init_jpeg_queue(zr); | |
1081 | zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO | |
1082 | ||
1083 | clear_interrupt_counters(zr); | |
1084 | dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_COMPRESS)\n", | |
1085 | ZR_DEVNAME(zr)); | |
1086 | break; | |
1087 | } | |
1088 | ||
1089 | case BUZ_MODE_MOTION_DECOMPRESS: | |
1090 | /* In motion decompression mode, the decoder output must be disabled, and | |
1091 | * the video bus direction set to output. | |
1092 | */ | |
1093 | decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero); | |
1094 | set_videobus_dir(zr, 1); | |
1095 | encoder_command(zr, ENCODER_SET_INPUT, &one); | |
1096 | ||
1097 | /* Take the JPEG codec and the VFE out of sleep */ | |
1098 | jpeg_codec_sleep(zr, 0); | |
1099 | /* Setup the VFE */ | |
1100 | if (zr->vfe) { | |
1101 | zr->vfe->set_video(zr->vfe, zr->timing, &cap, | |
1102 | &zr->card.vfe_pol); | |
1103 | zr->vfe->set_mode(zr->vfe, CODEC_DO_EXPANSION); | |
1104 | } | |
1105 | /* Setup the JPEG codec */ | |
1106 | zr->codec->set_video(zr->codec, zr->timing, &cap, | |
1107 | &zr->card.vfe_pol); | |
1108 | zr->codec->set_mode(zr->codec, CODEC_DO_EXPANSION); | |
1109 | ||
1110 | init_jpeg_queue(zr); | |
1111 | zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO | |
1112 | ||
1113 | clear_interrupt_counters(zr); | |
1114 | dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_DECOMPRESS)\n", | |
1115 | ZR_DEVNAME(zr)); | |
1116 | break; | |
1117 | ||
1118 | case BUZ_MODE_IDLE: | |
1119 | default: | |
1120 | /* shut down processing */ | |
1121 | btand(~(zr->card.jpeg_int | ZR36057_ICR_JPEGRepIRQ), | |
1122 | ZR36057_ICR); | |
1123 | btwrite(zr->card.jpeg_int | ZR36057_ICR_JPEGRepIRQ, | |
1124 | ZR36057_ISR); | |
1125 | btand(~ZR36057_JMC_Go_en, ZR36057_JMC); // \Go_en | |
1126 | ||
1127 | msleep(50); | |
1128 | ||
1129 | set_videobus_dir(zr, 0); | |
1130 | set_frame(zr, 1); // /FRAME | |
1131 | btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); // /CFlush | |
1132 | btwrite(0, ZR36057_JPC); // \P_Reset,\CodTrnsEn,\Active | |
1133 | btand(~ZR36057_JMC_VFIFO_FB, ZR36057_JMC); | |
1134 | btand(~ZR36057_JMC_SyncMstr, ZR36057_JMC); | |
1135 | jpeg_codec_reset(zr); | |
1136 | jpeg_codec_sleep(zr, 1); | |
1137 | zr36057_adjust_vfe(zr, mode); | |
1138 | ||
1139 | decoder_command(zr, DECODER_ENABLE_OUTPUT, &one); | |
1140 | encoder_command(zr, ENCODER_SET_INPUT, &zero); | |
1141 | ||
1142 | dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr)); | |
1143 | break; | |
1144 | ||
1145 | } | |
1146 | } | |
1147 | ||
1148 | /* when this is called the spinlock must be held */ | |
1149 | void | |
1150 | zoran_feed_stat_com (struct zoran *zr) | |
1151 | { | |
1152 | /* move frames from pending queue to DMA */ | |
1153 | ||
1154 | int frame, i, max_stat_com; | |
1155 | ||
1156 | max_stat_com = | |
1157 | (zr->jpg_settings.TmpDcm == | |
1158 | 1) ? BUZ_NUM_STAT_COM : (BUZ_NUM_STAT_COM >> 1); | |
1159 | ||
1160 | while ((zr->jpg_dma_head - zr->jpg_dma_tail) < max_stat_com && | |
1161 | zr->jpg_dma_head < zr->jpg_que_head) { | |
1162 | ||
1163 | frame = zr->jpg_pend[zr->jpg_dma_head & BUZ_MASK_FRAME]; | |
1164 | if (zr->jpg_settings.TmpDcm == 1) { | |
1165 | /* fill 1 stat_com entry */ | |
1166 | i = (zr->jpg_dma_head - | |
1167 | zr->jpg_err_shift) & BUZ_MASK_STAT_COM; | |
1168 | if (!(zr->stat_com[i] & cpu_to_le32(1))) | |
1169 | break; | |
1170 | zr->stat_com[i] = | |
1171 | cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus); | |
1172 | } else { | |
1173 | /* fill 2 stat_com entries */ | |
1174 | i = ((zr->jpg_dma_head - | |
1175 | zr->jpg_err_shift) & 1) * 2; | |
1176 | if (!(zr->stat_com[i] & cpu_to_le32(1))) | |
1177 | break; | |
1178 | zr->stat_com[i] = | |
1179 | cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus); | |
1180 | zr->stat_com[i + 1] = | |
1181 | cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus); | |
1182 | } | |
1183 | zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA; | |
1184 | zr->jpg_dma_head++; | |
1185 | ||
1186 | } | |
1187 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) | |
1188 | zr->jpg_queued_num++; | |
1189 | } | |
1190 | ||
1191 | /* when this is called the spinlock must be held */ | |
1192 | static void | |
1193 | zoran_reap_stat_com (struct zoran *zr) | |
1194 | { | |
1195 | /* move frames from DMA queue to done queue */ | |
1196 | ||
1197 | int i; | |
1198 | u32 stat_com; | |
1199 | unsigned int seq; | |
1200 | unsigned int dif; | |
1201 | struct zoran_jpg_buffer *buffer; | |
1202 | int frame; | |
1203 | ||
1204 | /* In motion decompress we don't have a hardware frame counter, | |
1205 | * we just count the interrupts here */ | |
1206 | ||
1207 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { | |
1208 | zr->jpg_seq_num++; | |
1209 | } | |
1210 | while (zr->jpg_dma_tail < zr->jpg_dma_head) { | |
1211 | if (zr->jpg_settings.TmpDcm == 1) | |
1212 | i = (zr->jpg_dma_tail - | |
1213 | zr->jpg_err_shift) & BUZ_MASK_STAT_COM; | |
1214 | else | |
1215 | i = ((zr->jpg_dma_tail - | |
1216 | zr->jpg_err_shift) & 1) * 2 + 1; | |
1217 | ||
1218 | stat_com = le32_to_cpu(zr->stat_com[i]); | |
1219 | ||
1220 | if ((stat_com & 1) == 0) { | |
1221 | return; | |
1222 | } | |
1223 | frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; | |
1224 | buffer = &zr->jpg_buffers.buffer[frame]; | |
1225 | do_gettimeofday(&buffer->bs.timestamp); | |
1226 | ||
1227 | if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { | |
1228 | buffer->bs.length = (stat_com & 0x7fffff) >> 1; | |
1229 | ||
1230 | /* update sequence number with the help of the counter in stat_com */ | |
1231 | ||
1232 | seq = ((stat_com >> 24) + zr->jpg_err_seq) & 0xff; | |
1233 | dif = (seq - zr->jpg_seq_num) & 0xff; | |
1234 | zr->jpg_seq_num += dif; | |
1235 | } else { | |
1236 | buffer->bs.length = 0; | |
1237 | } | |
1238 | buffer->bs.seq = | |
1239 | zr->jpg_settings.TmpDcm == | |
1240 | 2 ? (zr->jpg_seq_num >> 1) : zr->jpg_seq_num; | |
1241 | buffer->state = BUZ_STATE_DONE; | |
1242 | ||
1243 | zr->jpg_dma_tail++; | |
1244 | } | |
1245 | } | |
1246 | ||
1247 | static void | |
1248 | error_handler (struct zoran *zr, | |
1249 | u32 astat, | |
1250 | u32 stat) | |
1251 | { | |
1252 | /* This is JPEG error handling part */ | |
1253 | if ((zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) && | |
1254 | (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS)) { | |
1255 | //dprintk(1, KERN_ERR "%s: Internal error: error handling request in mode %d\n", ZR_DEVNAME(zr), zr->codec_mode); | |
1256 | return; | |
1257 | } | |
1258 | ||
1259 | if ((stat & 1) == 0 && | |
1260 | zr->codec_mode == BUZ_MODE_MOTION_COMPRESS && | |
1261 | zr->jpg_dma_tail - zr->jpg_que_tail >= | |
1262 | zr->jpg_buffers.num_buffers) { | |
1263 | /* No free buffers... */ | |
1264 | zoran_reap_stat_com(zr); | |
1265 | zoran_feed_stat_com(zr); | |
1266 | wake_up_interruptible(&zr->jpg_capq); | |
1267 | zr->JPEG_missed = 0; | |
1268 | return; | |
1269 | } | |
1270 | ||
1271 | if (zr->JPEG_error != 1) { | |
1272 | /* | |
1273 | * First entry: error just happened during normal operation | |
d56410e0 | 1274 | * |
1da177e4 | 1275 | * In BUZ_MODE_MOTION_COMPRESS: |
d56410e0 | 1276 | * |
1da177e4 LT |
1277 | * Possible glitch in TV signal. In this case we should |
1278 | * stop the codec and wait for good quality signal before | |
1279 | * restarting it to avoid further problems | |
d56410e0 | 1280 | * |
1da177e4 | 1281 | * In BUZ_MODE_MOTION_DECOMPRESS: |
d56410e0 | 1282 | * |
1da177e4 LT |
1283 | * Bad JPEG frame: we have to mark it as processed (codec crashed |
1284 | * and was not able to do it itself), and to remove it from queue. | |
1285 | */ | |
1286 | btand(~ZR36057_JMC_Go_en, ZR36057_JMC); | |
1287 | udelay(1); | |
1288 | stat = stat | (post_office_read(zr, 7, 0) & 3) << 8; | |
1289 | btwrite(0, ZR36057_JPC); | |
1290 | btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); | |
1291 | jpeg_codec_reset(zr); | |
1292 | jpeg_codec_sleep(zr, 1); | |
1293 | zr->JPEG_error = 1; | |
1294 | zr->num_errors++; | |
1295 | ||
1296 | /* Report error */ | |
1297 | if (*zr_debug > 1 && zr->num_errors <= 8) { | |
1298 | long frame; | |
1299 | frame = | |
1300 | zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; | |
1301 | printk(KERN_ERR | |
1302 | "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ", | |
1303 | ZR_DEVNAME(zr), stat, zr->last_isr, | |
1304 | zr->jpg_que_tail, zr->jpg_dma_tail, | |
1305 | zr->jpg_dma_head, zr->jpg_que_head, | |
1306 | zr->jpg_seq_num, frame); | |
1307 | printk("stat_com frames:"); | |
1308 | { | |
1309 | int i, j; | |
1310 | for (j = 0; j < BUZ_NUM_STAT_COM; j++) { | |
1311 | for (i = 0; | |
1312 | i < zr->jpg_buffers.num_buffers; | |
1313 | i++) { | |
1314 | if (le32_to_cpu(zr->stat_com[j]) == | |
1315 | zr->jpg_buffers. | |
1316 | buffer[i]. | |
1317 | frag_tab_bus) { | |
1318 | printk("% d->%d", | |
1319 | j, i); | |
1320 | } | |
1321 | } | |
1322 | } | |
1323 | printk("\n"); | |
1324 | } | |
1325 | } | |
1326 | /* Find an entry in stat_com and rotate contents */ | |
1327 | { | |
1328 | int i; | |
1329 | ||
1330 | if (zr->jpg_settings.TmpDcm == 1) | |
1331 | i = (zr->jpg_dma_tail - | |
1332 | zr->jpg_err_shift) & BUZ_MASK_STAT_COM; | |
1333 | else | |
1334 | i = ((zr->jpg_dma_tail - | |
1335 | zr->jpg_err_shift) & 1) * 2; | |
1336 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { | |
1337 | /* Mimic zr36067 operation */ | |
1338 | zr->stat_com[i] |= cpu_to_le32(1); | |
1339 | if (zr->jpg_settings.TmpDcm != 1) | |
1340 | zr->stat_com[i + 1] |= cpu_to_le32(1); | |
1341 | /* Refill */ | |
1342 | zoran_reap_stat_com(zr); | |
1343 | zoran_feed_stat_com(zr); | |
1344 | wake_up_interruptible(&zr->jpg_capq); | |
1345 | /* Find an entry in stat_com again after refill */ | |
1346 | if (zr->jpg_settings.TmpDcm == 1) | |
1347 | i = (zr->jpg_dma_tail - | |
1348 | zr->jpg_err_shift) & | |
1349 | BUZ_MASK_STAT_COM; | |
1350 | else | |
1351 | i = ((zr->jpg_dma_tail - | |
1352 | zr->jpg_err_shift) & 1) * 2; | |
1353 | } | |
1354 | if (i) { | |
1355 | /* Rotate stat_comm entries to make current entry first */ | |
1356 | int j; | |
1357 | u32 bus_addr[BUZ_NUM_STAT_COM]; | |
1358 | ||
1359 | /* Here we are copying the stat_com array, which | |
1360 | * is already in little endian format, so | |
1361 | * no endian conversions here | |
1362 | */ | |
1363 | memcpy(bus_addr, zr->stat_com, | |
1364 | sizeof(bus_addr)); | |
1365 | for (j = 0; j < BUZ_NUM_STAT_COM; j++) { | |
1366 | zr->stat_com[j] = | |
1367 | bus_addr[(i + j) & | |
1368 | BUZ_MASK_STAT_COM]; | |
1369 | ||
1370 | } | |
1371 | zr->jpg_err_shift += i; | |
1372 | zr->jpg_err_shift &= BUZ_MASK_STAT_COM; | |
1373 | } | |
1374 | if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) | |
1375 | zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */ | |
1376 | } | |
1377 | } | |
1378 | ||
1379 | /* Now the stat_comm buffer is ready for restart */ | |
1380 | do { | |
1381 | int status, mode; | |
1382 | ||
1383 | if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { | |
1384 | decoder_command(zr, DECODER_GET_STATUS, &status); | |
1385 | mode = CODEC_DO_COMPRESSION; | |
1386 | } else { | |
1387 | status = 0; | |
1388 | mode = CODEC_DO_EXPANSION; | |
1389 | } | |
1390 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || | |
1391 | (status & DECODER_STATUS_GOOD)) { | |
1392 | /********** RESTART code *************/ | |
1393 | jpeg_codec_reset(zr); | |
1394 | zr->codec->set_mode(zr->codec, mode); | |
1395 | zr36057_set_jpg(zr, zr->codec_mode); | |
1396 | jpeg_start(zr); | |
1397 | ||
1398 | if (zr->num_errors <= 8) | |
1399 | dprintk(2, KERN_INFO "%s: Restart\n", | |
1400 | ZR_DEVNAME(zr)); | |
1401 | ||
1402 | zr->JPEG_missed = 0; | |
1403 | zr->JPEG_error = 2; | |
1404 | /********** End RESTART code ***********/ | |
1405 | } | |
1406 | } while (0); | |
1407 | } | |
1408 | ||
1409 | irqreturn_t | |
1410 | zoran_irq (int irq, | |
1411 | void *dev_id, | |
1412 | struct pt_regs *regs) | |
1413 | { | |
1414 | u32 stat, astat; | |
1415 | int count; | |
1416 | struct zoran *zr; | |
1417 | unsigned long flags; | |
1418 | ||
1419 | zr = (struct zoran *) dev_id; | |
1420 | count = 0; | |
1421 | ||
1422 | if (zr->testing) { | |
1423 | /* Testing interrupts */ | |
1424 | spin_lock_irqsave(&zr->spinlock, flags); | |
1425 | while ((stat = count_reset_interrupt(zr))) { | |
1426 | if (count++ > 100) { | |
1427 | btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR); | |
1428 | dprintk(1, | |
1429 | KERN_ERR | |
1430 | "%s: IRQ lockup while testing, isr=0x%08x, cleared int mask\n", | |
1431 | ZR_DEVNAME(zr), stat); | |
1432 | wake_up_interruptible(&zr->test_q); | |
1433 | } | |
1434 | } | |
1435 | zr->last_isr = stat; | |
1436 | spin_unlock_irqrestore(&zr->spinlock, flags); | |
1437 | return IRQ_HANDLED; | |
1438 | } | |
1439 | ||
1440 | spin_lock_irqsave(&zr->spinlock, flags); | |
1441 | while (1) { | |
1442 | /* get/clear interrupt status bits */ | |
1443 | stat = count_reset_interrupt(zr); | |
1444 | astat = stat & IRQ_MASK; | |
1445 | if (!astat) { | |
1446 | break; | |
1447 | } | |
1448 | dprintk(4, | |
1449 | KERN_DEBUG | |
1450 | "zoran_irq: astat: 0x%08x, mask: 0x%08x\n", | |
1451 | astat, btread(ZR36057_ICR)); | |
1452 | if (astat & zr->card.vsync_int) { // SW | |
1453 | ||
1454 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || | |
1455 | zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { | |
1456 | /* count missed interrupts */ | |
1457 | zr->JPEG_missed++; | |
1458 | } | |
1459 | //post_office_read(zr,1,0); | |
1460 | /* Interrupts may still happen when | |
1461 | * zr->v4l_memgrab_active is switched off. | |
1462 | * We simply ignore them */ | |
1463 | ||
1464 | if (zr->v4l_memgrab_active) { | |
1465 | ||
1466 | /* A lot more checks should be here ... */ | |
1467 | if ((btread(ZR36057_VSSFGR) & | |
1468 | ZR36057_VSSFGR_SnapShot) == 0) | |
1469 | dprintk(1, | |
1470 | KERN_WARNING | |
1471 | "%s: BuzIRQ with SnapShot off ???\n", | |
1472 | ZR_DEVNAME(zr)); | |
1473 | ||
1474 | if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) { | |
1475 | /* There is a grab on a frame going on, check if it has finished */ | |
1476 | ||
1477 | if ((btread(ZR36057_VSSFGR) & | |
1478 | ZR36057_VSSFGR_FrameGrab) == | |
1479 | 0) { | |
1480 | /* it is finished, notify the user */ | |
1481 | ||
1482 | zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE; | |
1483 | zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.seq = zr->v4l_grab_seq; | |
1484 | do_gettimeofday(&zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.timestamp); | |
1485 | zr->v4l_grab_frame = NO_GRAB_ACTIVE; | |
1486 | zr->v4l_pend_tail++; | |
1487 | } | |
1488 | } | |
1489 | ||
1490 | if (zr->v4l_grab_frame == NO_GRAB_ACTIVE) | |
1491 | wake_up_interruptible(&zr->v4l_capq); | |
1492 | ||
1493 | /* Check if there is another grab queued */ | |
1494 | ||
1495 | if (zr->v4l_grab_frame == NO_GRAB_ACTIVE && | |
1496 | zr->v4l_pend_tail != zr->v4l_pend_head) { | |
1497 | ||
1498 | int frame = zr->v4l_pend[zr->v4l_pend_tail & | |
1499 | V4L_MASK_FRAME]; | |
1500 | u32 reg; | |
1501 | ||
1502 | zr->v4l_grab_frame = frame; | |
1503 | ||
1504 | /* Set zr36057 video front end and enable video */ | |
1505 | ||
1506 | /* Buffer address */ | |
1507 | ||
1508 | reg = | |
1509 | zr->v4l_buffers.buffer[frame]. | |
1510 | fbuffer_bus; | |
1511 | btwrite(reg, ZR36057_VDTR); | |
1512 | if (zr->v4l_settings.height > | |
1513 | BUZ_MAX_HEIGHT / 2) | |
1514 | reg += | |
1515 | zr->v4l_settings. | |
1516 | bytesperline; | |
1517 | btwrite(reg, ZR36057_VDBR); | |
1518 | ||
1519 | /* video stride, status, and frame grab register */ | |
1520 | reg = 0; | |
1521 | if (zr->v4l_settings.height > | |
1522 | BUZ_MAX_HEIGHT / 2) | |
1523 | reg += | |
1524 | zr->v4l_settings. | |
1525 | bytesperline; | |
1526 | reg = | |
1527 | (reg << | |
1528 | ZR36057_VSSFGR_DispStride); | |
1529 | reg |= ZR36057_VSSFGR_VidOvf; | |
1530 | reg |= ZR36057_VSSFGR_SnapShot; | |
1531 | reg |= ZR36057_VSSFGR_FrameGrab; | |
1532 | btwrite(reg, ZR36057_VSSFGR); | |
1533 | ||
1534 | btor(ZR36057_VDCR_VidEn, | |
1535 | ZR36057_VDCR); | |
1536 | } | |
1537 | } | |
1538 | ||
1539 | /* even if we don't grab, we do want to increment | |
1540 | * the sequence counter to see lost frames */ | |
1541 | zr->v4l_grab_seq++; | |
1542 | } | |
1543 | #if (IRQ_MASK & ZR36057_ISR_CodRepIRQ) | |
1544 | if (astat & ZR36057_ISR_CodRepIRQ) { | |
1545 | zr->intr_counter_CodRepIRQ++; | |
1546 | IDEBUG(printk | |
1547 | (KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", | |
1548 | ZR_DEVNAME(zr))); | |
1549 | btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR); | |
1550 | } | |
1551 | #endif /* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */ | |
1552 | ||
1553 | #if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) | |
1554 | if (astat & ZR36057_ISR_JPEGRepIRQ) { | |
1555 | ||
1556 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || | |
1557 | zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { | |
1558 | if (*zr_debug > 1 && | |
1559 | (!zr->frame_num || zr->JPEG_error)) { | |
1560 | printk(KERN_INFO | |
1561 | "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n", | |
1562 | ZR_DEVNAME(zr), stat, | |
1563 | zr->jpg_settings.odd_even, | |
1564 | zr->jpg_settings. | |
1565 | field_per_buff, | |
1566 | zr->JPEG_missed); | |
1567 | { | |
1568 | char sc[] = "0000"; | |
1569 | char sv[5]; | |
1570 | int i; | |
1571 | strcpy(sv, sc); | |
1572 | for (i = 0; i < 4; i++) { | |
1573 | if (le32_to_cpu(zr->stat_com[i]) & 1) | |
1574 | sv[i] = '1'; | |
1575 | } | |
1576 | sv[4] = 0; | |
1577 | printk(KERN_INFO | |
1578 | "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n", | |
1579 | ZR_DEVNAME(zr), sv, | |
1580 | zr->jpg_que_tail, | |
1581 | zr->jpg_dma_tail, | |
1582 | zr->jpg_dma_head, | |
1583 | zr->jpg_que_head); | |
1584 | } | |
1585 | } else { | |
1586 | if (zr->JPEG_missed > zr->JPEG_max_missed) // Get statistics | |
1587 | zr->JPEG_max_missed = | |
1588 | zr->JPEG_missed; | |
1589 | if (zr->JPEG_missed < | |
1590 | zr->JPEG_min_missed) | |
1591 | zr->JPEG_min_missed = | |
1592 | zr->JPEG_missed; | |
1593 | } | |
1594 | ||
1595 | if (*zr_debug > 2 && zr->frame_num < 6) { | |
1596 | int i; | |
1597 | printk("%s: seq=%ld stat_com:", | |
1598 | ZR_DEVNAME(zr), zr->jpg_seq_num); | |
1599 | for (i = 0; i < 4; i++) { | |
1600 | printk(" %08x", | |
1601 | le32_to_cpu(zr->stat_com[i])); | |
1602 | } | |
1603 | printk("\n"); | |
1604 | } | |
1605 | zr->frame_num++; | |
1606 | zr->JPEG_missed = 0; | |
1607 | zr->JPEG_error = 0; | |
1608 | zoran_reap_stat_com(zr); | |
1609 | zoran_feed_stat_com(zr); | |
1610 | wake_up_interruptible(&zr->jpg_capq); | |
1611 | } /*else { | |
1612 | dprintk(1, | |
1613 | KERN_ERR | |
1614 | "%s: JPEG interrupt while not in motion (de)compress mode!\n", | |
1615 | ZR_DEVNAME(zr)); | |
1616 | }*/ | |
1617 | } | |
1618 | #endif /* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */ | |
1619 | ||
1620 | /* DATERR, too many fields missed, error processing */ | |
1621 | if ((astat & zr->card.jpeg_int) || | |
1622 | zr->JPEG_missed > 25 || | |
1623 | zr->JPEG_error == 1 || | |
1624 | ((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) && | |
1625 | (zr->frame_num & (zr->JPEG_missed > | |
1626 | zr->jpg_settings.field_per_buff)))) { | |
1627 | error_handler(zr, astat, stat); | |
1628 | } | |
1629 | ||
1630 | count++; | |
1631 | if (count > 10) { | |
1632 | dprintk(2, KERN_WARNING "%s: irq loop %d\n", | |
1633 | ZR_DEVNAME(zr), count); | |
1634 | if (count > 20) { | |
1635 | btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR); | |
1636 | dprintk(2, | |
1637 | KERN_ERR | |
1638 | "%s: IRQ lockup, cleared int mask\n", | |
1639 | ZR_DEVNAME(zr)); | |
1640 | break; | |
1641 | } | |
1642 | } | |
1643 | zr->last_isr = stat; | |
1644 | } | |
1645 | spin_unlock_irqrestore(&zr->spinlock, flags); | |
1646 | ||
1647 | return IRQ_HANDLED; | |
1648 | } | |
1649 | ||
1650 | void | |
1651 | zoran_set_pci_master (struct zoran *zr, | |
1652 | int set_master) | |
1653 | { | |
1654 | if (set_master) { | |
1655 | pci_set_master(zr->pci_dev); | |
1656 | } else { | |
1657 | u16 command; | |
1658 | ||
1659 | pci_read_config_word(zr->pci_dev, PCI_COMMAND, &command); | |
1660 | command &= ~PCI_COMMAND_MASTER; | |
1661 | pci_write_config_word(zr->pci_dev, PCI_COMMAND, command); | |
1662 | } | |
1663 | } | |
1664 | ||
1665 | void | |
1666 | zoran_init_hardware (struct zoran *zr) | |
1667 | { | |
1668 | int j, zero = 0; | |
1669 | ||
1670 | /* Enable bus-mastering */ | |
1671 | zoran_set_pci_master(zr, 1); | |
1672 | ||
1673 | /* Initialize the board */ | |
1674 | if (zr->card.init) { | |
1675 | zr->card.init(zr); | |
1676 | } | |
1677 | ||
1678 | j = zr->card.input[zr->input].muxsel; | |
1679 | ||
1680 | decoder_command(zr, 0, NULL); | |
1681 | decoder_command(zr, DECODER_SET_NORM, &zr->norm); | |
1682 | decoder_command(zr, DECODER_SET_INPUT, &j); | |
1683 | ||
1684 | encoder_command(zr, 0, NULL); | |
1685 | encoder_command(zr, ENCODER_SET_NORM, &zr->norm); | |
1686 | encoder_command(zr, ENCODER_SET_INPUT, &zero); | |
1687 | ||
1688 | /* toggle JPEG codec sleep to sync PLL */ | |
1689 | jpeg_codec_sleep(zr, 1); | |
1690 | jpeg_codec_sleep(zr, 0); | |
1691 | ||
1692 | /* set individual interrupt enables (without GIRQ1) | |
1693 | * but don't global enable until zoran_open() */ | |
1694 | ||
1695 | //btwrite(IRQ_MASK & ~ZR36057_ISR_GIRQ1, ZR36057_ICR); // SW | |
1696 | // It looks like using only JPEGRepIRQEn is not always reliable, | |
1697 | // may be when JPEG codec crashes it won't generate IRQ? So, | |
1698 | /*CP*/ // btwrite(IRQ_MASK, ZR36057_ICR); // Enable Vsync interrupts too. SM WHY ? LP | |
1699 | zr36057_init_vfe(zr); | |
1700 | ||
1701 | zr36057_enable_jpg(zr, BUZ_MODE_IDLE); | |
1702 | ||
1703 | btwrite(IRQ_MASK, ZR36057_ISR); // Clears interrupts | |
1704 | } | |
1705 | ||
1706 | void | |
1707 | zr36057_restart (struct zoran *zr) | |
1708 | { | |
1709 | btwrite(0, ZR36057_SPGPPCR); | |
1710 | mdelay(1); | |
1711 | btor(ZR36057_SPGPPCR_SoftReset, ZR36057_SPGPPCR); | |
1712 | mdelay(1); | |
1713 | ||
1714 | /* assert P_Reset */ | |
1715 | btwrite(0, ZR36057_JPC); | |
1716 | /* set up GPIO direction - all output */ | |
1717 | btwrite(ZR36057_SPGPPCR_SoftReset | 0, ZR36057_SPGPPCR); | |
1718 | ||
1719 | /* set up GPIO pins and guest bus timing */ | |
1720 | btwrite((0x81 << 24) | 0x8888, ZR36057_GPPGCR1); | |
1721 | } | |
1722 | ||
1723 | /* | |
1724 | * initialize video front end | |
1725 | */ | |
1726 | ||
1727 | static void | |
1728 | zr36057_init_vfe (struct zoran *zr) | |
1729 | { | |
1730 | u32 reg; | |
1731 | ||
1732 | reg = btread(ZR36057_VFESPFR); | |
1733 | reg |= ZR36057_VFESPFR_LittleEndian; | |
1734 | reg &= ~ZR36057_VFESPFR_VCLKPol; | |
1735 | reg |= ZR36057_VFESPFR_ExtFl; | |
1736 | reg |= ZR36057_VFESPFR_TopField; | |
1737 | btwrite(reg, ZR36057_VFESPFR); | |
1738 | reg = btread(ZR36057_VDCR); | |
1739 | if (pci_pci_problems & PCIPCI_TRITON) | |
1740 | // || zr->revision < 1) // Revision 1 has also Triton support | |
1741 | reg &= ~ZR36057_VDCR_Triton; | |
1742 | else | |
1743 | reg |= ZR36057_VDCR_Triton; | |
1744 | btwrite(reg, ZR36057_VDCR); | |
1745 | } | |
1746 | ||
1747 | /* | |
1748 | * Interface to decoder and encoder chips using i2c bus | |
1749 | */ | |
1750 | ||
1751 | int | |
1752 | decoder_command (struct zoran *zr, | |
1753 | int cmd, | |
1754 | void *data) | |
1755 | { | |
1756 | if (zr->decoder == NULL) | |
1757 | return -EIO; | |
1758 | ||
1759 | if (zr->card.type == LML33 && | |
1760 | (cmd == DECODER_SET_NORM || DECODER_SET_INPUT)) { | |
1761 | int res; | |
1762 | ||
1763 | // Bt819 needs to reset its FIFO buffer using #FRST pin and | |
1764 | // LML33 card uses GPIO(7) for that. | |
1765 | GPIO(zr, 7, 0); | |
1766 | res = zr->decoder->driver->command(zr->decoder, cmd, data); | |
1767 | // Pull #FRST high. | |
1768 | GPIO(zr, 7, 1); | |
1769 | return res; | |
1770 | } else | |
1771 | return zr->decoder->driver->command(zr->decoder, cmd, | |
1772 | data); | |
1773 | } | |
1774 | ||
1775 | int | |
1776 | encoder_command (struct zoran *zr, | |
1777 | int cmd, | |
1778 | void *data) | |
1779 | { | |
1780 | if (zr->encoder == NULL) | |
1781 | return -1; | |
1782 | ||
1783 | return zr->encoder->driver->command(zr->encoder, cmd, data); | |
1784 | } |