1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Zoran zr36057/zr36067 PCI controller driver, for the |
4 | * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux |
5 | * Media Labs LML33/LML33R10. |
6 | * |
7 | * This part handles device access (PCI/I2C/codec/...) |
8 | * |
9 | * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> |
10 | */ |
11 | |
12 | #include <linux/types.h> |
13 | #include <linux/kernel.h> |
14 | #include <linux/module.h> |
15 | |
16 | #include <linux/interrupt.h> |
17 | #include <linux/i2c.h> |
18 | #include <linux/i2c-algo-bit.h> |
19 | #include <linux/videodev2.h> |
20 | #include <media/v4l2-common.h> |
21 | #include <linux/spinlock.h> |
22 | |
23 | #include <linux/pci.h> |
24 | #include <linux/delay.h> |
25 | #include <linux/wait.h> |
26 | #include <linux/dma-mapping.h> |
27 | |
28 | #include <linux/io.h> |
29 | |
30 | #include "videocodec.h" |
31 | #include "zoran.h" |
32 | #include "zoran_device.h" |
33 | #include "zoran_card.h" |
34 | |
35 | #define IRQ_MASK (ZR36057_ISR_GIRQ0 | \ |
36 | ZR36057_ISR_GIRQ1 | \ |
37 | ZR36057_ISR_JPEG_REP_IRQ) |
38 | |
39 | static bool lml33dpath; /* default = 0 |
40 | * 1 will use digital path in capture |
41 | * mode instead of analog. It can be |
42 | * used for picture adjustments using |
43 | * tool like xawtv while watching image |
44 | * on TV monitor connected to the output. |
45 | * However, due to absence of 75 Ohm |
46 | * load on Bt819 input, there will be |
47 | * some image imperfections |
48 | */ |
49 | |
50 | module_param(lml33dpath, bool, 0644); |
51 | MODULE_PARM_DESC(lml33dpath, "Use digital path capture mode (on LML33 cards)" ); |
52 | |
53 | /* |
54 | * initialize video front end |
55 | */ |
56 | static void zr36057_init_vfe(struct zoran *zr) |
57 | { |
58 | u32 reg; |
59 | |
60 | reg = btread(ZR36057_VFESPFR); |
61 | reg |= ZR36057_VFESPFR_LITTLE_ENDIAN; |
62 | reg &= ~ZR36057_VFESPFR_VCLK_POL; |
63 | reg |= ZR36057_VFESPFR_EXT_FL; |
64 | reg |= ZR36057_VFESPFR_TOP_FIELD; |
65 | btwrite(reg, ZR36057_VFESPFR); |
66 | reg = btread(ZR36057_VDCR); |
67 | if (pci_pci_problems & PCIPCI_TRITON) |
68 | // || zr->revision < 1) // Revision 1 has also Triton support |
69 | reg &= ~ZR36057_VDCR_TRITON; |
70 | else |
71 | reg |= ZR36057_VDCR_TRITON; |
72 | btwrite(reg, ZR36057_VDCR); |
73 | } |
74 | |
75 | /* |
76 | * General Purpose I/O and Guest bus access |
77 | */ |
78 | |
79 | /* |
80 | * This is a bit tricky. When a board lacks a GPIO function, the corresponding |
81 | * GPIO bit number in the card_info structure is set to 0. |
82 | */ |
83 | |
84 | void GPIO(struct zoran *zr, int bit, unsigned int value) |
85 | { |
86 | u32 reg; |
87 | u32 mask; |
88 | |
89 | /* Make sure the bit number is legal |
90 | * A bit number of -1 (lacking) gives a mask of 0, |
91 | * making it harmless |
92 | */ |
93 | mask = (1 << (24 + bit)) & 0xff000000; |
94 | reg = btread(ZR36057_GPPGCR1) & ~mask; |
95 | if (value) |
96 | reg |= mask; |
97 | |
98 | btwrite(reg, ZR36057_GPPGCR1); |
99 | udelay(1); |
100 | } |
101 | |
102 | /* |
103 | * Wait til post office is no longer busy |
104 | */ |
105 | |
106 | int post_office_wait(struct zoran *zr) |
107 | { |
108 | u32 por; |
109 | |
110 | while ((por = btread(ZR36057_POR)) & ZR36057_POR_PO_PEN) { |
111 | /* wait for something to happen */ |
112 | /* TODO add timeout */ |
113 | } |
114 | if ((por & ZR36057_POR_PO_TIME) && !zr->card.gws_not_connected) { |
115 | /* In LML33/BUZ \GWS line is not connected, so it has always timeout set */ |
116 | pci_info(zr->pci_dev, "pop timeout %08x\n" , por); |
117 | return -1; |
118 | } |
119 | |
120 | return 0; |
121 | } |
122 | |
123 | int post_office_write(struct zoran *zr, unsigned int guest, |
124 | unsigned int reg, unsigned int value) |
125 | { |
126 | u32 por; |
127 | |
128 | por = |
129 | ZR36057_POR_PO_DIR | ZR36057_POR_PO_TIME | ((guest & 7) << 20) | |
130 | ((reg & 7) << 16) | (value & 0xFF); |
131 | btwrite(por, ZR36057_POR); |
132 | |
133 | return post_office_wait(zr); |
134 | } |
135 | |
136 | int post_office_read(struct zoran *zr, unsigned int guest, unsigned int reg) |
137 | { |
138 | u32 por; |
139 | |
140 | por = ZR36057_POR_PO_TIME | ((guest & 7) << 20) | ((reg & 7) << 16); |
141 | btwrite(por, ZR36057_POR); |
142 | if (post_office_wait(zr) < 0) |
143 | return -1; |
144 | |
145 | return btread(ZR36057_POR) & 0xFF; |
146 | } |
147 | |
148 | /* |
149 | * JPEG Codec access |
150 | */ |
151 | |
152 | void jpeg_codec_sleep(struct zoran *zr, int sleep) |
153 | { |
154 | GPIO(zr, bit: zr->card.gpio[ZR_GPIO_JPEG_SLEEP], value: !sleep); |
155 | if (!sleep) { |
156 | pci_dbg(zr->pci_dev, "%s() - wake GPIO=0x%08x\n" , |
157 | __func__, btread(ZR36057_GPPGCR1)); |
158 | usleep_range(min: 500, max: 1000); |
159 | } else { |
160 | pci_dbg(zr->pci_dev, "%s() - sleep GPIO=0x%08x\n" , |
161 | __func__, btread(ZR36057_GPPGCR1)); |
162 | udelay(2); |
163 | } |
164 | } |
165 | |
166 | int jpeg_codec_reset(struct zoran *zr) |
167 | { |
168 | /* Take the codec out of sleep */ |
169 | jpeg_codec_sleep(zr, sleep: 0); |
170 | |
171 | if (zr->card.gpcs[GPCS_JPEG_RESET] != 0xff) { |
172 | post_office_write(zr, guest: zr->card.gpcs[GPCS_JPEG_RESET], reg: 0, |
173 | value: 0); |
174 | udelay(2); |
175 | } else { |
176 | GPIO(zr, bit: zr->card.gpio[ZR_GPIO_JPEG_RESET], value: 0); |
177 | udelay(2); |
178 | GPIO(zr, bit: zr->card.gpio[ZR_GPIO_JPEG_RESET], value: 1); |
179 | udelay(2); |
180 | } |
181 | |
182 | return 0; |
183 | } |
184 | |
185 | /* |
186 | * Set the registers for the size we have specified. Don't bother |
187 | * trying to understand this without the ZR36057 manual in front of |
188 | * you [AC]. |
189 | */ |
190 | static void zr36057_adjust_vfe(struct zoran *zr, enum zoran_codec_mode mode) |
191 | { |
192 | u32 reg; |
193 | |
194 | switch (mode) { |
195 | case BUZ_MODE_MOTION_DECOMPRESS: |
196 | btand(~ZR36057_VFESPFR_EXT_FL, ZR36057_VFESPFR); |
197 | reg = btread(ZR36057_VFEHCR); |
198 | if ((reg & (1 << 10)) && zr->card.type != LML33R10) |
199 | reg += ((1 << 10) | 1); |
200 | |
201 | btwrite(reg, ZR36057_VFEHCR); |
202 | break; |
203 | case BUZ_MODE_MOTION_COMPRESS: |
204 | case BUZ_MODE_IDLE: |
205 | default: |
206 | if ((zr->norm & V4L2_STD_NTSC) || |
207 | (zr->card.type == LML33R10 && |
208 | (zr->norm & V4L2_STD_PAL))) |
209 | btand(~ZR36057_VFESPFR_EXT_FL, ZR36057_VFESPFR); |
210 | else |
211 | btor(ZR36057_VFESPFR_EXT_FL, ZR36057_VFESPFR); |
212 | reg = btread(ZR36057_VFEHCR); |
213 | if (!(reg & (1 << 10)) && zr->card.type != LML33R10) |
214 | reg -= ((1 << 10) | 1); |
215 | |
216 | btwrite(reg, ZR36057_VFEHCR); |
217 | break; |
218 | } |
219 | } |
220 | |
221 | /* |
222 | * set geometry |
223 | */ |
224 | |
225 | static void zr36057_set_vfe(struct zoran *zr, int video_width, int video_height, |
226 | const struct zoran_format *format) |
227 | { |
228 | const struct tvnorm *tvn; |
229 | unsigned int h_start, h_end, v_start, v_end; |
230 | unsigned int disp_mode; |
231 | unsigned int vid_win_wid, vid_win_ht; |
232 | unsigned int hcrop1, hcrop2, vcrop1, vcrop2; |
233 | unsigned int wa, we, ha, he; |
234 | unsigned int X, Y, hor_dcm, ver_dcm; |
235 | u32 reg; |
236 | |
237 | tvn = zr->timing; |
238 | |
239 | wa = tvn->wa; |
240 | ha = tvn->ha; |
241 | |
242 | pci_dbg(zr->pci_dev, "set_vfe() - width = %d, height = %d\n" , video_width, video_height); |
243 | |
244 | if (video_width < BUZ_MIN_WIDTH || |
245 | video_height < BUZ_MIN_HEIGHT || |
246 | video_width > wa || video_height > ha) { |
247 | pci_err(zr->pci_dev, "set_vfe: w=%d h=%d not valid\n" , video_width, video_height); |
248 | return; |
249 | } |
250 | |
251 | /**** zr36057 ****/ |
252 | |
253 | /* horizontal */ |
254 | vid_win_wid = video_width; |
255 | X = DIV_ROUND_UP(vid_win_wid * 64, tvn->wa); |
256 | we = (vid_win_wid * 64) / X; |
257 | hor_dcm = 64 - X; |
258 | hcrop1 = 2 * ((tvn->wa - we) / 4); |
259 | hcrop2 = tvn->wa - we - hcrop1; |
260 | h_start = tvn->h_start ? tvn->h_start : 1; |
261 | /* (Ronald) Original comment: |
262 | * "| 1 Doesn't have any effect, tested on both a DC10 and a DC10+" |
263 | * this is false. It inverses chroma values on the LML33R10 (so Cr |
264 | * suddenly is shown as Cb and reverse, really cool effect if you |
265 | * want to see blue faces, not useful otherwise). So don't use |1. |
266 | * However, the DC10 has '0' as h_start, but does need |1, so we |
267 | * use a dirty check... |
268 | */ |
269 | h_end = h_start + tvn->wa - 1; |
270 | h_start += hcrop1; |
271 | h_end -= hcrop2; |
272 | reg = ((h_start & ZR36057_VFEHCR_HMASK) << ZR36057_VFEHCR_H_START) |
273 | | ((h_end & ZR36057_VFEHCR_HMASK) << ZR36057_VFEHCR_H_END); |
274 | if (zr->card.vfe_pol.hsync_pol) |
275 | reg |= ZR36057_VFEHCR_HS_POL; |
276 | btwrite(reg, ZR36057_VFEHCR); |
277 | |
278 | /* Vertical */ |
279 | disp_mode = !(video_height > BUZ_MAX_HEIGHT / 2); |
280 | vid_win_ht = disp_mode ? video_height : video_height / 2; |
281 | Y = DIV_ROUND_UP(vid_win_ht * 64 * 2, tvn->ha); |
282 | he = (vid_win_ht * 64) / Y; |
283 | ver_dcm = 64 - Y; |
284 | vcrop1 = (tvn->ha / 2 - he) / 2; |
285 | vcrop2 = tvn->ha / 2 - he - vcrop1; |
286 | v_start = tvn->v_start; |
287 | // FIXME SnapShot times out with -1 in 768*576 on the DC10 - LP |
288 | v_end = v_start + tvn->ha / 2; // - 1; |
289 | v_start += vcrop1; |
290 | v_end -= vcrop2; |
291 | reg = ((v_start & ZR36057_VFEVCR_VMASK) << ZR36057_VFEVCR_V_START) |
292 | | ((v_end & ZR36057_VFEVCR_VMASK) << ZR36057_VFEVCR_V_END); |
293 | if (zr->card.vfe_pol.vsync_pol) |
294 | reg |= ZR36057_VFEVCR_VS_POL; |
295 | btwrite(reg, ZR36057_VFEVCR); |
296 | |
297 | /* scaler and pixel format */ |
298 | reg = 0; |
299 | reg |= (hor_dcm << ZR36057_VFESPFR_HOR_DCM); |
300 | reg |= (ver_dcm << ZR36057_VFESPFR_VER_DCM); |
301 | reg |= (disp_mode << ZR36057_VFESPFR_DISP_MODE); |
302 | /* |
303 | * RJ: I don't know, why the following has to be the opposite |
304 | * of the corresponding ZR36060 setting, but only this way |
305 | * we get the correct colors when uncompressing to the screen |
306 | */ |
307 | //reg |= ZR36057_VFESPFR_VCLK_POL; |
308 | /* RJ: Don't know if that is needed for NTSC also */ |
309 | if (!(zr->norm & V4L2_STD_NTSC)) |
310 | reg |= ZR36057_VFESPFR_EXT_FL; // NEEDED!!!!!!! Wolfgang |
311 | reg |= ZR36057_VFESPFR_TOP_FIELD; |
312 | if (hor_dcm >= 48) |
313 | reg |= 3 << ZR36057_VFESPFR_H_FILTER; /* 5 tap filter */ |
314 | else if (hor_dcm >= 32) |
315 | reg |= 2 << ZR36057_VFESPFR_H_FILTER; /* 4 tap filter */ |
316 | else if (hor_dcm >= 16) |
317 | reg |= 1 << ZR36057_VFESPFR_H_FILTER; /* 3 tap filter */ |
318 | |
319 | reg |= format->vfespfr; |
320 | btwrite(reg, ZR36057_VFESPFR); |
321 | |
322 | /* display configuration */ |
323 | reg = (16 << ZR36057_VDCR_MIN_PIX) |
324 | | (vid_win_ht << ZR36057_VDCR_VID_WIN_HT) |
325 | | (vid_win_wid << ZR36057_VDCR_VID_WIN_WID); |
326 | if (pci_pci_problems & PCIPCI_TRITON) |
327 | // || zr->revision < 1) // Revision 1 has also Triton support |
328 | reg &= ~ZR36057_VDCR_TRITON; |
329 | else |
330 | reg |= ZR36057_VDCR_TRITON; |
331 | btwrite(reg, ZR36057_VDCR); |
332 | |
333 | zr36057_adjust_vfe(zr, mode: zr->codec_mode); |
334 | } |
335 | |
336 | /* Enable/Disable uncompressed memory grabbing of the 36057 */ |
337 | void zr36057_set_memgrab(struct zoran *zr, int mode) |
338 | { |
339 | if (mode) { |
340 | /* We only check SnapShot and not FrameGrab here. SnapShot==1 |
341 | * means a capture is already in progress, but FrameGrab==1 |
342 | * doesn't necessary mean that. It's more correct to say a 1 |
343 | * to 0 transition indicates a capture completed. If a |
344 | * capture is pending when capturing is tuned off, FrameGrab |
345 | * will be stuck at 1 until capturing is turned back on. |
346 | */ |
347 | if (btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SNAP_SHOT) |
348 | pci_warn(zr->pci_dev, "%s(1) with SnapShot on!?\n" , __func__); |
349 | |
350 | /* switch on VSync interrupts */ |
351 | btwrite(IRQ_MASK, ZR36057_ISR); // Clear Interrupts |
352 | btor(zr->card.vsync_int, ZR36057_ICR); // SW |
353 | |
354 | /* enable SnapShot */ |
355 | btor(ZR36057_VSSFGR_SNAP_SHOT, ZR36057_VSSFGR); |
356 | |
357 | /* Set zr36057 video front end and enable video */ |
358 | zr36057_set_vfe(zr, video_width: zr->v4l_settings.width, |
359 | video_height: zr->v4l_settings.height, |
360 | format: zr->v4l_settings.format); |
361 | } else { |
362 | /* switch off VSync interrupts */ |
363 | btand(~zr->card.vsync_int, ZR36057_ICR); // SW |
364 | |
365 | /* re-enable grabbing to screen if it was running */ |
366 | btand(~ZR36057_VDCR_VID_EN, ZR36057_VDCR); |
367 | btand(~ZR36057_VSSFGR_SNAP_SHOT, ZR36057_VSSFGR); |
368 | } |
369 | } |
370 | |
371 | /***************************************************************************** |
372 | * * |
373 | * Set up the Buz-specific MJPEG part * |
374 | * * |
375 | *****************************************************************************/ |
376 | |
377 | static inline void set_frame(struct zoran *zr, int val) |
378 | { |
379 | GPIO(zr, bit: zr->card.gpio[ZR_GPIO_JPEG_FRAME], value: val); |
380 | } |
381 | |
382 | static void set_videobus_dir(struct zoran *zr, int val) |
383 | { |
384 | switch (zr->card.type) { |
385 | case LML33: |
386 | case LML33R10: |
387 | if (!lml33dpath) |
388 | GPIO(zr, bit: 5, value: val); |
389 | else |
390 | GPIO(zr, bit: 5, value: 1); |
391 | break; |
392 | default: |
393 | GPIO(zr, bit: zr->card.gpio[ZR_GPIO_VID_DIR], |
394 | value: zr->card.gpio_pol[ZR_GPIO_VID_DIR] ? !val : val); |
395 | break; |
396 | } |
397 | } |
398 | |
399 | static void init_jpeg_queue(struct zoran *zr) |
400 | { |
401 | int i; |
402 | |
403 | /* re-initialize DMA ring stuff */ |
404 | zr->jpg_que_head = 0; |
405 | zr->jpg_dma_head = 0; |
406 | zr->jpg_dma_tail = 0; |
407 | zr->jpg_que_tail = 0; |
408 | zr->jpg_seq_num = 0; |
409 | zr->jpeg_error = 0; |
410 | zr->num_errors = 0; |
411 | zr->jpg_err_seq = 0; |
412 | zr->jpg_err_shift = 0; |
413 | zr->jpg_queued_num = 0; |
414 | for (i = 0; i < BUZ_NUM_STAT_COM; i++) |
415 | zr->stat_com[i] = cpu_to_le32(1); /* mark as unavailable to zr36057 */ |
416 | } |
417 | |
418 | static void zr36057_set_jpg(struct zoran *zr, enum zoran_codec_mode mode) |
419 | { |
420 | const struct tvnorm *tvn; |
421 | u32 reg; |
422 | |
423 | tvn = zr->timing; |
424 | |
425 | /* assert P_Reset, disable code transfer, deassert Active */ |
426 | btwrite(0, ZR36057_JPC); |
427 | |
428 | /* MJPEG compression mode */ |
429 | switch (mode) { |
430 | case BUZ_MODE_MOTION_COMPRESS: |
431 | default: |
432 | reg = ZR36057_JMC_MJPG_CMP_MODE; |
433 | break; |
434 | |
435 | case BUZ_MODE_MOTION_DECOMPRESS: |
436 | reg = ZR36057_JMC_MJPG_EXP_MODE; |
437 | reg |= ZR36057_JMC_SYNC_MSTR; |
438 | /* RJ: The following is experimental - improves the output to screen */ |
439 | //if(zr->jpg_settings.VFIFO_FB) reg |= ZR36057_JMC_VFIFO_FB; // No, it doesn't. SM |
440 | break; |
441 | |
442 | case BUZ_MODE_STILL_COMPRESS: |
443 | reg = ZR36057_JMC_JPG_CMP_MODE; |
444 | break; |
445 | |
446 | case BUZ_MODE_STILL_DECOMPRESS: |
447 | reg = ZR36057_JMC_JPG_EXP_MODE; |
448 | break; |
449 | } |
450 | reg |= ZR36057_JMC_JPG; |
451 | if (zr->jpg_settings.field_per_buff == 1) |
452 | reg |= ZR36057_JMC_FLD_PER_BUFF; |
453 | btwrite(reg, ZR36057_JMC); |
454 | |
455 | /* vertical */ |
456 | btor(ZR36057_VFEVCR_VS_POL, ZR36057_VFEVCR); |
457 | reg = (6 << ZR36057_VSP_VSYNC_SIZE) | |
458 | (tvn->ht << ZR36057_VSP_FRM_TOT); |
459 | btwrite(reg, ZR36057_VSP); |
460 | reg = ((zr->jpg_settings.img_y + tvn->v_start) << ZR36057_FVAP_NAY) | |
461 | (zr->jpg_settings.img_height << ZR36057_FVAP_PAY); |
462 | btwrite(reg, ZR36057_FVAP); |
463 | |
464 | /* horizontal */ |
465 | if (zr->card.vfe_pol.hsync_pol) |
466 | btor(ZR36057_VFEHCR_HS_POL, ZR36057_VFEHCR); |
467 | else |
468 | btand(~ZR36057_VFEHCR_HS_POL, ZR36057_VFEHCR); |
469 | reg = ((tvn->h_sync_start) << ZR36057_HSP_HSYNC_START) | |
470 | (tvn->wt << ZR36057_HSP_LINE_TOT); |
471 | btwrite(reg, ZR36057_HSP); |
472 | reg = ((zr->jpg_settings.img_x + |
473 | tvn->h_start + 4) << ZR36057_FHAP_NAX) | |
474 | (zr->jpg_settings.img_width << ZR36057_FHAP_PAX); |
475 | btwrite(reg, ZR36057_FHAP); |
476 | |
477 | /* field process parameters */ |
478 | if (zr->jpg_settings.odd_even) |
479 | reg = ZR36057_FPP_ODD_EVEN; |
480 | else |
481 | reg = 0; |
482 | |
483 | btwrite(reg, ZR36057_FPP); |
484 | |
485 | /* Set proper VCLK Polarity, else colors will be wrong during playback */ |
486 | //btor(ZR36057_VFESPFR_VCLK_POL, ZR36057_VFESPFR); |
487 | |
488 | /* code base address */ |
489 | btwrite(zr->p_sc, ZR36057_JCBA); |
490 | |
491 | /* FIFO threshold (FIFO is 160. double words) */ |
492 | /* NOTE: decimal values here */ |
493 | switch (mode) { |
494 | case BUZ_MODE_STILL_COMPRESS: |
495 | case BUZ_MODE_MOTION_COMPRESS: |
496 | if (zr->card.type != BUZ) |
497 | reg = 140; |
498 | else |
499 | reg = 60; |
500 | break; |
501 | |
502 | case BUZ_MODE_STILL_DECOMPRESS: |
503 | case BUZ_MODE_MOTION_DECOMPRESS: |
504 | reg = 20; |
505 | break; |
506 | |
507 | default: |
508 | reg = 80; |
509 | break; |
510 | } |
511 | btwrite(reg, ZR36057_JCFT); |
512 | zr36057_adjust_vfe(zr, mode); |
513 | } |
514 | |
515 | void clear_interrupt_counters(struct zoran *zr) |
516 | { |
517 | zr->intr_counter_GIRQ1 = 0; |
518 | zr->intr_counter_GIRQ0 = 0; |
519 | zr->intr_counter_cod_rep_irq = 0; |
520 | zr->intr_counter_jpeg_rep_irq = 0; |
521 | zr->field_counter = 0; |
522 | zr->irq1_in = 0; |
523 | zr->irq1_out = 0; |
524 | zr->jpeg_in = 0; |
525 | zr->jpeg_out = 0; |
526 | zr->JPEG_0 = 0; |
527 | zr->JPEG_1 = 0; |
528 | zr->end_event_missed = 0; |
529 | zr->jpeg_missed = 0; |
530 | zr->jpeg_max_missed = 0; |
531 | zr->jpeg_min_missed = 0x7fffffff; |
532 | } |
533 | |
534 | static u32 count_reset_interrupt(struct zoran *zr) |
535 | { |
536 | u32 isr; |
537 | |
538 | isr = btread(ZR36057_ISR) & 0x78000000; |
539 | if (isr) { |
540 | if (isr & ZR36057_ISR_GIRQ1) { |
541 | btwrite(ZR36057_ISR_GIRQ1, ZR36057_ISR); |
542 | zr->intr_counter_GIRQ1++; |
543 | } |
544 | if (isr & ZR36057_ISR_GIRQ0) { |
545 | btwrite(ZR36057_ISR_GIRQ0, ZR36057_ISR); |
546 | zr->intr_counter_GIRQ0++; |
547 | } |
548 | if (isr & ZR36057_ISR_COD_REP_IRQ) { |
549 | btwrite(ZR36057_ISR_COD_REP_IRQ, ZR36057_ISR); |
550 | zr->intr_counter_cod_rep_irq++; |
551 | } |
552 | if (isr & ZR36057_ISR_JPEG_REP_IRQ) { |
553 | btwrite(ZR36057_ISR_JPEG_REP_IRQ, ZR36057_ISR); |
554 | zr->intr_counter_jpeg_rep_irq++; |
555 | } |
556 | } |
557 | return isr; |
558 | } |
559 | |
560 | void jpeg_start(struct zoran *zr) |
561 | { |
562 | int reg; |
563 | |
564 | zr->frame_num = 0; |
565 | |
566 | /* deassert P_reset, disable code transfer, deassert Active */ |
567 | btwrite(ZR36057_JPC_P_RESET, ZR36057_JPC); |
568 | /* stop flushing the internal code buffer */ |
569 | btand(~ZR36057_MCTCR_C_FLUSH, ZR36057_MCTCR); |
570 | /* enable code transfer */ |
571 | btor(ZR36057_JPC_COD_TRNS_EN, ZR36057_JPC); |
572 | |
573 | /* clear IRQs */ |
574 | btwrite(IRQ_MASK, ZR36057_ISR); |
575 | /* enable the JPEG IRQs */ |
576 | btwrite(zr->card.jpeg_int | ZR36057_ICR_JPEG_REP_IRQ | ZR36057_ICR_INT_PIN_EN, |
577 | ZR36057_ICR); |
578 | |
579 | set_frame(zr, val: 0); // \FRAME |
580 | |
581 | /* set the JPEG codec guest ID */ |
582 | reg = (zr->card.gpcs[1] << ZR36057_JCGI_JPE_GUEST_ID) | |
583 | (0 << ZR36057_JCGI_JPE_GUEST_REG); |
584 | btwrite(reg, ZR36057_JCGI); |
585 | |
586 | if (zr->card.video_vfe == CODEC_TYPE_ZR36016 && |
587 | zr->card.video_codec == CODEC_TYPE_ZR36050) { |
588 | /* Enable processing on the ZR36016 */ |
589 | if (zr->vfe) |
590 | zr36016_write(codec: zr->vfe, reg: 0, val: 1); |
591 | |
592 | /* load the address of the GO register in the ZR36050 latch */ |
593 | post_office_write(zr, guest: 0, reg: 0, value: 0); |
594 | } |
595 | |
596 | /* assert Active */ |
597 | btor(ZR36057_JPC_ACTIVE, ZR36057_JPC); |
598 | |
599 | /* enable the Go generation */ |
600 | btor(ZR36057_JMC_GO_EN, ZR36057_JMC); |
601 | usleep_range(min: 30, max: 100); |
602 | |
603 | set_frame(zr, val: 1); // /FRAME |
604 | } |
605 | |
606 | void zr36057_enable_jpg(struct zoran *zr, enum zoran_codec_mode mode) |
607 | { |
608 | struct vfe_settings cap; |
609 | int field_size = zr->buffer_size / zr->jpg_settings.field_per_buff; |
610 | |
611 | zr->codec_mode = mode; |
612 | |
613 | cap.x = zr->jpg_settings.img_x; |
614 | cap.y = zr->jpg_settings.img_y; |
615 | cap.width = zr->jpg_settings.img_width; |
616 | cap.height = zr->jpg_settings.img_height; |
617 | cap.decimation = |
618 | zr->jpg_settings.hor_dcm | (zr->jpg_settings.ver_dcm << 8); |
619 | cap.quality = zr->jpg_settings.jpg_comp.quality; |
620 | |
621 | switch (mode) { |
622 | case BUZ_MODE_MOTION_COMPRESS: { |
623 | struct jpeg_app_marker app; |
624 | struct jpeg_com_marker com; |
625 | |
626 | /* In motion compress mode, the decoder output must be enabled, and |
627 | * the video bus direction set to input. |
628 | */ |
629 | set_videobus_dir(zr, val: 0); |
630 | decoder_call(zr, video, s_stream, 1); |
631 | encoder_call(zr, video, s_routing, 0, 0, 0); |
632 | |
633 | /* Take the JPEG codec and the VFE out of sleep */ |
634 | jpeg_codec_sleep(zr, sleep: 0); |
635 | |
636 | /* set JPEG app/com marker */ |
637 | app.appn = zr->jpg_settings.jpg_comp.APPn; |
638 | app.len = zr->jpg_settings.jpg_comp.APP_len; |
639 | memcpy(app.data, zr->jpg_settings.jpg_comp.APP_data, 60); |
640 | zr->codec->control(zr->codec, CODEC_S_JPEG_APP_DATA, |
641 | sizeof(struct jpeg_app_marker), &app); |
642 | |
643 | com.len = zr->jpg_settings.jpg_comp.COM_len; |
644 | memcpy(com.data, zr->jpg_settings.jpg_comp.COM_data, 60); |
645 | zr->codec->control(zr->codec, CODEC_S_JPEG_COM_DATA, |
646 | sizeof(struct jpeg_com_marker), &com); |
647 | |
648 | /* Setup the JPEG codec */ |
649 | zr->codec->control(zr->codec, CODEC_S_JPEG_TDS_BYTE, |
650 | sizeof(int), &field_size); |
651 | zr->codec->set_video(zr->codec, zr->timing, &cap, |
652 | &zr->card.vfe_pol); |
653 | zr->codec->set_mode(zr->codec, CODEC_DO_COMPRESSION); |
654 | |
655 | /* Setup the VFE */ |
656 | if (zr->vfe) { |
657 | zr->vfe->control(zr->vfe, CODEC_S_JPEG_TDS_BYTE, |
658 | sizeof(int), &field_size); |
659 | zr->vfe->set_video(zr->vfe, zr->timing, &cap, |
660 | &zr->card.vfe_pol); |
661 | zr->vfe->set_mode(zr->vfe, CODEC_DO_COMPRESSION); |
662 | } |
663 | |
664 | init_jpeg_queue(zr); |
665 | zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO |
666 | |
667 | clear_interrupt_counters(zr); |
668 | pci_dbg(zr->pci_dev, "enable_jpg(MOTION_COMPRESS)\n" ); |
669 | break; |
670 | } |
671 | |
672 | case BUZ_MODE_MOTION_DECOMPRESS: |
673 | /* In motion decompression mode, the decoder output must be disabled, and |
674 | * the video bus direction set to output. |
675 | */ |
676 | decoder_call(zr, video, s_stream, 0); |
677 | set_videobus_dir(zr, val: 1); |
678 | encoder_call(zr, video, s_routing, 1, 0, 0); |
679 | |
680 | /* Take the JPEG codec and the VFE out of sleep */ |
681 | jpeg_codec_sleep(zr, sleep: 0); |
682 | /* Setup the VFE */ |
683 | if (zr->vfe) { |
684 | zr->vfe->set_video(zr->vfe, zr->timing, &cap, |
685 | &zr->card.vfe_pol); |
686 | zr->vfe->set_mode(zr->vfe, CODEC_DO_EXPANSION); |
687 | } |
688 | /* Setup the JPEG codec */ |
689 | zr->codec->set_video(zr->codec, zr->timing, &cap, |
690 | &zr->card.vfe_pol); |
691 | zr->codec->set_mode(zr->codec, CODEC_DO_EXPANSION); |
692 | |
693 | init_jpeg_queue(zr); |
694 | zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO |
695 | |
696 | clear_interrupt_counters(zr); |
697 | pci_dbg(zr->pci_dev, "enable_jpg(MOTION_DECOMPRESS)\n" ); |
698 | break; |
699 | |
700 | case BUZ_MODE_IDLE: |
701 | default: |
702 | /* shut down processing */ |
703 | btand(~(zr->card.jpeg_int | ZR36057_ICR_JPEG_REP_IRQ), |
704 | ZR36057_ICR); |
705 | btwrite(zr->card.jpeg_int | ZR36057_ICR_JPEG_REP_IRQ, |
706 | ZR36057_ISR); |
707 | btand(~ZR36057_JMC_GO_EN, ZR36057_JMC); // \Go_en |
708 | |
709 | msleep(msecs: 50); |
710 | |
711 | set_videobus_dir(zr, val: 0); |
712 | set_frame(zr, val: 1); // /FRAME |
713 | btor(ZR36057_MCTCR_C_FLUSH, ZR36057_MCTCR); // /CFlush |
714 | btwrite(0, ZR36057_JPC); // \P_Reset,\CodTrnsEn,\Active |
715 | btand(~ZR36057_JMC_VFIFO_FB, ZR36057_JMC); |
716 | btand(~ZR36057_JMC_SYNC_MSTR, ZR36057_JMC); |
717 | jpeg_codec_reset(zr); |
718 | jpeg_codec_sleep(zr, sleep: 1); |
719 | zr36057_adjust_vfe(zr, mode); |
720 | |
721 | decoder_call(zr, video, s_stream, 1); |
722 | encoder_call(zr, video, s_routing, 0, 0, 0); |
723 | |
724 | pci_dbg(zr->pci_dev, "enable_jpg(IDLE)\n" ); |
725 | break; |
726 | } |
727 | } |
728 | |
729 | /* when this is called the spinlock must be held */ |
730 | void zoran_feed_stat_com(struct zoran *zr) |
731 | { |
732 | /* move frames from pending queue to DMA */ |
733 | |
734 | int i, max_stat_com; |
735 | struct zr_buffer *buf; |
736 | struct vb2_v4l2_buffer *vbuf; |
737 | dma_addr_t phys_addr = 0; |
738 | unsigned long flags; |
739 | unsigned long payload; |
740 | |
741 | max_stat_com = |
742 | (zr->jpg_settings.tmp_dcm == |
743 | 1) ? BUZ_NUM_STAT_COM : (BUZ_NUM_STAT_COM >> 1); |
744 | |
745 | spin_lock_irqsave(&zr->queued_bufs_lock, flags); |
746 | while ((zr->jpg_dma_head - zr->jpg_dma_tail) < max_stat_com) { |
747 | buf = list_first_entry_or_null(&zr->queued_bufs, struct zr_buffer, queue); |
748 | if (!buf) { |
749 | pci_err(zr->pci_dev, "No buffer available to queue\n" ); |
750 | spin_unlock_irqrestore(lock: &zr->queued_bufs_lock, flags); |
751 | return; |
752 | } |
753 | list_del(entry: &buf->queue); |
754 | zr->buf_in_reserve--; |
755 | vbuf = &buf->vbuf; |
756 | vbuf->vb2_buf.state = VB2_BUF_STATE_ACTIVE; |
757 | phys_addr = vb2_dma_contig_plane_dma_addr(vb: &vbuf->vb2_buf, plane_no: 0); |
758 | payload = vb2_get_plane_payload(vb: &vbuf->vb2_buf, plane_no: 0); |
759 | if (payload == 0) |
760 | payload = zr->buffer_size; |
761 | if (zr->jpg_settings.tmp_dcm == 1) { |
762 | /* fill 1 stat_com entry */ |
763 | i = (zr->jpg_dma_head - |
764 | zr->jpg_err_shift) & BUZ_MASK_STAT_COM; |
765 | if (!(zr->stat_com[i] & cpu_to_le32(1))) |
766 | break; |
767 | zr->stat_comb[i * 2] = cpu_to_le32(phys_addr); |
768 | zr->stat_comb[i * 2 + 1] = cpu_to_le32((payload >> 1) | 1); |
769 | zr->inuse[i] = buf; |
770 | zr->stat_com[i] = cpu_to_le32(zr->p_scb + i * 2 * 4); |
771 | } else { |
772 | /* fill 2 stat_com entries */ |
773 | i = ((zr->jpg_dma_head - |
774 | zr->jpg_err_shift) & 1) * 2; |
775 | if (!(zr->stat_com[i] & cpu_to_le32(1))) |
776 | break; |
777 | zr->stat_com[i] = cpu_to_le32(zr->p_scb + i * 2 * 4); |
778 | zr->stat_com[i + 1] = cpu_to_le32(zr->p_scb + i * 2 * 4); |
779 | |
780 | zr->stat_comb[i * 2] = cpu_to_le32(phys_addr); |
781 | zr->stat_comb[i * 2 + 1] = cpu_to_le32((payload >> 1) | 1); |
782 | |
783 | zr->inuse[i] = buf; |
784 | zr->inuse[i + 1] = NULL; |
785 | } |
786 | zr->jpg_dma_head++; |
787 | } |
788 | spin_unlock_irqrestore(lock: &zr->queued_bufs_lock, flags); |
789 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) |
790 | zr->jpg_queued_num++; |
791 | } |
792 | |
793 | /* when this is called the spinlock must be held */ |
794 | static void zoran_reap_stat_com(struct zoran *zr) |
795 | { |
796 | /* move frames from DMA queue to done queue */ |
797 | |
798 | int i; |
799 | u32 stat_com; |
800 | unsigned int seq; |
801 | unsigned int dif; |
802 | unsigned long flags; |
803 | struct zr_buffer *buf; |
804 | unsigned int size = 0; |
805 | u32 fcnt; |
806 | |
807 | /* |
808 | * In motion decompress we don't have a hardware frame counter, |
809 | * we just count the interrupts here |
810 | */ |
811 | |
812 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) |
813 | zr->jpg_seq_num++; |
814 | |
815 | spin_lock_irqsave(&zr->queued_bufs_lock, flags); |
816 | while (zr->jpg_dma_tail < zr->jpg_dma_head) { |
817 | if (zr->jpg_settings.tmp_dcm == 1) |
818 | i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; |
819 | else |
820 | i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2; |
821 | |
822 | stat_com = le32_to_cpu(zr->stat_com[i]); |
823 | if ((stat_com & 1) == 0) { |
824 | spin_unlock_irqrestore(lock: &zr->queued_bufs_lock, flags); |
825 | return; |
826 | } |
827 | |
828 | fcnt = (stat_com & GENMASK(31, 24)) >> 24; |
829 | size = (stat_com & GENMASK(22, 1)) >> 1; |
830 | |
831 | buf = zr->inuse[i]; |
832 | if (!buf) { |
833 | spin_unlock_irqrestore(lock: &zr->queued_bufs_lock, flags); |
834 | pci_err(zr->pci_dev, "No buffer at slot %d\n" , i); |
835 | return; |
836 | } |
837 | buf->vbuf.vb2_buf.timestamp = ktime_get_ns(); |
838 | |
839 | if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { |
840 | vb2_set_plane_payload(vb: &buf->vbuf.vb2_buf, plane_no: 0, size); |
841 | |
842 | /* update sequence number with the help of the counter in stat_com */ |
843 | seq = (fcnt + zr->jpg_err_seq) & 0xff; |
844 | dif = (seq - zr->jpg_seq_num) & 0xff; |
845 | zr->jpg_seq_num += dif; |
846 | } |
847 | buf->vbuf.sequence = zr->jpg_settings.tmp_dcm == |
848 | 2 ? (zr->jpg_seq_num >> 1) : zr->jpg_seq_num; |
849 | zr->inuse[i] = NULL; |
850 | if (zr->jpg_settings.tmp_dcm != 1) |
851 | buf->vbuf.field = zr->jpg_settings.odd_even ? |
852 | V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; |
853 | else |
854 | buf->vbuf.field = zr->jpg_settings.odd_even ? |
855 | V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT; |
856 | vb2_buffer_done(vb: &buf->vbuf.vb2_buf, state: VB2_BUF_STATE_DONE); |
857 | |
858 | zr->jpg_dma_tail++; |
859 | } |
860 | spin_unlock_irqrestore(lock: &zr->queued_bufs_lock, flags); |
861 | } |
862 | |
863 | irqreturn_t zoran_irq(int irq, void *dev_id) |
864 | { |
865 | struct zoran *zr = dev_id; |
866 | u32 stat, astat; |
867 | |
868 | stat = count_reset_interrupt(zr); |
869 | astat = stat & IRQ_MASK; |
870 | if (astat & zr->card.vsync_int) { |
871 | if (zr->running == ZORAN_MAP_MODE_RAW) { |
872 | if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SNAP_SHOT) == 0) |
873 | pci_warn(zr->pci_dev, "BuzIRQ with SnapShot off ???\n" ); |
874 | if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FRAME_GRAB) == 0) |
875 | zr_set_buf(zr); |
876 | return IRQ_HANDLED; |
877 | } |
878 | if (astat & ZR36057_ISR_JPEG_REP_IRQ) { |
879 | if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS && |
880 | zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) { |
881 | pci_err(zr->pci_dev, "JPG IRQ when not in good mode\n" ); |
882 | return IRQ_HANDLED; |
883 | } |
884 | zr->frame_num++; |
885 | zoran_reap_stat_com(zr); |
886 | zoran_feed_stat_com(zr); |
887 | return IRQ_HANDLED; |
888 | } |
889 | /* unused interrupts */ |
890 | } |
891 | zr->ghost_int++; |
892 | return IRQ_HANDLED; |
893 | } |
894 | |
895 | void zoran_set_pci_master(struct zoran *zr, int set_master) |
896 | { |
897 | if (set_master) { |
898 | pci_set_master(dev: zr->pci_dev); |
899 | } else { |
900 | u16 command; |
901 | |
902 | pci_read_config_word(dev: zr->pci_dev, PCI_COMMAND, val: &command); |
903 | command &= ~PCI_COMMAND_MASTER; |
904 | pci_write_config_word(dev: zr->pci_dev, PCI_COMMAND, val: command); |
905 | } |
906 | } |
907 | |
908 | void zoran_init_hardware(struct zoran *zr) |
909 | { |
910 | /* Enable bus-mastering */ |
911 | zoran_set_pci_master(zr, set_master: 1); |
912 | |
913 | /* Initialize the board */ |
914 | if (zr->card.init) |
915 | zr->card.init(zr); |
916 | |
917 | decoder_call(zr, core, init, 0); |
918 | decoder_call(zr, video, s_std, zr->norm); |
919 | decoder_call(zr, video, s_routing, |
920 | zr->card.input[zr->input].muxsel, 0, 0); |
921 | |
922 | encoder_call(zr, core, init, 0); |
923 | encoder_call(zr, video, s_std_output, zr->norm); |
924 | encoder_call(zr, video, s_routing, 0, 0, 0); |
925 | |
926 | /* toggle JPEG codec sleep to sync PLL */ |
927 | jpeg_codec_sleep(zr, sleep: 1); |
928 | jpeg_codec_sleep(zr, sleep: 0); |
929 | |
930 | /* |
931 | * set individual interrupt enables (without GIRQ1) |
932 | * but don't global enable until zoran_open() |
933 | */ |
934 | zr36057_init_vfe(zr); |
935 | |
936 | zr36057_enable_jpg(zr, mode: BUZ_MODE_IDLE); |
937 | |
938 | btwrite(IRQ_MASK, ZR36057_ISR); // Clears interrupts |
939 | } |
940 | |
941 | void zr36057_restart(struct zoran *zr) |
942 | { |
943 | btwrite(0, ZR36057_SPGPPCR); |
944 | usleep_range(min: 1000, max: 2000); |
945 | btor(ZR36057_SPGPPCR_SOFT_RESET, ZR36057_SPGPPCR); |
946 | usleep_range(min: 1000, max: 2000); |
947 | |
948 | /* assert P_Reset */ |
949 | btwrite(0, ZR36057_JPC); |
950 | /* set up GPIO direction - all output */ |
951 | btwrite(ZR36057_SPGPPCR_SOFT_RESET | 0, ZR36057_SPGPPCR); |
952 | |
953 | /* set up GPIO pins and guest bus timing */ |
954 | btwrite((0x81 << 24) | 0x8888, ZR36057_GPPGCR1); |
955 | } |
956 | |
957 | |