load a keymap in KEYBOARD_Init() based on the contents of "/wiikbd.map"
[libogc.git] / libogc / video.c
blob58c7b7e16a8bcc8e15f0c00450f2ff3597bd2b38
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 TVPal264Ds =
472 VI_TVMODE_PAL_DS, // viDisplayMode
473 640, // fbWidth
474 264, // efbHeight
475 264, // xfbHeight
476 (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin
477 (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin
478 640, // viWidth
479 528, // viHeight
480 VI_XFBMODE_SF, // xFBmode
481 GX_FALSE, // field_rendering
482 GX_FALSE, // aa
484 // sample points arranged in increasing Y order
486 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
487 {6,6},{6,6},{6,6}, // pix 1
488 {6,6},{6,6},{6,6}, // pix 2
489 {6,6},{6,6},{6,6} // pix 3
492 // vertical filter[7], 1/64 units, 6 bits each
494 0, // line n-1
495 0, // line n-1
496 21, // line n
497 22, // line n
498 21, // line n
499 0, // line n+1
500 0 // line n+1
504 GXRModeObj TVPal264DsAa =
506 VI_TVMODE_PAL_DS, // viDisplayMode
507 640, // fbWidth
508 264, // efbHeight
509 264, // xfbHeight
510 (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin
511 (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin
512 640, // viWidth
513 528, // viHeight
514 VI_XFBMODE_SF, // xFBmode
515 GX_FALSE, // field_rendering
516 GX_TRUE, // aa
518 // sample points arranged in increasing Y order
520 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
521 {3,2},{9,6},{3,10}, // pix 1
522 {9,2},{3,6},{9,10}, // pix 2
523 {9,2},{3,6},{9,10} // 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 TVPal264Int =
540 VI_TVMODE_PAL_INT, // viDisplayMode
541 640, // fbWidth
542 264, // efbHeight
543 264, // xfbHeight
544 (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin
545 (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin
546 640, // viWidth
547 528, // viHeight
548 VI_XFBMODE_SF, // xFBmode
549 GX_TRUE, // field_rendering
550 GX_FALSE, // aa
552 // sample points arranged in increasing Y order
554 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
555 {6,6},{6,6},{6,6}, // pix 1
556 {6,6},{6,6},{6,6}, // pix 2
557 {6,6},{6,6},{6,6} // 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 TVPal264IntAa =
574 VI_TVMODE_PAL_INT, // 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_TRUE, // field_rendering
584 GX_TRUE, // aa
586 // sample points arranged in increasing Y order
588 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
589 {3,2},{9,6},{3,10}, // pix 1
590 {9,2},{3,6},{9,10}, // pix 2
591 {9,2},{3,6},{9,10} // 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 TVPal524IntAa =
608 VI_TVMODE_PAL_INT,
609 640,
610 264,
611 524,
612 (VI_MAX_WIDTH_PAL-640)/2,
613 (VI_MAX_HEIGHT_PAL-528)/2,
614 640,
615 524,
616 VI_XFBMODE_DF,
617 GX_FALSE,
618 GX_TRUE,
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 4, // line n-1
631 8, // line n-1
632 12, // line n
633 16, // line n
634 12, // line n
635 8, // line n+1
636 4 // line n+1
640 GXRModeObj TVPal528Int =
642 VI_TVMODE_PAL_INT, // viDisplayMode
643 640, // fbWidth
644 528, // efbHeight
645 528, // 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_DF, // xFBmode
651 GX_FALSE, // 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 TVPal528IntDf =
676 VI_TVMODE_PAL_INT, // viDisplayMode
677 640, // fbWidth
678 528, // efbHeight
679 528, // 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_DF, // xFBmode
685 GX_FALSE, // field_rendering
686 GX_FALSE, // aa
688 // sample points arranged in increasing Y order
690 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
691 {6,6},{6,6},{6,6}, // pix 1
692 {6,6},{6,6},{6,6}, // pix 2
693 {6,6},{6,6},{6,6} // pix 3
695 // vertical filter[7], 1/64 units, 6 bits each
697 8, // line n-1
698 8, // line n-1
699 10, // line n
700 12, // line n
701 10, // line n
702 8, // line n+1
703 8 // line n+1
707 GXRModeObj TVPal574IntDfScale =
709 VI_TVMODE_PAL_INT, // viDisplayMode
710 640, // fbWidth
711 480, // efbHeight
712 574, // xfbHeight
713 (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin
714 (VI_MAX_HEIGHT_PAL - 574)/2, // viYOrigin
715 640, // viWidth
716 574, // viHeight
717 VI_XFBMODE_DF, // xFBmode
718 GX_FALSE, // field_rendering
719 GX_FALSE, // aa
721 // sample points arranged in increasing Y order
723 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
724 {6,6},{6,6},{6,6}, // pix 1
725 {6,6},{6,6},{6,6}, // pix 2
726 {6,6},{6,6},{6,6} // pix 3
728 // vertical filter[7], 1/64 units, 6 bits each
730 8, // line n-1
731 8, // line n-1
732 10, // line n
733 12, // line n
734 10, // line n
735 8, // line n+1
736 8 // line n+1
740 GXRModeObj TVEurgb60Hz240Ds =
742 VI_TVMODE_EURGB60_DS, // viDisplayMode
743 640, // fbWidth
744 240, // efbHeight
745 240, // xfbHeight
746 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
747 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
748 640, // viWidth
749 480, // viHeight
750 VI_XFBMODE_SF, // xFBmode
751 GX_FALSE, // field_rendering
752 GX_FALSE, // aa
754 // sample points arranged in increasing Y order
756 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
757 {6,6},{6,6},{6,6}, // pix 1
758 {6,6},{6,6},{6,6}, // pix 2
759 {6,6},{6,6},{6,6} // pix 3
761 // vertical filter[7], 1/64 units, 6 bits each
763 0, // line n-1
764 0, // line n-1
765 21, // line n
766 22, // line n
767 21, // line n
768 0, // line n+1
769 0 // line n+1
773 GXRModeObj TVEurgb60Hz240DsAa =
775 VI_TVMODE_EURGB60_DS, // viDisplayMode
776 640, // fbWidth
777 240, // efbHeight
778 240, // xfbHeight
779 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
780 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
781 640, // viWidth
782 480, // viHeight
783 VI_XFBMODE_SF, // xFBmode
784 GX_FALSE, // field_rendering
785 GX_TRUE, // aa
787 // sample points arranged in increasing Y order
789 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
790 {3,2},{9,6},{3,10}, // pix 1
791 {9,2},{3,6},{9,10}, // pix 2
792 {9,2},{3,6},{9,10} // pix 3
794 // vertical filter[7], 1/64 units, 6 bits each
796 0, // line n-1
797 0, // line n-1
798 21, // line n
799 22, // line n
800 21, // line n
801 0, // line n+1
802 0 // line n+1
806 GXRModeObj TVEurgb60Hz240Int =
808 VI_TVMODE_EURGB60_INT, // viDisplayMode
809 640, // fbWidth
810 240, // efbHeight
811 240, // xfbHeight
812 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
813 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
814 640, // viWidth
815 480, // viHeight
816 VI_XFBMODE_SF, // xFBmode
817 GX_TRUE, // field_rendering
818 GX_FALSE, // aa
820 // sample points arranged in increasing Y order
822 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
823 {6,6},{6,6},{6,6}, // pix 1
824 {6,6},{6,6},{6,6}, // pix 2
825 {6,6},{6,6},{6,6} // pix 3
827 // vertical filter[7], 1/64 units, 6 bits each
829 0, // line n-1
830 0, // line n-1
831 21, // line n
832 22, // line n
833 21, // line n
834 0, // line n+1
835 0 // line n+1
839 GXRModeObj TVEurgb60Hz240IntAa =
841 VI_TVMODE_EURGB60_INT, // viDisplayMode
842 640, // fbWidth
843 240, // efbHeight
844 240, // xfbHeight
845 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
846 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
847 640, // viWidth
848 480, // viHeight
849 VI_XFBMODE_SF, // xFBmode
850 GX_TRUE, // field_rendering
851 GX_TRUE, // aa
853 // sample points arranged in increasing Y order
855 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
856 {3,2},{9,6},{3,10}, // pix 1
857 {9,2},{3,6},{9,10}, // pix 2
858 {9,2},{3,6},{9,10} // pix 3
860 // vertical filter[7], 1/64 units, 6 bits each
862 0, // line n-1
863 0, // line n-1
864 21, // line n
865 22, // line n
866 21, // line n
867 0, // line n+1
868 0 // line n+1
872 GXRModeObj TVEurgb60Hz480Int =
874 VI_TVMODE_EURGB60_INT, // viDisplayMode
875 640, // fbWidth
876 480, // efbHeight
877 480, // xfbHeight
878 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
879 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
880 640, // viWidth
881 480, // viHeight
882 VI_XFBMODE_DF, // xFBmode
883 GX_FALSE, // field_rendering
884 GX_FALSE, // aa
886 // sample points arranged in increasing Y order
888 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
889 {6,6},{6,6},{6,6}, // pix 1
890 {6,6},{6,6},{6,6}, // pix 2
891 {6,6},{6,6},{6,6} // pix 3
893 // vertical filter[7], 1/64 units, 6 bits each
895 0, // line n-1
896 0, // line n-1
897 21, // line n
898 22, // line n
899 21, // line n
900 0, // line n+1
901 0 // line n+1
905 GXRModeObj TVEurgb60Hz480IntDf =
907 VI_TVMODE_EURGB60_INT, // viDisplayMode
908 640, // fbWidth
909 480, // efbHeight
910 480, // xfbHeight
911 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
912 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
913 640, // viWidth
914 480, // viHeight
915 VI_XFBMODE_DF, // xFBmode
916 GX_FALSE, // field_rendering
917 GX_FALSE, // aa
919 // sample points arranged in increasing Y order
921 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
922 {6,6},{6,6},{6,6}, // pix 1
923 {6,6},{6,6},{6,6}, // pix 2
924 {6,6},{6,6},{6,6} // pix 3
926 // vertical filter[7], 1/64 units, 6 bits each
928 8, // line n-1
929 8, // line n-1
930 10, // line n
931 12, // line n
932 10, // line n
933 8, // line n+1
934 8 // line n+1
938 GXRModeObj TVEurgb60Hz480IntAa =
940 VI_TVMODE_EURGB60_INT, // viDisplayMode
941 640, // fbWidth
942 242, // efbHeight
943 480, // xfbHeight
944 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
945 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
946 640, // viWidth
947 480, // viHeight
948 VI_XFBMODE_DF, // xFBmode
949 GX_FALSE, // field_rendering
950 GX_FALSE, // aa
952 // sample points arranged in increasing Y order
954 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
955 {3,2},{9,6},{3,10}, // pix 1
956 {9,2},{3,6},{9,10}, // pix 2
957 {9,2},{3,6},{9,10} // pix 3
959 // vertical filter[7], 1/64 units, 6 bits each
961 4, // line n-1
962 8, // line n-1
963 12, // line n
964 16, // line n
965 12, // line n
966 8, // line n+1
967 4 // line n+1
971 GXRModeObj TVEurgb60Hz480Prog =
973 VI_TVMODE_EURGB60_PROG, // viDisplayMode
974 640, // fbWidth
975 480, // efbHeight
976 480, // xfbHeight
977 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
978 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
979 640, // viWidth
980 480, // viHeight
981 VI_XFBMODE_SF, // xFBmode
982 GX_FALSE, // field_rendering
983 GX_FALSE, // aa
985 // sample points arranged in increasing Y order
987 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
988 {6,6},{6,6},{6,6}, // pix 1
989 {6,6},{6,6},{6,6}, // pix 2
990 {6,6},{6,6},{6,6} // pix 3
992 // vertical filter[7], 1/64 units, 6 bits each
994 0, // line n-1
995 0, // line n-1
996 21, // line n
997 22, // line n
998 21, // line n
999 0, // line n+1
1000 0 // line n+1
1004 GXRModeObj TVEurgb60Hz480ProgSoft =
1006 VI_TVMODE_EURGB60_PROG, // viDisplayMode
1007 640, // fbWidth
1008 480, // efbHeight
1009 480, // xfbHeight
1010 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
1011 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
1012 640, // viWidth
1013 480, // viHeight
1014 VI_XFBMODE_SF, // xFBmode
1015 GX_FALSE, // field_rendering
1016 GX_FALSE, // aa
1018 // sample points arranged in increasing Y order
1020 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
1021 {3,2},{9,6},{3,10}, // pix 1
1022 {9,2},{3,6},{9,10}, // pix 2
1023 {9,2},{3,6},{9,10} // pix 3
1025 // vertical filter[7], 1/64 units, 6 bits each
1027 4, // line n-1
1028 8, // line n-1
1029 12, // line n
1030 16, // line n
1031 12, // line n
1032 8, // line n+1
1033 4 // line n+1
1037 GXRModeObj TVEurgb60Hz480ProgAa =
1039 VI_TVMODE_EURGB60_PROG, // viDisplayMode
1040 640, // fbWidth
1041 242, // efbHeight
1042 480, // xfbHeight
1043 (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin
1044 (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin
1045 640, // viWidth
1046 480, // viHeight
1047 VI_XFBMODE_SF, // xFBmode
1048 GX_FALSE, // field_rendering
1049 GX_TRUE, // aa
1051 // sample points arranged in increasing Y order
1053 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
1054 {6,6},{6,6},{6,6}, // pix 1
1055 {6,6},{6,6},{6,6}, // pix 2
1056 {6,6},{6,6},{6,6} // pix 3
1058 // vertical filter[7], 1/64 units, 6 bits each
1060 8, // line n-1
1061 8, // line n-1
1062 10, // line n
1063 12, // line n
1064 10, // line n
1065 8, // line n+1
1066 8 // line n+1
1071 static const u16 taps[26] = {
1072 0x01F0,0x01DC,0x01AE,0x0174,0x0129,0x00DB,
1073 0x008E,0x0046,0x000C,0x00E2,0x00CB,0x00C0,
1074 0x00C4,0x00CF,0x00DE,0x00EC,0x00FC,0x0008,
1075 0x000F,0x0013,0x0013,0x000F,0x000C,0x0008,
1076 0x0001,0x0000
1079 static const struct _timing {
1080 u8 equ;
1081 u16 acv;
1082 u16 prbOdd,prbEven;
1083 u16 psbOdd,psbEven;
1084 u8 bs1,bs2,bs3,bs4;
1085 u16 be1,be2,be3,be4;
1086 u16 nhlines,hlw;
1087 u8 hsy,hcs,hce,hbe640;
1088 u16 hbs640;
1089 u8 hbeCCIR656;
1090 u16 hbsCCIR656;
1091 } video_timing[] = {
1093 0x06,0x00F0,
1094 0x0018,0x0019,0x0003,0x0002,
1095 0x0C,0x0D,0x0C,0x0D,
1096 0x0208,0x0207,0x0208,0x0207,
1097 0x020D,0x01AD,
1098 0x40,0x47,0x69,0xA2,
1099 0x0175,
1100 0x7A,0x019C
1103 0x06,0x00F0,
1104 0x0018,0x0018,0x0004,0x0004,
1105 0x0C,0x0C,0x0C,0x0C,
1106 0x0208,0x0208,0x0208,0x0208,
1107 0x020E,0x01AD,
1108 0x40,0x47,0x69,0xA2,
1109 0x0175,
1110 0x7A,0x019C
1113 0x05,0x011F,
1114 0x0023,0x0024,0x0001,0x0000,
1115 0x0D,0x0C,0x0B,0x0A,
1116 0x026B,0x026A,0x0269,0x026C,
1117 0x0271,0x01B0,
1118 0x40,0x4B,0x6A,0xAC,
1119 0x017C,
1120 0x85,0x01A4
1123 0x05,0x011F,
1124 0x0021,0x0021,0x0002,0x0002,
1125 0x0D,0x0B,0x0D,0x0B,
1126 0x026B,0x026D,0x026B,0x026D,
1127 0x0270,0x01B0,
1128 0x40,0x4B,0x6A,0xAC,
1129 0x017C,
1130 0x85,0x01A4
1133 0x06,0x00F0,
1134 0x0018,0x0019,0x0003,0x0002,
1135 0x10,0x0F,0x0E,0x0D,
1136 0x0206,0x0205,0x0204,0x0207,
1137 0x020D,0x01AD,
1138 0x40,0x4E,0x70,0xA2,
1139 0x0175,
1140 0x7A,0x019C
1143 0x06,0x00F0,
1144 0x0018,0x0018,0x0004,0x0004,
1145 0x10,0x0E,0x10,0x0E,
1146 0x0206,0x0208,0x0206,0x0208,
1147 0x020E,0x01AD,
1148 0x40,0x4E,0x70,0xA2,
1149 0x0175,
1150 0x7A,0x019C
1153 0x0C,0x01e0,
1154 0x0030,0x0030,0x0006,0x0006,
1155 0x18,0x18,0x18,0x18,
1156 0x040e,0x040e,0x040e,0x040e,
1157 0x041a,0x01ad,
1158 0x40,0x47,0x69,0xa2,
1159 0x0175,
1160 0x7a,0x019c
1163 0x0c,0x01e0,
1164 0x002c,0x002c,0x000a,0x000a,
1165 0x18,0x18,0x18,0x18,
1166 0x040e,0x040e,0x040e,0x040e,
1167 0x041a,0x01ad,
1168 0x40,0x47,0x69,0xa8,
1169 0x017b,
1170 0x7a,0x019c
1173 0x06,0x00F1,
1174 0x0018,0x0019,0x0001,0x0000,
1175 0x0C,0x0D,0x0C,0x0D,
1176 0x0208,0x0207,0x0208,0x0207,
1177 0x020D,0x01AD,
1178 0x40,0x47,0x69,0x9F,
1179 0x0172,
1180 0x7A,0x019C
1183 0x0C,0x01E0,
1184 0x0030,0x0030,0x0006,0x0006,
1185 0x18,0x18,0x18,0x18,
1186 0x040E,0x040E,0x040E,0x040E,
1187 0x041A,0x01AD,
1188 0x40,0x47,0x69,0xB4,
1189 0x0187,
1190 0x7A,0x019C
1194 #if defined(HW_RVL)
1195 static u32 vdacFlagRegion;
1196 static u32 i2cIdentFirst = 0;
1197 static u32 i2cIdentFlag = 1;
1198 static u32 oldTvStatus = 0x03e7;
1199 static u32 oldDtvStatus = 0x03e7;
1200 static vu32 *_i2cReg = (u32*)0xCD800000;
1201 #endif
1203 static u16 regs[60];
1204 static u16 shdw_regs[60];
1205 static u32 encoderType,fbSet = 0;
1206 static s16 displayOffsetH;
1207 static s16 displayOffsetV;
1208 static u32 currTvMode,changeMode;
1209 static u32 shdw_changeMode,flushFlag;
1210 static u64 changed,shdw_changed;
1211 static vu32 retraceCount;
1212 static const struct _timing *currTiming;
1213 static lwpq_t video_queue;
1214 static horVer HorVer;
1215 static void *currentFb = NULL;
1216 static void *nextFb = NULL;
1217 static VIRetraceCallback preRetraceCB = NULL;
1218 static VIRetraceCallback postRetraceCB = NULL;
1219 static VIPositionCallback positionCB = NULL;
1221 static vu16* const _viReg = (u16*)0xCC002000;
1223 extern void __UnmaskIrq(u32);
1224 extern void __MaskIrq(u32);
1226 extern syssram* __SYS_LockSram();
1227 extern u32 __SYS_UnlockSram(u32 write);
1229 extern void __VIClearFramebuffer(void*,u32,u32);
1231 extern void udelay(int us);
1233 #ifdef _VIDEO_DEBUG
1234 static u32 messages$128 = 0;
1235 static u32 printregs = 1;
1237 static void printRegs()
1239 if(!printregs) {
1240 printf("displayOffsetH = %d\ndisplayOffsetV = %d\n",displayOffsetH,displayOffsetV);
1241 printf("%08x%08x\n",(u32)(shdw_changed>>32),(u32)shdw_changed);
1243 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]);
1244 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]);
1245 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]);
1246 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]);
1247 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]);
1248 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]);
1249 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]);
1250 printf("%04x %04x %04x %04x\n\n",shdw_regs[56],shdw_regs[57],shdw_regs[58],shdw_regs[59]);
1252 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]);
1253 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]);
1254 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]);
1255 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]);
1256 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]);
1257 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]);
1258 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]);
1259 printf("%04x %04x %04x %04x\n",_viReg[56],_viReg[57],_viReg[58],_viReg[59]);
1260 printregs = 1;
1264 static void printDebugCalculations()
1266 if(!messages$128) {
1267 messages$128 = 1;
1268 printf("HorVer.dispPosX = %d\n",HorVer.dispPosX);
1269 printf("HorVer.dispPosY = %d\n",HorVer.dispPosY);
1270 printf("HorVer.dispSizeX = %d\n",HorVer.dispSizeX);
1271 printf("HorVer.dispSizeY = %d\n",HorVer.dispSizeY);
1272 printf("HorVer.adjustedDispPosX = %d\n",HorVer.adjustedDispPosX);
1273 printf("HorVer.adjustedDispPosY = %d\n",HorVer.adjustedDispPosY);
1274 printf("HorVer.adjustedDispSizeY = %d\n",HorVer.adjustedDispSizeY);
1275 printf("HorVer.adjustedPanPosY = %d\n",HorVer.adjustedPanPosY);
1276 printf("HorVer.adjustedPanSizeY = %d\n",HorVer.adjustedPanSizeY);
1277 printf("HorVer.fbSizeX = %d\n",HorVer.fbSizeX);
1278 printf("HorVer.fbSizeY = %d\n",HorVer.fbSizeY);
1279 printf("HorVer.panPosX = %d\n",HorVer.panPosX);
1280 printf("HorVer.panPosY = %d\n",HorVer.panPosY);
1281 printf("HorVer.panSizeX = %d\n",HorVer.panSizeX);
1282 printf("HorVer.panSizeY = %d\n",HorVer.panSizeY);
1283 printf("HorVer.fbMode = %d\n",HorVer.fbMode);
1284 printf("HorVer.nonInter = %d\n",HorVer.nonInter);
1285 printf("HorVer.tv = %d\n",HorVer.tv);
1286 printf("HorVer.wordPerLine = %d\n",HorVer.wordPerLine);
1287 printf("HorVer.wpl = %d\n",HorVer.wpl);
1288 printf("HorVer.std = %d\n",HorVer.std);
1289 printf("HorVer.xof = %d\n",HorVer.xof);
1290 printf("HorVer.bufAddr = %p\n",HorVer.bufAddr);
1291 printf("HorVer.tfbb = 0x%08x\n",HorVer.tfbb);
1292 printf("HorVer.bfbb = 0x%08x\n",HorVer.bfbb);
1293 printf("HorVer.rbufAddr = %p\n",HorVer.rbufAddr);
1294 printf("HorVer.rtfbb = 0x%08x\n",HorVer.rtfbb);
1295 printf("HorVer.rbfbb = 0x%08x\n",HorVer.rbfbb);
1296 printf("HorVer.black = %d\n",HorVer.black);
1297 printf("HorVer.threeD = %d\n",HorVer.threeD);
1300 #endif
1302 static __inline__ u32 cntlzd(u64 bit)
1304 u32 hi,lo,value = 0;
1306 hi = (u32)(bit>>32);
1307 lo = (u32)(bit&-1);
1309 value = cntlzw(hi);
1310 if(value>=32) value += cntlzw(lo);
1312 return value;
1315 static const struct _timing* __gettiming(u32 vimode)
1317 if(vimode>0x1e) return NULL;
1319 switch(vimode) {
1320 case VI_TVMODE_NTSC_INT:
1321 return &video_timing[0];
1322 break;
1323 case VI_TVMODE_NTSC_DS:
1324 return &video_timing[1];
1325 break;
1326 case VI_TVMODE_PAL_INT:
1327 return &video_timing[2];
1328 break;
1329 case VI_TVMODE_PAL_DS:
1330 return &video_timing[3];
1331 break;
1332 case VI_TVMODE_EURGB60_INT:
1333 return &video_timing[0];
1334 break;
1335 case VI_TVMODE_EURGB60_DS:
1336 return &video_timing[1];
1337 break;
1338 case VI_TVMODE_MPAL_INT:
1339 return &video_timing[4];
1340 break;
1341 case VI_TVMODE_MPAL_DS:
1342 return &video_timing[5];
1343 break;
1344 case VI_TVMODE_NTSC_PROG:
1345 return &video_timing[6];
1346 break;
1347 case VI_TVMODE_NTSC_PROG_DS:
1348 return &video_timing[7];
1349 break;
1350 case VI_TVMODE_DEBUG_PAL_INT:
1351 return &video_timing[2];
1352 break;
1353 case VI_TVMODE_DEBUG_PAL_DS:
1354 return &video_timing[3];
1355 break;
1356 default:
1357 break;
1359 return NULL;
1362 #if defined(HW_RVL)
1363 static inline void __viOpenI2C(u32 channel)
1365 u32 val = ((_i2cReg[49]&~0x8000)|0x4000);
1366 val |= _SHIFTL(channel,15,1);
1367 _i2cReg[49] = val;
1370 static inline u32 __viSetSCL(u32 channel)
1372 u32 val = (_i2cReg[48]&~0x4000);
1373 val |= _SHIFTL(channel,14,1);
1374 _i2cReg[48] = val;
1375 return 1;
1377 static inline u32 __viSetSDA(u32 channel)
1379 u32 val = (_i2cReg[48]&~0x8000);
1380 val |= _SHIFTL(channel,15,1);
1381 _i2cReg[48] = val;
1382 return 1;
1385 static inline u32 __viGetSDA()
1387 return _SHIFTR(_i2cReg[50],15,1);
1390 static inline void __viCheckI2C()
1392 __viOpenI2C(0);
1393 udelay(4);
1395 i2cIdentFlag = 0;
1396 if(__viGetSDA()!=0) i2cIdentFlag = 1;
1399 static u32 __sendSlaveAddress(u8 addr)
1401 u32 i;
1403 __viSetSDA(i2cIdentFlag^1);
1404 udelay(2);
1406 __viSetSCL(0);
1407 for(i=0;i<8;i++) {
1408 if(addr&0x80) __viSetSDA(i2cIdentFlag);
1409 else __viSetSDA(i2cIdentFlag^1);
1410 udelay(2);
1412 __viSetSCL(1);
1413 udelay(2);
1415 __viSetSCL(0);
1416 addr <<= 1;
1419 __viOpenI2C(0);
1420 udelay(2);
1422 __viSetSCL(1);
1423 udelay(2);
1425 if(i2cIdentFlag==1 && __viGetSDA()!=0) return 0;
1427 __viSetSDA(i2cIdentFlag^1);
1428 __viOpenI2C(1);
1429 __viSetSCL(0);
1431 return 1;
1433 #endif
1435 static inline void __setInterruptRegs(const struct _timing *tm)
1437 u16 hlw;
1439 hlw = 0;
1440 if(tm->nhlines%2) hlw = tm->hlw;
1441 regs[24] = 0x1000|((tm->nhlines/2)+1);
1442 regs[25] = hlw+1;
1443 changed |= VI_REGCHANGE(24);
1444 changed |= VI_REGCHANGE(25);
1447 static inline void __setPicConfig(u16 fbSizeX,u32 xfbMode,u16 panPosX,u16 panSizeX,u8 *wordPerLine,u8 *std,u8 *wpl,u8 *xof)
1449 *wordPerLine = (fbSizeX+15)/16;
1450 *std = *wordPerLine;
1451 if(xfbMode==VI_XFBMODE_DF) *std <<= 1;
1453 *xof = panPosX%16;
1454 *wpl = (*xof+(panSizeX+15))/16;
1455 regs[36] = (*wpl<<8)|*std;
1456 changed |= VI_REGCHANGE(36);
1459 static inline void __setBBIntervalRegs(const struct _timing *tm)
1461 regs[10] = (tm->be3<<5)|tm->bs3;
1462 regs[11] = (tm->be1<<5)|tm->bs1;
1463 changed |= VI_REGCHANGE(10);
1464 changed |= VI_REGCHANGE(11);
1466 regs[12] = (tm->be4<<5)|tm->bs4;
1467 regs[13] = (tm->be2<<5)|tm->bs2;
1468 changed |= VI_REGCHANGE(12);
1469 changed |= VI_REGCHANGE(13);
1472 static void __setScalingRegs(u16 panSizeX,u16 dispSizeX,s32 threeD)
1474 if(threeD) panSizeX = _SHIFTL(panSizeX,1,16);
1475 if(panSizeX<dispSizeX) {
1476 regs[37] = 0x1000|((dispSizeX+(_SHIFTL(panSizeX,8,16)-1))/dispSizeX);
1477 regs[56] = panSizeX;
1478 changed |= VI_REGCHANGE(37);
1479 changed |= VI_REGCHANGE(56);
1480 } else {
1481 regs[37] = 0x100;
1482 changed |= VI_REGCHANGE(37);
1486 static inline void __calcFbbs(u32 bufAddr,u16 panPosX,u16 panPosY,u8 wordperline,u32 xfbMode,u16 dispPosY,u32 *tfbb,u32 *bfbb)
1488 u32 bytesPerLine,tmp;
1490 panPosX &= 0xfff0;
1491 bytesPerLine = (wordperline<<5)&0x1fe0;
1492 *tfbb = bufAddr+((panPosX<<5)+(panPosY*bytesPerLine));
1493 *bfbb = *tfbb;
1494 if(xfbMode==VI_XFBMODE_DF) *bfbb = *tfbb+bytesPerLine;
1496 if(dispPosY%2) {
1497 tmp = *tfbb;
1498 *tfbb = *bfbb;
1499 *bfbb = tmp;
1502 *tfbb = MEM_VIRTUAL_TO_PHYSICAL(*tfbb);
1503 *bfbb = MEM_VIRTUAL_TO_PHYSICAL(*bfbb);
1506 static inline void __setFbbRegs(struct _horVer *horVer,u32 *tfbb,u32 *bfbb,u32 *rtfbb,u32 *rbfbb)
1508 u32 flag;
1509 __calcFbbs((u32)horVer->bufAddr,horVer->panPosX,horVer->adjustedPanPosY,horVer->wordPerLine,horVer->fbMode,horVer->adjustedDispPosY,tfbb,bfbb);
1510 if(horVer->threeD) __calcFbbs((u32)horVer->rbufAddr,horVer->panPosX,horVer->adjustedPanPosY,horVer->wordPerLine,horVer->fbMode,horVer->adjustedDispPosY,rtfbb,rbfbb);
1512 flag = 1;
1513 if((*tfbb)<0x01000000 && (*bfbb)<0x01000000
1514 && (*rtfbb)<0x01000000 && (*rbfbb)<0x01000000) flag = 0;
1516 if(flag) {
1517 *tfbb >>= 5;
1518 *bfbb >>= 5;
1519 *rtfbb >>= 5;
1520 *rbfbb >>= 5;
1523 regs[14] = _SHIFTL(flag,12,1)|_SHIFTL(horVer->xof,8,4)|_SHIFTR(*tfbb,16,8);
1524 regs[15] = *tfbb&0xffff;
1525 changed |= VI_REGCHANGE(14);
1526 changed |= VI_REGCHANGE(15);
1528 regs[18] = _SHIFTR(*bfbb,16,8);
1529 regs[19] = *bfbb&0xffff;
1530 changed |= VI_REGCHANGE(18);
1531 changed |= VI_REGCHANGE(19);
1533 if(horVer->threeD) {
1534 regs[16] = _SHIFTR(*rtfbb,16,8);
1535 regs[17] = *rtfbb&0xffff;
1536 changed |= VI_REGCHANGE(16);
1537 changed |= VI_REGCHANGE(17);
1539 regs[20] = _SHIFTR(*rbfbb,16,8);
1540 regs[21] = *rbfbb&0xffff;
1541 changed |= VI_REGCHANGE(20);
1542 changed |= VI_REGCHANGE(21);
1546 static inline void __setHorizontalRegs(const struct _timing *tm,u16 dispPosX,u16 dispSizeX)
1548 u32 val1,val2;
1550 regs[2] = (tm->hcs<<8)|tm->hce;
1551 regs[3] = tm->hlw;
1552 changed |= VI_REGCHANGE(2);
1553 changed |= VI_REGCHANGE(3);
1555 val1 = (tm->hbe640+dispPosX-40)&0x01ff;
1556 val2 = (tm->hbs640+dispPosX+40)-(720-dispSizeX);
1557 regs[4] = (val1>>9)|(val2<<1);
1558 regs[5] = (val1<<7)|tm->hsy;
1559 changed |= VI_REGCHANGE(4);
1560 changed |= VI_REGCHANGE(5);
1563 static inline void __setVerticalRegs(u16 dispPosY,u16 dispSizeY,u8 equ,u16 acv,u16 prbOdd,u16 prbEven,u16 psbOdd,u16 psbEven,s32 black)
1565 u16 tmp;
1566 u32 div1,div2;
1567 u32 psb,prb;
1568 u32 psbodd,prbodd;
1569 u32 psbeven,prbeven;
1571 div1 = 2;
1572 div2 = 1;
1573 if(equ>=10) {
1574 div1 = 1;
1575 div2 = 2;
1578 prb = div2*dispPosY;
1579 psb = div2*(((acv*div1)-dispSizeY)-dispPosY);
1580 if(dispPosY%2) {
1581 prbodd = prbEven+prb;
1582 psbodd = psbEven+psb;
1583 prbeven = prbOdd+prb;
1584 psbeven = psbOdd+psb;
1585 } else {
1586 prbodd = prbOdd+prb;
1587 psbodd = psbOdd+psb;
1588 prbeven = prbEven+prb;
1589 psbeven = psbEven+psb;
1592 tmp = dispSizeY/div1;
1593 if(black) {
1594 prbodd += ((tmp<<1)-2);
1595 prbeven += ((tmp<<1)-2);
1596 psbodd += 2;
1597 psbeven += 2;
1598 tmp = 0;
1601 regs[0] = ((tmp<<4)&~0x0f)|equ;
1602 changed |= VI_REGCHANGE(0);
1604 regs[6] = psbodd;
1605 regs[7] = prbodd;
1606 changed |= VI_REGCHANGE(6);
1607 changed |= VI_REGCHANGE(7);
1609 regs[8] = psbeven;
1610 regs[9] = prbeven;
1611 changed |= VI_REGCHANGE(8);
1612 changed |= VI_REGCHANGE(9);
1615 static inline void __adjustPosition(u16 acv)
1617 u32 fact,field;
1618 s16 dispPosX,dispPosY;
1619 s16 dispSizeY,maxDispSizeY;
1621 dispPosX = (HorVer.dispPosX+displayOffsetH);
1622 if(dispPosX<=(720-HorVer.dispSizeX)) {
1623 if(dispPosX>=0) HorVer.adjustedDispPosX = dispPosX;
1624 else HorVer.adjustedDispPosX = 0;
1625 } else HorVer.adjustedDispPosX = (720-HorVer.dispSizeX);
1627 fact = 1;
1628 if(HorVer.fbMode==VI_XFBMODE_SF) fact = 2;
1630 field = HorVer.dispPosY&0x0001;
1631 dispPosY = HorVer.dispPosY+displayOffsetV;
1632 if(dispPosY>field) HorVer.adjustedDispPosY = dispPosY;
1633 else HorVer.adjustedDispPosY = field;
1635 dispSizeY = HorVer.dispPosY+HorVer.dispSizeY+displayOffsetV;
1636 maxDispSizeY = ((acv<<1)-field);
1637 if(dispSizeY>maxDispSizeY) dispSizeY -= (acv<<1)-field;
1638 else dispSizeY = 0;
1640 dispPosY = HorVer.dispPosY+displayOffsetV;
1641 if(dispPosY<field) dispPosY -= field;
1642 else dispPosY = 0;
1643 HorVer.adjustedDispSizeY = HorVer.dispSizeY+dispPosY-dispSizeY;
1645 dispPosY = HorVer.dispPosY+displayOffsetV;
1646 if(dispPosY<field) dispPosY -= field;
1647 else dispPosY = 0;
1648 HorVer.adjustedPanPosY = HorVer.panPosY-(dispPosY/fact);
1650 dispSizeY = HorVer.dispPosY+HorVer.dispSizeY+displayOffsetV;
1651 if(dispSizeY>maxDispSizeY) dispSizeY -= maxDispSizeY;
1652 else dispSizeY = 0;
1654 dispPosY = HorVer.dispPosY+displayOffsetV;
1655 if(dispPosY<field) dispPosY -= field;
1656 else dispPosY = 0;
1657 HorVer.adjustedPanSizeY = HorVer.panSizeY+(dispPosY/fact)-(dispSizeY/fact);
1660 static inline void __importAdjustingValues()
1662 #ifdef HW_DOL
1663 syssram *sram;
1665 sram = __SYS_LockSram();
1666 displayOffsetH = sram->display_offsetH;
1667 __SYS_UnlockSram(0);
1668 #else
1669 s8 offset;
1670 if ( CONF_GetDisplayOffsetH(&offset) == 0 ) {
1671 displayOffsetH = offset;
1672 } else {
1673 displayOffsetH = 0;
1675 #endif
1676 displayOffsetV = 0;
1679 static void __VIInit(u32 vimode)
1681 u32 cnt;
1682 u32 vi_mode,interlace,progressive;
1683 const struct _timing *cur_timing = NULL;
1685 vi_mode = ((vimode>>2)&0x07);
1686 interlace = (vimode&0x01);
1687 progressive = (vimode&0x02);
1689 cur_timing = __gettiming(vimode);
1691 //reset the interface
1692 cnt = 0;
1693 _viReg[1] = 0x02;
1694 while(cnt<1000) cnt++;
1695 _viReg[1] = 0x00;
1697 // now begin to setup the interface
1698 _viReg[2] = ((cur_timing->hcs<<8)|cur_timing->hce); //set HCS & HCE
1699 _viReg[3] = cur_timing->hlw; //set Half Line Width
1701 _viReg[4] = (cur_timing->hbs640<<1); //set HBS640
1702 _viReg[5] = ((cur_timing->hbe640<<7)|cur_timing->hsy); //set HBE640 & HSY
1704 _viReg[0] = cur_timing->equ;
1706 _viReg[6] = (cur_timing->psbOdd+2); //set PSB odd field
1707 _viReg[7] = (cur_timing->prbOdd+((cur_timing->acv<<1)-2)); //set PRB odd field
1709 _viReg[8] = (cur_timing->psbEven+2); //set PSB even field
1710 _viReg[9] = (cur_timing->prbEven+((cur_timing->acv<<1)-2)); //set PRB even field
1712 _viReg[10] = ((cur_timing->be3<<5)|cur_timing->bs3); //set BE3 & BS3
1713 _viReg[11] = ((cur_timing->be1<<5)|cur_timing->bs1); //set BE1 & BS1
1715 _viReg[12] = ((cur_timing->be4<<5)|cur_timing->bs4); //set BE4 & BS4
1716 _viReg[13] = ((cur_timing->be2<<5)|cur_timing->bs2); //set BE2 & BS2
1718 _viReg[24] = (0x1000|((cur_timing->nhlines/2)+1));
1719 _viReg[25] = (cur_timing->hlw+1);
1721 _viReg[26] = 0x1001; //set DI1
1722 _viReg[27] = 0x0001; //set DI1
1723 _viReg[36] = 0x2828; //set HSR
1725 if(vi_mode<VI_PAL && vi_mode>=VI_DEBUG_PAL) vi_mode = VI_NTSC;
1726 if(progressive){
1727 _viReg[1] = ((vi_mode<<8)|0x0005); //set MODE & INT & enable
1728 _viReg[54] = 0x0001;
1729 } else {
1730 _viReg[1] = ((vi_mode<<8)|(interlace<<2)|0x0001);
1731 _viReg[54] = 0x0000;
1735 #if defined(HW_RVL)
1736 static u32 __VISendI2CData(u8 addr,void *val,u32 len)
1738 u8 c;
1739 s32 i,j;
1740 u32 level,ret;
1742 if(i2cIdentFirst==0) {
1743 __viCheckI2C();
1744 i2cIdentFirst = 1;
1747 _CPU_ISR_Disable(level);
1749 __viOpenI2C(1);
1750 __viSetSCL(1);
1752 __viSetSDA(i2cIdentFlag);
1753 udelay(4);
1755 ret = __sendSlaveAddress(addr);
1756 if(ret==0) {
1757 _CPU_ISR_Restore(level);
1758 return 0;
1761 __viOpenI2C(1);
1762 for(i=0;i<len;i++) {
1763 c = ((u8*)val)[i];
1764 for(j=0;j<8;j++) {
1765 if(c&0x80) __viSetSDA(i2cIdentFlag);
1766 else __viSetSDA(i2cIdentFlag^1);
1767 udelay(2);
1769 __viSetSCL(1);
1770 udelay(2);
1771 __viSetSCL(0);
1773 c <<= 1;
1775 __viOpenI2C(0);
1776 udelay(2);
1777 __viSetSCL(1);
1778 udelay(2);
1780 if(i2cIdentFlag==1 && __viGetSDA()!=0) {
1781 _CPU_ISR_Restore(level);
1782 return 0;
1785 __viSetSDA(i2cIdentFlag^1);
1786 __viOpenI2C(1);
1787 __viSetSCL(0);
1790 __viOpenI2C(1);
1791 __viSetSDA(i2cIdentFlag^1);
1792 udelay(2);
1793 __viSetSDA(i2cIdentFlag);
1795 _CPU_ISR_Restore(level);
1796 return 1;
1799 static void __VIWriteI2CRegister8(u8 reg, u8 data)
1801 u8 buf[2];
1802 buf[0] = reg;
1803 buf[1] = data;
1804 __VISendI2CData(0xe0,buf,2);
1805 udelay(2);
1808 static void __VIWriteI2CRegister16(u8 reg, u16 data)
1810 u8 buf[3];
1811 buf[0] = reg;
1812 buf[1] = data >> 8;
1813 buf[2] = data & 0xFF;
1814 __VISendI2CData(0xe0,buf,3);
1815 udelay(2);
1818 static void __VIWriteI2CRegister32(u8 reg, u32 data)
1820 u8 buf[5];
1821 buf[0] = reg;
1822 buf[1] = data >> 24;
1823 buf[2] = (data >> 16) & 0xFF;
1824 buf[3] = (data >> 8) & 0xFF;
1825 buf[4] = data & 0xFF;
1826 __VISendI2CData(0xe0,buf,5);
1827 udelay(2);
1830 static void __VIWriteI2CRegisterBuf(u8 reg, int size, u8 *data)
1832 u8 buf[0x100];
1833 buf[0] = reg;
1834 memcpy(&buf[1], data, size);
1835 __VISendI2CData(0xe0,buf,size+1);
1836 udelay(2);
1840 static void __VISetYUVSEL(u8 dtvstatus)
1842 if(currTvMode==VI_NTSC) vdacFlagRegion = 0x0000;
1843 else if(currTvMode==VI_PAL || currTvMode==VI_EURGB60) vdacFlagRegion = 0x0002;
1844 /* FIXME: setting this to 1 causes monochrome output on PAL systems*/
1845 else if(currTvMode==VI_MPAL) vdacFlagRegion = 0x0002;
1846 else vdacFlagRegion = 0x0000;
1848 __VIWriteI2CRegister8(0x01, _SHIFTL(dtvstatus,5,3)|(vdacFlagRegion&0x1f));
1851 static void __VISetFilterEURGB60(u8 enable)
1853 __VIWriteI2CRegister8(0x6e, enable);
1856 #if 0
1857 static void __VISetTiming(u8 timing)
1859 u16 val;
1861 val = (_SHIFTL(0x00,8,8)|timing);
1862 __VISendI2CData(0xe0,&val,sizeof(u16));
1863 udelay(2);
1866 static void __VISet3in1Output(u8 enable)
1868 u16 val;
1870 val = (_SHIFTL(0x04,8,8)|enable);
1871 __VISendI2CData(0xe0,&val,sizeof(u16));
1872 udelay(2);
1874 #endif
1876 static void __VISetupEncoder(void)
1878 u8 macrobuf[0x1a];
1880 u8 gamma[0x21] = {
1881 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00,
1882 0x10, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x60,
1883 0x80, 0xa0, 0xeb, 0x10, 0x00, 0x20, 0x00, 0x40,
1884 0x00, 0x60, 0x00, 0x80, 0x00, 0xa0, 0x00, 0xeb,
1885 0x00
1888 u8 dtv, tv;
1890 tv = VIDEO_GetCurrentTvMode();
1891 dtv = (_viReg[55]&0x01);
1892 oldDtvStatus = dtv;
1894 // SetRevolutionModeSimple
1896 memset(macrobuf, 0, 0x1a);
1898 __VIWriteI2CRegister8(0x6a, 1);
1899 __VIWriteI2CRegister8(0x65, 1);
1900 __VISetYUVSEL(dtv);
1901 __VIWriteI2CRegister8(0x00, 0);
1902 __VIWriteI2CRegister16(0x71, 0x8e8e);
1903 __VIWriteI2CRegister8(0x02, 7);
1904 __VIWriteI2CRegister16(0x05, 0x0000);
1905 __VIWriteI2CRegister16(0x08, 0x0000);
1906 __VIWriteI2CRegister32(0x7A, 0x00000000);
1908 // Macrovision crap
1909 __VIWriteI2CRegisterBuf(0x40, sizeof(macrobuf), macrobuf);
1911 // Sometimes 1 in RGB mode? (reg 1 == 3)
1912 __VIWriteI2CRegister8(0x0A, 0);
1914 __VIWriteI2CRegister8(0x03, 1);
1916 __VIWriteI2CRegisterBuf(0x10, sizeof(gamma), gamma);
1918 __VIWriteI2CRegister8(0x04, 1);
1919 __VIWriteI2CRegister32(0x7A, 0x00000000);
1920 __VIWriteI2CRegister16(0x08, 0x0000);
1921 __VIWriteI2CRegister8(0x03, 1);
1923 if(tv==VI_EURGB60) __VISetFilterEURGB60(1);
1924 else __VISetFilterEURGB60(0);
1925 oldTvStatus = tv;
1928 #endif
1930 static inline void __getCurrentDisplayPosition(u32 *px,u32 *py)
1932 u32 hpos = 0;
1933 u32 vpos = 0;
1934 u32 vpos_old;
1936 vpos = (_viReg[22]&0x7ff);
1937 do {
1938 vpos_old = vpos;
1939 hpos = (_viReg[23]&0x7ff);
1940 vpos = (_viReg[22]&0x7ff);
1941 } while(vpos_old!=vpos);
1942 *px = hpos;
1943 *py = vpos;
1946 static inline u32 __getCurrentHalfLine()
1948 u32 vpos = 0;
1949 u32 hpos = 0;
1951 __getCurrentDisplayPosition(&hpos,&vpos);
1953 hpos--;
1954 vpos--;
1955 vpos <<= 1;
1957 return vpos+(hpos/currTiming->hlw);
1960 static inline u32 __getCurrentFieldEvenOdd()
1962 u32 hline;
1964 hline = __getCurrentHalfLine();
1965 if(hline<currTiming->nhlines) return 1;
1967 return 0;
1970 static inline u32 __VISetRegs()
1972 u32 val;
1973 u64 mask;
1975 if(shdw_changeMode==1){
1976 if(!__getCurrentFieldEvenOdd()) return 0;
1979 while(shdw_changed) {
1980 val = cntlzd(shdw_changed);
1981 _viReg[val] = shdw_regs[val];
1982 mask = VI_REGCHANGE(val);
1983 shdw_changed &= ~mask;
1985 shdw_changeMode = 0;
1986 currTiming = HorVer.timing;
1987 currTvMode = HorVer.tv;
1989 currentFb = nextFb;
1991 return 1;
1994 static void __VIDisplayPositionToXY(s32 xpos,s32 ypos,s32 *px,s32 *py)
1996 u32 hpos,vpos;
1997 u32 hline,val;
1999 hpos = (xpos-1);
2000 vpos = (ypos-1);
2001 hline = ((vpos<<1)+(hpos/currTiming->hlw));
2003 *px = (s32)hpos;
2004 if(HorVer.nonInter==0x0000) {
2005 if(hline<currTiming->nhlines) {
2006 val = currTiming->prbOdd+(currTiming->equ*3);
2007 if(hline>=val) {
2008 val = (currTiming->nhlines-currTiming->psbOdd);
2009 if(hline<val) {
2010 *py = (s32)(((hline-(currTiming->equ*3))-currTiming->prbOdd)&~0x01);
2011 } else
2012 *py = -1;
2013 } else
2014 *py = -1;
2015 } else {
2016 hline -= currTiming->psbOdd;
2017 val = (currTiming->prbEven+(currTiming->equ*3));
2018 if(hline>=val) {
2019 val = (currTiming->nhlines-currTiming->psbEven);
2020 if(hline<val) {
2021 *py = (s32)((((hline-(currTiming->equ*3))-currTiming->prbEven)&~0x01)+1);
2022 } else
2023 *py = -1;
2024 } else
2025 *py = -1;
2027 } else if(HorVer.nonInter==0x0001) {
2028 if(hline>=currTiming->nhlines) hline -= currTiming->nhlines;
2030 val = (currTiming->prbOdd+(currTiming->equ*3));
2031 if(hline>=val) {
2032 val = (currTiming->nhlines-currTiming->psbOdd);
2033 if(hline<val) {
2034 *py = (s32)(((hline-(currTiming->equ*3))-currTiming->prbOdd)&~0x01);
2035 } else
2036 *py = -1;
2037 } else
2038 *py = -1;
2039 } else if(HorVer.nonInter==0x0002) {
2040 if(hline<currTiming->nhlines) {
2041 val = currTiming->prbOdd+(currTiming->equ*3);
2042 if(hline>=val) {
2043 val = (currTiming->nhlines-currTiming->psbOdd);
2044 if(hline<val) {
2045 *py = (s32)((hline-(currTiming->equ*3))-currTiming->prbOdd);
2046 } else
2047 *py = -1;
2048 } else
2049 *py = -1;
2050 } else {
2051 hline -= currTiming->psbOdd;
2052 val = (currTiming->prbEven+(currTiming->equ*3));
2053 if(hline>=val) {
2054 val = (currTiming->nhlines-currTiming->psbEven);
2055 if(hline<val) {
2056 *py = (s32)(((hline-(currTiming->equ*3))-currTiming->prbEven)&~0x01);
2057 } else
2058 *py = -1;
2059 } else
2060 *py = -1;
2065 static inline void __VIGetCurrentPosition(s32 *px,s32 *py)
2067 s32 xpos,ypos;
2069 __getCurrentDisplayPosition((u32*)&xpos,(u32*)&ypos);
2070 __VIDisplayPositionToXY(xpos,ypos,px,py);
2073 static void __VIRetraceHandler(u32 nIrq,void *pCtx)
2075 #if defined(HW_RVL)
2076 u8 dtv, tv;
2077 #endif
2078 u32 ret = 0;
2079 u32 intr;
2080 s32 xpos,ypos;
2082 intr = _viReg[24];
2083 if(intr&0x8000) {
2084 _viReg[24] = intr&~0x8000;
2085 ret |= 0x01;
2088 intr = _viReg[26];
2089 if(intr&0x8000) {
2090 _viReg[26] = intr&~0x8000;
2091 ret |= 0x02;
2094 intr = _viReg[28];
2095 if(intr&0x8000) {
2096 _viReg[28] = intr&~0x8000;
2097 ret |= 0x04;
2100 intr = _viReg[30];
2101 if(intr&0x8000) {
2102 _viReg[30] = intr&~0x8000;
2103 ret |= 0x08;
2106 intr = _viReg[30];
2107 if(ret&0x04 || ret&0x08) {
2108 if(positionCB!=NULL) {
2109 __VIGetCurrentPosition(&xpos,&ypos);
2110 positionCB(xpos,ypos);
2114 retraceCount++;
2115 if(preRetraceCB)
2116 preRetraceCB(retraceCount);
2118 if(flushFlag) {
2119 if(__VISetRegs()) {
2120 flushFlag = 0;
2121 SI_RefreshSamplingRate();
2124 #if defined(HW_RVL)
2125 tv = VIDEO_GetCurrentTvMode();
2126 dtv = (_viReg[55]&0x01);
2127 if(dtv!=oldDtvStatus || tv!=oldTvStatus) __VISetYUVSEL(dtv);
2128 oldDtvStatus = dtv;
2130 if(tv!=oldTvStatus) {
2131 if(tv==VI_EURGB60) __VISetFilterEURGB60(1);
2132 else __VISetFilterEURGB60(0);
2134 oldTvStatus = tv;
2135 #endif
2136 if(postRetraceCB)
2137 postRetraceCB(retraceCount);
2139 LWP_ThreadBroadcast(video_queue);
2142 void* VIDEO_GetNextFramebuffer()
2144 return nextFb;
2147 void* VIDEO_GetCurrentFramebuffer()
2149 return currentFb;
2152 void VIDEO_Init()
2154 u32 level,vimode = 0;
2156 _CPU_ISR_Disable(level);
2158 if(!(_viReg[1]&0x0001))
2159 __VIInit(VI_TVMODE_NTSC_INT);
2161 retraceCount = 0;
2162 changed = 0;
2163 shdw_changed = 0;
2164 shdw_changeMode = 0;
2165 flushFlag = 0;
2166 encoderType = 1;
2168 _viReg[38] = ((taps[1]>>6)|(taps[2]<<4));
2169 _viReg[39] = (taps[0]|_SHIFTL(taps[1],10,6));
2170 _viReg[40] = ((taps[4]>>6)|(taps[5]<<4));
2171 _viReg[41] = (taps[3]|_SHIFTL(taps[4],10,6));
2172 _viReg[42] = ((taps[7]>>6)|(taps[8]<<4));
2173 _viReg[43] = (taps[6]|_SHIFTL(taps[7],10,6));
2174 _viReg[44] = (taps[11]|(taps[12]<<8));
2175 _viReg[45] = (taps[9]|(taps[10]<<8));
2176 _viReg[46] = (taps[15]|(taps[16]<<8));
2177 _viReg[47] = (taps[13]|(taps[14]<<8));
2178 _viReg[48] = (taps[19]|(taps[20]<<8));
2179 _viReg[49] = (taps[17]|(taps[18]<<8));
2180 _viReg[50] = (taps[23]|(taps[24]<<8));
2181 _viReg[51] = (taps[21]|(taps[22]<<8));
2182 _viReg[56] = 640;
2184 __importAdjustingValues();
2186 HorVer.nonInter = _SHIFTR(_viReg[1],2,1);
2187 HorVer.tv = _SHIFTR(_viReg[1],8,2);
2189 vimode = HorVer.nonInter;
2190 if(HorVer.tv!=VI_DEBUG) vimode += (HorVer.tv<<2);
2191 currTiming = __gettiming(vimode);
2192 currTvMode = HorVer.tv;
2194 regs[1] = _viReg[1];
2195 HorVer.timing = currTiming;
2196 HorVer.dispSizeX = 640;
2197 HorVer.dispSizeY = currTiming->acv<<1;
2198 HorVer.dispPosX = (VI_MAX_WIDTH_NTSC-HorVer.dispSizeX)/2;
2199 HorVer.dispPosY = 0;
2201 __adjustPosition(currTiming->acv);
2203 HorVer.fbSizeX = 640;
2204 HorVer.fbSizeY = currTiming->acv<<1;
2205 HorVer.panPosX = 0;
2206 HorVer.panPosY = 0;
2207 HorVer.panSizeX = 640;
2208 HorVer.panSizeY = currTiming->acv<<1;
2209 HorVer.fbMode = VI_XFBMODE_SF;
2210 HorVer.wordPerLine = 40;
2211 HorVer.std = 40;
2212 HorVer.wpl = 40;
2213 HorVer.xof = 0;
2214 HorVer.black = 1;
2215 HorVer.threeD = 0;
2216 HorVer.bfbb = 0;
2217 HorVer.tfbb = 0;
2218 HorVer.rbfbb = 0;
2219 HorVer.rtfbb = 0;
2221 _viReg[24] &= ~0x8000;
2222 _viReg[26] &= ~0x8000;
2224 preRetraceCB = NULL;
2225 postRetraceCB = NULL;
2227 LWP_InitQueue(&video_queue);
2229 IRQ_Request(IRQ_PI_VI,__VIRetraceHandler,NULL);
2230 __UnmaskIrq(IRQMASK(IRQ_PI_VI));
2231 #if defined(HW_RVL)
2232 __VISetupEncoder();
2233 #endif
2234 _CPU_ISR_Restore(level);
2237 void VIDEO_Configure(GXRModeObj *rmode)
2239 u16 dcr;
2240 u32 nonint,vimode,level;
2241 const struct _timing *curtiming;
2242 #ifdef _VIDEO_DEBUG
2243 if(rmode->viHeight&0x0001) printf("VIDEO_Configure(): Odd number(%d) is specified to viHeight\n",rmode->viHeight);
2244 if((rmode->xfbMode==VI_XFBMODE_DF || rmode->viTVMode==VI_TVMODE_NTSC_PROG || rmode->viTVMode==VI_TVMODE_NTSC_PROG_DS)
2245 && 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);
2246 if(rmode->xfbMode==VI_XFBMODE_SF && !(rmode->viTVMode==VI_TVMODE_NTSC_PROG || rmode->viTVMode==VI_TVMODE_NTSC_PROG_DS)
2247 && (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);
2248 #endif
2249 _CPU_ISR_Disable(level);
2250 nonint = (rmode->viTVMode&0x0003);
2251 if(nonint!=HorVer.nonInter) {
2252 changeMode = 1;
2253 HorVer.nonInter = nonint;
2255 HorVer.tv = _SHIFTR(rmode->viTVMode,2,3);
2256 HorVer.dispPosX = rmode->viXOrigin;
2257 HorVer.dispPosY = rmode->viYOrigin;
2258 if(HorVer.nonInter==VI_NON_INTERLACE) HorVer.dispPosY = HorVer.dispPosY<<1;
2260 HorVer.dispSizeX = rmode->viWidth;
2261 HorVer.fbSizeX = rmode->fbWidth;
2262 HorVer.fbSizeY = rmode->xfbHeight;
2263 HorVer.fbMode = rmode->xfbMode;
2264 HorVer.panSizeX = HorVer.fbSizeX;
2265 HorVer.panSizeY = HorVer.fbSizeY;
2266 HorVer.panPosX = 0;
2267 HorVer.panPosY = 0;
2269 if(HorVer.nonInter==VI_PROGRESSIVE || HorVer.nonInter==(VI_NON_INTERLACE|VI_PROGRESSIVE)) HorVer.dispSizeY = HorVer.panSizeY;
2270 else if(HorVer.fbMode==VI_XFBMODE_SF) HorVer.dispSizeY = HorVer.panSizeY<<1;
2271 else HorVer.dispSizeY = HorVer.panSizeY;
2273 if(HorVer.nonInter==(VI_NON_INTERLACE|VI_PROGRESSIVE)) HorVer.threeD = 1;
2274 else HorVer.threeD = 0;
2276 vimode = VI_TVMODE(HorVer.tv,HorVer.nonInter);
2277 curtiming = __gettiming(vimode);
2278 HorVer.timing = curtiming;
2280 __adjustPosition(curtiming->acv);
2281 #ifdef _VIDEO_DEBUG
2282 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));
2283 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));
2284 #endif
2285 if(!encoderType) HorVer.tv = VI_DEBUG;
2287 __setInterruptRegs(curtiming);
2289 dcr = regs[1]&~0x030c;
2290 dcr |= _SHIFTL(HorVer.threeD,3,1);
2291 if(HorVer.nonInter==VI_PROGRESSIVE || HorVer.nonInter==(VI_NON_INTERLACE|VI_PROGRESSIVE)) dcr |= 0x0004;
2292 else dcr |= _SHIFTL(HorVer.nonInter,2,1);
2293 if(!(HorVer.tv==VI_DEBUG_PAL || HorVer.tv==VI_EURGB60)) dcr |= _SHIFTL(HorVer.tv,8,2);
2294 regs[1] = dcr;
2295 changed |= VI_REGCHANGE(1);
2297 regs[54] &= ~0x0001;
2298 if(rmode->viTVMode==VI_TVMODE_NTSC_PROG || rmode->viTVMode==VI_TVMODE_NTSC_PROG_DS) regs[54] |= 0x0001;
2299 changed |= VI_REGCHANGE(54);
2301 __setScalingRegs(HorVer.panSizeX,HorVer.dispSizeX,HorVer.threeD);
2302 __setHorizontalRegs(curtiming,HorVer.adjustedDispPosX,HorVer.dispSizeX);
2303 __setBBIntervalRegs(curtiming);
2304 __setPicConfig(HorVer.fbSizeX,HorVer.fbMode,HorVer.panPosX,HorVer.panSizeX,&HorVer.wordPerLine,&HorVer.std,&HorVer.wpl,&HorVer.xof);
2306 if(fbSet) __setFbbRegs(&HorVer,&HorVer.tfbb,&HorVer.bfbb,&HorVer.rtfbb,&HorVer.rbfbb);
2308 __setVerticalRegs(HorVer.adjustedDispPosY,HorVer.adjustedDispSizeY,curtiming->equ,curtiming->acv,curtiming->prbOdd,curtiming->prbEven,curtiming->psbOdd,curtiming->psbEven,HorVer.black);
2309 #ifdef _VIDEO_DEBUG
2310 printDebugCalculations();
2311 #endif
2312 _CPU_ISR_Restore(level);
2315 void VIDEO_WaitVSync(void)
2317 u32 level;
2318 u32 retcnt;
2320 _CPU_ISR_Disable(level);
2321 retcnt = retraceCount;
2322 do {
2323 LWP_ThreadSleep(video_queue);
2324 } while(retraceCount==retcnt);
2325 _CPU_ISR_Restore(level);
2328 void VIDEO_SetFramebuffer(void *fb)
2330 u32 level;
2332 _CPU_ISR_Disable(level);
2333 fbSet = 1;
2334 HorVer.bufAddr = fb;
2335 __setFbbRegs(&HorVer,&HorVer.tfbb,&HorVer.bfbb,&HorVer.rtfbb,&HorVer.rbfbb);
2336 _viReg[14] = regs[14];
2337 _viReg[15] = regs[15];
2339 _viReg[18] = regs[18];
2340 _viReg[19] = regs[19];
2342 if(HorVer.threeD) {
2343 _viReg[16] = regs[16];
2344 _viReg[17] = regs[17];
2346 _viReg[20] = regs[20];
2347 _viReg[21] = regs[21];
2349 _CPU_ISR_Restore(level);
2352 void VIDEO_SetNextFramebuffer(void *fb)
2354 u32 level;
2355 #ifdef _VIDEO_DEBUG
2356 if((u32)fb&0x1f) printf("VIDEO_SetNextFramebuffer(): Frame buffer address (%p) is not 32byte aligned\n",fb);
2357 #endif
2358 _CPU_ISR_Disable(level);
2359 fbSet = 1;
2360 HorVer.bufAddr = fb;
2361 __setFbbRegs(&HorVer,&HorVer.tfbb,&HorVer.bfbb,&HorVer.rtfbb,&HorVer.rbfbb);
2362 _CPU_ISR_Restore(level);
2365 void VIDEO_SetNextRightFramebuffer(void *fb)
2367 u32 level;
2369 _CPU_ISR_Disable(level);
2370 fbSet = 1;
2371 HorVer.rbufAddr = fb;
2372 __setFbbRegs(&HorVer,&HorVer.tfbb,&HorVer.bfbb,&HorVer.rtfbb,&HorVer.rbfbb);
2373 _CPU_ISR_Restore(level);
2376 void VIDEO_Flush()
2378 u32 level;
2379 u32 val;
2380 u64 mask;
2382 _CPU_ISR_Disable(level);
2383 shdw_changeMode |= changeMode;
2384 changeMode = 0;
2386 shdw_changed |= changed;
2387 while(changed) {
2388 val = cntlzd(changed);
2389 shdw_regs[val] = regs[val];
2390 mask = VI_REGCHANGE(val);
2391 changed &= ~mask;
2393 flushFlag = 1;
2394 #ifdef _VIDEO_DEBUG
2395 printRegs();
2396 #endif
2397 nextFb = HorVer.bufAddr;
2398 _CPU_ISR_Restore(level);
2401 void VIDEO_SetBlack(boolean black)
2403 u32 level;
2404 const struct _timing *curtiming;
2406 _CPU_ISR_Disable(level);
2407 HorVer.black = black;
2408 curtiming = HorVer.timing;
2409 __setVerticalRegs(HorVer.adjustedDispPosY,HorVer.dispSizeY,curtiming->equ,curtiming->acv,curtiming->prbOdd,curtiming->prbEven,curtiming->psbOdd,curtiming->psbEven,HorVer.black);
2410 _CPU_ISR_Restore(level);
2413 u32 VIDEO_GetNextField()
2415 u32 level,nextfield;
2417 _CPU_ISR_Disable(level);
2418 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
2419 _CPU_ISR_Restore(level);
2421 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
2424 u32 VIDEO_GetCurrentTvMode()
2426 u32 mode;
2427 u32 level;
2428 u32 tv;
2430 _CPU_ISR_Disable(level);
2431 mode = currTvMode;
2433 if(mode==VI_DEBUG) tv = VI_NTSC;
2434 else if(mode==VI_EURGB60) tv = mode;
2435 else if(mode==VI_MPAL) tv = VI_MPAL;
2436 else if(mode==VI_NTSC) tv = VI_NTSC;
2437 else tv = VI_PAL;
2438 _CPU_ISR_Restore(level);
2440 return tv;
2443 GXRModeObj * VIDEO_GetPreferredMode(GXRModeObj *mode)
2446 GXRModeObj *rmode;
2448 #if defined(HW_RVL)
2450 if ( CONF_GetProgressiveScan() > 0 && VIDEO_HaveComponentCable() ) {
2451 rmode = &TVNtsc480Prog;
2452 } else {
2454 u32 tvmode = CONF_GetVideo();
2456 switch ( tvmode ) {
2457 case CONF_VIDEO_NTSC:
2458 rmode = &TVNtsc480IntDf;
2459 break;
2460 case CONF_VIDEO_PAL:
2461 if ( CONF_GetEuRGB60() > 0 ) {
2462 rmode = &TVEurgb60Hz480Int;
2463 } else {
2464 rmode = &TVPal528IntDf;
2466 break;
2467 case CONF_VIDEO_MPAL:
2468 rmode = &TVMpal480IntDf;
2469 break;
2470 default:
2471 rmode = &TVNtsc480IntDf;
2474 #else
2475 u32 tvmode = VIDEO_GetCurrentTvMode();
2476 switch(tvmode)
2478 case VI_NTSC:
2479 rmode = &TVNtsc480IntDf;
2480 break;
2481 case VI_PAL:
2482 rmode = &TVPal528IntDf;
2483 break;
2484 case VI_MPAL:
2485 rmode = &TVMpal480IntDf;
2486 break;
2487 default:
2488 rmode = &TVNtsc480IntDf;
2489 break;
2491 #endif
2493 if ( NULL != mode ) {
2494 memcpy( mode, rmode, sizeof(GXRModeObj));
2495 } else {
2496 mode = rmode;
2499 return mode;
2505 u32 VIDEO_GetCurrentLine()
2507 u32 level,curr_hl = 0;
2509 _CPU_ISR_Disable(level);
2510 curr_hl = __getCurrentHalfLine();
2511 _CPU_ISR_Restore(level);
2513 if(curr_hl>=currTiming->nhlines) curr_hl -=currTiming->nhlines;
2514 curr_hl >>= 1;
2516 return curr_hl;
2519 VIRetraceCallback VIDEO_SetPreRetraceCallback(VIRetraceCallback callback)
2521 u32 level = 0;
2522 VIRetraceCallback ret = preRetraceCB;
2523 _CPU_ISR_Disable(level);
2524 preRetraceCB = callback;
2525 _CPU_ISR_Restore(level);
2526 return ret;
2529 VIRetraceCallback VIDEO_SetPostRetraceCallback(VIRetraceCallback callback)
2531 u32 level = 0;
2532 VIRetraceCallback ret = postRetraceCB;
2533 _CPU_ISR_Disable(level);
2534 postRetraceCB = callback;
2535 _CPU_ISR_Restore(level);
2536 return ret;
2539 void VIDEO_ClearFrameBuffer(GXRModeObj *rmode,void *fb,u32 color)
2541 u32 size = VIDEO_PadFramebufferWidth(rmode->fbWidth)*rmode->xfbHeight*VI_DISPLAY_PIX_SZ;
2542 __VIClearFramebuffer(fb,size,color);
2545 u32 VIDEO_HaveComponentCable(void)
2547 return (_viReg[55]&0x01);