/*------------------------------------------------------------- video.c -- VIDEO subsystem Copyright (C) 2004 - 2008 Michael Wiedenbauer (shagkur) Dave Murphy (WinterMute) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "video_sys.h" #include "video_types.h" #define _SHIFTL(v, s, w) \ ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s))) #define _SHIFTR(v, s, w) \ ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1))) #define VI_REGCHANGE(_reg) \ ((u64)0x01<<(63-_reg)) typedef struct _horVer { u16 dispPosX; u16 dispPosY; u16 dispSizeX; u16 dispSizeY; u16 adjustedDispPosX; u16 adjustedDispPosY; u16 adjustedDispSizeY; u16 adjustedPanPosY; u16 adjustedPanSizeY; u16 fbSizeX; u16 fbSizeY; u16 panPosX; u16 panPosY; u16 panSizeX; u16 panSizeY; u32 fbMode; u32 nonInter; u32 tv; u8 wordPerLine; u8 std; u8 wpl; void *bufAddr; u32 tfbb; u32 bfbb; u8 xof; s32 black; s32 threeD; void *rbufAddr; u32 rtfbb; u32 rbfbb; const struct _timing *timing; } horVer; GXRModeObj CUSTOM_TVNtsc240Ds = { VI_TVMODE_NTSC_DS, // viDisplayMode 640, // fbWidth 240, // efbHeight 240, // xfbHeight (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVNtsc240DsAa = { VI_TVMODE_NTSC_DS, // viDisplayMode 640, // fbWidth 240, // efbHeight 240, // xfbHeight (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_TRUE, // aa // sample points arranged in increasing Y order { {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {3,2},{9,6},{3,10}, // pix 1 {9,2},{3,6},{9,10}, // pix 2 {9,2},{3,6},{9,10} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVNtsc240Int = { VI_TVMODE_NTSC_INT, // viDisplayMode 640, // fbWidth 240, // efbHeight 240, // xfbHeight (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_TRUE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVNtsc240IntAa = { VI_TVMODE_NTSC_INT, // viDisplayMode 640, // fbWidth 240, // efbHeight 240, // xfbHeight (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_TRUE, // field_rendering GX_TRUE, // aa // sample points arranged in increasing Y order { {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {3,2},{9,6},{3,10}, // pix 1 {9,2},{3,6},{9,10}, // pix 2 {9,2},{3,6},{9,10} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVNtsc480Int = { VI_TVMODE_NTSC_INT, // viDisplayMode 640, // fbWidth 480, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_DF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVNtsc480IntDf = { VI_TVMODE_NTSC_INT, // viDisplayMode 640, // fbWidth 480, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_DF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 8, // line n-1 8, // line n-1 10, // line n 12, // line n 10, // line n 8, // line n+1 8 // line n+1 } }; GXRModeObj CUSTOM_TVNtsc480IntAa = { VI_TVMODE_NTSC_INT, // viDisplayMode 640, // fbWidth 242, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_DF, // xFBmode GX_FALSE, // field_rendering GX_TRUE, // aa // sample points arranged in increasing Y order { {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {3,2},{9,6},{3,10}, // pix 1 {9,2},{3,6},{9,10}, // pix 2 {9,2},{3,6},{9,10} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 4, // line n-1 8, // line n-1 12, // line n 16, // line n 12, // line n 8, // line n+1 4 // line n+1 } }; GXRModeObj CUSTOM_TVNtsc480Prog = { VI_TVMODE_NTSC_PROG, // viDisplayMode 640, // fbWidth 480, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVNtsc480ProgSoft = { VI_TVMODE_NTSC_PROG, // viDisplayMode 640, // fbWidth 480, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 8, // line n-1 8, // line n-1 10, // line n 12, // line n 10, // line n 8, // line n+1 8 // line n+1 } }; GXRModeObj CUSTOM_TVNtsc480ProgAa = { VI_TVMODE_NTSC_PROG, // viDisplayMode 640, // fbWidth 242, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_TRUE, // aa // sample points arranged in increasing Y order { {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {3,2},{9,6},{3,10}, // pix 1 {9,2},{3,6},{9,10}, // pix 2 {9,2},{3,6},{9,10} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 4, // line n-1 8, // line n-1 12, // line n 16, // line n 12, // line n 8, // line n+1 4 // line n+1 } }; GXRModeObj CUSTOM_TVMpal480IntDf = { VI_TVMODE_MPAL_INT, // viDisplayMode 640, // fbWidth 480, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_MPAL - 640)/2, // viXOrigin (VI_MAX_HEIGHT_MPAL - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_DF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 8, // line n-1 8, // line n-1 10, // line n 12, // line n 10, // line n 8, // line n+1 8 // line n+1 } }; GXRModeObj CUSTOM_TVMpal480IntAa = { VI_TVMODE_MPAL_INT, // viDisplayMode 640, // fbWidth 242, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_MPAL - 640)/2, // viXOrigin (VI_MAX_HEIGHT_MPAL - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_DF, // xFBmode GX_FALSE, // field_rendering GX_TRUE, // aa // sample points arranged in increasing Y order { {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {3,2},{9,6},{3,10}, // pix 1 {9,2},{3,6},{9,10}, // pix 2 {9,2},{3,6},{9,10} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 4, // line n-1 8, // line n-1 12, // line n 16, // line n 12, // line n 8, // line n+1 4 // line n+1 } }; GXRModeObj CUSTOM_TVMpal240Ds = { VI_TVMODE_MPAL_DS, // viDisplayMode 640, // fbWidth 240, // efbHeight 240, // xfbHeight (VI_MAX_WIDTH_MPAL - 640)/2, // viXOrigin (VI_MAX_HEIGHT_MPAL - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVMpal240DsAa = { VI_TVMODE_MPAL_DS, // viDisplayMode 640, // fbWidth 240, // efbHeight 240, // xfbHeight (VI_MAX_WIDTH_MPAL - 640)/2, // viXOrigin (VI_MAX_HEIGHT_MPAL - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_TRUE, // aa // sample points arranged in increasing Y order { {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {3,2},{9,6},{3,10}, // pix 1 {9,2},{3,6},{9,10}, // pix 2 {9,2},{3,6},{9,10} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVPal264Ds = { VI_TVMODE_PAL_DS, // viDisplayMode 640, // fbWidth 264, // efbHeight 264, // xfbHeight (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin 640, // viWidth 528, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVPal264DsAa = { VI_TVMODE_PAL_DS, // viDisplayMode 640, // fbWidth 264, // efbHeight 264, // xfbHeight (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin 640, // viWidth 528, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_TRUE, // aa // sample points arranged in increasing Y order { {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {3,2},{9,6},{3,10}, // pix 1 {9,2},{3,6},{9,10}, // pix 2 {9,2},{3,6},{9,10} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVPal264Int = { VI_TVMODE_PAL_INT, // viDisplayMode 640, // fbWidth 264, // efbHeight 264, // xfbHeight (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin 640, // viWidth 528, // viHeight VI_XFBMODE_SF, // xFBmode GX_TRUE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVPal264IntAa = { VI_TVMODE_PAL_INT, // viDisplayMode 640, // fbWidth 264, // efbHeight 264, // xfbHeight (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin 640, // viWidth 528, // viHeight VI_XFBMODE_SF, // xFBmode GX_TRUE, // field_rendering GX_TRUE, // aa // sample points arranged in increasing Y order { {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {3,2},{9,6},{3,10}, // pix 1 {9,2},{3,6},{9,10}, // pix 2 {9,2},{3,6},{9,10} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVPal524IntAa = { VI_TVMODE_PAL_INT, 640, 264, 524, (VI_MAX_WIDTH_PAL-640)/2, (VI_MAX_HEIGHT_PAL-528)/2, 640, 524, VI_XFBMODE_DF, GX_FALSE, GX_TRUE, // sample points arranged in increasing Y order { {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {3,2},{9,6},{3,10}, // pix 1 {9,2},{3,6},{9,10}, // pix 2 {9,2},{3,6},{9,10} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 4, // line n-1 8, // line n-1 12, // line n 16, // line n 12, // line n 8, // line n+1 4 // line n+1 } }; GXRModeObj CUSTOM_TVPal528Int = { VI_TVMODE_PAL_INT, // viDisplayMode 640, // fbWidth 528, // efbHeight 528, // xfbHeight (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin 640, // viWidth 528, // viHeight VI_XFBMODE_DF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVPal528IntDf = { VI_TVMODE_PAL_INT, // viDisplayMode 640, // fbWidth 528, // efbHeight 528, // xfbHeight (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin 640, // viWidth 528, // viHeight VI_XFBMODE_DF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 8, // line n-1 8, // line n-1 10, // line n 12, // line n 10, // line n 8, // line n+1 8 // line n+1 } }; GXRModeObj CUSTOM_TVPal574IntDfScale = { VI_TVMODE_PAL_INT, // viDisplayMode 640, // fbWidth 480, // efbHeight 574, // xfbHeight (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin (VI_MAX_HEIGHT_PAL - 574)/2, // viYOrigin 640, // viWidth 574, // viHeight VI_XFBMODE_DF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 8, // line n-1 8, // line n-1 10, // line n 12, // line n 10, // line n 8, // line n+1 8 // line n+1 } }; GXRModeObj CUSTOM_TVEurgb60Hz240Ds = { VI_TVMODE_EURGB60_DS, // viDisplayMode 640, // fbWidth 240, // efbHeight 240, // xfbHeight (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVEurgb60Hz240DsAa = { VI_TVMODE_EURGB60_DS, // viDisplayMode 640, // fbWidth 240, // efbHeight 240, // xfbHeight (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_TRUE, // aa // sample points arranged in increasing Y order { {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {3,2},{9,6},{3,10}, // pix 1 {9,2},{3,6},{9,10}, // pix 2 {9,2},{3,6},{9,10} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVEurgb60Hz240Int = { VI_TVMODE_EURGB60_INT, // viDisplayMode 640, // fbWidth 240, // efbHeight 240, // xfbHeight (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_TRUE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVEurgb60Hz240IntAa = { VI_TVMODE_EURGB60_INT, // viDisplayMode 640, // fbWidth 240, // efbHeight 240, // xfbHeight (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_TRUE, // field_rendering GX_TRUE, // aa // sample points arranged in increasing Y order { {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {3,2},{9,6},{3,10}, // pix 1 {9,2},{3,6},{9,10}, // pix 2 {9,2},{3,6},{9,10} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVEurgb60Hz480Int = { VI_TVMODE_EURGB60_INT, // viDisplayMode 640, // fbWidth 480, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_DF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVEurgb60Hz480IntDf = { VI_TVMODE_EURGB60_INT, // viDisplayMode 640, // fbWidth 480, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_DF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 8, // line n-1 8, // line n-1 10, // line n 12, // line n 10, // line n 8, // line n+1 8 // line n+1 } }; GXRModeObj CUSTOM_TVEurgb60Hz480IntAa = { VI_TVMODE_EURGB60_INT, // viDisplayMode 640, // fbWidth 242, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_DF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {3,2},{9,6},{3,10}, // pix 1 {9,2},{3,6},{9,10}, // pix 2 {9,2},{3,6},{9,10} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 4, // line n-1 8, // line n-1 12, // line n 16, // line n 12, // line n 8, // line n+1 4 // line n+1 } }; GXRModeObj CUSTOM_TVEurgb60Hz480Prog = { VI_TVMODE_EURGB60_PROG, // viDisplayMode 640, // fbWidth 480, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVEurgb60Hz480ProgSoft = { VI_TVMODE_EURGB60_PROG, // viDisplayMode 640, // fbWidth 480, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {3,2},{9,6},{3,10}, // pix 1 {9,2},{3,6},{9,10}, // pix 2 {9,2},{3,6},{9,10} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 4, // line n-1 8, // line n-1 12, // line n 16, // line n 12, // line n 8, // line n+1 4 // line n+1 } }; GXRModeObj CUSTOM_TVEurgb60Hz480ProgAa = { VI_TVMODE_EURGB60_PROG, // viDisplayMode 640, // fbWidth 242, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_EURGB60 - 640)/2, // viXOrigin (VI_MAX_HEIGHT_EURGB60 - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_TRUE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 8, // line n-1 8, // line n-1 10, // line n 12, // line n 10, // line n 8, // line n+1 8 // line n+1 } }; GXRModeObj CUSTOM_TVPal528Prog = { 6, // viDisplayMode 640, // fbWidth 528, // efbHeight 528, // xfbHeight (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin 640, // viWidth 528, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; GXRModeObj CUSTOM_TVPal528ProgSoft = { 6, // viDisplayMode 640, // fbWidth 528, // efbHeight 528, // xfbHeight (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin 640, // viWidth 528, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 8, // line n-1 8, // line n-1 10, // line n 12, // line n 10, // line n 8, // line n+1 8 // line n+1 } }; GXRModeObj CUSTOM_TVPal528ProgUnknown = { 6, // viDisplayMode 640, // fbWidth 264, // efbHeight 524, // xfbHeight (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin (VI_MAX_HEIGHT_PAL - 528)/2, // viYOrigin 640, // viWidth 524, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_TRUE, // aa // sample points arranged in increasing Y order { {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {3,2},{9,6},{3,10}, // pix 1 {9,2},{3,6},{9,10}, // pix 2 {9,2},{3,6},{9,10} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 4, // line n-1 8, // line n-1 12, // line n 16, // line n 12, // line n 8, // line n+1 4 // line n+1 } }; GXRModeObj CUSTOM_TVMpal480Prog = { 10, // viDisplayMode 640, // fbWidth 480, // efbHeight 480, // xfbHeight (VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin (VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin 640, // viWidth 480, // viHeight VI_XFBMODE_SF, // xFBmode GX_FALSE, // field_rendering GX_FALSE, // aa // sample points arranged in increasing Y order { {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 1 {6,6},{6,6},{6,6}, // pix 2 {6,6},{6,6},{6,6} // pix 3 }, // vertical filter[7], 1/64 units, 6 bits each { 0, // line n-1 0, // line n-1 21, // line n 22, // line n 21, // line n 0, // line n+1 0 // line n+1 } }; static const u16 taps[26] = { 0x01F0,0x01DC,0x01AE,0x0174,0x0129,0x00DB, 0x008E,0x0046,0x000C,0x00E2,0x00CB,0x00C0, 0x00C4,0x00CF,0x00DE,0x00EC,0x00FC,0x0008, 0x000F,0x0013,0x0013,0x000F,0x000C,0x0008, 0x0001,0x0000 }; static const struct _timing { u8 equ; u16 acv; u16 prbOdd,prbEven; u16 psbOdd,psbEven; u8 bs1,bs2,bs3,bs4; u16 be1,be2,be3,be4; u16 nhlines,hlw; u8 hsy,hcs,hce,hbe640; u16 hbs640; u8 hbeCCIR656; u16 hbsCCIR656; } CUSTOM_VIDEO_timing[] = { { 0x06,0x00F0, 0x0018,0x0019,0x0003,0x0002, 0x0C,0x0D,0x0C,0x0D, 0x0208,0x0207,0x0208,0x0207, 0x020D,0x01AD, 0x40,0x47,0x69,0xA2, 0x0175, 0x7A,0x019C }, { 0x06,0x00F0, 0x0018,0x0018,0x0004,0x0004, 0x0C,0x0C,0x0C,0x0C, 0x0208,0x0208,0x0208,0x0208, 0x020E,0x01AD, 0x40,0x47,0x69,0xA2, 0x0175, 0x7A,0x019C }, { 0x05,0x011F, 0x0023,0x0024,0x0001,0x0000, 0x0D,0x0C,0x0B,0x0A, 0x026B,0x026A,0x0269,0x026C, 0x0271,0x01B0, 0x40,0x4B,0x6A,0xAC, 0x017C, 0x85,0x01A4 }, { 0x05,0x011F, 0x0021,0x0021,0x0002,0x0002, 0x0D,0x0B,0x0D,0x0B, 0x026B,0x026D,0x026B,0x026D, 0x0270,0x01B0, 0x40,0x4B,0x6A,0xAC, 0x017C, 0x85,0x01A4 }, { 0x06,0x00F0, 0x0018,0x0019,0x0003,0x0002, 0x10,0x0F,0x0E,0x0D, 0x0206,0x0205,0x0204,0x0207, 0x020D,0x01AD, 0x40,0x4E,0x70,0xA2, 0x0175, 0x7A,0x019C }, { 0x06,0x00F0, 0x0018,0x0018,0x0004,0x0004, 0x10,0x0E,0x10,0x0E, 0x0206,0x0208,0x0206,0x0208, 0x020E,0x01AD, 0x40,0x4E,0x70,0xA2, 0x0175, 0x7A,0x019C }, { 0x0C,0x01e0, 0x0030,0x0030,0x0006,0x0006, 0x18,0x18,0x18,0x18, 0x040e,0x040e,0x040e,0x040e, 0x041a,0x01ad, 0x40,0x47,0x69,0xa2, 0x0175, 0x7a,0x019c }, { 0x0c,0x01e0, 0x002c,0x002c,0x000a,0x000a, 0x18,0x18,0x18,0x18, 0x040e,0x040e,0x040e,0x040e, 0x041a,0x01ad, 0x40,0x47,0x69,0xa8, 0x017b, 0x7a,0x019c }, { 0x06,0x00F1, 0x0018,0x0019,0x0001,0x0000, 0x0C,0x0D,0x0C,0x0D, 0x0208,0x0207,0x0208,0x0207, 0x020D,0x01AD, 0x40,0x47,0x69,0x9F, 0x0172, 0x7A,0x019C }, { 0x0C,0x01E0, 0x0030,0x0030,0x0006,0x0006, 0x18,0x18,0x18,0x18, 0x040E,0x040E,0x040E,0x040E, 0x041A,0x01AD, 0x40,0x47,0x69,0xB4, 0x0187, 0x7A,0x019C } }; #if defined(HW_RVL) static u32 vdacFlagRegion; static u32 i2cIdentFirst = 0; static u32 i2cIdentFlag = 1; static u32 oldTvStatus = 0x03e7; static u32 oldDtvStatus = 0x03e7; static vu32* const _i2cReg = (u32*)0xCD800000; #endif static u16 regs[60]; static u16 shdw_regs[60]; static u32 encoderType,fbSet = 0; static s16 displayOffsetH; static s16 displayOffsetV; static u32 currTvMode,changeMode; static u32 shdw_changeMode,flushFlag; static u64 changed,shdw_changed; static vu32 retraceCount; static const struct _timing *currTiming; static lwpq_t CUSTOM_VIDEO_queue; static horVer HorVer; static void *currentFb = NULL; static void *nextFb = NULL; static VIRetraceCallback preRetraceCB = NULL; static VIRetraceCallback postRetraceCB = NULL; static VIPositionCallback positionCB = NULL; static vu16* const _viReg = (u16*)0xCC002000; extern syssram* __SYS_LockSram(); extern u32 __SYS_UnlockSram(u32 write); extern void __VIClearFramebuffer(void*,u32,u32); extern void udelay(int us); #ifdef _CUSTOM_VIDEO_DEBUG static u32 messages$128 = 0; static u32 printregs = 1; static void printRegs() { if(!printregs) { printf("displayOffsetH = %d\ndisplayOffsetV = %d\n",displayOffsetH,displayOffsetV); printf("%08x%08x\n",(u32)(shdw_changed>>32),(u32)shdw_changed); 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]); 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]); 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]); 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]); 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]); 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]); 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]); printf("%04x %04x %04x %04x\n\n",shdw_regs[56],shdw_regs[57],shdw_regs[58],shdw_regs[59]); 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]); 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]); 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]); 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]); 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]); 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]); 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]); printf("%04x %04x %04x %04x\n",_viReg[56],_viReg[57],_viReg[58],_viReg[59]); printregs = 1; } } static void printDebugCalculations() { if(!messages$128) { messages$128 = 1; printf("HorVer.dispPosX = %d\n",HorVer.dispPosX); printf("HorVer.dispPosY = %d\n",HorVer.dispPosY); printf("HorVer.dispSizeX = %d\n",HorVer.dispSizeX); printf("HorVer.dispSizeY = %d\n",HorVer.dispSizeY); printf("HorVer.adjustedDispPosX = %d\n",HorVer.adjustedDispPosX); printf("HorVer.adjustedDispPosY = %d\n",HorVer.adjustedDispPosY); printf("HorVer.adjustedDispSizeY = %d\n",HorVer.adjustedDispSizeY); printf("HorVer.adjustedPanPosY = %d\n",HorVer.adjustedPanPosY); printf("HorVer.adjustedPanSizeY = %d\n",HorVer.adjustedPanSizeY); printf("HorVer.fbSizeX = %d\n",HorVer.fbSizeX); printf("HorVer.fbSizeY = %d\n",HorVer.fbSizeY); printf("HorVer.panPosX = %d\n",HorVer.panPosX); printf("HorVer.panPosY = %d\n",HorVer.panPosY); printf("HorVer.panSizeX = %d\n",HorVer.panSizeX); printf("HorVer.panSizeY = %d\n",HorVer.panSizeY); printf("HorVer.fbMode = %d\n",HorVer.fbMode); printf("HorVer.nonInter = %d\n",HorVer.nonInter); printf("HorVer.tv = %d\n",HorVer.tv); printf("HorVer.wordPerLine = %d\n",HorVer.wordPerLine); printf("HorVer.wpl = %d\n",HorVer.wpl); printf("HorVer.std = %d\n",HorVer.std); printf("HorVer.xof = %d\n",HorVer.xof); printf("HorVer.bufAddr = %p\n",HorVer.bufAddr); printf("HorVer.tfbb = 0x%08x\n",HorVer.tfbb); printf("HorVer.bfbb = 0x%08x\n",HorVer.bfbb); printf("HorVer.rbufAddr = %p\n",HorVer.rbufAddr); printf("HorVer.rtfbb = 0x%08x\n",HorVer.rtfbb); printf("HorVer.rbfbb = 0x%08x\n",HorVer.rbfbb); printf("HorVer.black = %d\n",HorVer.black); printf("HorVer.threeD = %d\n",HorVer.threeD); } } #endif static __inline__ u32 cntlzd(u64 bit) { u32 hi,lo,value = 0; hi = (u32)(bit>>32); lo = (u32)(bit&-1); value = cntlzw(hi); if(value>=32) value += cntlzw(lo); return value; } static const struct _timing* __gettiming(u32 vimode) { if(vimode>0x1e) return NULL; switch(vimode) { case VI_TVMODE_NTSC_INT: return &CUSTOM_VIDEO_timing[0]; break; case VI_TVMODE_NTSC_DS: return &CUSTOM_VIDEO_timing[1]; break; case VI_TVMODE_PAL_INT: return &CUSTOM_VIDEO_timing[2]; break; case VI_TVMODE_PAL_DS: return &CUSTOM_VIDEO_timing[3]; break; case VI_TVMODE_EURGB60_INT: return &CUSTOM_VIDEO_timing[0]; break; case VI_TVMODE_EURGB60_DS: return &CUSTOM_VIDEO_timing[1]; break; case VI_TVMODE_MPAL_INT: return &CUSTOM_VIDEO_timing[4]; break; case VI_TVMODE_MPAL_DS: return &CUSTOM_VIDEO_timing[5]; break; case VI_TVMODE_NTSC_PROG: return &CUSTOM_VIDEO_timing[6]; break; case VI_TVMODE_NTSC_PROG_DS: return &CUSTOM_VIDEO_timing[7]; break; case VI_TVMODE_DEBUG_PAL_INT: return &CUSTOM_VIDEO_timing[2]; break; case VI_TVMODE_DEBUG_PAL_DS: return &CUSTOM_VIDEO_timing[3]; break; default: break; } return NULL; } #if defined(HW_RVL) static inline void __viOpenI2C(u32 channel) { u32 val = ((_i2cReg[49]&~0x8000)|0x4000); val |= _SHIFTL(channel,15,1); _i2cReg[49] = val; } static inline u32 __viSetSCL(u32 channel) { u32 val = (_i2cReg[48]&~0x4000); val |= _SHIFTL(channel,14,1); _i2cReg[48] = val; return 1; } static inline u32 __viSetSDA(u32 channel) { u32 val = (_i2cReg[48]&~0x8000); val |= _SHIFTL(channel,15,1); _i2cReg[48] = val; return 1; } static inline u32 __viGetSDA() { return _SHIFTR(_i2cReg[50],15,1); } static inline void __viCheckI2C() { __viOpenI2C(0); udelay(4); i2cIdentFlag = 0; if(__viGetSDA()!=0) i2cIdentFlag = 1; } static u32 __sendSlaveAddress(u8 addr) { u32 i; __viSetSDA(i2cIdentFlag^1); udelay(2); __viSetSCL(0); for(i=0;i<8;i++) { if(addr&0x80) __viSetSDA(i2cIdentFlag); else __viSetSDA(i2cIdentFlag^1); udelay(2); __viSetSCL(1); udelay(2); __viSetSCL(0); addr <<= 1; } __viOpenI2C(0); udelay(2); __viSetSCL(1); udelay(2); if(i2cIdentFlag==1 && __viGetSDA()!=0) return 0; __viSetSDA(i2cIdentFlag^1); __viOpenI2C(1); __viSetSCL(0); return 1; } #endif static inline void __setInterruptRegs(const struct _timing *tm) { u16 hlw; hlw = 0; if(tm->nhlines%2) hlw = tm->hlw; regs[24] = 0x1000|((tm->nhlines/2)+1); regs[25] = hlw+1; changed |= VI_REGCHANGE(24); changed |= VI_REGCHANGE(25); } static inline void __setPicConfig(u16 fbSizeX,u32 xfbMode,u16 panPosX,u16 panSizeX,u8 *wordPerLine,u8 *std,u8 *wpl,u8 *xof) { *wordPerLine = (fbSizeX+15)/16; *std = *wordPerLine; if(xfbMode==VI_XFBMODE_DF) *std <<= 1; *xof = panPosX%16; *wpl = (*xof+(panSizeX+15))/16; regs[36] = (*wpl<<8)|*std; changed |= VI_REGCHANGE(36); } static inline void __setBBIntervalRegs(const struct _timing *tm) { regs[10] = (tm->be3<<5)|tm->bs3; regs[11] = (tm->be1<<5)|tm->bs1; changed |= VI_REGCHANGE(10); changed |= VI_REGCHANGE(11); regs[12] = (tm->be4<<5)|tm->bs4; regs[13] = (tm->be2<<5)|tm->bs2; changed |= VI_REGCHANGE(12); changed |= VI_REGCHANGE(13); } static void __setScalingRegs(u16 panSizeX,u16 dispSizeX,s32 threeD) { if(threeD) panSizeX = _SHIFTL(panSizeX,1,16); if(panSizeXbufAddr,horVer->panPosX,horVer->adjustedPanPosY,horVer->wordPerLine,horVer->fbMode,horVer->adjustedDispPosY,tfbb,bfbb); if(horVer->threeD) __calcFbbs((u32)horVer->rbufAddr,horVer->panPosX,horVer->adjustedPanPosY,horVer->wordPerLine,horVer->fbMode,horVer->adjustedDispPosY,rtfbb,rbfbb); flag = 1; if((*tfbb)<0x01000000 && (*bfbb)<0x01000000 && (*rtfbb)<0x01000000 && (*rbfbb)<0x01000000) flag = 0; if(flag) { *tfbb >>= 5; *bfbb >>= 5; *rtfbb >>= 5; *rbfbb >>= 5; } regs[14] = _SHIFTL(flag,12,1)|_SHIFTL(horVer->xof,8,4)|_SHIFTR(*tfbb,16,8); regs[15] = *tfbb&0xffff; changed |= VI_REGCHANGE(14); changed |= VI_REGCHANGE(15); regs[18] = _SHIFTR(*bfbb,16,8); regs[19] = *bfbb&0xffff; changed |= VI_REGCHANGE(18); changed |= VI_REGCHANGE(19); if(horVer->threeD) { regs[16] = _SHIFTR(*rtfbb,16,8); regs[17] = *rtfbb&0xffff; changed |= VI_REGCHANGE(16); changed |= VI_REGCHANGE(17); regs[20] = _SHIFTR(*rbfbb,16,8); regs[21] = *rbfbb&0xffff; changed |= VI_REGCHANGE(20); changed |= VI_REGCHANGE(21); } } static inline void __setHorizontalRegs(const struct _timing *tm,u16 dispPosX,u16 dispSizeX) { u32 val1,val2; regs[2] = (tm->hcs<<8)|tm->hce; regs[3] = tm->hlw; changed |= VI_REGCHANGE(2); changed |= VI_REGCHANGE(3); val1 = (tm->hbe640+dispPosX-40)&0x01ff; val2 = (tm->hbs640+dispPosX+40)-(720-dispSizeX); regs[4] = (val1>>9)|(val2<<1); regs[5] = (val1<<7)|tm->hsy; changed |= VI_REGCHANGE(4); changed |= VI_REGCHANGE(5); } static inline void __setVerticalRegs(u16 dispPosY,u16 dispSizeY,u8 equ,u16 acv,u16 prbOdd,u16 prbEven,u16 psbOdd,u16 psbEven,s32 black) { u16 tmp; u32 div1,div2; u32 psb,prb; u32 psbodd,prbodd; u32 psbeven,prbeven; div1 = 2; div2 = 1; if(equ>=10) { div1 = 1; div2 = 2; } prb = div2*dispPosY; psb = div2*(((acv*div1)-dispSizeY)-dispPosY); if(dispPosY%2) { prbodd = prbEven+prb; psbodd = psbEven+psb; prbeven = prbOdd+prb; psbeven = psbOdd+psb; } else { prbodd = prbOdd+prb; psbodd = psbOdd+psb; prbeven = prbEven+prb; psbeven = psbEven+psb; } tmp = dispSizeY/div1; if(black) { prbodd += ((tmp<<1)-2); prbeven += ((tmp<<1)-2); psbodd += 2; psbeven += 2; tmp = 0; } regs[0] = ((tmp<<4)&~0x0f)|equ; changed |= VI_REGCHANGE(0); regs[6] = psbodd; regs[7] = prbodd; changed |= VI_REGCHANGE(6); changed |= VI_REGCHANGE(7); regs[8] = psbeven; regs[9] = prbeven; changed |= VI_REGCHANGE(8); changed |= VI_REGCHANGE(9); } static inline void __adjustPosition(u16 acv) { u32 fact,field; s16 dispPosX,dispPosY; s16 dispSizeY,maxDispSizeY; dispPosX = (HorVer.dispPosX+displayOffsetH); if(dispPosX<=(720-HorVer.dispSizeX)) { if(dispPosX>=0) HorVer.adjustedDispPosX = dispPosX; else HorVer.adjustedDispPosX = 0; } else HorVer.adjustedDispPosX = (720-HorVer.dispSizeX); fact = 1; if(HorVer.fbMode==VI_XFBMODE_SF) fact = 2; field = HorVer.dispPosY&0x0001; dispPosY = HorVer.dispPosY+displayOffsetV; if(dispPosY>(s32)field) HorVer.adjustedDispPosY = dispPosY; else HorVer.adjustedDispPosY = field; dispSizeY = HorVer.dispPosY+HorVer.dispSizeY+displayOffsetV; maxDispSizeY = ((acv<<1)-field); if(dispSizeY>maxDispSizeY) dispSizeY -= (acv<<1)-field; else dispSizeY = 0; dispPosY = HorVer.dispPosY+displayOffsetV; if(dispPosY<(s32)field) dispPosY -= field; else dispPosY = 0; HorVer.adjustedDispSizeY = HorVer.dispSizeY+dispPosY-dispSizeY; dispPosY = HorVer.dispPosY+displayOffsetV; if(dispPosY<(s32)field) dispPosY -= field; else dispPosY = 0; HorVer.adjustedPanPosY = HorVer.panPosY-(dispPosY/fact); dispSizeY = HorVer.dispPosY+HorVer.dispSizeY+displayOffsetV; if(dispSizeY>maxDispSizeY) dispSizeY -= maxDispSizeY; else dispSizeY = 0; dispPosY = HorVer.dispPosY+displayOffsetV; if(dispPosY<(s32)field) dispPosY -= field; else dispPosY = 0; HorVer.adjustedPanSizeY = HorVer.panSizeY+(dispPosY/fact)-(dispSizeY/fact); } static inline void __importAdjustingValues() { #ifdef HW_DOL syssram *sram; sram = __SYS_LockSram(); displayOffsetH = sram->display_offsetH; __SYS_UnlockSram(0); #else s8 offset; if ( CONF_GetDisplayOffsetH(&offset) == 0 ) { displayOffsetH = offset; } else { displayOffsetH = 0; } #endif displayOffsetV = 0; } static void __VIInit(u32 vimode) { u32 cnt; u32 vi_mode,interlace,progressive; const struct _timing *cur_timing = NULL; vi_mode = ((vimode>>2)&0x07); interlace = (vimode&0x01); progressive = (vimode&0x02); cur_timing = __gettiming(vimode); //reset the interface cnt = 0; _viReg[1] = 0x02; while(cnt<1000) cnt++; _viReg[1] = 0x00; // now begin to setup the interface _viReg[2] = ((cur_timing->hcs<<8)|cur_timing->hce); //set HCS & HCE _viReg[3] = cur_timing->hlw; //set Half Line Width _viReg[4] = (cur_timing->hbs640<<1); //set HBS640 _viReg[5] = ((cur_timing->hbe640<<7)|cur_timing->hsy); //set HBE640 & HSY _viReg[0] = cur_timing->equ; _viReg[6] = (cur_timing->psbOdd+2); //set PSB odd field _viReg[7] = (cur_timing->prbOdd+((cur_timing->acv<<1)-2)); //set PRB odd field _viReg[8] = (cur_timing->psbEven+2); //set PSB even field _viReg[9] = (cur_timing->prbEven+((cur_timing->acv<<1)-2)); //set PRB even field _viReg[10] = ((cur_timing->be3<<5)|cur_timing->bs3); //set BE3 & BS3 _viReg[11] = ((cur_timing->be1<<5)|cur_timing->bs1); //set BE1 & BS1 _viReg[12] = ((cur_timing->be4<<5)|cur_timing->bs4); //set BE4 & BS4 _viReg[13] = ((cur_timing->be2<<5)|cur_timing->bs2); //set BE2 & BS2 _viReg[24] = (0x1000|((cur_timing->nhlines/2)+1)); _viReg[25] = (cur_timing->hlw+1); _viReg[26] = 0x1001; //set DI1 _viReg[27] = 0x0001; //set DI1 _viReg[36] = 0x2828; //set HSR if(vi_mode=VI_DEBUG_PAL) vi_mode = VI_NTSC; if(progressive){ _viReg[1] = ((vi_mode<<8)|0x0005); //set MODE & INT & enable _viReg[54] = 0x0001; } else { _viReg[1] = ((vi_mode<<8)|(interlace<<2)|0x0001); _viReg[54] = 0x0000; } } #if defined(HW_RVL) static u32 __VISendI2CData(u8 addr,void *val,u32 len) { u8 c; s32 i,j; u32 level,ret; if(i2cIdentFirst==0) { __viCheckI2C(); i2cIdentFirst = 1; } _CPU_ISR_Disable(level); __viOpenI2C(1); __viSetSCL(1); __viSetSDA(i2cIdentFlag); udelay(4); ret = __sendSlaveAddress(addr); if(ret==0) { _CPU_ISR_Restore(level); return 0; } __viOpenI2C(1); for(i=0;i<(s32)len;i++) { c = ((u8*)val)[i]; for(j=0;j<8;j++) { if(c&0x80) __viSetSDA(i2cIdentFlag); else __viSetSDA(i2cIdentFlag^1); udelay(2); __viSetSCL(1); udelay(2); __viSetSCL(0); c <<= 1; } __viOpenI2C(0); udelay(2); __viSetSCL(1); udelay(2); if(i2cIdentFlag==1 && __viGetSDA()!=0) { _CPU_ISR_Restore(level); return 0; } __viSetSDA(i2cIdentFlag^1); __viOpenI2C(1); __viSetSCL(0); } __viOpenI2C(1); __viSetSDA(i2cIdentFlag^1); udelay(2); __viSetSDA(i2cIdentFlag); _CPU_ISR_Restore(level); return 1; } static void __VIWriteI2CRegister8(u8 reg, u8 data) { u8 buf[2]; buf[0] = reg; buf[1] = data; __VISendI2CData(0xe0,buf,2); udelay(2); } static void __VIWriteI2CRegister16(u8 reg, u16 data) { u8 buf[3]; buf[0] = reg; buf[1] = data >> 8; buf[2] = data & 0xFF; __VISendI2CData(0xe0,buf,3); udelay(2); } static void __VIWriteI2CRegister32(u8 reg, u32 data) { u8 buf[5]; buf[0] = reg; buf[1] = data >> 24; buf[2] = (data >> 16) & 0xFF; buf[3] = (data >> 8) & 0xFF; buf[4] = data & 0xFF; __VISendI2CData(0xe0,buf,5); udelay(2); } static void __VIWriteI2CRegisterBuf(u8 reg, int size, u8 *data) { u8 buf[0x100]; buf[0] = reg; memcpy(&buf[1], data, size); __VISendI2CData(0xe0,buf,size+1); udelay(2); } static void __VISetYUVSEL(u8 dtvstatus) { if(currTvMode==VI_NTSC) vdacFlagRegion = 0x0000; else if(currTvMode==VI_PAL || currTvMode==VI_EURGB60) vdacFlagRegion = 0x0002; /* FIXME: setting this to 1 causes monochrome output on PAL systems*/ else if(currTvMode==VI_MPAL) vdacFlagRegion = 0x0002; else vdacFlagRegion = 0x0000; __VIWriteI2CRegister8(0x01, _SHIFTL(dtvstatus,5,3)|(vdacFlagRegion&0x1f)); } static void __VISetFilterEURGB60(u8 enable) { __VIWriteI2CRegister8(0x6e, enable); } #if 0 static void __VISetTiming(u8 timing) { u16 val; val = (_SHIFTL(0x00,8,8)|timing); __VISendI2CData(0xe0,&val,sizeof(u16)); udelay(2); } static void __VISet3in1Output(u8 enable) { u16 val; val = (_SHIFTL(0x04,8,8)|enable); __VISendI2CData(0xe0,&val,sizeof(u16)); udelay(2); } #endif static void __VISetupEncoder(void) { u8 macrobuf[0x1a]; u8 gamma[0x21] = { 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xeb, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x60, 0x00, 0x80, 0x00, 0xa0, 0x00, 0xeb, 0x00 }; u8 dtv, tv; tv = CUSTOM_VIDEO_GetCurrentTvMode(); dtv = (_viReg[55]&0x01); oldDtvStatus = dtv; // SetRevolutionModeSimple memset(macrobuf, 0, 0x1a); __VIWriteI2CRegister8(0x6a, 1); __VIWriteI2CRegister8(0x65, 1); __VISetYUVSEL(dtv); __VIWriteI2CRegister8(0x00, 0); __VIWriteI2CRegister16(0x71, 0x8e8e); __VIWriteI2CRegister8(0x02, 7); __VIWriteI2CRegister16(0x05, 0x0000); __VIWriteI2CRegister16(0x08, 0x0000); __VIWriteI2CRegister32(0x7A, 0x00000000); // Macrovision crap __VIWriteI2CRegisterBuf(0x40, sizeof(macrobuf), macrobuf); // Sometimes 1 in RGB mode? (reg 1 == 3) __VIWriteI2CRegister8(0x0A, 0); __VIWriteI2CRegister8(0x03, 1); __VIWriteI2CRegisterBuf(0x10, sizeof(gamma), gamma); __VIWriteI2CRegister8(0x04, 1); __VIWriteI2CRegister32(0x7A, 0x00000000); __VIWriteI2CRegister16(0x08, 0x0000); __VIWriteI2CRegister8(0x03, 1); if(tv==VI_EURGB60) __VISetFilterEURGB60(1); else __VISetFilterEURGB60(0); oldTvStatus = tv; } #endif static inline void __getCurrentDisplayPosition(u32 *px,u32 *py) { u32 hpos = 0; u32 vpos = 0; u32 vpos_old; vpos = (_viReg[22]&0x7ff); do { vpos_old = vpos; hpos = (_viReg[23]&0x7ff); vpos = (_viReg[22]&0x7ff); } while(vpos_old!=vpos); *px = hpos; *py = vpos; } static inline u32 __getCurrentHalfLine() { u32 vpos = 0; u32 hpos = 0; __getCurrentDisplayPosition(&hpos,&vpos); hpos--; vpos--; vpos <<= 1; return vpos+(hpos/currTiming->hlw); } static inline u32 __getCurrentFieldEvenOdd() { u32 hline; hline = __getCurrentHalfLine(); if(hlinenhlines) return 1; return 0; } static inline u32 __VISetRegs() { u32 val; u64 mask; if(shdw_changeMode==1){ if(!__getCurrentFieldEvenOdd()) return 0; } while(shdw_changed) { val = cntlzd(shdw_changed); _viReg[val] = shdw_regs[val]; mask = VI_REGCHANGE(val); shdw_changed &= ~mask; } shdw_changeMode = 0; currTiming = HorVer.timing; currTvMode = HorVer.tv; currentFb = nextFb; return 1; } static void __VIDisplayPositionToXY(s32 xpos,s32 ypos,s32 *px,s32 *py) { u32 hpos,vpos; u32 hline,val; hpos = (xpos-1); vpos = (ypos-1); hline = ((vpos<<1)+(hpos/currTiming->hlw)); *px = (s32)hpos; if(HorVer.nonInter==0x0000) { if(hlinenhlines) { val = currTiming->prbOdd+(currTiming->equ*3); if(hline>=val) { val = (currTiming->nhlines-currTiming->psbOdd); if(hlineequ*3))-currTiming->prbOdd)&~0x01); } else *py = -1; } else *py = -1; } else { hline -= currTiming->psbOdd; val = (currTiming->prbEven+(currTiming->equ*3)); if(hline>=val) { val = (currTiming->nhlines-currTiming->psbEven); if(hlineequ*3))-currTiming->prbEven)&~0x01)+1); } else *py = -1; } else *py = -1; } } else if(HorVer.nonInter==0x0001) { if(hline>=currTiming->nhlines) hline -= currTiming->nhlines; val = (currTiming->prbOdd+(currTiming->equ*3)); if(hline>=val) { val = (currTiming->nhlines-currTiming->psbOdd); if(hlineequ*3))-currTiming->prbOdd)&~0x01); } else *py = -1; } else *py = -1; } else if(HorVer.nonInter==0x0002) { if(hlinenhlines) { val = currTiming->prbOdd+(currTiming->equ*3); if(hline>=val) { val = (currTiming->nhlines-currTiming->psbOdd); if(hlineequ*3))-currTiming->prbOdd); } else *py = -1; } else *py = -1; } else { hline -= currTiming->psbOdd; val = (currTiming->prbEven+(currTiming->equ*3)); if(hline>=val) { val = (currTiming->nhlines-currTiming->psbEven); if(hlineequ*3))-currTiming->prbEven)&~0x01); } else *py = -1; } else *py = -1; } } } static inline void __VIGetCurrentPosition(s32 *px,s32 *py) { s32 xpos,ypos; __getCurrentDisplayPosition((u32*)&xpos,(u32*)&ypos); __VIDisplayPositionToXY(xpos,ypos,px,py); } static void __VIRetraceHandler() { #if defined(HW_RVL) u8 dtv, tv; #endif u32 ret = 0; u32 intr; s32 xpos,ypos; intr = _viReg[24]; if(intr&0x8000) { _viReg[24] = intr&~0x8000; ret |= 0x01; } intr = _viReg[26]; if(intr&0x8000) { _viReg[26] = intr&~0x8000; ret |= 0x02; } intr = _viReg[28]; if(intr&0x8000) { _viReg[28] = intr&~0x8000; ret |= 0x04; } intr = _viReg[30]; if(intr&0x8000) { _viReg[30] = intr&~0x8000; ret |= 0x08; } intr = _viReg[30]; if(ret&0x04 || ret&0x08) { if(positionCB!=NULL) { __VIGetCurrentPosition(&xpos,&ypos); positionCB(xpos,ypos); } } retraceCount++; if(preRetraceCB) preRetraceCB(retraceCount); if(flushFlag) { if(__VISetRegs()) { flushFlag = 0; SI_RefreshSamplingRate(); } } #if defined(HW_RVL) tv = CUSTOM_VIDEO_GetCurrentTvMode(); dtv = (_viReg[55]&0x01); if(dtv!=oldDtvStatus || tv!=oldTvStatus) __VISetYUVSEL(dtv); oldDtvStatus = dtv; if(tv!=oldTvStatus) { if(tv==VI_EURGB60) __VISetFilterEURGB60(1); else __VISetFilterEURGB60(0); } oldTvStatus = tv; #endif if(postRetraceCB) postRetraceCB(retraceCount); LWP_ThreadBroadcast(CUSTOM_VIDEO_queue); } void* CUSTOM_VIDEO_GetNextFramebuffer() { return nextFb; } void* CUSTOM_VIDEO_GetCurrentFramebuffer() { return currentFb; } void CUSTOM_VIDEO_Init() { u32 level,vimode = 0; _CPU_ISR_Disable(level); if(!(_viReg[1]&0x0001)) __VIInit(VI_TVMODE_NTSC_INT); retraceCount = 0; changed = 0; shdw_changed = 0; shdw_changeMode = 0; flushFlag = 0; encoderType = 1; _viReg[38] = ((taps[1]>>6)|(taps[2]<<4)); _viReg[39] = (taps[0]|_SHIFTL(taps[1],10,6)); _viReg[40] = ((taps[4]>>6)|(taps[5]<<4)); _viReg[41] = (taps[3]|_SHIFTL(taps[4],10,6)); _viReg[42] = ((taps[7]>>6)|(taps[8]<<4)); _viReg[43] = (taps[6]|_SHIFTL(taps[7],10,6)); _viReg[44] = (taps[11]|(taps[12]<<8)); _viReg[45] = (taps[9]|(taps[10]<<8)); _viReg[46] = (taps[15]|(taps[16]<<8)); _viReg[47] = (taps[13]|(taps[14]<<8)); _viReg[48] = (taps[19]|(taps[20]<<8)); _viReg[49] = (taps[17]|(taps[18]<<8)); _viReg[50] = (taps[23]|(taps[24]<<8)); _viReg[51] = (taps[21]|(taps[22]<<8)); _viReg[56] = 640; __importAdjustingValues(); HorVer.nonInter = _SHIFTR(_viReg[1],2,1); HorVer.tv = _SHIFTR(_viReg[1],8,2); vimode = HorVer.nonInter; if(HorVer.tv!=VI_DEBUG) vimode += (HorVer.tv<<2); currTiming = __gettiming(vimode); currTvMode = HorVer.tv; regs[1] = _viReg[1]; HorVer.timing = currTiming; HorVer.dispSizeX = 640; HorVer.dispSizeY = currTiming->acv<<1; HorVer.dispPosX = (VI_MAX_WIDTH_NTSC-HorVer.dispSizeX)/2; HorVer.dispPosY = 0; __adjustPosition(currTiming->acv); HorVer.fbSizeX = 640; HorVer.fbSizeY = currTiming->acv<<1; HorVer.panPosX = 0; HorVer.panPosY = 0; HorVer.panSizeX = 640; HorVer.panSizeY = currTiming->acv<<1; HorVer.fbMode = VI_XFBMODE_SF; HorVer.wordPerLine = 40; HorVer.std = 40; HorVer.wpl = 40; HorVer.xof = 0; HorVer.black = 1; HorVer.threeD = 0; HorVer.bfbb = 0; HorVer.tfbb = 0; HorVer.rbfbb = 0; HorVer.rtfbb = 0; _viReg[24] &= ~0x8000; _viReg[26] &= ~0x8000; preRetraceCB = NULL; postRetraceCB = NULL; LWP_InitQueue(&CUSTOM_VIDEO_queue); IRQ_Request(IRQ_PI_VI,(void (*)(u32, void*))__VIRetraceHandler,NULL); __UnmaskIrq(IRQMASK(IRQ_PI_VI)); #if defined(HW_RVL) __VISetupEncoder(); #endif _CPU_ISR_Restore(level); } void CUSTOM_VIDEO_Configure(GXRModeObj *rmode) { u16 dcr; u32 nonint,vimode,level; const struct _timing *curtiming; #ifdef _CUSTOM_VIDEO_DEBUG if(rmode->viHeight&0x0001) printf("CUSTOM_VIDEO_Configure(): Odd number(%d) is specified to viHeight\n",rmode->viHeight); if((rmode->xfbMode==VI_XFBMODE_DF || rmode->viTVMode==VI_TVMODE_NTSC_PROG || rmode->viTVMode==VI_TVMODE_NTSC_PROG_DS) && rmode->xfbHeight!=rmode->viHeight) printf("CUSTOM_VIDEO_Configure(): xfbHeight(%d) is not equal to viHeight(%d) when DF XFB mode or progressive mode is specified\n",rmode->xfbHeight,rmode->viHeight); if(rmode->xfbMode==VI_XFBMODE_SF && !(rmode->viTVMode==VI_TVMODE_NTSC_PROG || rmode->viTVMode==VI_TVMODE_NTSC_PROG_DS) && (rmode->xfbHeight<<1)!=rmode->viHeight) printf("CUSTOM_VIDEO_Configure(): xfbHeight(%d) is not as twice as viHeight(%d) when SF XFB mode is specified\n",rmode->xfbHeight,rmode->viHeight); #endif _CPU_ISR_Disable(level); nonint = (rmode->viTVMode&0x0003); if(nonint!=HorVer.nonInter) { changeMode = 1; HorVer.nonInter = nonint; } HorVer.tv = _SHIFTR(rmode->viTVMode,2,3); HorVer.dispPosX = rmode->viXOrigin; HorVer.dispPosY = rmode->viYOrigin; if(HorVer.nonInter==VI_NON_INTERLACE) HorVer.dispPosY = HorVer.dispPosY<<1; HorVer.dispSizeX = rmode->viWidth; HorVer.fbSizeX = rmode->fbWidth; HorVer.fbSizeY = rmode->xfbHeight; HorVer.fbMode = rmode->xfbMode; HorVer.panSizeX = HorVer.fbSizeX; HorVer.panSizeY = HorVer.fbSizeY; HorVer.panPosX = 0; HorVer.panPosY = 0; if(HorVer.nonInter==VI_PROGRESSIVE || HorVer.nonInter==(VI_NON_INTERLACE|VI_PROGRESSIVE)) HorVer.dispSizeY = HorVer.panSizeY; else if(HorVer.fbMode==VI_XFBMODE_SF) HorVer.dispSizeY = HorVer.panSizeY<<1; else HorVer.dispSizeY = HorVer.panSizeY; if(HorVer.nonInter==(VI_NON_INTERLACE|VI_PROGRESSIVE)) HorVer.threeD = 1; else HorVer.threeD = 0; vimode = VI_TVMODE(HorVer.tv,HorVer.nonInter); curtiming = __gettiming(vimode); HorVer.timing = curtiming; __adjustPosition(curtiming->acv); #ifdef _CUSTOM_VIDEO_DEBUG if(rmode->viXOrigin>((curtiming->hlw+40)-curtiming->hbe640)) printf("CUSTOM_VIDEO_Configure(): viXOrigin(%d) cannot be greater than %d in this TV mode\n",rmode->viXOrigin,((curtiming->hlw+40)-curtiming->hbe640)); if((rmode->viXOrigin+rmode->viWidth)<(680-curtiming->hbs640)) printf("CUSTOM_VIDEO_Configure(): viXOrigin + viWidth(%d) cannot be less than %d in this TV mode\n",(rmode->viXOrigin+rmode->viWidth),(680-curtiming->hbs640)); #endif if(!encoderType) HorVer.tv = VI_DEBUG; __setInterruptRegs(curtiming); dcr = regs[1]&~0x030c; dcr |= _SHIFTL(HorVer.threeD,3,1); if(HorVer.nonInter==VI_PROGRESSIVE || HorVer.nonInter==(VI_NON_INTERLACE|VI_PROGRESSIVE)) dcr |= 0x0004; else dcr |= _SHIFTL(HorVer.nonInter,2,1); if(!(HorVer.tv==VI_DEBUG_PAL || HorVer.tv==VI_EURGB60)) dcr |= _SHIFTL(HorVer.tv,8,2); regs[1] = dcr; changed |= VI_REGCHANGE(1); regs[54] &= ~0x0001; if(rmode->viTVMode==VI_TVMODE_NTSC_PROG || rmode->viTVMode==VI_TVMODE_NTSC_PROG_DS) regs[54] |= 0x0001; changed |= VI_REGCHANGE(54); __setScalingRegs(HorVer.panSizeX,HorVer.dispSizeX,HorVer.threeD); __setHorizontalRegs(curtiming,HorVer.adjustedDispPosX,HorVer.dispSizeX); __setBBIntervalRegs(curtiming); __setPicConfig(HorVer.fbSizeX,HorVer.fbMode,HorVer.panPosX,HorVer.panSizeX,&HorVer.wordPerLine,&HorVer.std,&HorVer.wpl,&HorVer.xof); if(fbSet) __setFbbRegs(&HorVer,&HorVer.tfbb,&HorVer.bfbb,&HorVer.rtfbb,&HorVer.rbfbb); __setVerticalRegs(HorVer.adjustedDispPosY,HorVer.adjustedDispSizeY,curtiming->equ,curtiming->acv,curtiming->prbOdd,curtiming->prbEven,curtiming->psbOdd,curtiming->psbEven,HorVer.black); #ifdef _CUSTOM_VIDEO_DEBUG printDebugCalculations(); #endif _CPU_ISR_Restore(level); } void CUSTOM_VIDEO_WaitVSync(void) { u32 level; u32 retcnt; _CPU_ISR_Disable(level); retcnt = retraceCount; do { LWP_ThreadSleep(CUSTOM_VIDEO_queue); } while(retraceCount==retcnt); _CPU_ISR_Restore(level); } void CUSTOM_VIDEO_SetFramebuffer(void *fb) { u32 level; _CPU_ISR_Disable(level); fbSet = 1; HorVer.bufAddr = fb; __setFbbRegs(&HorVer,&HorVer.tfbb,&HorVer.bfbb,&HorVer.rtfbb,&HorVer.rbfbb); _viReg[14] = regs[14]; _viReg[15] = regs[15]; _viReg[18] = regs[18]; _viReg[19] = regs[19]; if(HorVer.threeD) { _viReg[16] = regs[16]; _viReg[17] = regs[17]; _viReg[20] = regs[20]; _viReg[21] = regs[21]; } _CPU_ISR_Restore(level); } void CUSTOM_VIDEO_SetNextFramebuffer(void *fb) { u32 level; #ifdef _CUSTOM_VIDEO_DEBUG if((u32)fb&0x1f) printf("CUSTOM_VIDEO_SetNextFramebuffer(): Frame buffer address (%p) is not 32byte aligned\n",fb); #endif _CPU_ISR_Disable(level); fbSet = 1; HorVer.bufAddr = fb; __setFbbRegs(&HorVer,&HorVer.tfbb,&HorVer.bfbb,&HorVer.rtfbb,&HorVer.rbfbb); _CPU_ISR_Restore(level); } void CUSTOM_VIDEO_SetNextRightFramebuffer(void *fb) { u32 level; _CPU_ISR_Disable(level); fbSet = 1; HorVer.rbufAddr = fb; __setFbbRegs(&HorVer,&HorVer.tfbb,&HorVer.bfbb,&HorVer.rtfbb,&HorVer.rbfbb); _CPU_ISR_Restore(level); } void CUSTOM_VIDEO_Flush() { u32 level; u32 val; u64 mask; _CPU_ISR_Disable(level); shdw_changeMode |= changeMode; changeMode = 0; shdw_changed |= changed; while(changed) { val = cntlzd(changed); shdw_regs[val] = regs[val]; mask = VI_REGCHANGE(val); changed &= ~mask; } flushFlag = 1; #ifdef _CUSTOM_VIDEO_DEBUG printRegs(); #endif nextFb = HorVer.bufAddr; _CPU_ISR_Restore(level); } void CUSTOM_VIDEO_SetBlack(bool black) { u32 level; const struct _timing *curtiming; _CPU_ISR_Disable(level); HorVer.black = black; curtiming = HorVer.timing; __setVerticalRegs(HorVer.adjustedDispPosY,HorVer.dispSizeY,curtiming->equ,curtiming->acv,curtiming->prbOdd,curtiming->prbEven,curtiming->psbOdd,curtiming->psbEven,HorVer.black); _CPU_ISR_Restore(level); } u32 CUSTOM_VIDEO_GetNextField() { u32 level,nextfield; _CPU_ISR_Disable(level); 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 _CPU_ISR_Restore(level); 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 } u32 CUSTOM_VIDEO_GetCurrentTvMode() { u32 mode; u32 level; u32 tv; _CPU_ISR_Disable(level); mode = currTvMode; if(mode==VI_DEBUG) tv = VI_NTSC; else if(mode==VI_EURGB60) tv = mode; else if(mode==VI_MPAL) tv = VI_MPAL; else if(mode==VI_NTSC) tv = VI_NTSC; else tv = VI_PAL; _CPU_ISR_Restore(level); return tv; } GXRModeObj * CUSTOM_VIDEO_GetPreferredMode(GXRModeObj *mode) { GXRModeObj *rmode; #if defined(HW_RVL) if ( CONF_GetProgressiveScan() > 0 && CUSTOM_VIDEO_HaveComponentCable() ) { rmode = &CUSTOM_TVNtsc480Prog; } else { u32 tvmode = CONF_GetVideo(); switch ( tvmode ) { case CONF_VIDEO_NTSC: rmode = &CUSTOM_TVNtsc480IntDf; break; case CONF_VIDEO_PAL: if ( CONF_GetEuRGB60() > 0 ) { rmode = &CUSTOM_TVEurgb60Hz480IntDf; } else { rmode = &CUSTOM_TVPal528IntDf; } break; case CONF_VIDEO_MPAL: rmode = &CUSTOM_TVMpal480IntDf; break; default: rmode = &CUSTOM_TVNtsc480IntDf; } } #else u32 tvmode = CUSTOM_VIDEO_GetCurrentTvMode(); switch(tvmode) { case VI_NTSC: rmode = &CUSTOM_TVNtsc480IntDf; break; case VI_PAL: rmode = &CUSTOM_TVPal528IntDf; break; case VI_MPAL: rmode = &CUSTOM_TVMpal480IntDf; break; default: rmode = &CUSTOM_TVNtsc480IntDf; break; } #endif if ( NULL != mode ) { memcpy( mode, rmode, sizeof(GXRModeObj)); } else { mode = rmode; } return mode; } u32 CUSTOM_VIDEO_GetCurrentLine() { u32 level,curr_hl = 0; _CPU_ISR_Disable(level); curr_hl = __getCurrentHalfLine(); _CPU_ISR_Restore(level); if(curr_hl>=currTiming->nhlines) curr_hl -=currTiming->nhlines; curr_hl >>= 1; return curr_hl; } VIRetraceCallback CUSTOM_VIDEO_SetPreRetraceCallback(VIRetraceCallback callback) { u32 level = 0; VIRetraceCallback ret = preRetraceCB; _CPU_ISR_Disable(level); preRetraceCB = callback; _CPU_ISR_Restore(level); return ret; } VIRetraceCallback CUSTOM_VIDEO_SetPostRetraceCallback(VIRetraceCallback callback) { u32 level = 0; VIRetraceCallback ret = postRetraceCB; _CPU_ISR_Disable(level); postRetraceCB = callback; _CPU_ISR_Restore(level); return ret; } u32 CUSTOM_VIDEO_GetFrameBufferSize(GXRModeObj *rmode) { u16 w, h; w = VIDEO_PadFramebufferWidth(rmode->fbWidth); h = rmode->xfbHeight; if (rmode->aa) h += 4; return w * h * VI_DISPLAY_PIX_SZ; } void CUSTOM_VIDEO_ClearFrameBuffer(GXRModeObj *rmode,void *fb,u32 color) { __VIClearFramebuffer(fb, CUSTOM_VIDEO_GetFrameBufferSize(rmode), color); } u32 CUSTOM_VIDEO_HaveComponentCable(void) { return (_viReg[55]&0x01); }