remove const from TPL_OpenTPLFromMemory since the memory is altered
[libogc.git] / libogc / video.c
blob98e78a01d2605ae1494637bb09fd7810afce1753
1 /*-------------------------------------------------------------
3 video.c -- VIDEO subsystem
5 Copyright (C) 2004 - 2008
6 Michael Wiedenbauer (shagkur)
7 Dave Murphy (WinterMute)
9 Redistribution and use in source and binary forms, with or without modification,
10 are permitted provided that the following conditions are met:
12 1. Redistributions of source code must retain the above copyright notice,
13 this list of conditions and the following disclaimer.
14 2. Redistributions in binary form must reproduce the above copyright notice,
15 this list of conditions and the following disclaimer in the documentation and/or
16 other materials provided with the distribution.
17 3. The name of the author may not be used to endorse or promote products derived
18 from this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 -------------------------------------------------------------*/
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <time.h>
37 #include "asm.h"
38 #include "processor.h"
39 #include "ogcsys.h"
40 #include "irq.h"
41 #include "exi.h"
42 #include "gx.h"
43 #include "si.h"
44 #include "lwp.h"
45 #include "system.h"
46 #include "video.h"
47 #include "video_types.h"
49 //#define _VIDEO_DEBUG
51 #define VIDEO_MQ 1
53 #define _SHIFTL(v, s, w) \
54 ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s)))
55 #define _SHIFTR(v, s, w) \
56 ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1)))
58 #define VI_REGCHANGE(_reg) \
59 ((u64)0x01<<(63-_reg))
61 typedef struct _horVer {
62 u16 dispPosX;
63 u16 dispPosY;
64 u16 dispSizeX;
65 u16 dispSizeY;
66 u16 adjustedDispPosX;
67 u16 adjustedDispPosY;
68 u16 adjustedDispSizeY;
69 u16 adjustedPanPosY;
70 u16 adjustedPanSizeY;
71 u16 fbSizeX;
72 u16 fbSizeY;
73 u16 panPosX;
74 u16 panPosY;
75 u16 panSizeX;
76 u16 panSizeY;
77 u32 fbMode;
78 u32 nonInter;
79 u32 tv;
80 u8 wordPerLine;
81 u8 std;
82 u8 wpl;
83 void *bufAddr;
84 u32 tfbb;
85 u32 bfbb;
86 u8 xof;
87 s32 black;
88 s32 threeD;
89 void *rbufAddr;
90 u32 rtfbb;
91 u32 rbfbb;
92 const struct _timing *timing;
93 } horVer;
95 GXRModeObj TVNtsc240Ds =
97 VI_TVMODE_NTSC_DS, // viDisplayMode
98 640, // fbWidth
99 240, // efbHeight
100 240, // xfbHeight
101 (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin
102 (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
103 640, // viWidth
104 480, // viHeight
105 VI_XFBMODE_SF, // xFBmode
106 GX_FALSE, // field_rendering
107 GX_FALSE, // aa
109 // sample points arranged in increasing Y order
111 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
112 {6,6},{6,6},{6,6}, // pix 1
113 {6,6},{6,6},{6,6}, // pix 2
114 {6,6},{6,6},{6,6} // pix 3
117 // vertical filter[7], 1/64 units, 6 bits each
119 0, // line n-1
120 0, // line n-1
121 21, // line n
122 22, // line n
123 21, // line n
124 0, // line n+1
125 0 // line n+1
129 GXRModeObj TVNtsc240DsAa =
131 VI_TVMODE_NTSC_DS, // viDisplayMode
132 640, // fbWidth
133 240, // efbHeight
134 240, // xfbHeight
135 (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin
136 (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
137 640, // viWidth
138 480, // viHeight
139 VI_XFBMODE_SF, // xFBmode
140 GX_FALSE, // field_rendering
141 GX_TRUE, // aa
143 // sample points arranged in increasing Y order
145 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
146 {3,2},{9,6},{3,10}, // pix 1
147 {9,2},{3,6},{9,10}, // pix 2
148 {9,2},{3,6},{9,10} // pix 3
151 // vertical filter[7], 1/64 units, 6 bits each
153 0, // line n-1
154 0, // line n-1
155 21, // line n
156 22, // line n
157 21, // line n
158 0, // line n+1
159 0 // line n+1
163 GXRModeObj TVNtsc240Int =
165 VI_TVMODE_NTSC_INT, // viDisplayMode
166 640, // fbWidth
167 240, // efbHeight
168 240, // xfbHeight
169 (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin
170 (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
171 640, // viWidth
172 480, // viHeight
173 VI_XFBMODE_SF, // xFBmode
174 GX_TRUE, // field_rendering
175 GX_FALSE, // aa
177 // sample points arranged in increasing Y order
179 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
180 {6,6},{6,6},{6,6}, // pix 1
181 {6,6},{6,6},{6,6}, // pix 2
182 {6,6},{6,6},{6,6} // pix 3
185 // vertical filter[7], 1/64 units, 6 bits each
187 0, // line n-1
188 0, // line n-1
189 21, // line n
190 22, // line n
191 21, // line n
192 0, // line n+1
193 0 // line n+1
197 GXRModeObj TVNtsc240IntAa =
199 VI_TVMODE_NTSC_INT, // viDisplayMode
200 640, // fbWidth
201 240, // efbHeight
202 240, // xfbHeight
203 (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin
204 (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
205 640, // viWidth
206 480, // viHeight
207 VI_XFBMODE_SF, // xFBmode
208 GX_TRUE, // field_rendering
209 GX_TRUE, // aa
211 // sample points arranged in increasing Y order
213 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
214 {3,2},{9,6},{3,10}, // pix 1
215 {9,2},{3,6},{9,10}, // pix 2
216 {9,2},{3,6},{9,10} // pix 3
219 // vertical filter[7], 1/64 units, 6 bits each
221 0, // line n-1
222 0, // line n-1
223 21, // line n
224 22, // line n
225 21, // line n
226 0, // line n+1
227 0 // line n+1
231 GXRModeObj TVNtsc480Int =
233 VI_TVMODE_NTSC_INT, // viDisplayMode
234 640, // fbWidth
235 480, // efbHeight
236 480, // xfbHeight
237 (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin
238 (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
239 640, // viWidth
240 480, // viHeight
241 VI_XFBMODE_DF, // xFBmode
242 GX_FALSE, // field_rendering
243 GX_FALSE, // aa
245 // sample points arranged in increasing Y order
247 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
248 {6,6},{6,6},{6,6}, // pix 1
249 {6,6},{6,6},{6,6}, // pix 2
250 {6,6},{6,6},{6,6} // pix 3
253 // vertical filter[7], 1/64 units, 6 bits each
255 0, // line n-1
256 0, // line n-1
257 21, // line n
258 22, // line n
259 21, // line n
260 0, // line n+1
261 0 // line n+1
265 GXRModeObj TVNtsc480IntDf =
267 VI_TVMODE_NTSC_INT, // viDisplayMode
268 640, // fbWidth
269 480, // efbHeight
270 480, // xfbHeight
271 (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin
272 (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
273 640, // viWidth
274 480, // viHeight
275 VI_XFBMODE_DF, // xFBmode
276 GX_FALSE, // field_rendering
277 GX_FALSE, // aa
279 // sample points arranged in increasing Y order
281 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
282 {6,6},{6,6},{6,6}, // pix 1
283 {6,6},{6,6},{6,6}, // pix 2
284 {6,6},{6,6},{6,6} // pix 3
287 // vertical filter[7], 1/64 units, 6 bits each
289 8, // line n-1
290 8, // line n-1
291 10, // line n
292 12, // line n
293 10, // line n
294 8, // line n+1
295 8 // line n+1
299 GXRModeObj TVNtsc480IntAa =
301 VI_TVMODE_NTSC_INT, // viDisplayMode
302 640, // fbWidth
303 242, // efbHeight
304 480, // xfbHeight
305 (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin
306 (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
307 640, // viWidth
308 480, // viHeight
309 VI_XFBMODE_DF, // xFBmode
310 GX_FALSE, // field_rendering
311 GX_TRUE, // aa
313 // sample points arranged in increasing Y order
315 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
316 {3,2},{9,6},{3,10}, // pix 1
317 {9,2},{3,6},{9,10}, // pix 2
318 {9,2},{3,6},{9,10} // pix 3
321 // vertical filter[7], 1/64 units, 6 bits each
323 4, // line n-1
324 8, // line n-1
325 12, // line n
326 16, // line n
327 12, // line n
328 8, // line n+1
329 4 // line n+1
334 GXRModeObj TVNtsc480Prog =
336 VI_TVMODE_NTSC_PROG, // viDisplayMode
337 640, // fbWidth
338 480, // efbHeight
339 480, // xfbHeight
340 (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin
341 (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
342 640, // viWidth
343 480, // viHeight
344 VI_XFBMODE_SF, // xFBmode
345 GX_FALSE, // field_rendering
346 GX_FALSE, // aa
348 // sample points arranged in increasing Y order
350 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
351 {6,6},{6,6},{6,6}, // pix 1
352 {6,6},{6,6},{6,6}, // pix 2
353 {6,6},{6,6},{6,6} // pix 3
356 // vertical filter[7], 1/64 units, 6 bits each
358 0, // line n-1
359 0, // line n-1
360 21, // line n
361 22, // line n
362 21, // line n
363 0, // line n+1
364 0 // line n+1
368 GXRModeObj TVNtsc480ProgSoft =
370 VI_TVMODE_NTSC_PROG, // viDisplayMode
371 640, // fbWidth
372 480, // efbHeight
373 480, // xfbHeight
374 (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin
375 (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
376 640, // viWidth
377 480, // viHeight
378 VI_XFBMODE_SF, // xFBmode
379 GX_FALSE, // field_rendering
380 GX_FALSE, // aa
382 // sample points arranged in increasing Y order
384 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
385 {6,6},{6,6},{6,6}, // pix 1
386 {6,6},{6,6},{6,6}, // pix 2
387 {6,6},{6,6},{6,6} // pix 3
390 // vertical filter[7], 1/64 units, 6 bits each
392 8, // line n-1
393 8, // line n-1
394 10, // line n
395 12, // line n
396 10, // line n
397 8, // line n+1
398 8 // line n+1
402 GXRModeObj TVNtsc480ProgAa =
404 VI_TVMODE_NTSC_PROG, // viDisplayMode
405 640, // fbWidth
406 242, // efbHeight
407 480, // xfbHeight
408 (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin
409 (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
410 640, // viWidth
411 480, // viHeight
412 VI_XFBMODE_SF, // xFBmode
413 GX_FALSE, // field_rendering
414 GX_TRUE, // aa
416 // sample points arranged in increasing Y order
418 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
419 {3,2},{9,6},{3,10}, // pix 1
420 {9,2},{3,6},{9,10}, // pix 2
421 {9,2},{3,6},{9,10} // pix 3
424 // vertical filter[7], 1/64 units, 6 bits each
426 4, // line n-1
427 8, // line n-1
428 12, // line n
429 16, // line n
430 12, // line n
431 8, // line n+1
432 4 // line n+1
436 GXRModeObj TVMpal480IntDf =
438 VI_TVMODE_MPAL_INT, // viDisplayMode
439 640, // fbWidth
440 480, // efbHeight
441 480, // xfbHeight
442 (VI_MAX_WIDTH_MPAL - 640)/2, // viXOrigin
443 (VI_MAX_HEIGHT_MPAL - 480)/2, // viYOrigin
444 640, // viWidth
445 480, // viHeight
446 VI_XFBMODE_DF, // xFBmode
447 GX_FALSE, // field_rendering
448 GX_FALSE, // aa
450 // sample points arranged in increasing Y order
452 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
453 {6,6},{6,6},{6,6}, // pix 1
454 {6,6},{6,6},{6,6}, // pix 2
455 {6,6},{6,6},{6,6} // pix 3
458 // vertical filter[7], 1/64 units, 6 bits each
460 8, // line n-1
461 8, // line n-1
462 10, // line n
463 12, // line n
464 10, // line n
465 8, // line n+1
466 8 // line n+1
470 GXRModeObj TVMpal480IntAa =
472 VI_TVMODE_MPAL_INT, // viDisplayMode
473 640, // fbWidth
474 242, // efbHeight
475 480, // xfbHeight
476 (VI_MAX_WIDTH_MPAL - 640)/2, // viXOrigin
477 (VI_MAX_HEIGHT_MPAL - 480)/2, // viYOrigin
478 640, // viWidth
479 480, // viHeight
480 VI_XFBMODE_DF, // xFBmode
481 GX_FALSE, // field_rendering
482 GX_TRUE, // aa
484 // sample points arranged in increasing Y order
486 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
487 {3,2},{9,6},{3,10}, // pix 1
488 {9,2},{3,6},{9,10}, // pix 2
489 {9,2},{3,6},{9,10} // pix 3
492 // vertical filter[7], 1/64 units, 6 bits each
494 4, // line n-1
495 8, // line n-1
496 12, // line n
497 16, // line n
498 12, // line n
499 8, // line n+1
500 4 // line n+1
504 GXRModeObj TVMpal240Ds =
506 VI_TVMODE_MPAL_DS, // viDisplayMode
507 640, // fbWidth
508 240, // efbHeight
509 240, // xfbHeight
510 (VI_MAX_WIDTH_MPAL - 640)/2, // viXOrigin
511 (VI_MAX_HEIGHT_MPAL - 480)/2, // viYOrigin
512 640, // viWidth
513 480, // viHeight
514 VI_XFBMODE_SF, // xFBmode
515 GX_FALSE, // field_rendering
516 GX_FALSE, // aa
518 // sample points arranged in increasing Y order
520 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
521 {6,6},{6,6},{6,6}, // pix 1
522 {6,6},{6,6},{6,6}, // pix 2
523 {6,6},{6,6},{6,6} // pix 3
526 // vertical filter[7], 1/64 units, 6 bits each
528 0, // line n-1
529 0, // line n-1
530 21, // line n
531 22, // line n
532 21, // line n
533 0, // line n+1
534 0 // line n+1
538 GXRModeObj TVMpal240DsAa =
540 VI_TVMODE_MPAL_DS, // viDisplayMode
541 640, // fbWidth
542 240, // efbHeight
543 240, // xfbHeight
544 (VI_MAX_WIDTH_MPAL - 640)/2, // viXOrigin
545 (VI_MAX_HEIGHT_MPAL - 480)/2, // viYOrigin
546 640, // viWidth
547 480, // viHeight
548 VI_XFBMODE_SF, // xFBmode
549 GX_FALSE, // field_rendering
550 GX_TRUE, // aa
552 // sample points arranged in increasing Y order
554 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
555 {3,2},{9,6},{3,10}, // pix 1
556 {9,2},{3,6},{9,10}, // pix 2
557 {9,2},{3,6},{9,10} // pix 3
560 // vertical filter[7], 1/64 units, 6 bits each
562 0, // line n-1
563 0, // line n-1
564 21, // line n
565 22, // line n
566 21, // line n
567 0, // line n+1
568 0 // line n+1
572 GXRModeObj TVPal264Ds =
574 VI_TVMODE_PAL_DS, // viDisplayMode
575 640, // fbWidth
576 264, // efbHeight
577 264, // xfbHeight
578 (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin
579 (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin
580 640, // viWidth
581 528, // viHeight
582 VI_XFBMODE_SF, // xFBmode
583 GX_FALSE, // field_rendering
584 GX_FALSE, // aa
586 // sample points arranged in increasing Y order
588 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
589 {6,6},{6,6},{6,6}, // pix 1
590 {6,6},{6,6},{6,6}, // pix 2
591 {6,6},{6,6},{6,6} // pix 3
594 // vertical filter[7], 1/64 units, 6 bits each
596 0, // line n-1
597 0, // line n-1
598 21, // line n
599 22, // line n
600 21, // line n
601 0, // line n+1
602 0 // line n+1
606 GXRModeObj TVPal264DsAa =
608 VI_TVMODE_PAL_DS, // viDisplayMode
609 640, // fbWidth
610 264, // efbHeight
611 264, // xfbHeight
612 (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin
613 (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin
614 640, // viWidth
615 528, // viHeight
616 VI_XFBMODE_SF, // xFBmode
617 GX_FALSE, // field_rendering
618 GX_TRUE, // aa
620 // sample points arranged in increasing Y order
622 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
623 {3,2},{9,6},{3,10}, // pix 1
624 {9,2},{3,6},{9,10}, // pix 2
625 {9,2},{3,6},{9,10} // pix 3
628 // vertical filter[7], 1/64 units, 6 bits each
630 0, // line n-1
631 0, // line n-1
632 21, // line n
633 22, // line n
634 21, // line n
635 0, // line n+1
636 0 // line n+1
640 GXRModeObj TVPal264Int =
642 VI_TVMODE_PAL_INT, // viDisplayMode
643 640, // fbWidth
644 264, // efbHeight
645 264, // xfbHeight
646 (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin
647 (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin
648 640, // viWidth
649 528, // viHeight
650 VI_XFBMODE_SF, // xFBmode
651 GX_TRUE, // field_rendering
652 GX_FALSE, // aa
654 // sample points arranged in increasing Y order
656 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
657 {6,6},{6,6},{6,6}, // pix 1
658 {6,6},{6,6},{6,6}, // pix 2
659 {6,6},{6,6},{6,6} // pix 3
662 // vertical filter[7], 1/64 units, 6 bits each
664 0, // line n-1
665 0, // line n-1
666 21, // line n
667 22, // line n
668 21, // line n
669 0, // line n+1
670 0 // line n+1
674 GXRModeObj TVPal264IntAa =
676 VI_TVMODE_PAL_INT, // viDisplayMode
677 640, // fbWidth
678 264, // efbHeight
679 264, // xfbHeight
680 (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin
681 (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin
682 640, // viWidth
683 528, // viHeight
684 VI_XFBMODE_SF, // xFBmode
685 GX_TRUE, // field_rendering
686 GX_TRUE, // aa
688 // sample points arranged in increasing Y order
690 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
691 {3,2},{9,6},{3,10}, // pix 1
692 {9,2},{3,6},{9,10}, // pix 2
693 {9,2},{3,6},{9,10} // pix 3
696 // vertical filter[7], 1/64 units, 6 bits each
698 0, // line n-1
699 0, // line n-1
700 21, // line n
701 22, // line n
702 21, // line n
703 0, // line n+1
704 0 // line n+1
708 GXRModeObj TVPal524IntAa =
710 VI_TVMODE_PAL_INT,
711 640,
712 264,
713 524,
714 (VI_MAX_WIDTH_PAL-640)/2,
715 (VI_MAX_HEIGHT_PAL-528)/2,
716 640,
717 524,
718 VI_XFBMODE_DF,
719 GX_FALSE,
720 GX_TRUE,
722 // sample points arranged in increasing Y order
724 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
725 {3,2},{9,6},{3,10}, // pix 1
726 {9,2},{3,6},{9,10}, // pix 2
727 {9,2},{3,6},{9,10} // pix 3
730 // vertical filter[7], 1/64 units, 6 bits each
732 4, // line n-1
733 8, // line n-1
734 12, // line n
735 16, // line n
736 12, // line n
737 8, // line n+1
738 4 // line n+1
742 GXRModeObj TVPal528Int =
744 VI_TVMODE_PAL_INT, // viDisplayMode
745 640, // fbWidth
746 528, // efbHeight
747 528, // xfbHeight
748 (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin
749 (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin
750 640, // viWidth
751 528, // viHeight
752 VI_XFBMODE_DF, // xFBmode
753 GX_FALSE, // field_rendering
754 GX_FALSE, // aa
756 // sample points arranged in increasing Y order
758 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
759 {6,6},{6,6},{6,6}, // pix 1
760 {6,6},{6,6},{6,6}, // pix 2
761 {6,6},{6,6},{6,6} // pix 3
764 // vertical filter[7], 1/64 units, 6 bits each
766 0, // line n-1
767 0, // line n-1
768 21, // line n
769 22, // line n
770 21, // line n
771 0, // line n+1
772 0 // line n+1
776 GXRModeObj TVPal528IntDf =
778 VI_TVMODE_PAL_INT, // viDisplayMode
779 640, // fbWidth
780 528, // efbHeight
781 528, // xfbHeight
782 (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin
783 (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin
784 640, // viWidth
785 528, // viHeight
786 VI_XFBMODE_DF, // xFBmode
787 GX_FALSE, // field_rendering
788 GX_FALSE, // aa
790 // sample points arranged in increasing Y order
792 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
793 {6,6},{6,6},{6,6}, // pix 1
794 {6,6},{6,6},{6,6}, // pix 2
795 {6,6},{6,6},{6,6} // pix 3
797 // vertical filter[7], 1/64 units, 6 bits each
799 8, // line n-1
800 8, // line n-1
801 10, // line n
802 12, // line n
803 10, // line n
804 8, // line n+1
805 8 // line n+1
809 GXRModeObj TVPal574IntDfScale =
811 VI_TVMODE_PAL_INT, // viDisplayMode
812 640, // fbWidth
813 480, // efbHeight
814 574, // xfbHeight
815 (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin
816 (VI_MAX_HEIGHT_PAL - 574)/2, // viYOrigin
817 640, // viWidth
818 574, // viHeight
819 VI_XFBMODE_DF, // xFBmode
820 GX_FALSE, // field_rendering
821 GX_FALSE, // aa
823 // sample points arranged in increasing Y order
825 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
826 {6,6},{6,6},{6,6}, // pix 1
827 {6,6},{6,6},{6,6}, // pix 2
828 {6,6},{6,6},{6,6} // pix 3
830 // vertical filter[7], 1/64 units, 6 bits each
832 8, // line n-1
833 8, // line n-1
834 10, // line n
835 12, // line n
836 10, // line n
837 8, // line n+1
838 8 // line n+1
842 GXRModeObj TVEurgb60Hz240Ds =
844 VI_TVMODE_EURGB60_DS, // viDisplayMode
845 640, // fbWidth
846 240, // efbHeight
847 240, // xfbHeight
848 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
849 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
850 640, // viWidth
851 480, // viHeight
852 VI_XFBMODE_SF, // xFBmode
853 GX_FALSE, // field_rendering
854 GX_FALSE, // aa
856 // sample points arranged in increasing Y order
858 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
859 {6,6},{6,6},{6,6}, // pix 1
860 {6,6},{6,6},{6,6}, // pix 2
861 {6,6},{6,6},{6,6} // pix 3
863 // vertical filter[7], 1/64 units, 6 bits each
865 0, // line n-1
866 0, // line n-1
867 21, // line n
868 22, // line n
869 21, // line n
870 0, // line n+1
871 0 // line n+1
875 GXRModeObj TVEurgb60Hz240DsAa =
877 VI_TVMODE_EURGB60_DS, // viDisplayMode
878 640, // fbWidth
879 240, // efbHeight
880 240, // xfbHeight
881 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
882 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
883 640, // viWidth
884 480, // viHeight
885 VI_XFBMODE_SF, // xFBmode
886 GX_FALSE, // field_rendering
887 GX_TRUE, // aa
889 // sample points arranged in increasing Y order
891 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
892 {3,2},{9,6},{3,10}, // pix 1
893 {9,2},{3,6},{9,10}, // pix 2
894 {9,2},{3,6},{9,10} // pix 3
896 // vertical filter[7], 1/64 units, 6 bits each
898 0, // line n-1
899 0, // line n-1
900 21, // line n
901 22, // line n
902 21, // line n
903 0, // line n+1
904 0 // line n+1
908 GXRModeObj TVEurgb60Hz240Int =
910 VI_TVMODE_EURGB60_INT, // viDisplayMode
911 640, // fbWidth
912 240, // efbHeight
913 240, // xfbHeight
914 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
915 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
916 640, // viWidth
917 480, // viHeight
918 VI_XFBMODE_SF, // xFBmode
919 GX_TRUE, // field_rendering
920 GX_FALSE, // aa
922 // sample points arranged in increasing Y order
924 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
925 {6,6},{6,6},{6,6}, // pix 1
926 {6,6},{6,6},{6,6}, // pix 2
927 {6,6},{6,6},{6,6} // pix 3
929 // vertical filter[7], 1/64 units, 6 bits each
931 0, // line n-1
932 0, // line n-1
933 21, // line n
934 22, // line n
935 21, // line n
936 0, // line n+1
937 0 // line n+1
941 GXRModeObj TVEurgb60Hz240IntAa =
943 VI_TVMODE_EURGB60_INT, // viDisplayMode
944 640, // fbWidth
945 240, // efbHeight
946 240, // xfbHeight
947 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
948 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
949 640, // viWidth
950 480, // viHeight
951 VI_XFBMODE_SF, // xFBmode
952 GX_TRUE, // field_rendering
953 GX_TRUE, // aa
955 // sample points arranged in increasing Y order
957 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
958 {3,2},{9,6},{3,10}, // pix 1
959 {9,2},{3,6},{9,10}, // pix 2
960 {9,2},{3,6},{9,10} // pix 3
962 // vertical filter[7], 1/64 units, 6 bits each
964 0, // line n-1
965 0, // line n-1
966 21, // line n
967 22, // line n
968 21, // line n
969 0, // line n+1
970 0 // line n+1
974 GXRModeObj TVEurgb60Hz480Int =
976 VI_TVMODE_EURGB60_INT, // viDisplayMode
977 640, // fbWidth
978 480, // efbHeight
979 480, // xfbHeight
980 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
981 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
982 640, // viWidth
983 480, // viHeight
984 VI_XFBMODE_DF, // xFBmode
985 GX_FALSE, // field_rendering
986 GX_FALSE, // aa
988 // sample points arranged in increasing Y order
990 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
991 {6,6},{6,6},{6,6}, // pix 1
992 {6,6},{6,6},{6,6}, // pix 2
993 {6,6},{6,6},{6,6} // pix 3
995 // vertical filter[7], 1/64 units, 6 bits each
997 0, // line n-1
998 0, // line n-1
999 21, // line n
1000 22, // line n
1001 21, // line n
1002 0, // line n+1
1003 0 // line n+1
1007 GXRModeObj TVEurgb60Hz480IntDf =
1009 VI_TVMODE_EURGB60_INT, // viDisplayMode
1010 640, // fbWidth
1011 480, // efbHeight
1012 480, // xfbHeight
1013 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
1014 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
1015 640, // viWidth
1016 480, // viHeight
1017 VI_XFBMODE_DF, // xFBmode
1018 GX_FALSE, // field_rendering
1019 GX_FALSE, // aa
1021 // sample points arranged in increasing Y order
1023 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
1024 {6,6},{6,6},{6,6}, // pix 1
1025 {6,6},{6,6},{6,6}, // pix 2
1026 {6,6},{6,6},{6,6} // pix 3
1028 // vertical filter[7], 1/64 units, 6 bits each
1030 8, // line n-1
1031 8, // line n-1
1032 10, // line n
1033 12, // line n
1034 10, // line n
1035 8, // line n+1
1036 8 // line n+1
1040 GXRModeObj TVEurgb60Hz480IntAa =
1042 VI_TVMODE_EURGB60_INT, // viDisplayMode
1043 640, // fbWidth
1044 242, // efbHeight
1045 480, // xfbHeight
1046 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
1047 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
1048 640, // viWidth
1049 480, // viHeight
1050 VI_XFBMODE_DF, // xFBmode
1051 GX_FALSE, // field_rendering
1052 GX_FALSE, // aa
1054 // sample points arranged in increasing Y order
1056 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
1057 {3,2},{9,6},{3,10}, // pix 1
1058 {9,2},{3,6},{9,10}, // pix 2
1059 {9,2},{3,6},{9,10} // pix 3
1061 // vertical filter[7], 1/64 units, 6 bits each
1063 4, // line n-1
1064 8, // line n-1
1065 12, // line n
1066 16, // line n
1067 12, // line n
1068 8, // line n+1
1069 4 // line n+1
1073 GXRModeObj TVEurgb60Hz480Prog =
1075 VI_TVMODE_EURGB60_PROG, // viDisplayMode
1076 640, // fbWidth
1077 480, // efbHeight
1078 480, // xfbHeight
1079 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
1080 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
1081 640, // viWidth
1082 480, // viHeight
1083 VI_XFBMODE_SF, // xFBmode
1084 GX_FALSE, // field_rendering
1085 GX_FALSE, // aa
1087 // sample points arranged in increasing Y order
1089 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
1090 {6,6},{6,6},{6,6}, // pix 1
1091 {6,6},{6,6},{6,6}, // pix 2
1092 {6,6},{6,6},{6,6} // pix 3
1094 // vertical filter[7], 1/64 units, 6 bits each
1096 0, // line n-1
1097 0, // line n-1
1098 21, // line n
1099 22, // line n
1100 21, // line n
1101 0, // line n+1
1102 0 // line n+1
1106 GXRModeObj TVEurgb60Hz480ProgSoft =
1108 VI_TVMODE_EURGB60_PROG, // viDisplayMode
1109 640, // fbWidth
1110 480, // efbHeight
1111 480, // xfbHeight
1112 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
1113 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
1114 640, // viWidth
1115 480, // viHeight
1116 VI_XFBMODE_SF, // xFBmode
1117 GX_FALSE, // field_rendering
1118 GX_FALSE, // aa
1120 // sample points arranged in increasing Y order
1122 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
1123 {3,2},{9,6},{3,10}, // pix 1
1124 {9,2},{3,6},{9,10}, // pix 2
1125 {9,2},{3,6},{9,10} // pix 3
1127 // vertical filter[7], 1/64 units, 6 bits each
1129 4, // line n-1
1130 8, // line n-1
1131 12, // line n
1132 16, // line n
1133 12, // line n
1134 8, // line n+1
1135 4 // line n+1
1139 GXRModeObj TVEurgb60Hz480ProgAa =
1141 VI_TVMODE_EURGB60_PROG, // viDisplayMode
1142 640, // fbWidth
1143 242, // efbHeight
1144 480, // xfbHeight
1145 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
1146 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
1147 640, // viWidth
1148 480, // viHeight
1149 VI_XFBMODE_SF, // xFBmode
1150 GX_FALSE, // field_rendering
1151 GX_TRUE, // aa
1153 // sample points arranged in increasing Y order
1155 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
1156 {6,6},{6,6},{6,6}, // pix 1
1157 {6,6},{6,6},{6,6}, // pix 2
1158 {6,6},{6,6},{6,6} // pix 3
1160 // vertical filter[7], 1/64 units, 6 bits each
1162 8, // line n-1
1163 8, // line n-1
1164 10, // line n
1165 12, // line n
1166 10, // line n
1167 8, // line n+1
1168 8 // line n+1
1173 static const u16 taps[26] = {
1174 0x01F0,0x01DC,0x01AE,0x0174,0x0129,0x00DB,
1175 0x008E,0x0046,0x000C,0x00E2,0x00CB,0x00C0,
1176 0x00C4,0x00CF,0x00DE,0x00EC,0x00FC,0x0008,
1177 0x000F,0x0013,0x0013,0x000F,0x000C,0x0008,
1178 0x0001,0x0000
1181 static const struct _timing {
1182 u8 equ;
1183 u16 acv;
1184 u16 prbOdd,prbEven;
1185 u16 psbOdd,psbEven;
1186 u8 bs1,bs2,bs3,bs4;
1187 u16 be1,be2,be3,be4;
1188 u16 nhlines,hlw;
1189 u8 hsy,hcs,hce,hbe640;
1190 u16 hbs640;
1191 u8 hbeCCIR656;
1192 u16 hbsCCIR656;
1193 } video_timing[] = {
1195 0x06,0x00F0,
1196 0x0018,0x0019,0x0003,0x0002,
1197 0x0C,0x0D,0x0C,0x0D,
1198 0x0208,0x0207,0x0208,0x0207,
1199 0x020D,0x01AD,
1200 0x40,0x47,0x69,0xA2,
1201 0x0175,
1202 0x7A,0x019C
1205 0x06,0x00F0,
1206 0x0018,0x0018,0x0004,0x0004,
1207 0x0C,0x0C,0x0C,0x0C,
1208 0x0208,0x0208,0x0208,0x0208,
1209 0x020E,0x01AD,
1210 0x40,0x47,0x69,0xA2,
1211 0x0175,
1212 0x7A,0x019C
1215 0x05,0x011F,
1216 0x0023,0x0024,0x0001,0x0000,
1217 0x0D,0x0C,0x0B,0x0A,
1218 0x026B,0x026A,0x0269,0x026C,
1219 0x0271,0x01B0,
1220 0x40,0x4B,0x6A,0xAC,
1221 0x017C,
1222 0x85,0x01A4
1225 0x05,0x011F,
1226 0x0021,0x0021,0x0002,0x0002,
1227 0x0D,0x0B,0x0D,0x0B,
1228 0x026B,0x026D,0x026B,0x026D,
1229 0x0270,0x01B0,
1230 0x40,0x4B,0x6A,0xAC,
1231 0x017C,
1232 0x85,0x01A4
1235 0x06,0x00F0,
1236 0x0018,0x0019,0x0003,0x0002,
1237 0x10,0x0F,0x0E,0x0D,
1238 0x0206,0x0205,0x0204,0x0207,
1239 0x020D,0x01AD,
1240 0x40,0x4E,0x70,0xA2,
1241 0x0175,
1242 0x7A,0x019C
1245 0x06,0x00F0,
1246 0x0018,0x0018,0x0004,0x0004,
1247 0x10,0x0E,0x10,0x0E,
1248 0x0206,0x0208,0x0206,0x0208,
1249 0x020E,0x01AD,
1250 0x40,0x4E,0x70,0xA2,
1251 0x0175,
1252 0x7A,0x019C
1255 0x0C,0x01e0,
1256 0x0030,0x0030,0x0006,0x0006,
1257 0x18,0x18,0x18,0x18,
1258 0x040e,0x040e,0x040e,0x040e,
1259 0x041a,0x01ad,
1260 0x40,0x47,0x69,0xa2,
1261 0x0175,
1262 0x7a,0x019c
1265 0x0c,0x01e0,
1266 0x002c,0x002c,0x000a,0x000a,
1267 0x18,0x18,0x18,0x18,
1268 0x040e,0x040e,0x040e,0x040e,
1269 0x041a,0x01ad,
1270 0x40,0x47,0x69,0xa8,
1271 0x017b,
1272 0x7a,0x019c
1275 0x06,0x00F1,
1276 0x0018,0x0019,0x0001,0x0000,
1277 0x0C,0x0D,0x0C,0x0D,
1278 0x0208,0x0207,0x0208,0x0207,
1279 0x020D,0x01AD,
1280 0x40,0x47,0x69,0x9F,
1281 0x0172,
1282 0x7A,0x019C
1285 0x0C,0x01E0,
1286 0x0030,0x0030,0x0006,0x0006,
1287 0x18,0x18,0x18,0x18,
1288 0x040E,0x040E,0x040E,0x040E,
1289 0x041A,0x01AD,
1290 0x40,0x47,0x69,0xB4,
1291 0x0187,
1292 0x7A,0x019C
1296 #if defined(HW_RVL)
1297 static u32 vdacFlagRegion;
1298 static u32 i2cIdentFirst = 0;
1299 static u32 i2cIdentFlag = 1;
1300 static u32 oldTvStatus = 0x03e7;
1301 static u32 oldDtvStatus = 0x03e7;
1302 static vu32* const _i2cReg = (u32*)0xCD800000;
1303 #endif
1305 static u16 regs[60];
1306 static u16 shdw_regs[60];
1307 static u32 encoderType,fbSet = 0;
1308 static s16 displayOffsetH;
1309 static s16 displayOffsetV;
1310 static u32 currTvMode,changeMode;
1311 static u32 shdw_changeMode,flushFlag;
1312 static u64 changed,shdw_changed;
1313 static vu32 retraceCount;
1314 static const struct _timing *currTiming;
1315 static lwpq_t video_queue;
1316 static horVer HorVer;
1317 static void *currentFb = NULL;
1318 static void *nextFb = NULL;
1319 static VIRetraceCallback preRetraceCB = NULL;
1320 static VIRetraceCallback postRetraceCB = NULL;
1321 static VIPositionCallback positionCB = NULL;
1323 static vu16* const _viReg = (u16*)0xCC002000;
1325 extern syssram* __SYS_LockSram();
1326 extern u32 __SYS_UnlockSram(u32 write);
1328 extern void __VIClearFramebuffer(void*,u32,u32);
1330 extern void udelay(int us);
1332 #ifdef _VIDEO_DEBUG
1333 static u32 messages$128 = 0;
1334 static u32 printregs = 1;
1336 static void printRegs()
1338 if(!printregs) {
1339 printf("displayOffsetH = %d\ndisplayOffsetV = %d\n",displayOffsetH,displayOffsetV);
1340 printf("%08x%08x\n",(u32)(shdw_changed>>32),(u32)shdw_changed);
1342 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",shdw_regs[0],shdw_regs[1],shdw_regs[2],shdw_regs[3],shdw_regs[4],shdw_regs[5],shdw_regs[6],shdw_regs[7]);
1343 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",shdw_regs[8],shdw_regs[9],shdw_regs[10],shdw_regs[11],shdw_regs[12],shdw_regs[13],shdw_regs[14],shdw_regs[15]);
1344 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",shdw_regs[16],shdw_regs[17],shdw_regs[18],shdw_regs[19],shdw_regs[20],shdw_regs[21],shdw_regs[22],shdw_regs[23]);
1345 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",shdw_regs[24],shdw_regs[25],shdw_regs[26],shdw_regs[27],shdw_regs[28],shdw_regs[29],shdw_regs[30],shdw_regs[31]);
1346 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",shdw_regs[32],shdw_regs[33],shdw_regs[34],shdw_regs[35],shdw_regs[36],shdw_regs[37],shdw_regs[38],shdw_regs[39]);
1347 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",shdw_regs[40],shdw_regs[41],shdw_regs[42],shdw_regs[43],shdw_regs[44],shdw_regs[45],shdw_regs[46],shdw_regs[47]);
1348 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",shdw_regs[48],shdw_regs[49],shdw_regs[50],shdw_regs[51],shdw_regs[52],shdw_regs[53],shdw_regs[54],shdw_regs[55]);
1349 printf("%04x %04x %04x %04x\n\n",shdw_regs[56],shdw_regs[57],shdw_regs[58],shdw_regs[59]);
1351 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",_viReg[0],_viReg[1],_viReg[2],_viReg[3],_viReg[4],_viReg[5],_viReg[6],_viReg[7]);
1352 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",_viReg[8],_viReg[9],_viReg[10],_viReg[11],_viReg[12],_viReg[13],_viReg[14],_viReg[15]);
1353 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",_viReg[16],_viReg[17],_viReg[18],_viReg[19],_viReg[20],_viReg[21],_viReg[22],_viReg[23]);
1354 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",_viReg[24],_viReg[25],_viReg[26],_viReg[27],_viReg[28],_viReg[29],_viReg[30],_viReg[31]);
1355 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",_viReg[32],_viReg[33],_viReg[34],_viReg[35],_viReg[36],_viReg[37],_viReg[38],_viReg[39]);
1356 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",_viReg[40],_viReg[41],_viReg[42],_viReg[43],_viReg[44],_viReg[45],_viReg[46],_viReg[47]);
1357 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",_viReg[48],_viReg[49],_viReg[50],_viReg[51],_viReg[52],_viReg[53],_viReg[54],_viReg[55]);
1358 printf("%04x %04x %04x %04x\n",_viReg[56],_viReg[57],_viReg[58],_viReg[59]);
1359 printregs = 1;
1363 static void printDebugCalculations()
1365 if(!messages$128) {
1366 messages$128 = 1;
1367 printf("HorVer.dispPosX = %d\n",HorVer.dispPosX);
1368 printf("HorVer.dispPosY = %d\n",HorVer.dispPosY);
1369 printf("HorVer.dispSizeX = %d\n",HorVer.dispSizeX);
1370 printf("HorVer.dispSizeY = %d\n",HorVer.dispSizeY);
1371 printf("HorVer.adjustedDispPosX = %d\n",HorVer.adjustedDispPosX);
1372 printf("HorVer.adjustedDispPosY = %d\n",HorVer.adjustedDispPosY);
1373 printf("HorVer.adjustedDispSizeY = %d\n",HorVer.adjustedDispSizeY);
1374 printf("HorVer.adjustedPanPosY = %d\n",HorVer.adjustedPanPosY);
1375 printf("HorVer.adjustedPanSizeY = %d\n",HorVer.adjustedPanSizeY);
1376 printf("HorVer.fbSizeX = %d\n",HorVer.fbSizeX);
1377 printf("HorVer.fbSizeY = %d\n",HorVer.fbSizeY);
1378 printf("HorVer.panPosX = %d\n",HorVer.panPosX);
1379 printf("HorVer.panPosY = %d\n",HorVer.panPosY);
1380 printf("HorVer.panSizeX = %d\n",HorVer.panSizeX);
1381 printf("HorVer.panSizeY = %d\n",HorVer.panSizeY);
1382 printf("HorVer.fbMode = %d\n",HorVer.fbMode);
1383 printf("HorVer.nonInter = %d\n",HorVer.nonInter);
1384 printf("HorVer.tv = %d\n",HorVer.tv);
1385 printf("HorVer.wordPerLine = %d\n",HorVer.wordPerLine);
1386 printf("HorVer.wpl = %d\n",HorVer.wpl);
1387 printf("HorVer.std = %d\n",HorVer.std);
1388 printf("HorVer.xof = %d\n",HorVer.xof);
1389 printf("HorVer.bufAddr = %p\n",HorVer.bufAddr);
1390 printf("HorVer.tfbb = 0x%08x\n",HorVer.tfbb);
1391 printf("HorVer.bfbb = 0x%08x\n",HorVer.bfbb);
1392 printf("HorVer.rbufAddr = %p\n",HorVer.rbufAddr);
1393 printf("HorVer.rtfbb = 0x%08x\n",HorVer.rtfbb);
1394 printf("HorVer.rbfbb = 0x%08x\n",HorVer.rbfbb);
1395 printf("HorVer.black = %d\n",HorVer.black);
1396 printf("HorVer.threeD = %d\n",HorVer.threeD);
1399 #endif
1401 static __inline__ u32 cntlzd(u64 bit)
1403 u32 hi,lo,value = 0;
1405 hi = (u32)(bit>>32);
1406 lo = (u32)(bit&-1);
1408 value = cntlzw(hi);
1409 if(value>=32) value += cntlzw(lo);
1411 return value;
1414 static const struct _timing* __gettiming(u32 vimode)
1416 if(vimode>0x1e) return NULL;
1418 switch(vimode) {
1419 case VI_TVMODE_NTSC_INT:
1420 return &video_timing[0];
1421 break;
1422 case VI_TVMODE_NTSC_DS:
1423 return &video_timing[1];
1424 break;
1425 case VI_TVMODE_PAL_INT:
1426 return &video_timing[2];
1427 break;
1428 case VI_TVMODE_PAL_DS:
1429 return &video_timing[3];
1430 break;
1431 case VI_TVMODE_EURGB60_INT:
1432 return &video_timing[0];
1433 break;
1434 case VI_TVMODE_EURGB60_DS:
1435 return &video_timing[1];
1436 break;
1437 case VI_TVMODE_MPAL_INT:
1438 return &video_timing[4];
1439 break;
1440 case VI_TVMODE_MPAL_DS:
1441 return &video_timing[5];
1442 break;
1443 case VI_TVMODE_NTSC_PROG:
1444 return &video_timing[6];
1445 break;
1446 case VI_TVMODE_NTSC_PROG_DS:
1447 return &video_timing[7];
1448 break;
1449 case VI_TVMODE_DEBUG_PAL_INT:
1450 return &video_timing[2];
1451 break;
1452 case VI_TVMODE_DEBUG_PAL_DS:
1453 return &video_timing[3];
1454 break;
1455 default:
1456 break;
1458 return NULL;
1461 #if defined(HW_RVL)
1462 static inline void __viOpenI2C(u32 channel)
1464 u32 val = ((_i2cReg[49]&~0x8000)|0x4000);
1465 val |= _SHIFTL(channel,15,1);
1466 _i2cReg[49] = val;
1469 static inline u32 __viSetSCL(u32 channel)
1471 u32 val = (_i2cReg[48]&~0x4000);
1472 val |= _SHIFTL(channel,14,1);
1473 _i2cReg[48] = val;
1474 return 1;
1476 static inline u32 __viSetSDA(u32 channel)
1478 u32 val = (_i2cReg[48]&~0x8000);
1479 val |= _SHIFTL(channel,15,1);
1480 _i2cReg[48] = val;
1481 return 1;
1484 static inline u32 __viGetSDA()
1486 return _SHIFTR(_i2cReg[50],15,1);
1489 static inline void __viCheckI2C()
1491 __viOpenI2C(0);
1492 udelay(4);
1494 i2cIdentFlag = 0;
1495 if(__viGetSDA()!=0) i2cIdentFlag = 1;
1498 static u32 __sendSlaveAddress(u8 addr)
1500 u32 i;
1502 __viSetSDA(i2cIdentFlag^1);
1503 udelay(2);
1505 __viSetSCL(0);
1506 for(i=0;i<8;i++) {
1507 if(addr&0x80) __viSetSDA(i2cIdentFlag);
1508 else __viSetSDA(i2cIdentFlag^1);
1509 udelay(2);
1511 __viSetSCL(1);
1512 udelay(2);
1514 __viSetSCL(0);
1515 addr <<= 1;
1518 __viOpenI2C(0);
1519 udelay(2);
1521 __viSetSCL(1);
1522 udelay(2);
1524 if(i2cIdentFlag==1 && __viGetSDA()!=0) return 0;
1526 __viSetSDA(i2cIdentFlag^1);
1527 __viOpenI2C(1);
1528 __viSetSCL(0);
1530 return 1;
1532 #endif
1534 static inline void __setInterruptRegs(const struct _timing *tm)
1536 u16 hlw;
1538 hlw = 0;
1539 if(tm->nhlines%2) hlw = tm->hlw;
1540 regs[24] = 0x1000|((tm->nhlines/2)+1);
1541 regs[25] = hlw+1;
1542 changed |= VI_REGCHANGE(24);
1543 changed |= VI_REGCHANGE(25);
1546 static inline void __setPicConfig(u16 fbSizeX,u32 xfbMode,u16 panPosX,u16 panSizeX,u8 *wordPerLine,u8 *std,u8 *wpl,u8 *xof)
1548 *wordPerLine = (fbSizeX+15)/16;
1549 *std = *wordPerLine;
1550 if(xfbMode==VI_XFBMODE_DF) *std <<= 1;
1552 *xof = panPosX%16;
1553 *wpl = (*xof+(panSizeX+15))/16;
1554 regs[36] = (*wpl<<8)|*std;
1555 changed |= VI_REGCHANGE(36);
1558 static inline void __setBBIntervalRegs(const struct _timing *tm)
1560 regs[10] = (tm->be3<<5)|tm->bs3;
1561 regs[11] = (tm->be1<<5)|tm->bs1;
1562 changed |= VI_REGCHANGE(10);
1563 changed |= VI_REGCHANGE(11);
1565 regs[12] = (tm->be4<<5)|tm->bs4;
1566 regs[13] = (tm->be2<<5)|tm->bs2;
1567 changed |= VI_REGCHANGE(12);
1568 changed |= VI_REGCHANGE(13);
1571 static void __setScalingRegs(u16 panSizeX,u16 dispSizeX,s32 threeD)
1573 if(threeD) panSizeX = _SHIFTL(panSizeX,1,16);
1574 if(panSizeX<dispSizeX) {
1575 regs[37] = 0x1000|((dispSizeX+(_SHIFTL(panSizeX,8,16)-1))/dispSizeX);
1576 regs[56] = panSizeX;
1577 changed |= VI_REGCHANGE(37);
1578 changed |= VI_REGCHANGE(56);
1579 } else {
1580 regs[37] = 0x100;
1581 changed |= VI_REGCHANGE(37);
1585 static inline void __calcFbbs(u32 bufAddr,u16 panPosX,u16 panPosY,u8 wordperline,u32 xfbMode,u16 dispPosY,u32 *tfbb,u32 *bfbb)
1587 u32 bytesPerLine,tmp;
1589 panPosX &= 0xfff0;
1590 bytesPerLine = (wordperline<<5)&0x1fe0;
1591 *tfbb = bufAddr+((panPosX<<5)+(panPosY*bytesPerLine));
1592 *bfbb = *tfbb;
1593 if(xfbMode==VI_XFBMODE_DF) *bfbb = *tfbb+bytesPerLine;
1595 if(dispPosY%2) {
1596 tmp = *tfbb;
1597 *tfbb = *bfbb;
1598 *bfbb = tmp;
1601 *tfbb = MEM_VIRTUAL_TO_PHYSICAL(*tfbb);
1602 *bfbb = MEM_VIRTUAL_TO_PHYSICAL(*bfbb);
1605 static inline void __setFbbRegs(struct _horVer *horVer,u32 *tfbb,u32 *bfbb,u32 *rtfbb,u32 *rbfbb)
1607 u32 flag;
1608 __calcFbbs((u32)horVer->bufAddr,horVer->panPosX,horVer->adjustedPanPosY,horVer->wordPerLine,horVer->fbMode,horVer->adjustedDispPosY,tfbb,bfbb);
1609 if(horVer->threeD) __calcFbbs((u32)horVer->rbufAddr,horVer->panPosX,horVer->adjustedPanPosY,horVer->wordPerLine,horVer->fbMode,horVer->adjustedDispPosY,rtfbb,rbfbb);
1611 flag = 1;
1612 if((*tfbb)<0x01000000 && (*bfbb)<0x01000000
1613 && (*rtfbb)<0x01000000 && (*rbfbb)<0x01000000) flag = 0;
1615 if(flag) {
1616 *tfbb >>= 5;
1617 *bfbb >>= 5;
1618 *rtfbb >>= 5;
1619 *rbfbb >>= 5;
1622 regs[14] = _SHIFTL(flag,12,1)|_SHIFTL(horVer->xof,8,4)|_SHIFTR(*tfbb,16,8);
1623 regs[15] = *tfbb&0xffff;
1624 changed |= VI_REGCHANGE(14);
1625 changed |= VI_REGCHANGE(15);
1627 regs[18] = _SHIFTR(*bfbb,16,8);
1628 regs[19] = *bfbb&0xffff;
1629 changed |= VI_REGCHANGE(18);
1630 changed |= VI_REGCHANGE(19);
1632 if(horVer->threeD) {
1633 regs[16] = _SHIFTR(*rtfbb,16,8);
1634 regs[17] = *rtfbb&0xffff;
1635 changed |= VI_REGCHANGE(16);
1636 changed |= VI_REGCHANGE(17);
1638 regs[20] = _SHIFTR(*rbfbb,16,8);
1639 regs[21] = *rbfbb&0xffff;
1640 changed |= VI_REGCHANGE(20);
1641 changed |= VI_REGCHANGE(21);
1645 static inline void __setHorizontalRegs(const struct _timing *tm,u16 dispPosX,u16 dispSizeX)
1647 u32 val1,val2;
1649 regs[2] = (tm->hcs<<8)|tm->hce;
1650 regs[3] = tm->hlw;
1651 changed |= VI_REGCHANGE(2);
1652 changed |= VI_REGCHANGE(3);
1654 val1 = (tm->hbe640+dispPosX-40)&0x01ff;
1655 val2 = (tm->hbs640+dispPosX+40)-(720-dispSizeX);
1656 regs[4] = (val1>>9)|(val2<<1);
1657 regs[5] = (val1<<7)|tm->hsy;
1658 changed |= VI_REGCHANGE(4);
1659 changed |= VI_REGCHANGE(5);
1662 static inline void __setVerticalRegs(u16 dispPosY,u16 dispSizeY,u8 equ,u16 acv,u16 prbOdd,u16 prbEven,u16 psbOdd,u16 psbEven,s32 black)
1664 u16 tmp;
1665 u32 div1,div2;
1666 u32 psb,prb;
1667 u32 psbodd,prbodd;
1668 u32 psbeven,prbeven;
1670 div1 = 2;
1671 div2 = 1;
1672 if(equ>=10) {
1673 div1 = 1;
1674 div2 = 2;
1677 prb = div2*dispPosY;
1678 psb = div2*(((acv*div1)-dispSizeY)-dispPosY);
1679 if(dispPosY%2) {
1680 prbodd = prbEven+prb;
1681 psbodd = psbEven+psb;
1682 prbeven = prbOdd+prb;
1683 psbeven = psbOdd+psb;
1684 } else {
1685 prbodd = prbOdd+prb;
1686 psbodd = psbOdd+psb;
1687 prbeven = prbEven+prb;
1688 psbeven = psbEven+psb;
1691 tmp = dispSizeY/div1;
1692 if(black) {
1693 prbodd += ((tmp<<1)-2);
1694 prbeven += ((tmp<<1)-2);
1695 psbodd += 2;
1696 psbeven += 2;
1697 tmp = 0;
1700 regs[0] = ((tmp<<4)&~0x0f)|equ;
1701 changed |= VI_REGCHANGE(0);
1703 regs[6] = psbodd;
1704 regs[7] = prbodd;
1705 changed |= VI_REGCHANGE(6);
1706 changed |= VI_REGCHANGE(7);
1708 regs[8] = psbeven;
1709 regs[9] = prbeven;
1710 changed |= VI_REGCHANGE(8);
1711 changed |= VI_REGCHANGE(9);
1714 static inline void __adjustPosition(u16 acv)
1716 u32 fact,field;
1717 s16 dispPosX,dispPosY;
1718 s16 dispSizeY,maxDispSizeY;
1720 dispPosX = (HorVer.dispPosX+displayOffsetH);
1721 if(dispPosX<=(720-HorVer.dispSizeX)) {
1722 if(dispPosX>=0) HorVer.adjustedDispPosX = dispPosX;
1723 else HorVer.adjustedDispPosX = 0;
1724 } else HorVer.adjustedDispPosX = (720-HorVer.dispSizeX);
1726 fact = 1;
1727 if(HorVer.fbMode==VI_XFBMODE_SF) fact = 2;
1729 field = HorVer.dispPosY&0x0001;
1730 dispPosY = HorVer.dispPosY+displayOffsetV;
1731 if(dispPosY>field) HorVer.adjustedDispPosY = dispPosY;
1732 else HorVer.adjustedDispPosY = field;
1734 dispSizeY = HorVer.dispPosY+HorVer.dispSizeY+displayOffsetV;
1735 maxDispSizeY = ((acv<<1)-field);
1736 if(dispSizeY>maxDispSizeY) dispSizeY -= (acv<<1)-field;
1737 else dispSizeY = 0;
1739 dispPosY = HorVer.dispPosY+displayOffsetV;
1740 if(dispPosY<field) dispPosY -= field;
1741 else dispPosY = 0;
1742 HorVer.adjustedDispSizeY = HorVer.dispSizeY+dispPosY-dispSizeY;
1744 dispPosY = HorVer.dispPosY+displayOffsetV;
1745 if(dispPosY<field) dispPosY -= field;
1746 else dispPosY = 0;
1747 HorVer.adjustedPanPosY = HorVer.panPosY-(dispPosY/fact);
1749 dispSizeY = HorVer.dispPosY+HorVer.dispSizeY+displayOffsetV;
1750 if(dispSizeY>maxDispSizeY) dispSizeY -= maxDispSizeY;
1751 else dispSizeY = 0;
1753 dispPosY = HorVer.dispPosY+displayOffsetV;
1754 if(dispPosY<field) dispPosY -= field;
1755 else dispPosY = 0;
1756 HorVer.adjustedPanSizeY = HorVer.panSizeY+(dispPosY/fact)-(dispSizeY/fact);
1759 static inline void __importAdjustingValues()
1761 #ifdef HW_DOL
1762 syssram *sram;
1764 sram = __SYS_LockSram();
1765 displayOffsetH = sram->display_offsetH;
1766 __SYS_UnlockSram(0);
1767 #else
1768 s8 offset;
1769 if ( CONF_GetDisplayOffsetH(&offset) == 0 ) {
1770 displayOffsetH = offset;
1771 } else {
1772 displayOffsetH = 0;
1774 #endif
1775 displayOffsetV = 0;
1778 static void __VIInit(u32 vimode)
1780 u32 cnt;
1781 u32 vi_mode,interlace,progressive;
1782 const struct _timing *cur_timing = NULL;
1784 vi_mode = ((vimode>>2)&0x07);
1785 interlace = (vimode&0x01);
1786 progressive = (vimode&0x02);
1788 cur_timing = __gettiming(vimode);
1790 //reset the interface
1791 cnt = 0;
1792 _viReg[1] = 0x02;
1793 while(cnt<1000) cnt++;
1794 _viReg[1] = 0x00;
1796 // now begin to setup the interface
1797 _viReg[2] = ((cur_timing->hcs<<8)|cur_timing->hce); //set HCS & HCE
1798 _viReg[3] = cur_timing->hlw; //set Half Line Width
1800 _viReg[4] = (cur_timing->hbs640<<1); //set HBS640
1801 _viReg[5] = ((cur_timing->hbe640<<7)|cur_timing->hsy); //set HBE640 & HSY
1803 _viReg[0] = cur_timing->equ;
1805 _viReg[6] = (cur_timing->psbOdd+2); //set PSB odd field
1806 _viReg[7] = (cur_timing->prbOdd+((cur_timing->acv<<1)-2)); //set PRB odd field
1808 _viReg[8] = (cur_timing->psbEven+2); //set PSB even field
1809 _viReg[9] = (cur_timing->prbEven+((cur_timing->acv<<1)-2)); //set PRB even field
1811 _viReg[10] = ((cur_timing->be3<<5)|cur_timing->bs3); //set BE3 & BS3
1812 _viReg[11] = ((cur_timing->be1<<5)|cur_timing->bs1); //set BE1 & BS1
1814 _viReg[12] = ((cur_timing->be4<<5)|cur_timing->bs4); //set BE4 & BS4
1815 _viReg[13] = ((cur_timing->be2<<5)|cur_timing->bs2); //set BE2 & BS2
1817 _viReg[24] = (0x1000|((cur_timing->nhlines/2)+1));
1818 _viReg[25] = (cur_timing->hlw+1);
1820 _viReg[26] = 0x1001; //set DI1
1821 _viReg[27] = 0x0001; //set DI1
1822 _viReg[36] = 0x2828; //set HSR
1824 if(vi_mode<VI_PAL && vi_mode>=VI_DEBUG_PAL) vi_mode = VI_NTSC;
1825 if(progressive){
1826 _viReg[1] = ((vi_mode<<8)|0x0005); //set MODE & INT & enable
1827 _viReg[54] = 0x0001;
1828 } else {
1829 _viReg[1] = ((vi_mode<<8)|(interlace<<2)|0x0001);
1830 _viReg[54] = 0x0000;
1834 #if defined(HW_RVL)
1835 static u32 __VISendI2CData(u8 addr,void *val,u32 len)
1837 u8 c;
1838 s32 i,j;
1839 u32 level,ret;
1841 if(i2cIdentFirst==0) {
1842 __viCheckI2C();
1843 i2cIdentFirst = 1;
1846 _CPU_ISR_Disable(level);
1848 __viOpenI2C(1);
1849 __viSetSCL(1);
1851 __viSetSDA(i2cIdentFlag);
1852 udelay(4);
1854 ret = __sendSlaveAddress(addr);
1855 if(ret==0) {
1856 _CPU_ISR_Restore(level);
1857 return 0;
1860 __viOpenI2C(1);
1861 for(i=0;i<len;i++) {
1862 c = ((u8*)val)[i];
1863 for(j=0;j<8;j++) {
1864 if(c&0x80) __viSetSDA(i2cIdentFlag);
1865 else __viSetSDA(i2cIdentFlag^1);
1866 udelay(2);
1868 __viSetSCL(1);
1869 udelay(2);
1870 __viSetSCL(0);
1872 c <<= 1;
1874 __viOpenI2C(0);
1875 udelay(2);
1876 __viSetSCL(1);
1877 udelay(2);
1879 if(i2cIdentFlag==1 && __viGetSDA()!=0) {
1880 _CPU_ISR_Restore(level);
1881 return 0;
1884 __viSetSDA(i2cIdentFlag^1);
1885 __viOpenI2C(1);
1886 __viSetSCL(0);
1889 __viOpenI2C(1);
1890 __viSetSDA(i2cIdentFlag^1);
1891 udelay(2);
1892 __viSetSDA(i2cIdentFlag);
1894 _CPU_ISR_Restore(level);
1895 return 1;
1898 static void __VIWriteI2CRegister8(u8 reg, u8 data)
1900 u8 buf[2];
1901 buf[0] = reg;
1902 buf[1] = data;
1903 __VISendI2CData(0xe0,buf,2);
1904 udelay(2);
1907 static void __VIWriteI2CRegister16(u8 reg, u16 data)
1909 u8 buf[3];
1910 buf[0] = reg;
1911 buf[1] = data >> 8;
1912 buf[2] = data & 0xFF;
1913 __VISendI2CData(0xe0,buf,3);
1914 udelay(2);
1917 static void __VIWriteI2CRegister32(u8 reg, u32 data)
1919 u8 buf[5];
1920 buf[0] = reg;
1921 buf[1] = data >> 24;
1922 buf[2] = (data >> 16) & 0xFF;
1923 buf[3] = (data >> 8) & 0xFF;
1924 buf[4] = data & 0xFF;
1925 __VISendI2CData(0xe0,buf,5);
1926 udelay(2);
1929 static void __VIWriteI2CRegisterBuf(u8 reg, int size, u8 *data)
1931 u8 buf[0x100];
1932 buf[0] = reg;
1933 memcpy(&buf[1], data, size);
1934 __VISendI2CData(0xe0,buf,size+1);
1935 udelay(2);
1939 static void __VISetYUVSEL(u8 dtvstatus)
1941 if(currTvMode==VI_NTSC) vdacFlagRegion = 0x0000;
1942 else if(currTvMode==VI_PAL || currTvMode==VI_EURGB60) vdacFlagRegion = 0x0002;
1943 /* FIXME: setting this to 1 causes monochrome output on PAL systems*/
1944 else if(currTvMode==VI_MPAL) vdacFlagRegion = 0x0002;
1945 else vdacFlagRegion = 0x0000;
1947 __VIWriteI2CRegister8(0x01, _SHIFTL(dtvstatus,5,3)|(vdacFlagRegion&0x1f));
1950 static void __VISetFilterEURGB60(u8 enable)
1952 __VIWriteI2CRegister8(0x6e, enable);
1955 #if 0
1956 static void __VISetTiming(u8 timing)
1958 u16 val;
1960 val = (_SHIFTL(0x00,8,8)|timing);
1961 __VISendI2CData(0xe0,&val,sizeof(u16));
1962 udelay(2);
1965 static void __VISet3in1Output(u8 enable)
1967 u16 val;
1969 val = (_SHIFTL(0x04,8,8)|enable);
1970 __VISendI2CData(0xe0,&val,sizeof(u16));
1971 udelay(2);
1973 #endif
1975 static void __VISetupEncoder(void)
1977 u8 macrobuf[0x1a];
1979 u8 gamma[0x21] = {
1980 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00,
1981 0x10, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x60,
1982 0x80, 0xa0, 0xeb, 0x10, 0x00, 0x20, 0x00, 0x40,
1983 0x00, 0x60, 0x00, 0x80, 0x00, 0xa0, 0x00, 0xeb,
1984 0x00
1987 u8 dtv, tv;
1989 tv = VIDEO_GetCurrentTvMode();
1990 dtv = (_viReg[55]&0x01);
1991 oldDtvStatus = dtv;
1993 // SetRevolutionModeSimple
1995 memset(macrobuf, 0, 0x1a);
1997 __VIWriteI2CRegister8(0x6a, 1);
1998 __VIWriteI2CRegister8(0x65, 1);
1999 __VISetYUVSEL(dtv);
2000 __VIWriteI2CRegister8(0x00, 0);
2001 __VIWriteI2CRegister16(0x71, 0x8e8e);
2002 __VIWriteI2CRegister8(0x02, 7);
2003 __VIWriteI2CRegister16(0x05, 0x0000);
2004 __VIWriteI2CRegister16(0x08, 0x0000);
2005 __VIWriteI2CRegister32(0x7A, 0x00000000);
2007 // Macrovision crap
2008 __VIWriteI2CRegisterBuf(0x40, sizeof(macrobuf), macrobuf);
2010 // Sometimes 1 in RGB mode? (reg 1 == 3)
2011 __VIWriteI2CRegister8(0x0A, 0);
2013 __VIWriteI2CRegister8(0x03, 1);
2015 __VIWriteI2CRegisterBuf(0x10, sizeof(gamma), gamma);
2017 __VIWriteI2CRegister8(0x04, 1);
2018 __VIWriteI2CRegister32(0x7A, 0x00000000);
2019 __VIWriteI2CRegister16(0x08, 0x0000);
2020 __VIWriteI2CRegister8(0x03, 1);
2022 if(tv==VI_EURGB60) __VISetFilterEURGB60(1);
2023 else __VISetFilterEURGB60(0);
2024 oldTvStatus = tv;
2027 #endif
2029 static inline void __getCurrentDisplayPosition(u32 *px,u32 *py)
2031 u32 hpos = 0;
2032 u32 vpos = 0;
2033 u32 vpos_old;
2035 vpos = (_viReg[22]&0x7ff);
2036 do {
2037 vpos_old = vpos;
2038 hpos = (_viReg[23]&0x7ff);
2039 vpos = (_viReg[22]&0x7ff);
2040 } while(vpos_old!=vpos);
2041 *px = hpos;
2042 *py = vpos;
2045 static inline u32 __getCurrentHalfLine()
2047 u32 vpos = 0;
2048 u32 hpos = 0;
2050 __getCurrentDisplayPosition(&hpos,&vpos);
2052 hpos--;
2053 vpos--;
2054 vpos <<= 1;
2056 return vpos+(hpos/currTiming->hlw);
2059 static inline u32 __getCurrentFieldEvenOdd()
2061 u32 hline;
2063 hline = __getCurrentHalfLine();
2064 if(hline<currTiming->nhlines) return 1;
2066 return 0;
2069 static inline u32 __VISetRegs()
2071 u32 val;
2072 u64 mask;
2074 if(shdw_changeMode==1){
2075 if(!__getCurrentFieldEvenOdd()) return 0;
2078 while(shdw_changed) {
2079 val = cntlzd(shdw_changed);
2080 _viReg[val] = shdw_regs[val];
2081 mask = VI_REGCHANGE(val);
2082 shdw_changed &= ~mask;
2084 shdw_changeMode = 0;
2085 currTiming = HorVer.timing;
2086 currTvMode = HorVer.tv;
2088 currentFb = nextFb;
2090 return 1;
2093 static void __VIDisplayPositionToXY(s32 xpos,s32 ypos,s32 *px,s32 *py)
2095 u32 hpos,vpos;
2096 u32 hline,val;
2098 hpos = (xpos-1);
2099 vpos = (ypos-1);
2100 hline = ((vpos<<1)+(hpos/currTiming->hlw));
2102 *px = (s32)hpos;
2103 if(HorVer.nonInter==0x0000) {
2104 if(hline<currTiming->nhlines) {
2105 val = currTiming->prbOdd+(currTiming->equ*3);
2106 if(hline>=val) {
2107 val = (currTiming->nhlines-currTiming->psbOdd);
2108 if(hline<val) {
2109 *py = (s32)(((hline-(currTiming->equ*3))-currTiming->prbOdd)&~0x01);
2110 } else
2111 *py = -1;
2112 } else
2113 *py = -1;
2114 } else {
2115 hline -= currTiming->psbOdd;
2116 val = (currTiming->prbEven+(currTiming->equ*3));
2117 if(hline>=val) {
2118 val = (currTiming->nhlines-currTiming->psbEven);
2119 if(hline<val) {
2120 *py = (s32)((((hline-(currTiming->equ*3))-currTiming->prbEven)&~0x01)+1);
2121 } else
2122 *py = -1;
2123 } else
2124 *py = -1;
2126 } else if(HorVer.nonInter==0x0001) {
2127 if(hline>=currTiming->nhlines) hline -= currTiming->nhlines;
2129 val = (currTiming->prbOdd+(currTiming->equ*3));
2130 if(hline>=val) {
2131 val = (currTiming->nhlines-currTiming->psbOdd);
2132 if(hline<val) {
2133 *py = (s32)(((hline-(currTiming->equ*3))-currTiming->prbOdd)&~0x01);
2134 } else
2135 *py = -1;
2136 } else
2137 *py = -1;
2138 } else if(HorVer.nonInter==0x0002) {
2139 if(hline<currTiming->nhlines) {
2140 val = currTiming->prbOdd+(currTiming->equ*3);
2141 if(hline>=val) {
2142 val = (currTiming->nhlines-currTiming->psbOdd);
2143 if(hline<val) {
2144 *py = (s32)((hline-(currTiming->equ*3))-currTiming->prbOdd);
2145 } else
2146 *py = -1;
2147 } else
2148 *py = -1;
2149 } else {
2150 hline -= currTiming->psbOdd;
2151 val = (currTiming->prbEven+(currTiming->equ*3));
2152 if(hline>=val) {
2153 val = (currTiming->nhlines-currTiming->psbEven);
2154 if(hline<val) {
2155 *py = (s32)(((hline-(currTiming->equ*3))-currTiming->prbEven)&~0x01);
2156 } else
2157 *py = -1;
2158 } else
2159 *py = -1;
2164 static inline void __VIGetCurrentPosition(s32 *px,s32 *py)
2166 s32 xpos,ypos;
2168 __getCurrentDisplayPosition((u32*)&xpos,(u32*)&ypos);
2169 __VIDisplayPositionToXY(xpos,ypos,px,py);
2172 static void __VIRetraceHandler(u32 nIrq,void *pCtx)
2174 #if defined(HW_RVL)
2175 u8 dtv, tv;
2176 #endif
2177 u32 ret = 0;
2178 u32 intr;
2179 s32 xpos,ypos;
2181 intr = _viReg[24];
2182 if(intr&0x8000) {
2183 _viReg[24] = intr&~0x8000;
2184 ret |= 0x01;
2187 intr = _viReg[26];
2188 if(intr&0x8000) {
2189 _viReg[26] = intr&~0x8000;
2190 ret |= 0x02;
2193 intr = _viReg[28];
2194 if(intr&0x8000) {
2195 _viReg[28] = intr&~0x8000;
2196 ret |= 0x04;
2199 intr = _viReg[30];
2200 if(intr&0x8000) {
2201 _viReg[30] = intr&~0x8000;
2202 ret |= 0x08;
2205 intr = _viReg[30];
2206 if(ret&0x04 || ret&0x08) {
2207 if(positionCB!=NULL) {
2208 __VIGetCurrentPosition(&xpos,&ypos);
2209 positionCB(xpos,ypos);
2213 retraceCount++;
2214 if(preRetraceCB)
2215 preRetraceCB(retraceCount);
2217 if(flushFlag) {
2218 if(__VISetRegs()) {
2219 flushFlag = 0;
2220 SI_RefreshSamplingRate();
2223 #if defined(HW_RVL)
2224 tv = VIDEO_GetCurrentTvMode();
2225 dtv = (_viReg[55]&0x01);
2226 if(dtv!=oldDtvStatus || tv!=oldTvStatus) __VISetYUVSEL(dtv);
2227 oldDtvStatus = dtv;
2229 if(tv!=oldTvStatus) {
2230 if(tv==VI_EURGB60) __VISetFilterEURGB60(1);
2231 else __VISetFilterEURGB60(0);
2233 oldTvStatus = tv;
2234 #endif
2235 if(postRetraceCB)
2236 postRetraceCB(retraceCount);
2238 LWP_ThreadBroadcast(video_queue);
2241 void* VIDEO_GetNextFramebuffer()
2243 return nextFb;
2246 void* VIDEO_GetCurrentFramebuffer()
2248 return currentFb;
2251 void VIDEO_Init()
2253 u32 level,vimode = 0;
2255 _CPU_ISR_Disable(level);
2257 if(!(_viReg[1]&0x0001))
2258 __VIInit(VI_TVMODE_NTSC_INT);
2260 retraceCount = 0;
2261 changed = 0;
2262 shdw_changed = 0;
2263 shdw_changeMode = 0;
2264 flushFlag = 0;
2265 encoderType = 1;
2267 _viReg[38] = ((taps[1]>>6)|(taps[2]<<4));
2268 _viReg[39] = (taps[0]|_SHIFTL(taps[1],10,6));
2269 _viReg[40] = ((taps[4]>>6)|(taps[5]<<4));
2270 _viReg[41] = (taps[3]|_SHIFTL(taps[4],10,6));
2271 _viReg[42] = ((taps[7]>>6)|(taps[8]<<4));
2272 _viReg[43] = (taps[6]|_SHIFTL(taps[7],10,6));
2273 _viReg[44] = (taps[11]|(taps[12]<<8));
2274 _viReg[45] = (taps[9]|(taps[10]<<8));
2275 _viReg[46] = (taps[15]|(taps[16]<<8));
2276 _viReg[47] = (taps[13]|(taps[14]<<8));
2277 _viReg[48] = (taps[19]|(taps[20]<<8));
2278 _viReg[49] = (taps[17]|(taps[18]<<8));
2279 _viReg[50] = (taps[23]|(taps[24]<<8));
2280 _viReg[51] = (taps[21]|(taps[22]<<8));
2281 _viReg[56] = 640;
2283 __importAdjustingValues();
2285 HorVer.nonInter = _SHIFTR(_viReg[1],2,1);
2286 HorVer.tv = _SHIFTR(_viReg[1],8,2);
2288 vimode = HorVer.nonInter;
2289 if(HorVer.tv!=VI_DEBUG) vimode += (HorVer.tv<<2);
2290 currTiming = __gettiming(vimode);
2291 currTvMode = HorVer.tv;
2293 regs[1] = _viReg[1];
2294 HorVer.timing = currTiming;
2295 HorVer.dispSizeX = 640;
2296 HorVer.dispSizeY = currTiming->acv<<1;
2297 HorVer.dispPosX = (VI_MAX_WIDTH_NTSC-HorVer.dispSizeX)/2;
2298 HorVer.dispPosY = 0;
2300 __adjustPosition(currTiming->acv);
2302 HorVer.fbSizeX = 640;
2303 HorVer.fbSizeY = currTiming->acv<<1;
2304 HorVer.panPosX = 0;
2305 HorVer.panPosY = 0;
2306 HorVer.panSizeX = 640;
2307 HorVer.panSizeY = currTiming->acv<<1;
2308 HorVer.fbMode = VI_XFBMODE_SF;
2309 HorVer.wordPerLine = 40;
2310 HorVer.std = 40;
2311 HorVer.wpl = 40;
2312 HorVer.xof = 0;
2313 HorVer.black = 1;
2314 HorVer.threeD = 0;
2315 HorVer.bfbb = 0;
2316 HorVer.tfbb = 0;
2317 HorVer.rbfbb = 0;
2318 HorVer.rtfbb = 0;
2320 _viReg[24] &= ~0x8000;
2321 _viReg[26] &= ~0x8000;
2323 preRetraceCB = NULL;
2324 postRetraceCB = NULL;
2326 LWP_InitQueue(&video_queue);
2328 IRQ_Request(IRQ_PI_VI,__VIRetraceHandler,NULL);
2329 __UnmaskIrq(IRQMASK(IRQ_PI_VI));
2330 #if defined(HW_RVL)
2331 __VISetupEncoder();
2332 #endif
2333 _CPU_ISR_Restore(level);
2336 void VIDEO_Configure(GXRModeObj *rmode)
2338 u16 dcr;
2339 u32 nonint,vimode,level;
2340 const struct _timing *curtiming;
2341 #ifdef _VIDEO_DEBUG
2342 if(rmode->viHeight&0x0001) printf("VIDEO_Configure(): Odd number(%d) is specified to viHeight\n",rmode->viHeight);
2343 if((rmode->xfbMode==VI_XFBMODE_DF || rmode->viTVMode==VI_TVMODE_NTSC_PROG || rmode->viTVMode==VI_TVMODE_NTSC_PROG_DS)
2344 && rmode->xfbHeight!=rmode->viHeight) printf("VIDEO_Configure(): xfbHeight(%d) is not equal to viHeight(%d) when DF XFB mode or progressive mode is specified\n",rmode->xfbHeight,rmode->viHeight);
2345 if(rmode->xfbMode==VI_XFBMODE_SF && !(rmode->viTVMode==VI_TVMODE_NTSC_PROG || rmode->viTVMode==VI_TVMODE_NTSC_PROG_DS)
2346 && (rmode->xfbHeight<<1)!=rmode->viHeight) printf("VIDEO_Configure(): xfbHeight(%d) is not as twice as viHeight(%d) when SF XFB mode is specified\n",rmode->xfbHeight,rmode->viHeight);
2347 #endif
2348 _CPU_ISR_Disable(level);
2349 nonint = (rmode->viTVMode&0x0003);
2350 if(nonint!=HorVer.nonInter) {
2351 changeMode = 1;
2352 HorVer.nonInter = nonint;
2354 HorVer.tv = _SHIFTR(rmode->viTVMode,2,3);
2355 HorVer.dispPosX = rmode->viXOrigin;
2356 HorVer.dispPosY = rmode->viYOrigin;
2357 if(HorVer.nonInter==VI_NON_INTERLACE) HorVer.dispPosY = HorVer.dispPosY<<1;
2359 HorVer.dispSizeX = rmode->viWidth;
2360 HorVer.fbSizeX = rmode->fbWidth;
2361 HorVer.fbSizeY = rmode->xfbHeight;
2362 HorVer.fbMode = rmode->xfbMode;
2363 HorVer.panSizeX = HorVer.fbSizeX;
2364 HorVer.panSizeY = HorVer.fbSizeY;
2365 HorVer.panPosX = 0;
2366 HorVer.panPosY = 0;
2368 if(HorVer.nonInter==VI_PROGRESSIVE || HorVer.nonInter==(VI_NON_INTERLACE|VI_PROGRESSIVE)) HorVer.dispSizeY = HorVer.panSizeY;
2369 else if(HorVer.fbMode==VI_XFBMODE_SF) HorVer.dispSizeY = HorVer.panSizeY<<1;
2370 else HorVer.dispSizeY = HorVer.panSizeY;
2372 if(HorVer.nonInter==(VI_NON_INTERLACE|VI_PROGRESSIVE)) HorVer.threeD = 1;
2373 else HorVer.threeD = 0;
2375 vimode = VI_TVMODE(HorVer.tv,HorVer.nonInter);
2376 curtiming = __gettiming(vimode);
2377 HorVer.timing = curtiming;
2379 __adjustPosition(curtiming->acv);
2380 #ifdef _VIDEO_DEBUG
2381 if(rmode->viXOrigin>((curtiming->hlw+40)-curtiming->hbe640)) printf("VIDEO_Configure(): viXOrigin(%d) cannot be greater than %d in this TV mode\n",rmode->viXOrigin,((curtiming->hlw+40)-curtiming->hbe640));
2382 if((rmode->viXOrigin+rmode->viWidth)<(680-curtiming->hbs640)) printf("VIDEO_Configure(): viXOrigin + viWidth(%d) cannot be less than %d in this TV mode\n",(rmode->viXOrigin+rmode->viWidth),(680-curtiming->hbs640));
2383 #endif
2384 if(!encoderType) HorVer.tv = VI_DEBUG;
2386 __setInterruptRegs(curtiming);
2388 dcr = regs[1]&~0x030c;
2389 dcr |= _SHIFTL(HorVer.threeD,3,1);
2390 if(HorVer.nonInter==VI_PROGRESSIVE || HorVer.nonInter==(VI_NON_INTERLACE|VI_PROGRESSIVE)) dcr |= 0x0004;
2391 else dcr |= _SHIFTL(HorVer.nonInter,2,1);
2392 if(!(HorVer.tv==VI_DEBUG_PAL || HorVer.tv==VI_EURGB60)) dcr |= _SHIFTL(HorVer.tv,8,2);
2393 regs[1] = dcr;
2394 changed |= VI_REGCHANGE(1);
2396 regs[54] &= ~0x0001;
2397 if(rmode->viTVMode==VI_TVMODE_NTSC_PROG || rmode->viTVMode==VI_TVMODE_NTSC_PROG_DS) regs[54] |= 0x0001;
2398 changed |= VI_REGCHANGE(54);
2400 __setScalingRegs(HorVer.panSizeX,HorVer.dispSizeX,HorVer.threeD);
2401 __setHorizontalRegs(curtiming,HorVer.adjustedDispPosX,HorVer.dispSizeX);
2402 __setBBIntervalRegs(curtiming);
2403 __setPicConfig(HorVer.fbSizeX,HorVer.fbMode,HorVer.panPosX,HorVer.panSizeX,&HorVer.wordPerLine,&HorVer.std,&HorVer.wpl,&HorVer.xof);
2405 if(fbSet) __setFbbRegs(&HorVer,&HorVer.tfbb,&HorVer.bfbb,&HorVer.rtfbb,&HorVer.rbfbb);
2407 __setVerticalRegs(HorVer.adjustedDispPosY,HorVer.adjustedDispSizeY,curtiming->equ,curtiming->acv,curtiming->prbOdd,curtiming->prbEven,curtiming->psbOdd,curtiming->psbEven,HorVer.black);
2408 #ifdef _VIDEO_DEBUG
2409 printDebugCalculations();
2410 #endif
2411 _CPU_ISR_Restore(level);
2414 void VIDEO_WaitVSync(void)
2416 u32 level;
2417 u32 retcnt;
2419 _CPU_ISR_Disable(level);
2420 retcnt = retraceCount;
2421 do {
2422 LWP_ThreadSleep(video_queue);
2423 } while(retraceCount==retcnt);
2424 _CPU_ISR_Restore(level);
2427 void VIDEO_SetFramebuffer(void *fb)
2429 u32 level;
2431 _CPU_ISR_Disable(level);
2432 fbSet = 1;
2433 HorVer.bufAddr = fb;
2434 __setFbbRegs(&HorVer,&HorVer.tfbb,&HorVer.bfbb,&HorVer.rtfbb,&HorVer.rbfbb);
2435 _viReg[14] = regs[14];
2436 _viReg[15] = regs[15];
2438 _viReg[18] = regs[18];
2439 _viReg[19] = regs[19];
2441 if(HorVer.threeD) {
2442 _viReg[16] = regs[16];
2443 _viReg[17] = regs[17];
2445 _viReg[20] = regs[20];
2446 _viReg[21] = regs[21];
2448 _CPU_ISR_Restore(level);
2451 void VIDEO_SetNextFramebuffer(void *fb)
2453 u32 level;
2454 #ifdef _VIDEO_DEBUG
2455 if((u32)fb&0x1f) printf("VIDEO_SetNextFramebuffer(): Frame buffer address (%p) is not 32byte aligned\n",fb);
2456 #endif
2457 _CPU_ISR_Disable(level);
2458 fbSet = 1;
2459 HorVer.bufAddr = fb;
2460 __setFbbRegs(&HorVer,&HorVer.tfbb,&HorVer.bfbb,&HorVer.rtfbb,&HorVer.rbfbb);
2461 _CPU_ISR_Restore(level);
2464 void VIDEO_SetNextRightFramebuffer(void *fb)
2466 u32 level;
2468 _CPU_ISR_Disable(level);
2469 fbSet = 1;
2470 HorVer.rbufAddr = fb;
2471 __setFbbRegs(&HorVer,&HorVer.tfbb,&HorVer.bfbb,&HorVer.rtfbb,&HorVer.rbfbb);
2472 _CPU_ISR_Restore(level);
2475 void VIDEO_Flush()
2477 u32 level;
2478 u32 val;
2479 u64 mask;
2481 _CPU_ISR_Disable(level);
2482 shdw_changeMode |= changeMode;
2483 changeMode = 0;
2485 shdw_changed |= changed;
2486 while(changed) {
2487 val = cntlzd(changed);
2488 shdw_regs[val] = regs[val];
2489 mask = VI_REGCHANGE(val);
2490 changed &= ~mask;
2492 flushFlag = 1;
2493 #ifdef _VIDEO_DEBUG
2494 printRegs();
2495 #endif
2496 nextFb = HorVer.bufAddr;
2497 _CPU_ISR_Restore(level);
2500 void VIDEO_SetBlack(bool black)
2502 u32 level;
2503 const struct _timing *curtiming;
2505 _CPU_ISR_Disable(level);
2506 HorVer.black = black;
2507 curtiming = HorVer.timing;
2508 __setVerticalRegs(HorVer.adjustedDispPosY,HorVer.dispSizeY,curtiming->equ,curtiming->acv,curtiming->prbOdd,curtiming->prbEven,curtiming->psbOdd,curtiming->psbEven,HorVer.black);
2509 _CPU_ISR_Restore(level);
2512 u32 VIDEO_GetNextField()
2514 u32 level,nextfield;
2516 _CPU_ISR_Disable(level);
2517 nextfield = __getCurrentFieldEvenOdd()^1; //we've to swap the result because it shows us only the current field,so we've the next field either even or odd
2518 _CPU_ISR_Restore(level);
2520 return nextfield^(HorVer.adjustedDispPosY&0x0001); //if the YOrigin is at an odd position we've to swap it again, since the Fb registers are set swapped if this rule applies
2523 u32 VIDEO_GetCurrentTvMode()
2525 u32 mode;
2526 u32 level;
2527 u32 tv;
2529 _CPU_ISR_Disable(level);
2530 mode = currTvMode;
2532 if(mode==VI_DEBUG) tv = VI_NTSC;
2533 else if(mode==VI_EURGB60) tv = mode;
2534 else if(mode==VI_MPAL) tv = VI_MPAL;
2535 else if(mode==VI_NTSC) tv = VI_NTSC;
2536 else tv = VI_PAL;
2537 _CPU_ISR_Restore(level);
2539 return tv;
2542 GXRModeObj * VIDEO_GetPreferredMode(GXRModeObj *mode)
2545 GXRModeObj *rmode;
2547 #if defined(HW_RVL)
2549 if ( CONF_GetProgressiveScan() > 0 && VIDEO_HaveComponentCable() ) {
2550 rmode = &TVNtsc480Prog;
2551 } else {
2553 u32 tvmode = CONF_GetVideo();
2555 switch ( tvmode ) {
2556 case CONF_VIDEO_NTSC:
2557 rmode = &TVNtsc480IntDf;
2558 break;
2559 case CONF_VIDEO_PAL:
2560 if ( CONF_GetEuRGB60() > 0 ) {
2561 rmode = &TVEurgb60Hz480IntDf;
2562 } else {
2563 rmode = &TVPal528IntDf;
2565 break;
2566 case CONF_VIDEO_MPAL:
2567 rmode = &TVMpal480IntDf;
2568 break;
2569 default:
2570 rmode = &TVNtsc480IntDf;
2573 #else
2574 u32 tvmode = VIDEO_GetCurrentTvMode();
2575 switch(tvmode)
2577 case VI_NTSC:
2578 rmode = &TVNtsc480IntDf;
2579 break;
2580 case VI_PAL:
2581 rmode = &TVPal528IntDf;
2582 break;
2583 case VI_MPAL:
2584 rmode = &TVMpal480IntDf;
2585 break;
2586 default:
2587 rmode = &TVNtsc480IntDf;
2588 break;
2590 #endif
2592 if ( NULL != mode ) {
2593 memcpy( mode, rmode, sizeof(GXRModeObj));
2594 } else {
2595 mode = rmode;
2598 return mode;
2604 u32 VIDEO_GetCurrentLine()
2606 u32 level,curr_hl = 0;
2608 _CPU_ISR_Disable(level);
2609 curr_hl = __getCurrentHalfLine();
2610 _CPU_ISR_Restore(level);
2612 if(curr_hl>=currTiming->nhlines) curr_hl -=currTiming->nhlines;
2613 curr_hl >>= 1;
2615 return curr_hl;
2618 VIRetraceCallback VIDEO_SetPreRetraceCallback(VIRetraceCallback callback)
2620 u32 level = 0;
2621 VIRetraceCallback ret = preRetraceCB;
2622 _CPU_ISR_Disable(level);
2623 preRetraceCB = callback;
2624 _CPU_ISR_Restore(level);
2625 return ret;
2628 VIRetraceCallback VIDEO_SetPostRetraceCallback(VIRetraceCallback callback)
2630 u32 level = 0;
2631 VIRetraceCallback ret = postRetraceCB;
2632 _CPU_ISR_Disable(level);
2633 postRetraceCB = callback;
2634 _CPU_ISR_Restore(level);
2635 return ret;
2638 u32 VIDEO_GetFrameBufferSize(GXRModeObj *rmode) {
2639 u16 w, h;
2641 w = VIDEO_PadFramebufferWidth(rmode->fbWidth);
2642 h = rmode->xfbHeight;
2644 if (rmode->aa)
2645 h += 4;
2647 return w * h * VI_DISPLAY_PIX_SZ;
2650 void VIDEO_ClearFrameBuffer(GXRModeObj *rmode,void *fb,u32 color)
2652 __VIClearFramebuffer(fb, VIDEO_GetFrameBufferSize(rmode), color);
2655 u32 VIDEO_HaveComponentCable(void)
2657 return (_viReg[55]&0x01);