171d7fec4Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_fs450.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ 271d7fec4Smrg/* 371d7fec4Smrg * $Workfile: tv_fs450.c $ 471d7fec4Smrg * 571d7fec4Smrg * This file contains routines to control the FS450 tvout encoder. 671d7fec4Smrg * 771d7fec4Smrg * NSC_LIC_ALTERNATIVE_PREAMBLE 871d7fec4Smrg * 971d7fec4Smrg * Revision 1.0 1071d7fec4Smrg * 1171d7fec4Smrg * National Semiconductor Alternative GPL-BSD License 1271d7fec4Smrg * 1371d7fec4Smrg * National Semiconductor Corporation licenses this software 1471d7fec4Smrg * ("Software"): 1571d7fec4Smrg * 1671d7fec4Smrg * Durango 1771d7fec4Smrg * 1871d7fec4Smrg * under one of the two following licenses, depending on how the 1971d7fec4Smrg * Software is received by the Licensee. 2071d7fec4Smrg * 2171d7fec4Smrg * If this Software is received as part of the Linux Framebuffer or 2271d7fec4Smrg * other GPL licensed software, then the GPL license designated 2371d7fec4Smrg * NSC_LIC_GPL applies to this Software; in all other circumstances 2471d7fec4Smrg * then the BSD-style license designated NSC_LIC_BSD shall apply. 2571d7fec4Smrg * 2671d7fec4Smrg * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ 2771d7fec4Smrg 2871d7fec4Smrg/* NSC_LIC_BSD 2971d7fec4Smrg * 3071d7fec4Smrg * National Semiconductor Corporation Open Source License for Durango 3171d7fec4Smrg * 3271d7fec4Smrg * (BSD License with Export Notice) 3371d7fec4Smrg * 3471d7fec4Smrg * Copyright (c) 1999-2001 3571d7fec4Smrg * National Semiconductor Corporation. 3671d7fec4Smrg * All rights reserved. 3771d7fec4Smrg * 3871d7fec4Smrg * Redistribution and use in source and binary forms, with or without 3971d7fec4Smrg * modification, are permitted provided that the following conditions 4071d7fec4Smrg * are met: 4171d7fec4Smrg * 4271d7fec4Smrg * * Redistributions of source code must retain the above copyright 4371d7fec4Smrg * notice, this list of conditions and the following disclaimer. 4471d7fec4Smrg * 4571d7fec4Smrg * * Redistributions in binary form must reproduce the above 4671d7fec4Smrg * copyright notice, this list of conditions and the following 4771d7fec4Smrg * disclaimer in the documentation and/or other materials provided 4871d7fec4Smrg * with the distribution. 4971d7fec4Smrg * 5071d7fec4Smrg * * Neither the name of the National Semiconductor Corporation nor 5171d7fec4Smrg * the names of its contributors may be used to endorse or promote 5271d7fec4Smrg * products derived from this software without specific prior 5371d7fec4Smrg * written permission. 5471d7fec4Smrg * 5571d7fec4Smrg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 5671d7fec4Smrg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 5771d7fec4Smrg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 5871d7fec4Smrg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 5971d7fec4Smrg * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 6071d7fec4Smrg * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 6171d7fec4Smrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 6271d7fec4Smrg * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 6371d7fec4Smrg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 6471d7fec4Smrg * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 6571d7fec4Smrg * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 6671d7fec4Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 6771d7fec4Smrg * OF SUCH DAMAGE. 6871d7fec4Smrg * 6971d7fec4Smrg * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 7071d7fec4Smrg * YOUR JURISDICTION. It is licensee's responsibility to comply with 7171d7fec4Smrg * any export regulations applicable in licensee's jurisdiction. Under 7271d7fec4Smrg * CURRENT (2001) U.S. export regulations this software 7371d7fec4Smrg * is eligible for export from the U.S. and can be downloaded by or 7471d7fec4Smrg * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 7571d7fec4Smrg * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 7671d7fec4Smrg * Syria, Sudan, Afghanistan and any other country to which the U.S. 7771d7fec4Smrg * has embargoed goods and services. 7871d7fec4Smrg * 7971d7fec4Smrg * END_NSC_LIC_BSD */ 8071d7fec4Smrg 8171d7fec4Smrg/* NSC_LIC_GPL 8271d7fec4Smrg * 8371d7fec4Smrg * National Semiconductor Corporation Gnu General Public License for Durango 8471d7fec4Smrg * 8571d7fec4Smrg * (GPL License with Export Notice) 8671d7fec4Smrg * 8771d7fec4Smrg * Copyright (c) 1999-2001 8871d7fec4Smrg * National Semiconductor Corporation. 8971d7fec4Smrg * All rights reserved. 9071d7fec4Smrg * 9171d7fec4Smrg * Redistribution and use in source and binary forms, with or without 9271d7fec4Smrg * modification, are permitted under the terms of the GNU General 9371d7fec4Smrg * Public License as published by the Free Software Foundation; either 9471d7fec4Smrg * version 2 of the License, or (at your option) any later version 9571d7fec4Smrg * 9671d7fec4Smrg * In addition to the terms of the GNU General Public License, neither 9771d7fec4Smrg * the name of the National Semiconductor Corporation nor the names of 9871d7fec4Smrg * its contributors may be used to endorse or promote products derived 9971d7fec4Smrg * from this software without specific prior written permission. 10071d7fec4Smrg * 10171d7fec4Smrg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 10271d7fec4Smrg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 10371d7fec4Smrg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 10471d7fec4Smrg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 10571d7fec4Smrg * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 10671d7fec4Smrg * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 10771d7fec4Smrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 10871d7fec4Smrg * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 10971d7fec4Smrg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 11071d7fec4Smrg * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 11171d7fec4Smrg * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 11271d7fec4Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 11371d7fec4Smrg * OF SUCH DAMAGE. See the GNU General Public License for more details. 11471d7fec4Smrg * 11571d7fec4Smrg * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 11671d7fec4Smrg * YOUR JURISDICTION. It is licensee's responsibility to comply with 11771d7fec4Smrg * any export regulations applicable in licensee's jurisdiction. Under 11871d7fec4Smrg * CURRENT (2001) U.S. export regulations this software 11971d7fec4Smrg * is eligible for export from the U.S. and can be downloaded by or 12071d7fec4Smrg * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 12171d7fec4Smrg * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 12271d7fec4Smrg * Syria, Sudan, Afghanistan and any other country to which the U.S. 12371d7fec4Smrg * has embargoed goods and services. 12471d7fec4Smrg * 12571d7fec4Smrg * You should have received a copy of the GNU General Public License 12671d7fec4Smrg * along with this file; if not, write to the Free Software Foundation, 12771d7fec4Smrg * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 12871d7fec4Smrg * 12971d7fec4Smrg * END_NSC_LIC_GPL */ 13071d7fec4Smrg 13171d7fec4Smrg#define FS450_DIRECTREG 0 13271d7fec4Smrg 13371d7fec4Smrg#include "tv_fs450.h" 13471d7fec4Smrg 13571d7fec4Smrg/*========================================================================== 13671d7fec4Smrg* 13771d7fec4Smrg* Macros 13871d7fec4Smrg* 13971d7fec4Smrg*========================================================================== 14071d7fec4Smrg*/ 14171d7fec4Smrg 14271d7fec4Smrg#undef fsmax 14371d7fec4Smrg#undef fsmin 14471d7fec4Smrg#define fsmax(a, b) ((a) > (b) ? (a) : (b)) 14571d7fec4Smrg#define fsmin(a, b) ((a) < (b) ? (a) : (b)) 14671d7fec4Smrg 14771d7fec4Smrg#undef range_limit 14871d7fec4Smrg#define range_limit(val,min_val,max_val) (fsmax((min_val),fsmin((val),(max_val)))) 14971d7fec4Smrg 15071d7fec4Smrg/*========================================================================== 15171d7fec4Smrg* 15271d7fec4Smrg* Registers 15371d7fec4Smrg* 15471d7fec4Smrg*========================================================================== 15571d7fec4Smrg*/ 15671d7fec4Smrg 15771d7fec4Smrg#define MAX_REGISTERS 32 15871d7fec4Smrg#define MAX_BITS 32 15971d7fec4Smrg 16071d7fec4Smrg#define READ 1 16171d7fec4Smrg#define WRITE 2 16271d7fec4Smrg#define READ_WRITE (READ | WRITE) 16371d7fec4Smrg 16471d7fec4Smrgtypedef struct 16571d7fec4Smrg{ 16671d7fec4Smrg char *name; 16771d7fec4Smrg unsigned long offset; 16871d7fec4Smrg unsigned char bit_length; 16971d7fec4Smrg unsigned char valid_bits; 17071d7fec4Smrg unsigned char read_write; 17171d7fec4Smrg char *bitfield_names[MAX_BITS]; 17271d7fec4Smrg} 17371d7fec4SmrgS_REGISTER_DESCRIP; 17471d7fec4Smrg 17571d7fec4Smrgtypedef struct 17671d7fec4Smrg{ 17771d7fec4Smrg int source; 17871d7fec4Smrg char *name; 17971d7fec4Smrg S_REGISTER_DESCRIP registers[MAX_REGISTERS]; 18071d7fec4Smrg} 18171d7fec4SmrgS_SET_DESCRIP; 18271d7fec4Smrg 18371d7fec4Smrgconst S_SET_DESCRIP *houston_regs(void); 18471d7fec4Smrgconst S_SET_DESCRIP *encoder_regs(void); 18571d7fec4Smrgconst S_SET_DESCRIP *macrovision_regs(void); 18671d7fec4Smrgconst S_SET_DESCRIP *gcc_regs(void); 18771d7fec4Smrg 18871d7fec4Smrg/*========================================================================== 18971d7fec4Smrg* 19071d7fec4Smrg* Houston Register Addresses & Bit Definitions 19171d7fec4Smrg* 19271d7fec4Smrg*========================================================================== 19371d7fec4Smrg*/ 19471d7fec4Smrg 19571d7fec4Smrg#define HOUSTON_IHO 0x00 /*Input Horizontal Offset */ 19671d7fec4Smrg#define HOUSTON_IVO 0x02 /*Input Vertical Offset */ 19771d7fec4Smrg#define HOUSTON_IHA 0x04 /*Input Horizontal Active Width */ 19871d7fec4Smrg#define HOUSTON_VSC 0x06 /*Vertical Scaling Coeficient */ 19971d7fec4Smrg#define HOUSTON_HSC 0x08 /*Horizontal Scaling Coeficient */ 20071d7fec4Smrg#define HOUSTON_BYP 0x0A /*Bypass Register */ 20171d7fec4Smrg#define HOUSTON_CR 0x0C /*Control Register */ 20271d7fec4Smrg#define HOUSTON_SP 0x0E /*Status */ 20371d7fec4Smrg#define HOUSTON_NCONL 0x10 /*NCO numerator low word */ 20471d7fec4Smrg#define HOUSTON_NCONH 0x12 /*NCO numerator high word */ 20571d7fec4Smrg#define HOUSTON_NCODL 0x14 /*NCO denominator low word */ 20671d7fec4Smrg#define HOUSTON_NCODH 0x16 /*NCO denominator high word */ 20771d7fec4Smrg#define HOUSTON_APO 0x18 /**/ 20871d7fec4Smrg#define HOUSTON_ALO 0x1A /**/ 20971d7fec4Smrg#define HOUSTON_AFO 0x1C /**/ 21071d7fec4Smrg#define HOUSTON_HSOUTWID 0x1E /**/ 21171d7fec4Smrg#define HOUSTON_HSOUTST 0x20 /**/ 21271d7fec4Smrg#define HOUSTON_HSOUTEND 0x22 /**/ 21371d7fec4Smrg#define HOUSTON_SHP 0x24 /*Sharpness */ 21471d7fec4Smrg#define HOUSTON_FLK 0x26 /*Flicker Filter */ 21571d7fec4Smrg#define HOUSTON_BCONTL 0x28 /**/ 21671d7fec4Smrg#define HOUSTON_BCONTH 0x2A /**/ 21771d7fec4Smrg#define HOUSTON_BDONE 0x2C /**/ 21871d7fec4Smrg#define HOUSTON_BDIAGL 0x2E /**/ 21971d7fec4Smrg#define HOUSTON_BDIAGH 0x30 /**/ 22071d7fec4Smrg#define HOUSTON_REV 0x32 /**/ 22171d7fec4Smrg#define HOUSTON_MISC 0x34 /**/ 22271d7fec4Smrg#define HOUSTON_FFO 0x36 /**/ 22371d7fec4Smrg#define HOUSTON_FFO_LAT 0x38 /**/ 22471d7fec4Smrg#define HOUSTON_VSOUTWID 0x3A 22571d7fec4Smrg#define HOUSTON_VSOUTST 0x3C 22671d7fec4Smrg#define HOUSTON_VSOUTEND 0x3E 22771d7fec4Smrg/*// BYP Register Bits*/ 22871d7fec4Smrg#define BYP_RGB_BYPASS 0x0001 22971d7fec4Smrg#define BYP_HDS_BYPASS 0x0002 23071d7fec4Smrg#define BYP_HDS_TBYPASS 0x0004 23171d7fec4Smrg#define BYP_CAC_BYPASS 0x0008 23271d7fec4Smrg#define BYP_R2V_SBYPASS 0x0010 23371d7fec4Smrg#define BYP_R2V_BYPASS 0x0020 23471d7fec4Smrg#define BYP_VDS_BYPASS 0x0040 23571d7fec4Smrg#define BYP_FFT_BYPASS 0x0080 23671d7fec4Smrg#define BYP_FIF_BYPASS 0x0100 23771d7fec4Smrg#define BYP_FIF_TBYPASS 0x0200 23871d7fec4Smrg#define BYP_HUS_BYPASS 0x0400 23971d7fec4Smrg#define BYP_HUS_TBYPASS 0x0800 24071d7fec4Smrg#define BYP_CCR_BYPASS 0x1000 24171d7fec4Smrg#define BYP_PLL_BYPASS 0x2000 24271d7fec4Smrg#define BYP_NCO_BYPASS 0x4000 24371d7fec4Smrg#define BYP_ENC_BYPASS 0x8000 24471d7fec4Smrg/*// CR Register Bits*/ 24571d7fec4Smrg#define CR_RESET 0x0001 24671d7fec4Smrg#define CR_CLKOFF 0x0002 24771d7fec4Smrg#define CR_NCO_EN 0x0004 24871d7fec4Smrg#define CR_COMPOFF 0x0008 24971d7fec4Smrg#define CR_YCOFF 0x0010 25071d7fec4Smrg#define CR_LP_EN 0x0020 25171d7fec4Smrg#define CR_CACQ_CLR 0x0040 25271d7fec4Smrg#define CR_FFO_CLR 0x0080 25371d7fec4Smrg#define CR_656_PAL_NTSC 0x0100 25471d7fec4Smrg#define CR_656_STD_VMI 0x0200 25571d7fec4Smrg#define CR_OFMT 0x0400 25671d7fec4Smrg#define CR_UIM_CLK 0x0800 25771d7fec4Smrg#define CR_UIM_DEC 0x1000 25871d7fec4Smrg#define CR_BIPGEN_EN1 0x2000 25971d7fec4Smrg#define CR_UIM_MOD0 0x4000 26071d7fec4Smrg#define CR_UIM_MOD1 0x8000 26171d7fec4Smrg/*// Status Register Bits*/ 26271d7fec4Smrg#define SP_CACQ_ST 0x0001 26371d7fec4Smrg#define SP_FFO_ST 0x0002 26471d7fec4Smrg#define SP_REVID_MASK 0x7FFC 26571d7fec4Smrg#define SP_MV_EN 0x8000 26671d7fec4Smrg/*// BDONE Register Bits*/ 26771d7fec4Smrg#define BDONE_BIST_DONE_A 0x0001 26871d7fec4Smrg#define BDONE_BIST_DONE_B 0x0002 26971d7fec4Smrg#define BDONE_BIST_DONE_C 0x0004 27071d7fec4Smrg#define BDONE_BIST_DONE_D 0x0008 27171d7fec4Smrg#define BDONE_BIST_DONE_E 0x0010 27271d7fec4Smrg#define BDONE_BIST_DONE_F 0x0020 27371d7fec4Smrg#define BDONE_BIST_DONE_G 0x0040 27471d7fec4Smrg/*// BDIAGL Register Bits*/ 27571d7fec4Smrg#define BDIAGL_BIST_DIAG_A 0x000F 27671d7fec4Smrg#define BDIAGL_BIST_DIAG_B 0x00F0 27771d7fec4Smrg#define BDIAGL_BIST_DIAG_C 0x0F00 27871d7fec4Smrg#define BDIAGL_BIST_DIAG_D 0xF000 27971d7fec4Smrg/*// BDIAGH Register Bits*/ 28071d7fec4Smrg#define BDIAGH_BIST_DIAG_E 0x000F 28171d7fec4Smrg#define BDIAGH_BIST_DIAG_F 0x000F 28271d7fec4Smrg#define BDIAGH_BIST_DIAG_G 0x000F 28371d7fec4Smrg/*// MISC Register Bits*/ 28471d7fec4Smrg#define MISC_TV_SHORT_FLD 0x0001 28571d7fec4Smrg#define MISC_ENC_TEST 0x0002 28671d7fec4Smrg#define MISC_DAC_TEST 0x0004 28771d7fec4Smrg#define MISC_MV_SOFT_EN 0x0008 28871d7fec4Smrg#define MISC_NCO_LOAD0 0x0010 28971d7fec4Smrg#define MISC_NCO_LOAD1 0x0020 29071d7fec4Smrg#define MISC_VGACKDIV 0x0200 29171d7fec4Smrg#define MISC_BRIDGE_SYNC 0x0400 29271d7fec4Smrg#define MISC_GTLIO_PD 0x8000 29371d7fec4Smrg/*========================================================================== 29471d7fec4Smrg* 29571d7fec4Smrg* Encoder Registers & Bit Definitions 29671d7fec4Smrg* 29771d7fec4Smrg*========================================================================== 29871d7fec4Smrg*/ 29971d7fec4Smrg#define ENC_CHROMA_FREQ 0x40 30071d7fec4Smrg#define ENC_CHROMA_PHASE 0x44 30171d7fec4Smrg#define ENC_REG05 0x45 30271d7fec4Smrg#define ENC_REG06 0x46 30371d7fec4Smrg#define ENC_REG07 0x47 30471d7fec4Smrg#define ENC_HSYNC_WIDTH 0x48 30571d7fec4Smrg#define ENC_BURST_WIDTH 0x49 30671d7fec4Smrg#define ENC_BACK_PORCH 0x4A 30771d7fec4Smrg#define ENC_CB_BURST_LEVEL 0x4B 30871d7fec4Smrg#define ENC_CR_BURST_LEVEL 0x4C 30971d7fec4Smrg#define ENC_SLAVE_MODE 0x4D 31071d7fec4Smrg#define ENC_BLACK_LEVEL 0x4e 31171d7fec4Smrg#define ENC_BLANK_LEVEL 0x50 31271d7fec4Smrg#define ENC_NUM_LINES 0x57 31371d7fec4Smrg#define ENC_WHITE_LEVEL 0x5e 31471d7fec4Smrg#define ENC_CB_GAIN 0x60 31571d7fec4Smrg#define ENC_CR_GAIN 0x62 31671d7fec4Smrg#define ENC_TINT 0x65 31771d7fec4Smrg#define ENC_BREEZE_WAY 0x69 31871d7fec4Smrg#define ENC_FRONT_PORCH 0x6C 31971d7fec4Smrg#define ENC_ACTIVELINE 0x71 32071d7fec4Smrg#define ENC_FIRST_LINE 0x73 32171d7fec4Smrg#define ENC_REG34 0x74 32271d7fec4Smrg#define ENC_SYNC_LEVEL 0x75 32371d7fec4Smrg#define ENC_VBI_BLANK_LEVEL 0x7C 32471d7fec4Smrg#define ENC_RESET 0x7e 32571d7fec4Smrg#define ENC_NOTCH_FILTER 0x8d 32671d7fec4Smrg/*========================================================================== 32771d7fec4Smrg* 32871d7fec4Smrg* Macrovision Registers & Bit Definitions 32971d7fec4Smrg* 33071d7fec4Smrg*========================================================================== 33171d7fec4Smrg*/ 33271d7fec4Smrg#define MV_N0 0x59 33371d7fec4Smrg#define MV_N1 0x52 33471d7fec4Smrg#define MV_N2 0x7b 33571d7fec4Smrg#define MV_N3 0x53 33671d7fec4Smrg#define MV_N4 0x79 33771d7fec4Smrg#define MV_N5 0x5d 33871d7fec4Smrg#define MV_N6 0x7a 33971d7fec4Smrg#define MV_N7 0x64 34071d7fec4Smrg#define MV_N8 0x54 34171d7fec4Smrg#define MV_N9 0x55 34271d7fec4Smrg#define MV_N10 0x56 34371d7fec4Smrg#define MV_N11 0x6d 34471d7fec4Smrg#define MV_N12 0x6f 34571d7fec4Smrg#define MV_N13 0x5a 34671d7fec4Smrg#define MV_N14 0x5b 34771d7fec4Smrg#define MV_N15 0x5c 34871d7fec4Smrg#define MV_N16 0x63 34971d7fec4Smrg#define MV_N17 0x66 35071d7fec4Smrg#define MV_N18 0x68 35171d7fec4Smrg#define MV_N19 0x67 35271d7fec4Smrg#define MV_N20 0x61 35371d7fec4Smrg#define MV_N21 0x6a 35471d7fec4Smrg#define MV_N22 0x76 35571d7fec4Smrg#define MV_AGC_PULSE_LEVEL 0x77 35671d7fec4Smrg#define MV_BP_PULSE_LEVEL 0x78 35771d7fec4Smrg/*========================================================================== 35871d7fec4Smrg* 35971d7fec4Smrg* The TRACE macro can be used to display debug information. It can display 36071d7fec4Smrg* one or more parameters in a formatted string like printf. No code will be 36171d7fec4Smrg* generated for a release build. Use double parentheses for compatibility 36271d7fec4Smrg* with C #define statements. Newline characters are not added 36371d7fec4Smrg* automatically. Usage example: 36471d7fec4Smrg* 36571d7fec4Smrg* TRACE(("Number is %d, Name is %s.\n",iNumber,lpszName)) 36671d7fec4Smrg* 36771d7fec4Smrg*========================================================================== 36871d7fec4Smrg*/ 36971d7fec4Smrg/*//#ifdef _DEBUG*/ 37071d7fec4Smrg/*//void trace(const char *p_fmt,...);*/ 37171d7fec4Smrg/*//#define TRACE(parameters) {trace parameters;}*/ 37271d7fec4Smrg/*//#else*/ 37371d7fec4Smrg#define TRACE(parameters) {} 37471d7fec4Smrg/*//#endif*/ 37571d7fec4Smrg/****/ 37671d7fec4Smrg/*// GCC timing structure.*/ 37771d7fec4Smrg/****/ 37871d7fec4Smrg typedef struct _S_TIMING_SPECS 37971d7fec4Smrg{ 38071d7fec4Smrg int vga_width; 38171d7fec4Smrg int vga_lines; 38271d7fec4Smrg int tv_width; 38371d7fec4Smrg int tv_lines; 38471d7fec4Smrg int h_total; 38571d7fec4Smrg int h_sync; 38671d7fec4Smrg int v_total; 38771d7fec4Smrg int v_sync; 38871d7fec4Smrg} 38971d7fec4SmrgS_TIMING_SPECS; 39071d7fec4Smrg 39171d7fec4Smrg/****/ 39271d7fec4Smrg/*// Revision of Houston chip*/ 39371d7fec4Smrg/****/ 39471d7fec4Smrg#define HOUSTON_REV_A 0 39571d7fec4Smrg#define HOUSTON_REV_B 1 39671d7fec4Smrgstatic int houston_Rev(void); 39771d7fec4Smrg 39871d7fec4Smrg/*========================================================================== 39971d7fec4Smrg* 40071d7fec4Smrg* Functions 40171d7fec4Smrg* 40271d7fec4Smrg*========================================================================== 40371d7fec4Smrg*/ 40471d7fec4Smrg 40571d7fec4Smrgstatic int houston_init(void); 40671d7fec4Smrg 40771d7fec4Smrgstatic unsigned char PLAL_FS450_i2c_address(void); 40871d7fec4Smrgstatic int PLAL_FS450_UIM_mode(void); 40971d7fec4Smrgstatic int PLAL_ReadRegister(S_REG_INFO * p_reg); 41071d7fec4Smrgstatic int PLAL_WriteRegister(const S_REG_INFO * p_reg); 41171d7fec4Smrgstatic int PLAL_IsTVOn(void); 41271d7fec4Smrgstatic int PLAL_EnableVga(void); 41371d7fec4Smrgstatic int PLAL_PrepForTVout(void); 41471d7fec4Smrgstatic int PLAL_SetTVTimingRegisters(const S_TIMING_SPECS * p_specs); 41571d7fec4Smrgstatic int PLAL_FinalEnableTVout(unsigned long vga_mode); 41671d7fec4Smrg 41771d7fec4Smrg/****/ 41871d7fec4Smrg/*Direct Memory Access Functions*/ 41971d7fec4Smrg/****/ 42071d7fec4Smrg/*NOTE: Cx5530 is assumed hardcoded at 0x10000 offset*/ 42171d7fec4Smrg/*from MediaGX base. F4Bar is bogus as described in the*/ 42271d7fec4Smrg/*Cx5530 datasheet (actually points to GX frame buffer).*/ 42371d7fec4Smrg/****/ 42471d7fec4Smrgstatic int 42571d7fec4SmrgDMAL_ReadUInt32(unsigned long phys_addr, unsigned long *p_data) 42671d7fec4Smrg{ 42771d7fec4Smrg *p_data = READ_REG32(phys_addr); 42871d7fec4Smrg return 0; 42971d7fec4Smrg} 43071d7fec4Smrg 43171d7fec4Smrgstatic int 43271d7fec4SmrgDMAL_WriteUInt32(unsigned long phys_addr, unsigned long data) 43371d7fec4Smrg{ 43471d7fec4Smrg WRITE_REG32(phys_addr, data); 43571d7fec4Smrg return 0; 43671d7fec4Smrg} 43771d7fec4Smrg 43871d7fec4Smrg/****/ 43971d7fec4Smrg/*Houston register access functions.*/ 44071d7fec4Smrg/****/ 44171d7fec4Smrgstatic int 44271d7fec4Smrghouston_ReadReg(unsigned int reg, unsigned long *p_value, unsigned int bytes) 44371d7fec4Smrg{ 44471d7fec4Smrg return gfx_i2c_read(1, PLAL_FS450_i2c_address(), (unsigned char)reg, 44571d7fec4Smrg (unsigned char)bytes, (unsigned char *)p_value); 44671d7fec4Smrg} 44771d7fec4Smrg 44871d7fec4Smrgstatic int 44971d7fec4Smrghouston_WriteReg(unsigned int reg, unsigned long value, unsigned int bytes) 45071d7fec4Smrg{ 45171d7fec4Smrg return gfx_i2c_write(1, PLAL_FS450_i2c_address(), (unsigned char)reg, 45271d7fec4Smrg (unsigned char)bytes, (unsigned char *)&value); 45371d7fec4Smrg} 45471d7fec4Smrg 45571d7fec4Smrg/****/ 45671d7fec4Smrg/*TV configuration functions.*/ 45771d7fec4Smrg/****/ 45871d7fec4Smrgstatic int config_init(void); 45971d7fec4Smrgstatic const S_TIMING_SPECS *p_specs(void); 46071d7fec4Smrgstatic void config_power(int on); 46171d7fec4Smrgstatic void config_vga_mode(unsigned long vga_mode); 46271d7fec4Smrgstatic void config_tv_std(unsigned long tv_std, unsigned int trigger_bits); 46371d7fec4Smrgstatic void conget_tv_std(unsigned long *p_tv_std); 46471d7fec4Smrgstatic unsigned long supported_standards(void); 46571d7fec4Smrgstatic void config_tvout_mode(unsigned long tvout_mode); 46671d7fec4Smrgstatic void conget_tvout_mode(unsigned long *p_tvout_mode); 46771d7fec4Smrgstatic void config_overscan_xy(unsigned long tv_std, unsigned long vga_mode, 46871d7fec4Smrg int overscan_x, int overscan_y, int pos_x, 46971d7fec4Smrg int pos_y); 47071d7fec4Smrgstatic void config_nco(unsigned long tv_std, unsigned long vga_mode); 47171d7fec4Smrgstatic void config_sharpness(int sharpness); 47271d7fec4Smrgstatic void conget_sharpness(int *p_sharpness); 47371d7fec4Smrgstatic void config_flicker(int flicker); 47471d7fec4Smrgstatic void conget_flicker(int *p_flicker); 47571d7fec4Smrgstatic void config_color(int color); 47671d7fec4Smrgstatic void conget_color(int *p_color); 47771d7fec4Smrgstatic void config_brightness_contrast(unsigned long tv_std, 47871d7fec4Smrg unsigned int trigger_bits, 47971d7fec4Smrg int brightness, int contrast); 48071d7fec4Smrgstatic void conget_brightness_contrast(unsigned long tv_std, 48171d7fec4Smrg unsigned int trigger_bits, 48271d7fec4Smrg int *p_brightness, int *p_contrast); 48371d7fec4Smrgstatic void config_yc_filter(unsigned long tv_std, int luma_filter, 48471d7fec4Smrg int chroma_filter); 48571d7fec4Smrgstatic void conget_yc_filter(int *p_luma_filter, int *p_chroma_filter); 48671d7fec4Smrgstatic void config_macrovision(unsigned long tv_std, 48771d7fec4Smrg unsigned int cp_trigger_bits); 48871d7fec4Smrgstatic void conget_macrovision(unsigned long tv_std, 48971d7fec4Smrg unsigned int *p_cp_trigger_bits); 49071d7fec4Smrg 49171d7fec4Smrg/****/ 49271d7fec4Smrg/*Device settings.*/ 49371d7fec4Smrg/****/ 49471d7fec4Smrgtypedef struct _S_DEVICE_SETTINGS 49571d7fec4Smrg{ 49671d7fec4Smrg int tv_on; 49771d7fec4Smrg unsigned long vga_mode; 49871d7fec4Smrg unsigned long tv_std; 49971d7fec4Smrg unsigned long tvout_mode; 50071d7fec4Smrg int overscan_x; 50171d7fec4Smrg int overscan_y; 50271d7fec4Smrg int position_x; 50371d7fec4Smrg int position_y; 50471d7fec4Smrg int sharpness; 50571d7fec4Smrg int flicker; 50671d7fec4Smrg int color; 50771d7fec4Smrg int brightness; 50871d7fec4Smrg int contrast; 50971d7fec4Smrg unsigned char yc_filter; 51071d7fec4Smrg unsigned int aps_trigger_bits; 51171d7fec4Smrg int last_overscan_y; 51271d7fec4Smrg} 51371d7fec4SmrgS_DEVICE_SETTINGS; 51471d7fec4Smrg 51571d7fec4Smrgstatic S_DEVICE_SETTINGS d; 51671d7fec4Smrg 51771d7fec4Smrg/*//==========================================================================*/ 51871d7fec4Smrg/****/ 51971d7fec4Smrg/*TV Setup Parameters*/ 52071d7fec4Smrg/****/ 52171d7fec4Smrg/*//==========================================================================*/ 52271d7fec4Smrg 52371d7fec4Smrgstatic const struct 52471d7fec4Smrg{ 52571d7fec4Smrg unsigned long chroma_freq[5]; 52671d7fec4Smrg unsigned short chroma_phase[5]; 52771d7fec4Smrg unsigned short cphase_rst[5]; 52871d7fec4Smrg unsigned short color[5]; 52971d7fec4Smrg unsigned short cr_burst_level[5]; 53071d7fec4Smrg unsigned short cb_burst_level[5]; 53171d7fec4Smrg unsigned short sys625_50[5]; 53271d7fec4Smrg unsigned short vsync5[5]; 53371d7fec4Smrg unsigned short pal_mode[5]; 53471d7fec4Smrg unsigned short hsync_width[5]; 53571d7fec4Smrg unsigned short burst_width[5]; 53671d7fec4Smrg unsigned short back_porch[5]; 53771d7fec4Smrg unsigned short front_porch[5]; 53871d7fec4Smrg unsigned short breeze_way[5]; 53971d7fec4Smrg unsigned short activeline[5]; 54071d7fec4Smrg unsigned short blank_level[5]; 54171d7fec4Smrg unsigned short vbi_blank_level[5]; 54271d7fec4Smrg unsigned short black_level[5]; 54371d7fec4Smrg unsigned short white_level[5]; 54471d7fec4Smrg unsigned short hamp_offset[5]; 54571d7fec4Smrg unsigned short sync_level[5]; 54671d7fec4Smrg unsigned short tv_lines[5]; 54771d7fec4Smrg unsigned short tv_width[5]; 54871d7fec4Smrg unsigned short tv_active_lines[5]; 54971d7fec4Smrg unsigned short tv_active_width[5]; 55071d7fec4Smrg unsigned char notch_filter[5]; 55171d7fec4Smrg unsigned short houston_cr[5]; 55271d7fec4Smrg unsigned short houston_ncodl[5]; 55371d7fec4Smrg unsigned short houston_ncodh[5]; 55471d7fec4Smrg} 55571d7fec4Smrgtvsetup = 55671d7fec4Smrg{ 55771d7fec4Smrg /* ntsc, pal, ntsc-eij, pal-m, pal-n */ 55871d7fec4Smrg { 55971d7fec4Smrg 0x1f7cf021, 0xcb8a092a, 0x1f7cf021, 0xe3efe621, 0xcb8a092a} 56071d7fec4Smrg , /*chroma_freq */ 56171d7fec4Smrg { 56271d7fec4Smrg 0, 0, 0, 0, 0} 56371d7fec4Smrg , /*chroma_phase */ 56471d7fec4Smrg { 56571d7fec4Smrg 2, 0, 2, 0, 0} 56671d7fec4Smrg , /*cphase_rst */ 56771d7fec4Smrg { 56871d7fec4Smrg 54, 43, 54, 43, 43} 56971d7fec4Smrg , /*color */ 57071d7fec4Smrg { 57171d7fec4Smrg 0, 31, 0, 29, 29} 57271d7fec4Smrg , /*cr_burst_level */ 57371d7fec4Smrg { 57471d7fec4Smrg 59, 44, 59, 41, 41} 57571d7fec4Smrg , /*cb_burst_level */ 57671d7fec4Smrg { 57771d7fec4Smrg 0, 1, 0, 0, 1} 57871d7fec4Smrg , /*sys625_50 */ 57971d7fec4Smrg { 58071d7fec4Smrg 0, 1, 0, 0, 0} 58171d7fec4Smrg , /*vsync5 */ 58271d7fec4Smrg { 58371d7fec4Smrg 0, 1, 0, 1, 1} 58471d7fec4Smrg , /*pal_mode */ 58571d7fec4Smrg { 58671d7fec4Smrg 0x7a, 0x7a, 0x7a, 0x7a, 0x7a} 58771d7fec4Smrg , /*hsync_width */ 58871d7fec4Smrg { 58971d7fec4Smrg 0x40, 0x3c, 0x40, 0x40, 0x3c} 59071d7fec4Smrg , /*burst_width */ 59171d7fec4Smrg { 59271d7fec4Smrg 0x80, 0x9a, 0x80, 0x80, 0x9a} 59371d7fec4Smrg , /*back_porch */ 59471d7fec4Smrg { 59571d7fec4Smrg 0x24, 0x1e, 0x24, 0x24, 0x1e} 59671d7fec4Smrg , /*front_porch */ 59771d7fec4Smrg { 59871d7fec4Smrg 0x19, 0x1a, 0x19, 0x12, 0x1a} 59971d7fec4Smrg , /*breeze_way */ 60071d7fec4Smrg { 60171d7fec4Smrg 0xb4, 0xb4, 0xb4, 0xb4, 0xb4} 60271d7fec4Smrg , /*active_line */ 60371d7fec4Smrg { 60471d7fec4Smrg 240, 251, 240, 240, 240} 60571d7fec4Smrg , /*blank_level */ 60671d7fec4Smrg { 60771d7fec4Smrg 240, 251, 240, 240, 240} 60871d7fec4Smrg , /*vbi_blank_level */ 60971d7fec4Smrg { 61071d7fec4Smrg 284, 252, 240, 252, 252} 61171d7fec4Smrg , /*black_level */ 61271d7fec4Smrg { 61371d7fec4Smrg 823, 821, 823, 821, 821} 61471d7fec4Smrg , /*white_level */ 61571d7fec4Smrg { 61671d7fec4Smrg 60, 48, 60, 48, 48} 61771d7fec4Smrg , /*hamp_offset */ 61871d7fec4Smrg { 61971d7fec4Smrg 0x08, 0x08, 0x08, 0x08, 0x08} 62071d7fec4Smrg , /*sync_level */ 62171d7fec4Smrg { 62271d7fec4Smrg 525, 625, 525, 525, 625} 62371d7fec4Smrg , /*tv_lines */ 62471d7fec4Smrg { 62571d7fec4Smrg 858, 864, 858, 858, 864} 62671d7fec4Smrg , /*tv_width */ 62771d7fec4Smrg { 62871d7fec4Smrg 487, 576, 487, 487, 576} 62971d7fec4Smrg , /*tv_active_lines */ 63071d7fec4Smrg { 63171d7fec4Smrg 800, 800, 800, 800, 800} 63271d7fec4Smrg , /*tv_active_width */ 63371d7fec4Smrg { 63471d7fec4Smrg 0x1a, 0x1d, 0x1a, 0x1d, 0x1d} 63571d7fec4Smrg , /*notch filter enabled */ 63671d7fec4Smrg { 63771d7fec4Smrg 0x0000, 0x0100, 0x0000, 0x0000, 0x0100} 63871d7fec4Smrg , /*houston cr pal */ 63971d7fec4Smrg { 64071d7fec4Smrg 0x7e48, 0xf580, 0x7e48, 0x7e48, 0xf580} 64171d7fec4Smrg , /*houston ncodl */ 64271d7fec4Smrg { 64371d7fec4Smrg 0x001b, 0x0020, 0x001b, 0x001b, 0x0020} /*houston ncodh */ 64471d7fec4Smrg}; 64571d7fec4Smrg 64671d7fec4Smrg/****/ 64771d7fec4Smrg/*MediaGX default underscan and centered position setups.*/ 64871d7fec4Smrg/****/ 64971d7fec4Smrg#define SCANTABLE_ENTRIES 5 65071d7fec4Smrgstruct _scantable 65171d7fec4Smrg{ 65271d7fec4Smrg unsigned long mode; 65371d7fec4Smrg unsigned short v_total[5]; 65471d7fec4Smrg unsigned short v_sync[5]; 65571d7fec4Smrg unsigned short iha[5]; 65671d7fec4Smrg signed short iho[5]; 65771d7fec4Smrg signed short hsc[5]; 65871d7fec4Smrg}; 65971d7fec4Smrg 66071d7fec4Smrgstatic struct _scantable scantable[SCANTABLE_ENTRIES] = { 66171d7fec4Smrg { 66271d7fec4Smrg GFX_VGA_MODE_640X480, 66371d7fec4Smrg {617, 624, 617, 624, 624}, /*v_total */ 66471d7fec4Smrg {69, 88, 69, 88, 88}, /*v_sync */ 66571d7fec4Smrg {720, 720, 720, 720, 720}, /*iha */ 66671d7fec4Smrg {0, 0, 0, 0, 0}, /*iho */ 66771d7fec4Smrg {-12, 0, -6, 0, 0} /*hsc */ 66871d7fec4Smrg }, 66971d7fec4Smrg { 67071d7fec4Smrg GFX_VGA_MODE_800X600, 67171d7fec4Smrg {740, 740, 740, 740, 740}, /*v_total */ 67271d7fec4Smrg {90, 88, 90, 88, 88}, /*v_sync */ 67371d7fec4Smrg {720, 720, 508, 720, 720}, /*iha */ 67471d7fec4Smrg {-8, 11, -8, -8, 11}, /*iho */ 67571d7fec4Smrg {-27, -27, -27, -27, -27} /*hsc */ 67671d7fec4Smrg }, 67771d7fec4Smrg { 67871d7fec4Smrg GFX_VGA_MODE_720X487, 67971d7fec4Smrg {525, 720, 525, 720, 720}, /*v_total */ 68071d7fec4Smrg {23, 230, 23, 230, 230}, /*v_sync */ 68171d7fec4Smrg {720, 720, 720, 720, 720}, /*iha */ 68271d7fec4Smrg {0xa2, 0xa2, 0xa2, 0xa2, 0xa2}, /*iho */ 68371d7fec4Smrg {0, 0, 0, 0, 0} /*hsc */ 68471d7fec4Smrg }, 68571d7fec4Smrg { 68671d7fec4Smrg GFX_VGA_MODE_720X576, 68771d7fec4Smrg {720, 625, 720, 625, 625}, /*v_total */ 68871d7fec4Smrg {129, 25, 129, 25, 25}, /*v_sync */ 68971d7fec4Smrg {720, 720, 720, 720, 720}, /*iha */ 69071d7fec4Smrg {0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, /*iho */ 69171d7fec4Smrg {0, 0, 0, 0, 0} /*hsc */ 69271d7fec4Smrg }, 69371d7fec4Smrg { 69471d7fec4Smrg GFX_VGA_MODE_1024X768, 69571d7fec4Smrg {933, 942, 933, 806, 806}, /*v_total */ 69671d7fec4Smrg {121, 112, 121, 88, 88}, /*v_sync */ 69771d7fec4Smrg {600, 600, 600, 600, 600}, /*iha */ 69871d7fec4Smrg {0x3c, 0x23, 0x3c, 0x65, 0x65}, /*iho */ 69971d7fec4Smrg {35, 26, 35, 26, 26} /*hsc */ 70071d7fec4Smrg }, 70171d7fec4Smrg}; 70271d7fec4Smrg 70371d7fec4Smrg/****/ 70471d7fec4Smrg/*Houston fifo configuration constants.*/ 70571d7fec4Smrg/****/ 70671d7fec4Smrgstruct _ffolat 70771d7fec4Smrg{ 70871d7fec4Smrg int v_total; 70971d7fec4Smrg unsigned short ffolat; 71071d7fec4Smrg}; 71171d7fec4Smrg 71271d7fec4Smrgstruct _ffolativo 71371d7fec4Smrg{ 71471d7fec4Smrg int v_total; 71571d7fec4Smrg unsigned short ivo; 71671d7fec4Smrg unsigned short ffolat; 71771d7fec4Smrg}; 71871d7fec4Smrg 71971d7fec4Smrg/*h_total=832, ivo=40, tv_width=858, tv_lines=525, vga_lines=480*/ 72071d7fec4Smrg#define SIZE6X4NTSC 66 72171d7fec4Smrgstatic struct _ffolat ffo6x4ntsc[SIZE6X4NTSC + 1] = { 72271d7fec4Smrg {541, 0x40}, {545, 0x40}, {549, 0x40}, {553, 0x40}, 72371d7fec4Smrg {557, 0x58}, {561, 0x40}, {565, 0x40}, {569, 0x40}, 72471d7fec4Smrg {573, 0x48}, {577, 0x40}, {581, 0x40}, {585, 0x40}, 72571d7fec4Smrg {589, 0x40}, {593, 0x48}, {597, 0x40}, {601, 0x40}, 72671d7fec4Smrg {605, 0x40}, {609, 0x40}, {613, 0x5b}, {617, 0x48}, 72771d7fec4Smrg {621, 0x60}, {625, 0x48}, {629, 0x48}, {633, 0x40}, 72871d7fec4Smrg {637, 0x5e}, {641, 0x40}, {645, 0x50}, {649, 0x56}, 72971d7fec4Smrg {653, 0x58}, {657, 0x6c}, {661, 0x40}, {665, 0x40}, 73071d7fec4Smrg {669, 0x40}, {673, 0x40}, {677, 0x40}, {681, 0x40}, 73171d7fec4Smrg {685, 0x40}, {689, 0x40}, {693, 0x40}, {697, 0x40}, 73271d7fec4Smrg {701, 0x40}, {705, 0x40}, {709, 0x40}, {713, 0x40}, 73371d7fec4Smrg {717, 0x40}, {721, 0x40}, {725, 0x40}, {729, 0x40}, 73471d7fec4Smrg {733, 0x40}, {737, 0x40}, {741, 0x40}, {745, 0x40}, 73571d7fec4Smrg {749, 0x40}, {753, 0x40}, {757, 0x40}, {761, 0x40}, 73671d7fec4Smrg {765, 0x40}, {769, 0x40}, {773, 0x40}, {777, 0x40}, 73771d7fec4Smrg {781, 0x40}, {785, 0x40}, {789, 0x40}, {793, 0x40}, 73871d7fec4Smrg {797, 0x30}, {801, 0x40}, 73971d7fec4Smrg {-1, 0} 74071d7fec4Smrg}; 74171d7fec4Smrg 74271d7fec4Smrg#define SIZE6X4PAL 45 74371d7fec4Smrgstatic struct _ffolat ffo6x4pal[SIZE6X4PAL + 1] = { 74471d7fec4Smrg {625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60}, 74571d7fec4Smrg {641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60}, 74671d7fec4Smrg {657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60}, 74771d7fec4Smrg {673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60}, 74871d7fec4Smrg {689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60}, 74971d7fec4Smrg {705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60}, 75071d7fec4Smrg {721, 0x60}, {725, 0x60}, {729, 0x60}, {733, 0x60}, 75171d7fec4Smrg {737, 0x60}, {741, 0x60}, {745, 0x60}, {749, 0x60}, 75271d7fec4Smrg {753, 0x60}, {757, 0x60}, {761, 0x60}, {765, 0x60}, 75371d7fec4Smrg {769, 0x60}, {773, 0x60}, {777, 0x60}, {781, 0x60}, 75471d7fec4Smrg {785, 0x60}, {789, 0x60}, {793, 0x60}, {797, 0x60}, 75571d7fec4Smrg {801, 0x60}, 75671d7fec4Smrg {-1, 0} 75771d7fec4Smrg}; 75871d7fec4Smrg 75971d7fec4Smrg#define SIZE7X4NTSC 40 76071d7fec4Smrgstatic struct _ffolat ffo7x4ntsc[SIZE7X4NTSC + 1] = { 76171d7fec4Smrg {525, 0x52}, {529, 0x52}, {533, 0x52}, {537, 0x52}, 76271d7fec4Smrg {541, 0x52}, {545, 0x40}, {549, 0x40}, {553, 0x40}, 76371d7fec4Smrg {557, 0x58}, {561, 0x40}, {565, 0x58}, {569, 0x40}, 76471d7fec4Smrg {573, 0x48}, {577, 0x40}, {581, 0x40}, {585, 0x40}, 76571d7fec4Smrg {589, 0x40}, {593, 0x48}, {597, 0x40}, {601, 0x40}, 76671d7fec4Smrg {605, 0x40}, {609, 0x40}, {613, 0x5b}, {617, 0x48}, 76771d7fec4Smrg {621, 0x60}, {625, 0x48}, {629, 0x48}, {633, 0x40}, 76871d7fec4Smrg {637, 0x5e}, {641, 0x40}, {645, 0x50}, {649, 0x56}, 76971d7fec4Smrg {653, 0x58}, {657, 0x6c}, {661, 0x40}, {665, 0x40}, 77071d7fec4Smrg {669, 0x40}, {673, 0x40}, {677, 0x40}, {681, 0x40}, 77171d7fec4Smrg {-1, 0} 77271d7fec4Smrg}; 77371d7fec4Smrg 77471d7fec4Smrg#define SIZE7X4PAL 24 77571d7fec4Smrgstatic struct _ffolat ffo7x4pal[SIZE7X4PAL + 1] = { 77671d7fec4Smrg {625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60}, 77771d7fec4Smrg {641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60}, 77871d7fec4Smrg {657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60}, 77971d7fec4Smrg {673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60}, 78071d7fec4Smrg {689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60}, 78171d7fec4Smrg {705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60}, 78271d7fec4Smrg {-1, 0} 78371d7fec4Smrg}; 78471d7fec4Smrg 78571d7fec4Smrg#define SIZE7X5NTSC 54 78671d7fec4Smrgstatic struct _ffolat ffo7x5ntsc[SIZE7X5NTSC + 1] = { 78771d7fec4Smrg {590, 0x40}, {594, 0x48}, {598, 0x40}, {602, 0x40}, 78871d7fec4Smrg {606, 0x40}, {610, 0x40}, {614, 0x5b}, {618, 0x48}, 78971d7fec4Smrg {622, 0x60}, {626, 0x48}, {630, 0x48}, {634, 0x40}, 79071d7fec4Smrg {638, 0x5e}, {642, 0x40}, {646, 0x50}, {650, 0x56}, 79171d7fec4Smrg {654, 0x58}, {658, 0x6c}, {662, 0x40}, {666, 0x40}, 79271d7fec4Smrg {670, 0x40}, {674, 0x40}, {678, 0x40}, {682, 0x40}, 79371d7fec4Smrg {686, 0x40}, {690, 0x40}, {694, 0x40}, {698, 0x40}, 79471d7fec4Smrg {702, 0x40}, {706, 0x40}, {710, 0x40}, {714, 0x40}, 79571d7fec4Smrg {718, 0x40}, {722, 0x40}, {726, 0x40}, {730, 0x40}, 79671d7fec4Smrg {734, 0x40}, {738, 0x40}, {742, 0x40}, {746, 0x40}, 79771d7fec4Smrg {750, 0x40}, {754, 0x40}, {758, 0x40}, {762, 0x40}, 79871d7fec4Smrg {766, 0x40}, {770, 0x40}, {774, 0x40}, {778, 0x40}, 79971d7fec4Smrg {782, 0x40}, {786, 0x40}, {790, 0x40}, {794, 0x40}, 80071d7fec4Smrg {798, 0x30}, {802, 0x40}, 80171d7fec4Smrg {-1, 0} 80271d7fec4Smrg}; 80371d7fec4Smrg 80471d7fec4Smrg#define SIZE7X5PAL 45 80571d7fec4Smrgstatic struct _ffolat ffo7x5pal[SIZE7X5PAL + 1] = { 80671d7fec4Smrg {625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60}, 80771d7fec4Smrg {641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60}, 80871d7fec4Smrg {657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60}, 80971d7fec4Smrg {673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60}, 81071d7fec4Smrg {689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60}, 81171d7fec4Smrg {705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60}, 81271d7fec4Smrg {721, 0x60}, {725, 0x60}, {729, 0x60}, {733, 0x60}, 81371d7fec4Smrg {737, 0x60}, {741, 0x60}, {745, 0x60}, {749, 0x60}, 81471d7fec4Smrg {753, 0x60}, {757, 0x60}, {761, 0x60}, {765, 0x60}, 81571d7fec4Smrg {769, 0x60}, {773, 0x60}, {777, 0x60}, {781, 0x60}, 81671d7fec4Smrg {785, 0x60}, {789, 0x60}, {793, 0x60}, {797, 0x60}, 81771d7fec4Smrg {801, 0x60}, 81871d7fec4Smrg {-1, 0} 81971d7fec4Smrg}; 82071d7fec4Smrg 82171d7fec4Smrg/*h_total=1056, vga_lines=600*/ 82271d7fec4Smrg#define SIZE8X6NTSC 37 82371d7fec4Smrgstatic struct _ffolat ffo8x6ntsc[SIZE8X6NTSC + 1] = { 82471d7fec4Smrg {620, 0x40}, /*v_total_min >= vsync+10 >= vga_lines+10 = 610 */ 82571d7fec4Smrg {625, 0x58}, {630, 0x40}, {635, 0x40}, {640, 0x40}, 82671d7fec4Smrg {645, 0x46}, {650, 0x46}, {655, 0x4f}, {660, 0x4c}, 82771d7fec4Smrg {665, 0x4a}, {670, 0x50}, {675, 0x2f}, {680, 0x48}, 82871d7fec4Smrg {685, 0x38}, {690, 0x31}, {695, 0x40}, {700, 0x21}, 82971d7fec4Smrg {705, 0x25}, {710, 0x40}, {715, 0x48}, {720, 0x50}, 83071d7fec4Smrg {725, 0x30}, {730, 0x50}, {735, 0x50}, {740, 0x50}, 83171d7fec4Smrg {745, 0x40}, {750, 0x38}, {755, 0x50}, {760, 0x50}, 83271d7fec4Smrg {765, 0x40}, {770, 0x38}, {775, 0x40}, {780, 0x40}, 83371d7fec4Smrg {785, 0x40}, {790, 0x38}, {795, 0x50}, {800, 0x50}, 83471d7fec4Smrg {-1, 0} 83571d7fec4Smrg}; 83671d7fec4Smrg 83771d7fec4Smrg/*h_total=1056, vga_lines=600*/ 83871d7fec4Smrg#define SIZE8X6PAL 36 83971d7fec4Smrgstatic struct _ffolat ffo8x6pal[SIZE8X6PAL + 1] = { 84071d7fec4Smrg {625, 0x80}, {630, 0x80}, {635, 0x5a}, {640, 0x55}, 84171d7fec4Smrg {645, 0x48}, {650, 0x65}, {655, 0x65}, {660, 0x50}, 84271d7fec4Smrg {665, 0x80}, {670, 0x70}, {675, 0x56}, {680, 0x80}, 84371d7fec4Smrg {685, 0x58}, {690, 0x31}, {695, 0x80}, {700, 0x60}, 84471d7fec4Smrg {705, 0x45}, {710, 0x4a}, {715, 0x50}, {720, 0x50}, 84571d7fec4Smrg {725, 0x50}, {730, 0x45}, {735, 0x50}, {740, 0x50}, 84671d7fec4Smrg {745, 0x50}, {750, 0x50}, {755, 0x50}, {760, 0x50}, 84771d7fec4Smrg {765, 0x50}, {770, 0x50}, {775, 0x50}, {780, 0x50}, 84871d7fec4Smrg {785, 0x50}, {790, 0x50}, {795, 0x50}, {800, 0x50}, 84971d7fec4Smrg {-1, 0} 85071d7fec4Smrg}; 85171d7fec4Smrg 85271d7fec4Smrg/*h_total=1344, vga_lines=768*/ 85371d7fec4Smrg#define SIZE10X7NTSC 45 85471d7fec4Smrgstatic struct _ffolativo ffo10x7ntsc[SIZE10X7NTSC] = { 85571d7fec4Smrg {783, 0x4d, 0x40}, 85671d7fec4Smrg {789, 0x47, 0x14}, 85771d7fec4Smrg {795, 0x47, 0x7f}, 85871d7fec4Smrg {801, 0x47, 0x53}, 85971d7fec4Smrg {807, 0x47, 0x11}, 86071d7fec4Smrg {813, 0x47, 0x78}, 86171d7fec4Smrg {819, 0x47, 0x54}, 86271d7fec4Smrg {825, 0x47, 0x40}, 86371d7fec4Smrg {831, 0x47, 0x0f}, 86471d7fec4Smrg {837, 0x4d, 0x40}, 86571d7fec4Smrg {843, 0x47, 0x5a}, 86671d7fec4Smrg {849, 0x4d, 0x40}, 86771d7fec4Smrg {855, 0x47, 0x4b}, 86871d7fec4Smrg {861, 0x4d, 0x40}, 86971d7fec4Smrg {867, 0x47, 0x4b}, 87071d7fec4Smrg {873, 0x4d, 0x40}, 87171d7fec4Smrg {879, 0x47, 0x07}, 87271d7fec4Smrg {885, 0x48, 0x20}, 87371d7fec4Smrg {891, 0x47, 0x82}, 87471d7fec4Smrg {897, 0x47, 0x60}, 87571d7fec4Smrg {903, 0x47, 0x7f}, 87671d7fec4Smrg {909, 0x4d, 0x40}, 87771d7fec4Smrg {915, 0x48, 0x40}, 87871d7fec4Smrg {921, 0x4c, 0x40}, 87971d7fec4Smrg {927, 0x49, 0x40}, 88071d7fec4Smrg {933, 0x48, 0x40}, 88171d7fec4Smrg {939, 0x4a, 0x40}, 88271d7fec4Smrg {945, 0x46, 0x40}, 88371d7fec4Smrg {951, 0x4a, 0x40}, 88471d7fec4Smrg {957, 0x4a, 0x40}, 88571d7fec4Smrg {963, 0x4b, 0x40}, 88671d7fec4Smrg {969, 0x4b, 0x40}, 88771d7fec4Smrg {975, 0x48, 0x40}, 88871d7fec4Smrg {981, 0x47, 0x40}, 88971d7fec4Smrg {987, 0x47, 0x40}, 89071d7fec4Smrg {993, 0x47, 0x40}, 89171d7fec4Smrg {999, 0x48, 0x40}, 89271d7fec4Smrg {1005, 0x48, 0x40}, 89371d7fec4Smrg {1011, 0x47, 0x40}, 89471d7fec4Smrg {1017, 0x47, 0x40}, 89571d7fec4Smrg {1023, 0x48, 0x40}, 89671d7fec4Smrg {1029, 0x48, 0x40}, 89771d7fec4Smrg {1035, 0x46, 0x40}, 89871d7fec4Smrg {1041, 0x47, 0x40}, 89971d7fec4Smrg {1047, 0x47, 0x40} 90071d7fec4Smrg}; 90171d7fec4Smrg 90271d7fec4Smrg/*h_total=1344, vga_lines=768*/ 90371d7fec4Smrg#define SIZE10X7PAL 46 90471d7fec4Smrgstatic struct _ffolativo ffo10x7pal[SIZE10X7PAL] = { 90571d7fec4Smrg {781, 0x49, 0x40}, 90671d7fec4Smrg {787, 0x46, 0x40}, 90771d7fec4Smrg {793, 0x48, 0x40}, 90871d7fec4Smrg {799, 0x46, 0x40}, 90971d7fec4Smrg {805, 0x49, 0x40}, 91071d7fec4Smrg {811, 0x47, 0x40}, 91171d7fec4Smrg {817, 0x46, 0x40}, 91271d7fec4Smrg {823, 0x46, 0x56}, 91371d7fec4Smrg {829, 0x46, 0x2d}, 91471d7fec4Smrg {835, 0x46, 0x40}, 91571d7fec4Smrg {841, 0x46, 0x2d}, 91671d7fec4Smrg {847, 0x46, 0x3f}, 91771d7fec4Smrg {853, 0x46, 0x10}, 91871d7fec4Smrg {859, 0x46, 0x86}, 91971d7fec4Smrg {865, 0x46, 0xc9}, 92071d7fec4Smrg {871, 0x46, 0x83}, 92171d7fec4Smrg {877, 0x46, 0xa8}, 92271d7fec4Smrg {883, 0x46, 0x81}, 92371d7fec4Smrg {889, 0x46, 0xa5}, 92471d7fec4Smrg {895, 0x46, 0xa9}, 92571d7fec4Smrg {901, 0x46, 0x81}, 92671d7fec4Smrg {907, 0x46, 0xa4}, 92771d7fec4Smrg {913, 0x46, 0xa5}, 92871d7fec4Smrg {919, 0x46, 0x7f}, 92971d7fec4Smrg {925, 0x46, 0xa2}, 93071d7fec4Smrg {931, 0x46, 0x9d}, 93171d7fec4Smrg {937, 0x46, 0xc1}, 93271d7fec4Smrg {943, 0x46, 0x96}, 93371d7fec4Smrg {949, 0x46, 0xb7}, 93471d7fec4Smrg {955, 0x46, 0xb1}, 93571d7fec4Smrg {961, 0x46, 0x8a}, 93671d7fec4Smrg {967, 0x46, 0xa9}, 93771d7fec4Smrg {973, 0x46, 0xa0}, 93871d7fec4Smrg {979, 0x46, 0x40}, 93971d7fec4Smrg {985, 0x46, 0x97}, 94071d7fec4Smrg {991, 0x46, 0xb5}, 94171d7fec4Smrg {997, 0x46, 0xaa}, 94271d7fec4Smrg {1003, 0x46, 0x83}, 94371d7fec4Smrg {1009, 0x46, 0x9f}, 94471d7fec4Smrg {1015, 0x47, 0x40}, 94571d7fec4Smrg {1021, 0x46, 0xad}, 94671d7fec4Smrg {1027, 0x46, 0x87}, 94771d7fec4Smrg {1033, 0x46, 0xa2}, 94871d7fec4Smrg {1039, 0x47, 0x40}, 94971d7fec4Smrg {1045, 0x46, 0xac}, 95071d7fec4Smrg {1051, 0x46, 0x86} 95171d7fec4Smrg}; 95271d7fec4Smrg 95371d7fec4Smrg/*//==========================================================================*/ 95471d7fec4Smrg/****/ 95571d7fec4Smrg/*FS450 API Functions.*/ 95671d7fec4Smrg/****/ 95771d7fec4Smrg/*//==========================================================================*/ 95871d7fec4Smrg 95971d7fec4Smrg/****/ 96071d7fec4Smrg/*Initialize device settings*/ 96171d7fec4Smrg/****/ 96271d7fec4Smrgstatic void 96371d7fec4Smrginitialize_houston_static_registers(void) 96471d7fec4Smrg{ 96571d7fec4Smrg houston_WriteReg(HOUSTON_BYP, 0, 2); 96671d7fec4Smrg houston_WriteReg(HOUSTON_APO, 0, 2); 96771d7fec4Smrg houston_WriteReg(HOUSTON_ALO, 0, 2); 96871d7fec4Smrg houston_WriteReg(HOUSTON_AFO, 0, 2); 96971d7fec4Smrg houston_WriteReg(HOUSTON_BCONTL, 0, 2); 97071d7fec4Smrg houston_WriteReg(HOUSTON_BCONTH, 0, 2); 97171d7fec4Smrg houston_WriteReg(HOUSTON_BDONE, 0, 2); 97271d7fec4Smrg houston_WriteReg(HOUSTON_BDIAGL, 0, 2); 97371d7fec4Smrg houston_WriteReg(HOUSTON_BDIAGH, 0, 2); 97471d7fec4Smrg houston_WriteReg(HOUSTON_MISC, 0, 2); 97571d7fec4Smrg} 97671d7fec4Smrg 97771d7fec4Smrgint 97871d7fec4SmrgFS450_init(void) 97971d7fec4Smrg{ 98071d7fec4Smrg int err; 98171d7fec4Smrg 98271d7fec4Smrg TRACE(("FS450_Init()\n")) 98371d7fec4Smrg 98471d7fec4Smrg err = houston_init(); 98571d7fec4Smrg if (err) 98671d7fec4Smrg return err; 98771d7fec4Smrg 98871d7fec4Smrg initialize_houston_static_registers(); 98971d7fec4Smrg 99071d7fec4Smrg#if 1 99171d7fec4Smrg d.tv_on = PLAL_IsTVOn()? 1 : 0; 99271d7fec4Smrg#else 99371d7fec4Smrg d.tv_on = 0; 99471d7fec4Smrg#endif 99571d7fec4Smrg 99671d7fec4Smrg#if 1 99771d7fec4Smrg /*get the current tv standard */ 99871d7fec4Smrg conget_tv_std(&d.tv_std); 99971d7fec4Smrg#else 100071d7fec4Smrg /*default to VP_TV_STANDARD_NTSC_M */ 100171d7fec4Smrg d.tv_std = VP_TV_STANDARD_NTSC_M; 100271d7fec4Smrg config_tv_std(d.tv_std); 100371d7fec4Smrg#endif 100471d7fec4Smrg 100571d7fec4Smrg d.vga_mode = 0; 100671d7fec4Smrg 100771d7fec4Smrg#if 0 100871d7fec4Smrg /*get the current tvout mode */ 100971d7fec4Smrg conget_tvout_mode(&d.tvout_mode); 101071d7fec4Smrg#else 101171d7fec4Smrg /*default to VP_TVOUT_MODE_CVBS_YC */ 101271d7fec4Smrg d.tvout_mode = GFX_TVOUT_MODE_CVBS_YC; 101371d7fec4Smrg#endif 101471d7fec4Smrg 101571d7fec4Smrg#if 0 101671d7fec4Smrg /*get the current sharpness */ 101771d7fec4Smrg conget_sharpness(d.sharpness); 101871d7fec4Smrg#else 101971d7fec4Smrg /*default to 1000 out of 1000 */ 102071d7fec4Smrg d.sharpness = 1000; 102171d7fec4Smrg config_sharpness(d.sharpness); 102271d7fec4Smrg#endif 102371d7fec4Smrg 102471d7fec4Smrg#if 0 102571d7fec4Smrg /*get the current flicker */ 102671d7fec4Smrg conget_flicker(d.flicker); 102771d7fec4Smrg#else 102871d7fec4Smrg /*default to 800 out of 1000 */ 102971d7fec4Smrg d.flicker = 800; 103071d7fec4Smrg config_flicker(d.flicker); 103171d7fec4Smrg#endif 103271d7fec4Smrg 103371d7fec4Smrg#if 0 103471d7fec4Smrg /*get the current size and position */ 103571d7fec4Smrg#else 103671d7fec4Smrg /*default to zeros */ 103771d7fec4Smrg d.overscan_x = 0; 103871d7fec4Smrg d.overscan_y = 0; 103971d7fec4Smrg d.position_x = 0; 104071d7fec4Smrg d.position_y = 0; 104171d7fec4Smrg#endif 104271d7fec4Smrg 104371d7fec4Smrg#if 0 104471d7fec4Smrg /*get the current color */ 104571d7fec4Smrg conget_color(d.color); 104671d7fec4Smrg#else 104771d7fec4Smrg d.color = 50; 104871d7fec4Smrg /*//d.color = tvsetup.color[k]; */ 104971d7fec4Smrg config_color(d.color); 105071d7fec4Smrg#endif 105171d7fec4Smrg 105271d7fec4Smrg#if 0 105371d7fec4Smrg /*get the current brightness and contrast */ 105471d7fec4Smrg conget_brightness_contrast(d.tv_std, d.aps_trigger_bits, d.brightness, 105571d7fec4Smrg d.contrast); 105671d7fec4Smrg#else 105771d7fec4Smrg /*default */ 105871d7fec4Smrg d.brightness = 50; 105971d7fec4Smrg d.contrast = 60; 106071d7fec4Smrg config_brightness_contrast(d.tv_std, d.aps_trigger_bits, d.brightness, 106171d7fec4Smrg d.contrast); 106271d7fec4Smrg#endif 106371d7fec4Smrg 106471d7fec4Smrg#if 1 106571d7fec4Smrg /*get the current yc filtering */ 106671d7fec4Smrg { 106771d7fec4Smrg int luma_filter, chroma_filter; 106871d7fec4Smrg 106971d7fec4Smrg conget_yc_filter(&luma_filter, &chroma_filter); 107071d7fec4Smrg d.yc_filter = 0; 107171d7fec4Smrg if (luma_filter) 107271d7fec4Smrg d.yc_filter |= GFX_LUMA_FILTER; 107371d7fec4Smrg if (chroma_filter) 107471d7fec4Smrg d.yc_filter |= GFX_CHROMA_FILTER; 107571d7fec4Smrg } 107671d7fec4Smrg#else 107771d7fec4Smrg /*default */ 107871d7fec4Smrg d.yc_filter = GFX_LUMA_FILTER + GFX_CHROMA_FILTER; 107971d7fec4Smrg#endif 108071d7fec4Smrg 108171d7fec4Smrg#if 0 108271d7fec4Smrg /*get the current cp settings */ 108371d7fec4Smrg conget_macrovision(d.tv_std, &d.aps_trigger_bits); 108471d7fec4Smrg#else 108571d7fec4Smrg d.aps_trigger_bits = 0; 108671d7fec4Smrg config_macrovision(d.tv_std, d.aps_trigger_bits); 108771d7fec4Smrg#endif 108871d7fec4Smrg 108971d7fec4Smrg d.last_overscan_y = -10000; 109071d7fec4Smrg 109171d7fec4Smrg return 0; 109271d7fec4Smrg} 109371d7fec4Smrg 109471d7fec4Smrgvoid 109571d7fec4SmrgFS450_cleanup(void) 109671d7fec4Smrg{ 109771d7fec4Smrg} 109871d7fec4Smrg 109971d7fec4Smrg/*//==========================================================================*/ 110071d7fec4Smrg/****/ 110171d7fec4Smrg/*// Required configuration calls to write new settings to the device*/ 110271d7fec4Smrg 110371d7fec4Smrg#define REQ_TV_STANDARD_BIT 0x0002 110471d7fec4Smrg#define REQ_VGA_MODE_BIT 0x0004 110571d7fec4Smrg#define REQ_TVOUT_MODE_BIT 0x0008 110671d7fec4Smrg#define REQ_SHARPNESS_BIT 0x0010 110771d7fec4Smrg#define REQ_FLICKER_BIT 0x0020 110871d7fec4Smrg#define REQ_OVERSCAN_POSITION_BIT 0x0040 110971d7fec4Smrg#define REQ_COLOR_BIT 0x0080 111071d7fec4Smrg#define REQ_BRIGHTNESS_CONTRAST_BIT 0x0100 111171d7fec4Smrg#define REQ_YC_FILTER_BIT 0x0200 111271d7fec4Smrg#define REQ_MACROVISION_BIT 0x0400 111371d7fec4Smrg#define REQ_NCO_BIT 0x1000 111471d7fec4Smrg 111571d7fec4Smrg#define REQ_TV_STANDARD (REQ_TV_STANDARD_BIT | REQ_OVERSCAN_POSITION | REQ_BRIGHTNESS_CONTRAST | REQ_MACROVISION_BIT | REQ_YC_FILTER) 111671d7fec4Smrg#define REQ_VGA_MODE (REQ_VGA_MODE_BIT | REQ_OVERSCAN_POSITION) 111771d7fec4Smrg#define REQ_TVOUT_MODE (REQ_TVOUT_MODE_BIT) 111871d7fec4Smrg#define REQ_SHARPNESS (REQ_SHARPNESS_BIT) 111971d7fec4Smrg#define REQ_FLICKER (REQ_FLICKER_BIT) 112071d7fec4Smrg#define REQ_OVERSCAN_POSITION (REQ_OVERSCAN_POSITION_BIT | REQ_NCO) 112171d7fec4Smrg#define REQ_COLOR (REQ_COLOR_BIT) 112271d7fec4Smrg#define REQ_BRIGHTNESS_CONTRAST (REQ_BRIGHTNESS_CONTRAST_BIT) 112371d7fec4Smrg#define REQ_YC_FILTER (REQ_YC_FILTER_BIT) 112471d7fec4Smrg#define REQ_MACROVISION (REQ_TV_STANDARD_BIT | REQ_BRIGHTNESS_CONTRAST_BIT | REQ_MACROVISION_BIT) 112571d7fec4Smrg#define REQ_NCO (REQ_NCO_BIT) 112671d7fec4Smrg#define REQ_ENCODER (REQ_TV_STANDARD | REQ_COLOR | REQ_BRIGHTNESS_CONTRAST | REQ_YC_FILTER) 112771d7fec4Smrg 112871d7fec4Smrgstatic int 112971d7fec4Smrgwrite_config(int req) 113071d7fec4Smrg{ 113171d7fec4Smrg unsigned long reg, reg_encoder_reset = 0; 113271d7fec4Smrg int reset; 113371d7fec4Smrg 113471d7fec4Smrg /*if we're changing the nco, and the vertical scaling has changed... */ 113571d7fec4Smrg reset = ((REQ_NCO_BIT & req) && (d.overscan_y != d.last_overscan_y)); 113671d7fec4Smrg if (reset) { 113771d7fec4Smrg /*put the encoder into reset while making changes */ 113871d7fec4Smrg houston_ReadReg(ENC_RESET, ®, 1); 113971d7fec4Smrg houston_WriteReg(ENC_RESET, reg | 0x01, 1); 114071d7fec4Smrg reg_encoder_reset = reg & 0x01; 114171d7fec4Smrg } 114271d7fec4Smrg 114371d7fec4Smrg if (REQ_TV_STANDARD_BIT & req) 114471d7fec4Smrg config_tv_std(d.tv_std, d.aps_trigger_bits); 114571d7fec4Smrg 114671d7fec4Smrg if (REQ_VGA_MODE_BIT & req) 114771d7fec4Smrg config_vga_mode(d.vga_mode); 114871d7fec4Smrg 114971d7fec4Smrg if (REQ_TVOUT_MODE_BIT & req) 115071d7fec4Smrg config_tvout_mode(d.tvout_mode); 115171d7fec4Smrg 115271d7fec4Smrg if (REQ_OVERSCAN_POSITION_BIT & req) { 115371d7fec4Smrg config_overscan_xy(d.tv_std, 115471d7fec4Smrg d.vga_mode, 115571d7fec4Smrg d.overscan_x, 115671d7fec4Smrg d.overscan_y, d.position_x, d.position_y); 115771d7fec4Smrg 115871d7fec4Smrg /*h_timing and v_timing and syncs. */ 115971d7fec4Smrg if (PLAL_IsTVOn()) 116071d7fec4Smrg PLAL_SetTVTimingRegisters(p_specs()); 116171d7fec4Smrg } 116271d7fec4Smrg 116371d7fec4Smrg if (REQ_NCO_BIT & req) 116471d7fec4Smrg config_nco(d.tv_std, d.vga_mode); 116571d7fec4Smrg 116671d7fec4Smrg if (REQ_SHARPNESS_BIT & req) 116771d7fec4Smrg config_sharpness(d.sharpness); 116871d7fec4Smrg 116971d7fec4Smrg if (REQ_FLICKER_BIT & req) 117071d7fec4Smrg config_flicker(d.flicker); 117171d7fec4Smrg 117271d7fec4Smrg if (REQ_COLOR_BIT & req) 117371d7fec4Smrg config_color(d.color); 117471d7fec4Smrg 117571d7fec4Smrg if (REQ_BRIGHTNESS_CONTRAST_BIT & req) { 117671d7fec4Smrg config_brightness_contrast(d.tv_std, 117771d7fec4Smrg d.aps_trigger_bits, 117871d7fec4Smrg d.brightness, d.contrast); 117971d7fec4Smrg } 118071d7fec4Smrg 118171d7fec4Smrg if (REQ_YC_FILTER_BIT & req) { 118271d7fec4Smrg config_yc_filter(d.tv_std, 118371d7fec4Smrg (d.yc_filter & GFX_LUMA_FILTER), 118471d7fec4Smrg (d.yc_filter & GFX_CHROMA_FILTER)); 118571d7fec4Smrg } 118671d7fec4Smrg 118771d7fec4Smrg if (REQ_MACROVISION_BIT & req) 118871d7fec4Smrg config_macrovision(d.tv_std, d.aps_trigger_bits); 118971d7fec4Smrg 119071d7fec4Smrg /*if we decided to put the encoder into reset, put it back */ 119171d7fec4Smrg if (reset) { 119271d7fec4Smrg houston_ReadReg(ENC_RESET, ®, 1); 119371d7fec4Smrg houston_WriteReg(ENC_RESET, reg_encoder_reset | (reg & ~0x01), 1); 119471d7fec4Smrg 119571d7fec4Smrg d.last_overscan_y = d.overscan_y; 119671d7fec4Smrg } 119771d7fec4Smrg return 0; 119871d7fec4Smrg} 119971d7fec4Smrg 120071d7fec4Smrg/*==========================================================================*/ 120171d7fec4Smrg/****/ 120271d7fec4Smrg/*// TV On*/ 120371d7fec4Smrg 120471d7fec4Smrg#if GFX_TV_DYNAMIC 120571d7fec4Smrgint 120671d7fec4Smrgfs450_get_tv_enable(unsigned int *p_on) 120771d7fec4Smrg#else 120871d7fec4Smrgint 120971d7fec4Smrggfx_get_tv_enable(unsigned int *p_on) 121071d7fec4Smrg#endif 121171d7fec4Smrg{ 121271d7fec4Smrg if (!p_on) 121371d7fec4Smrg return ERR_INVALID_PARAMETER; 121471d7fec4Smrg 121571d7fec4Smrg *p_on = d.tv_on; 121671d7fec4Smrg 121771d7fec4Smrg return 0; 121871d7fec4Smrg} 121971d7fec4Smrg 122071d7fec4Smrg/*//int FS450_set_tv_on(unsigned int on)*/ 122171d7fec4Smrg#if GFX_TV_DYNAMIC 122271d7fec4Smrgint 122371d7fec4Smrgfs450_set_tv_enable(int on) 122471d7fec4Smrg#else 122571d7fec4Smrgint 122671d7fec4Smrggfx_set_tv_enable(int on) 122771d7fec4Smrg#endif 122871d7fec4Smrg{ 122971d7fec4Smrg unsigned long reg; 123071d7fec4Smrg 123171d7fec4Smrg /*if not mode change, just return */ 123271d7fec4Smrg if ((d.tv_on && on) || (!d.tv_on && !on)) 123371d7fec4Smrg return 0; 123471d7fec4Smrg 123571d7fec4Smrg /*if turning off... */ 123671d7fec4Smrg if (!on) { 123771d7fec4Smrg /*reenable vga. */ 123871d7fec4Smrg PLAL_EnableVga(); 123971d7fec4Smrg 124071d7fec4Smrg /*power down houston */ 124171d7fec4Smrg config_power(0); 124271d7fec4Smrg 124371d7fec4Smrg d.tv_on = 0; 124471d7fec4Smrg 124571d7fec4Smrg return 0; 124671d7fec4Smrg } 124771d7fec4Smrg 124871d7fec4Smrg /*turning on... */ 124971d7fec4Smrg 125071d7fec4Smrg /*power up houston */ 125171d7fec4Smrg config_power(1); 125271d7fec4Smrg 125371d7fec4Smrg /*assert encoder reset. */ 125471d7fec4Smrg houston_WriteReg(ENC_RESET, 0x01, 1); 125571d7fec4Smrg 125671d7fec4Smrg /*initial platform preparation */ 125771d7fec4Smrg PLAL_PrepForTVout(); 125871d7fec4Smrg 125971d7fec4Smrg /*configure encoder and nco. */ 126071d7fec4Smrg write_config(REQ_VGA_MODE | 126171d7fec4Smrg REQ_TV_STANDARD | 126271d7fec4Smrg REQ_TVOUT_MODE | 126371d7fec4Smrg REQ_OVERSCAN_POSITION | REQ_YC_FILTER | REQ_MACROVISION); 126471d7fec4Smrg 126571d7fec4Smrg /*set LP_EN and UIM */ 126671d7fec4Smrg houston_ReadReg(HOUSTON_CR, ®, 2); 126771d7fec4Smrg reg |= CR_LP_EN; 126871d7fec4Smrg reg &= ~(CR_UIM_MOD0 | CR_UIM_MOD1); 126971d7fec4Smrg reg |= (PLAL_FS450_UIM_mode() << 14); 127071d7fec4Smrg houston_WriteReg(HOUSTON_CR, reg, 2); 127171d7fec4Smrg 127271d7fec4Smrg /*set platform timing registers */ 127371d7fec4Smrg PLAL_SetTVTimingRegisters(p_specs()); 127471d7fec4Smrg 127571d7fec4Smrg PLAL_FinalEnableTVout(d.vga_mode); 127671d7fec4Smrg 127771d7fec4Smrg /*sync bridge */ 127871d7fec4Smrg { 127971d7fec4Smrg int retry_count = 0; 128071d7fec4Smrg 128171d7fec4Smrg /*sync 50 times */ 128271d7fec4Smrg while (retry_count++ < 50) { 128371d7fec4Smrg /*sync bridge. */ 128471d7fec4Smrg houston_ReadReg(HOUSTON_MISC, ®, 2); 128571d7fec4Smrg reg |= MISC_BRIDGE_SYNC; 128671d7fec4Smrg houston_WriteReg(HOUSTON_MISC, reg, 2); 128771d7fec4Smrg reg &= ~MISC_BRIDGE_SYNC; 128871d7fec4Smrg houston_WriteReg(HOUSTON_MISC, reg, 2); 128971d7fec4Smrg } 129071d7fec4Smrg } 129171d7fec4Smrg 129271d7fec4Smrg /*deassert encoder reset. */ 129371d7fec4Smrg houston_WriteReg(ENC_RESET, 0x00, 1); 129471d7fec4Smrg 129571d7fec4Smrg d.tv_on = 1; 129671d7fec4Smrg 129771d7fec4Smrg return 0; 129871d7fec4Smrg} 129971d7fec4Smrg 130071d7fec4Smrg#if GFX_TV_DYNAMIC 130171d7fec4Smrgint 130271d7fec4Smrgfs450_set_tv_defaults(int format) 130371d7fec4Smrg#else 130471d7fec4Smrgint 130571d7fec4Smrggfx_set_tv_defaults(int format) 130671d7fec4Smrg#endif 130771d7fec4Smrg{ 130871d7fec4Smrg return 0; 130971d7fec4Smrg} 131071d7fec4Smrg 131171d7fec4Smrg/*==========================================================================*/ 131271d7fec4Smrg/****/ 131371d7fec4Smrg/*// TV standard*/ 131471d7fec4Smrg 131571d7fec4Smrg#if GFX_TV_DYNAMIC 131671d7fec4Smrgint 131771d7fec4Smrgfs450_get_tv_standard(unsigned long *p_standard) 131871d7fec4Smrg#else 131971d7fec4Smrgint 132071d7fec4Smrggfx_get_tv_standard(unsigned long *p_standard) 132171d7fec4Smrg#endif 132271d7fec4Smrg{ 132371d7fec4Smrg if (!p_standard) 132471d7fec4Smrg return ERR_INVALID_PARAMETER; 132571d7fec4Smrg 132671d7fec4Smrg *p_standard = d.tv_std; 132771d7fec4Smrg 132871d7fec4Smrg return 0; 132971d7fec4Smrg} 133071d7fec4Smrg 133171d7fec4Smrg#if GFX_TV_DYNAMIC 133271d7fec4Smrgint 133371d7fec4Smrgfs450_get_available_tv_standards(unsigned long *p_standards) 133471d7fec4Smrg#else 133571d7fec4Smrgint 133671d7fec4Smrggfx_get_available_tv_standards(unsigned long *p_standards) 133771d7fec4Smrg#endif 133871d7fec4Smrg{ 133971d7fec4Smrg if (!p_standards) 134071d7fec4Smrg return ERR_INVALID_PARAMETER; 134171d7fec4Smrg 134271d7fec4Smrg *p_standards = supported_standards(); 134371d7fec4Smrg 134471d7fec4Smrg return 0; 134571d7fec4Smrg} 134671d7fec4Smrg 134771d7fec4Smrg#if GFX_TV_DYNAMIC 134871d7fec4Smrgint 134971d7fec4Smrgfs450_set_tv_standard(unsigned long standard) 135071d7fec4Smrg#else 135171d7fec4Smrgint 135271d7fec4Smrggfx_set_tv_standard(unsigned long standard) 135371d7fec4Smrg#endif 135471d7fec4Smrg{ 135571d7fec4Smrg /*verify supported standard. */ 135671d7fec4Smrg if (!(standard & supported_standards())) 135771d7fec4Smrg return ERR_INVALID_PARAMETER; 135871d7fec4Smrg 135971d7fec4Smrg /*disallow if tv is on */ 136071d7fec4Smrg if (d.tv_on) 136171d7fec4Smrg return ERR_CANNOT_CHANGE_WHILE_TV_ON; 136271d7fec4Smrg 136371d7fec4Smrg d.tv_std = standard; 136471d7fec4Smrg/*// d.color = tvsetup.color[k];*/ 136571d7fec4Smrg 136671d7fec4Smrg return write_config(REQ_TV_STANDARD); 136771d7fec4Smrg} 136871d7fec4Smrg 136971d7fec4Smrg/*==========================================================================*/ 137071d7fec4Smrg/****/ 137171d7fec4Smrg/*// vga mode as known by the driver*/ 137271d7fec4Smrg#if GFX_TV_DYNAMIC 137371d7fec4Smrgint 137471d7fec4Smrgfs450_get_tv_vga_mode(unsigned long *p_vga_mode) 137571d7fec4Smrg#else 137671d7fec4Smrgint 137771d7fec4Smrggfx_get_tv_vga_mode(unsigned long *p_vga_mode) 137871d7fec4Smrg#endif 137971d7fec4Smrg{ 138071d7fec4Smrg if (!p_vga_mode) 138171d7fec4Smrg return ERR_INVALID_PARAMETER; 138271d7fec4Smrg 138371d7fec4Smrg *p_vga_mode = d.vga_mode; 138471d7fec4Smrg 138571d7fec4Smrg return 0; 138671d7fec4Smrg} 138771d7fec4Smrg 138871d7fec4Smrg#if GFX_TV_DYNAMIC 138971d7fec4Smrgint 139071d7fec4Smrgfs450_get_available_tv_vga_modes(unsigned long *p_vga_modes) 139171d7fec4Smrg#else 139271d7fec4Smrgint 139371d7fec4Smrggfx_get_available_tv_vga_modes(unsigned long *p_vga_modes) 139471d7fec4Smrg#endif 139571d7fec4Smrg{ 139671d7fec4Smrg if (!p_vga_modes) 139771d7fec4Smrg return ERR_INVALID_PARAMETER; 139871d7fec4Smrg 139971d7fec4Smrg *p_vga_modes = 140071d7fec4Smrg GFX_VGA_MODE_640X480 | 140171d7fec4Smrg GFX_VGA_MODE_720X487 | GFX_VGA_MODE_720X576 | GFX_VGA_MODE_800X600; 140271d7fec4Smrg if (houston_Rev() >= HOUSTON_REV_B) 140371d7fec4Smrg *p_vga_modes |= GFX_VGA_MODE_1024X768; 140471d7fec4Smrg 140571d7fec4Smrg return 0; 140671d7fec4Smrg} 140771d7fec4Smrg 140871d7fec4Smrg#if GFX_TV_DYNAMIC 140971d7fec4Smrgint 141071d7fec4Smrgfs450_set_tv_vga_mode(unsigned long vga_mode) 141171d7fec4Smrg#else 141271d7fec4Smrgint 141371d7fec4Smrggfx_set_tv_vga_mode(unsigned long vga_mode) 141471d7fec4Smrg#endif 141571d7fec4Smrg{ 141671d7fec4Smrg /*reject if not a single valid VGA mode */ 141771d7fec4Smrg switch (vga_mode) { 141871d7fec4Smrg default: 141971d7fec4Smrg return ERR_INVALID_PARAMETER; 142071d7fec4Smrg 142171d7fec4Smrg case GFX_VGA_MODE_640X480: 142271d7fec4Smrg case GFX_VGA_MODE_720X487: 142371d7fec4Smrg case GFX_VGA_MODE_720X576: 142471d7fec4Smrg case GFX_VGA_MODE_800X600: 142571d7fec4Smrg break; 142671d7fec4Smrg 142771d7fec4Smrg case GFX_VGA_MODE_1024X768: 142871d7fec4Smrg if (houston_Rev() >= HOUSTON_REV_B) 142971d7fec4Smrg break; 143071d7fec4Smrg return ERR_INVALID_PARAMETER; 143171d7fec4Smrg } 143271d7fec4Smrg 143371d7fec4Smrg /*if the mode has changed... */ 143471d7fec4Smrg if (vga_mode != d.vga_mode) { 143571d7fec4Smrg d.vga_mode = vga_mode; 143671d7fec4Smrg 143771d7fec4Smrg return write_config(REQ_VGA_MODE); 143871d7fec4Smrg } 143971d7fec4Smrg 144071d7fec4Smrg return 0; 144171d7fec4Smrg} 144271d7fec4Smrg 144371d7fec4Smrg/*==========================================================================*/ 144471d7fec4Smrg/****/ 144571d7fec4Smrg/*// tvout mode*/ 144671d7fec4Smrg 144771d7fec4Smrg#if GFX_TV_DYNAMIC 144871d7fec4Smrgint 144971d7fec4Smrgfs450_get_tvout_mode(unsigned long *p_tvout_mode) 145071d7fec4Smrg#else 145171d7fec4Smrgint 145271d7fec4Smrggfx_get_tvout_mode(unsigned long *p_tvout_mode) 145371d7fec4Smrg#endif 145471d7fec4Smrg{ 145571d7fec4Smrg if (!p_tvout_mode) 145671d7fec4Smrg return ERR_INVALID_PARAMETER; 145771d7fec4Smrg 145871d7fec4Smrg *p_tvout_mode = d.tvout_mode; 145971d7fec4Smrg 146071d7fec4Smrg return 0; 146171d7fec4Smrg} 146271d7fec4Smrg 146371d7fec4Smrg#if GFX_TV_DYNAMIC 146471d7fec4Smrgint 146571d7fec4Smrgfs450_set_tvout_mode(unsigned long tvout_mode) 146671d7fec4Smrg#else 146771d7fec4Smrgint 146871d7fec4Smrggfx_set_tvout_mode(unsigned long tvout_mode) 146971d7fec4Smrg#endif 147071d7fec4Smrg{ 147171d7fec4Smrg d.tvout_mode = tvout_mode; 147271d7fec4Smrg 147371d7fec4Smrg return write_config(REQ_TVOUT_MODE); 147471d7fec4Smrg} 147571d7fec4Smrg 147671d7fec4Smrg/*==========================================================================*/ 147771d7fec4Smrg/****/ 147871d7fec4Smrg/*// Sharpness*/ 147971d7fec4Smrg 148071d7fec4Smrg#if GFX_TV_DYNAMIC 148171d7fec4Smrgint 148271d7fec4Smrgfs450_get_sharpness(int *p_sharpness) 148371d7fec4Smrg#else 148471d7fec4Smrgint 148571d7fec4Smrggfx_get_sharpness(int *p_sharpness) 148671d7fec4Smrg#endif 148771d7fec4Smrg{ 148871d7fec4Smrg if (!p_sharpness) 148971d7fec4Smrg return ERR_INVALID_PARAMETER; 149071d7fec4Smrg 149171d7fec4Smrg *p_sharpness = d.sharpness; 149271d7fec4Smrg 149371d7fec4Smrg return 0; 149471d7fec4Smrg} 149571d7fec4Smrg 149671d7fec4Smrg#if GFX_TV_DYNAMIC 149771d7fec4Smrgint 149871d7fec4Smrgfs450_set_sharpness(int sharpness) 149971d7fec4Smrg#else 150071d7fec4Smrgint 150171d7fec4Smrggfx_set_sharpness(int sharpness) 150271d7fec4Smrg#endif 150371d7fec4Smrg{ 150471d7fec4Smrg d.sharpness = range_limit(sharpness, 0, 1000); 150571d7fec4Smrg 150671d7fec4Smrg return write_config(REQ_SHARPNESS); 150771d7fec4Smrg} 150871d7fec4Smrg 150971d7fec4Smrg/*==========================================================================*/ 151071d7fec4Smrg/****/ 151171d7fec4Smrg/*flicker filter control.*/ 151271d7fec4Smrg 151371d7fec4Smrg#if GFX_TV_DYNAMIC 151471d7fec4Smrgint 151571d7fec4Smrgfs450_get_flicker_filter(int *p_flicker) 151671d7fec4Smrg#else 151771d7fec4Smrgint 151871d7fec4Smrggfx_get_flicker_filter(int *p_flicker) 151971d7fec4Smrg#endif 152071d7fec4Smrg{ 152171d7fec4Smrg if (!p_flicker) 152271d7fec4Smrg return ERR_INVALID_PARAMETER; 152371d7fec4Smrg 152471d7fec4Smrg *p_flicker = d.flicker; 152571d7fec4Smrg 152671d7fec4Smrg return 0; 152771d7fec4Smrg} 152871d7fec4Smrg 152971d7fec4Smrg#if GFX_TV_DYNAMIC 153071d7fec4Smrgint 153171d7fec4Smrgfs450_set_flicker_filter(int flicker) 153271d7fec4Smrg#else 153371d7fec4Smrgint 153471d7fec4Smrggfx_set_flicker_filter(int flicker) 153571d7fec4Smrg#endif 153671d7fec4Smrg{ 153771d7fec4Smrg d.flicker = range_limit(flicker, 0, 1000); 153871d7fec4Smrg 153971d7fec4Smrg return write_config(REQ_FLICKER); 154071d7fec4Smrg} 154171d7fec4Smrg 154271d7fec4Smrg/*==========================================================================*/ 154371d7fec4Smrg/****/ 154471d7fec4Smrg/*// Overscan and Position*/ 154571d7fec4Smrg 154671d7fec4Smrg#if GFX_TV_DYNAMIC 154771d7fec4Smrgint 154871d7fec4Smrgfs450_get_overscan(int *p_x, int *p_y) 154971d7fec4Smrg#else 155071d7fec4Smrgint 155171d7fec4Smrggfx_get_overscan(int *p_x, int *p_y) 155271d7fec4Smrg#endif 155371d7fec4Smrg{ 155471d7fec4Smrg if (!p_x || !p_y) 155571d7fec4Smrg return ERR_INVALID_PARAMETER; 155671d7fec4Smrg 155771d7fec4Smrg *p_x = d.overscan_x; 155871d7fec4Smrg *p_y = d.overscan_y; 155971d7fec4Smrg 156071d7fec4Smrg return 0; 156171d7fec4Smrg} 156271d7fec4Smrg 156371d7fec4Smrg#if GFX_TV_DYNAMIC 156471d7fec4Smrgint 156571d7fec4Smrgfs450_set_overscan(int x, int y) 156671d7fec4Smrg#else 156771d7fec4Smrgint 156871d7fec4Smrggfx_set_overscan(int x, int y) 156971d7fec4Smrg#endif 157071d7fec4Smrg{ 157171d7fec4Smrg d.overscan_x = range_limit(x, -1000, 1000); 157271d7fec4Smrg d.overscan_y = range_limit(y, -1000, 1000); 157371d7fec4Smrg 157471d7fec4Smrg return write_config(REQ_OVERSCAN_POSITION); 157571d7fec4Smrg} 157671d7fec4Smrg 157771d7fec4Smrg#if GFX_TV_DYNAMIC 157871d7fec4Smrgint 157971d7fec4Smrgfs450_get_position(int *p_x, int *p_y) 158071d7fec4Smrg#else 158171d7fec4Smrgint 158271d7fec4Smrggfx_get_position(int *p_x, int *p_y) 158371d7fec4Smrg#endif 158471d7fec4Smrg{ 158571d7fec4Smrg if (!p_x || !p_y) 158671d7fec4Smrg return ERR_INVALID_PARAMETER; 158771d7fec4Smrg 158871d7fec4Smrg *p_x = d.position_x; 158971d7fec4Smrg *p_y = d.position_y; 159071d7fec4Smrg 159171d7fec4Smrg return 0; 159271d7fec4Smrg} 159371d7fec4Smrg 159471d7fec4Smrg#if GFX_TV_DYNAMIC 159571d7fec4Smrgint 159671d7fec4Smrgfs450_set_position(int x, int y) 159771d7fec4Smrg#else 159871d7fec4Smrgint 159971d7fec4Smrggfx_set_position(int x, int y) 160071d7fec4Smrg#endif 160171d7fec4Smrg{ 160271d7fec4Smrg d.position_x = range_limit(x, -1000, 1000); 160371d7fec4Smrg d.position_y = range_limit(y, -1000, 1000); 160471d7fec4Smrg 160571d7fec4Smrg return write_config(REQ_OVERSCAN_POSITION); 160671d7fec4Smrg} 160771d7fec4Smrg 160871d7fec4Smrg/*==========================================================================*/ 160971d7fec4Smrg/****/ 161071d7fec4Smrg/*// Color, Brightness, and Contrast*/ 161171d7fec4Smrg 161271d7fec4Smrg#if GFX_TV_DYNAMIC 161371d7fec4Smrgint 161471d7fec4Smrgfs450_get_color(int *p_color) 161571d7fec4Smrg#else 161671d7fec4Smrgint 161771d7fec4Smrggfx_get_color(int *p_color) 161871d7fec4Smrg#endif 161971d7fec4Smrg{ 162071d7fec4Smrg if (!p_color) 162171d7fec4Smrg return ERR_INVALID_PARAMETER; 162271d7fec4Smrg 162371d7fec4Smrg *p_color = d.color; 162471d7fec4Smrg 162571d7fec4Smrg return 0; 162671d7fec4Smrg} 162771d7fec4Smrg 162871d7fec4Smrg#if GFX_TV_DYNAMIC 162971d7fec4Smrgint 163071d7fec4Smrgfs450_set_color(int color) 163171d7fec4Smrg#else 163271d7fec4Smrgint 163371d7fec4Smrggfx_set_color(int color) 163471d7fec4Smrg#endif 163571d7fec4Smrg{ 163671d7fec4Smrg d.color = range_limit(color, 0, 100); 163771d7fec4Smrg 163871d7fec4Smrg return write_config(REQ_COLOR); 163971d7fec4Smrg} 164071d7fec4Smrg 164171d7fec4Smrg#if GFX_TV_DYNAMIC 164271d7fec4Smrgint 164371d7fec4Smrgfs450_get_brightness(int *p_brightness) 164471d7fec4Smrg#else 164571d7fec4Smrgint 164671d7fec4Smrggfx_get_brightness(int *p_brightness) 164771d7fec4Smrg#endif 164871d7fec4Smrg{ 164971d7fec4Smrg if (!p_brightness) 165071d7fec4Smrg return ERR_INVALID_PARAMETER; 165171d7fec4Smrg 165271d7fec4Smrg *p_brightness = d.brightness; 165371d7fec4Smrg 165471d7fec4Smrg return 0; 165571d7fec4Smrg} 165671d7fec4Smrg 165771d7fec4Smrg#if GFX_TV_DYNAMIC 165871d7fec4Smrgint 165971d7fec4Smrgfs450_set_brightness(int brightness) 166071d7fec4Smrg#else 166171d7fec4Smrgint 166271d7fec4Smrggfx_set_brightness(int brightness) 166371d7fec4Smrg#endif 166471d7fec4Smrg{ 166571d7fec4Smrg d.brightness = range_limit(brightness, 0, 100); 166671d7fec4Smrg 166771d7fec4Smrg return write_config(REQ_BRIGHTNESS_CONTRAST); 166871d7fec4Smrg} 166971d7fec4Smrg 167071d7fec4Smrg#if GFX_TV_DYNAMIC 167171d7fec4Smrgint 167271d7fec4Smrgfs450_get_contrast(int *p_contrast) 167371d7fec4Smrg#else 167471d7fec4Smrgint 167571d7fec4Smrggfx_get_contrast(int *p_contrast) 167671d7fec4Smrg#endif 167771d7fec4Smrg{ 167871d7fec4Smrg if (!p_contrast) 167971d7fec4Smrg return ERR_INVALID_PARAMETER; 168071d7fec4Smrg 168171d7fec4Smrg *p_contrast = d.contrast; 168271d7fec4Smrg 168371d7fec4Smrg return 0; 168471d7fec4Smrg} 168571d7fec4Smrg 168671d7fec4Smrg#if GFX_TV_DYNAMIC 168771d7fec4Smrgint 168871d7fec4Smrgfs450_set_contrast(int constrast) 168971d7fec4Smrg#else 169071d7fec4Smrgint 169171d7fec4Smrggfx_set_contrast(int constrast) 169271d7fec4Smrg#endif 169371d7fec4Smrg{ 169471d7fec4Smrg d.contrast = range_limit(constrast, 0, 100); 169571d7fec4Smrg 169671d7fec4Smrg return write_config(REQ_BRIGHTNESS_CONTRAST); 169771d7fec4Smrg} 169871d7fec4Smrg 169971d7fec4Smrg/*==========================================================================*/ 170071d7fec4Smrg/****/ 170171d7fec4Smrg/*// YC filters*/ 170271d7fec4Smrg 170371d7fec4Smrg#if GFX_TV_DYNAMIC 170471d7fec4Smrgint 170571d7fec4Smrgfs450_get_yc_filter(unsigned int *p_yc_filter) 170671d7fec4Smrg#else 170771d7fec4Smrgint 170871d7fec4Smrggfx_get_yc_filter(unsigned int *p_yc_filter) 170971d7fec4Smrg#endif 171071d7fec4Smrg{ 171171d7fec4Smrg if (!p_yc_filter) 171271d7fec4Smrg return ERR_INVALID_PARAMETER; 171371d7fec4Smrg 171471d7fec4Smrg if (houston_Rev() < HOUSTON_REV_B) 171571d7fec4Smrg return ERR_NOT_SUPPORTED; 171671d7fec4Smrg 171771d7fec4Smrg *p_yc_filter = d.yc_filter; 171871d7fec4Smrg 171971d7fec4Smrg return 0; 172071d7fec4Smrg} 172171d7fec4Smrg 172271d7fec4Smrg#if GFX_TV_DYNAMIC 172371d7fec4Smrgint 172471d7fec4Smrgfs450_set_yc_filter(unsigned int yc_filter) 172571d7fec4Smrg#else 172671d7fec4Smrgint 172771d7fec4Smrggfx_set_yc_filter(unsigned int yc_filter) 172871d7fec4Smrg#endif 172971d7fec4Smrg{ 173071d7fec4Smrg if (houston_Rev() < HOUSTON_REV_B) 173171d7fec4Smrg return ERR_NOT_SUPPORTED; 173271d7fec4Smrg 173371d7fec4Smrg /*luma filter. */ 173471d7fec4Smrg if (yc_filter & GFX_LUMA_FILTER) 173571d7fec4Smrg d.yc_filter |= GFX_LUMA_FILTER; 173671d7fec4Smrg else 173771d7fec4Smrg d.yc_filter &= ~GFX_LUMA_FILTER; 173871d7fec4Smrg 173971d7fec4Smrg /*chroma filter. */ 174071d7fec4Smrg if (yc_filter & GFX_CHROMA_FILTER) 174171d7fec4Smrg d.yc_filter |= GFX_CHROMA_FILTER; 174271d7fec4Smrg else 174371d7fec4Smrg d.yc_filter &= ~GFX_CHROMA_FILTER; 174471d7fec4Smrg 174571d7fec4Smrg return write_config(REQ_YC_FILTER); 174671d7fec4Smrg} 174771d7fec4Smrg 174871d7fec4Smrg#if GFX_TV_DYNAMIC 174971d7fec4Smrgint 175071d7fec4Smrgfs450_get_aps_trigger_bits(unsigned int *p_trigger_bits) 175171d7fec4Smrg#else 175271d7fec4Smrgint 175371d7fec4Smrggfx_get_aps_trigger_bits(unsigned int *p_trigger_bits) 175471d7fec4Smrg#endif 175571d7fec4Smrg{ 175671d7fec4Smrg if (!p_trigger_bits) 175771d7fec4Smrg return ERR_INVALID_PARAMETER; 175871d7fec4Smrg 175971d7fec4Smrg *p_trigger_bits = d.aps_trigger_bits; 176071d7fec4Smrg 176171d7fec4Smrg return 0; 176271d7fec4Smrg} 176371d7fec4Smrg 176471d7fec4Smrg#if GFX_TV_DYNAMIC 176571d7fec4Smrgint 176671d7fec4Smrgfs450_set_aps_trigger_bits(unsigned int trigger_bits) 176771d7fec4Smrg#else 176871d7fec4Smrgint 176971d7fec4Smrggfx_set_aps_trigger_bits(unsigned int trigger_bits) 177071d7fec4Smrg#endif 177171d7fec4Smrg{ 177271d7fec4Smrg d.aps_trigger_bits = trigger_bits; 177371d7fec4Smrg 177471d7fec4Smrg return write_config(REQ_MACROVISION); 177571d7fec4Smrg} 177671d7fec4Smrg 177771d7fec4Smrg/*----------------------------------------------------------------------------- 177871d7fec4Smrg * gfx_set_tv_format 177971d7fec4Smrg * 178071d7fec4Smrg * This routine sets the TV encoder registers to the specified format 178171d7fec4Smrg * and resolution. 178271d7fec4Smrg * Currently only NTSC 640x480 is supported. 178371d7fec4Smrg *----------------------------------------------------------------------------- 178471d7fec4Smrg */ 178571d7fec4Smrg#if GFX_TV_DYNAMIC 178671d7fec4Smrgint 178771d7fec4Smrgfs450_set_tv_format(TVStandardType format, GfxOnTVType resolution) 178871d7fec4Smrg#else 178971d7fec4Smrgint 179071d7fec4Smrggfx_set_tv_format(TVStandardType format, GfxOnTVType resolution) 179171d7fec4Smrg#endif 179271d7fec4Smrg{ 179371d7fec4Smrg /* ### ADD ### IMPLEMENTATION */ 179471d7fec4Smrg return (0); 179571d7fec4Smrg} 179671d7fec4Smrg 179771d7fec4Smrg/*----------------------------------------------------------------------------- 179871d7fec4Smrg * gfx_set_tv_output 179971d7fec4Smrg * 180071d7fec4Smrg * This routine sets the TV encoder registers to the specified output type. 180171d7fec4Smrg * Supported output types are : S-VIDEO and Composite. 180271d7fec4Smrg *----------------------------------------------------------------------------- 180371d7fec4Smrg */ 180471d7fec4Smrg#if GFX_TV_DYNAMIC 180571d7fec4Smrgint 180671d7fec4Smrgfs450_set_tv_output(int output) 180771d7fec4Smrg#else 180871d7fec4Smrgint 180971d7fec4Smrggfx_set_tv_output(int output) 181071d7fec4Smrg#endif 181171d7fec4Smrg{ 181271d7fec4Smrg /* ### ADD ### IMPLEMENTATION */ 181371d7fec4Smrg return (0); 181471d7fec4Smrg} 181571d7fec4Smrg 181671d7fec4Smrg/*----------------------------------------------------------------------------- 181771d7fec4Smrg * gfx_set_tv_cc_enable 181871d7fec4Smrg * 181971d7fec4Smrg * This routine enables or disables the use of the hardware CC registers 182071d7fec4Smrg * in the TV encoder. 182171d7fec4Smrg *----------------------------------------------------------------------------- 182271d7fec4Smrg */ 182371d7fec4Smrg#if GFX_TV_DYNAMIC 182471d7fec4Smrgint 182571d7fec4Smrgfs450_set_tv_cc_enable(int enable) 182671d7fec4Smrg#else 182771d7fec4Smrgint 182871d7fec4Smrggfx_set_tv_cc_enable(int enable) 182971d7fec4Smrg#endif 183071d7fec4Smrg{ 183171d7fec4Smrg /* ### ADD ### IMPLEMENTATION */ 183271d7fec4Smrg return (0); 183371d7fec4Smrg} 183471d7fec4Smrg 183571d7fec4Smrg/*----------------------------------------------------------------------------- 183671d7fec4Smrg * gfx_set_tv_cc_data 183771d7fec4Smrg * 183871d7fec4Smrg * This routine writes the two specified characters to the CC data register 183971d7fec4Smrg * of the TV encoder. 184071d7fec4Smrg *----------------------------------------------------------------------------- 184171d7fec4Smrg */ 184271d7fec4Smrg#if GFX_TV_DYNAMIC 184371d7fec4Smrgint 184471d7fec4Smrgfs450_set_tv_cc_data(unsigned char data1, unsigned char data2) 184571d7fec4Smrg#else 184671d7fec4Smrgint 184771d7fec4Smrggfx_set_tv_cc_data(unsigned char data1, unsigned char data2) 184871d7fec4Smrg#endif 184971d7fec4Smrg{ 185071d7fec4Smrg /* ### ADD ### IMPLEMENTATION */ 185171d7fec4Smrg return (0); 185271d7fec4Smrg} 185371d7fec4Smrg 185471d7fec4Smrg#ifdef FS450_DIRECTREG 185571d7fec4Smrg 185671d7fec4Smrg/*//==========================================================================*/ 185771d7fec4Smrg/****/ 185871d7fec4Smrg/*// Direct Read and Write registers*/ 185971d7fec4Smrg 186071d7fec4Smrgint 186171d7fec4SmrgFS450_ReadRegister(S_REG_INFO * p_reg) 186271d7fec4Smrg{ 186371d7fec4Smrg unsigned long tmp; 186471d7fec4Smrg 186571d7fec4Smrg if (PLAL_ReadRegister(p_reg)) 186671d7fec4Smrg return 0; 186771d7fec4Smrg 186871d7fec4Smrg if (SOURCE_HOUSTON == p_reg->source) { 186971d7fec4Smrg switch (p_reg->size) { 187071d7fec4Smrg case 1: 187171d7fec4Smrg case 2: 187271d7fec4Smrg { 187371d7fec4Smrg houston_ReadReg((int)p_reg->offset, &tmp, (int)p_reg->size); 187471d7fec4Smrg p_reg->value = tmp; 187571d7fec4Smrg } 187671d7fec4Smrg return 0; 187771d7fec4Smrg 187871d7fec4Smrg case 4: 187971d7fec4Smrg { 188071d7fec4Smrg houston_ReadReg((unsigned int)p_reg->offset, &tmp, 2); 188171d7fec4Smrg p_reg->value = (tmp << 16); 188271d7fec4Smrg houston_ReadReg((unsigned int)(p_reg->offset + 2), &tmp, 2); 188371d7fec4Smrg p_reg->value |= tmp; 188471d7fec4Smrg } 188571d7fec4Smrg return 0; 188671d7fec4Smrg } 188771d7fec4Smrg } 188871d7fec4Smrg 188971d7fec4Smrg return ERR_INVALID_PARAMETER; 189071d7fec4Smrg} 189171d7fec4Smrg 189271d7fec4Smrgint 189371d7fec4SmrgFS450_WriteRegister(S_REG_INFO * p_reg) 189471d7fec4Smrg{ 189571d7fec4Smrg if (PLAL_WriteRegister(p_reg)) 189671d7fec4Smrg return 0; 189771d7fec4Smrg 189871d7fec4Smrg if (SOURCE_HOUSTON == p_reg->source) { 189971d7fec4Smrg houston_WriteReg((unsigned int)p_reg->offset, p_reg->value, 190071d7fec4Smrg p_reg->size); 190171d7fec4Smrg 190271d7fec4Smrg return 0; 190371d7fec4Smrg } 190471d7fec4Smrg 190571d7fec4Smrg return ERR_INVALID_PARAMETER; 190671d7fec4Smrg} 190771d7fec4Smrg 190871d7fec4Smrg#endif 190971d7fec4Smrg 191071d7fec4Smrg/****/ 191171d7fec4Smrg/*Houston initialization function.*/ 191271d7fec4Smrg/****/ 191371d7fec4Smrgstatic int g_houston_rev = -1; 191471d7fec4Smrg 191571d7fec4Smrgstatic int 191671d7fec4Smrghouston_init(void) 191771d7fec4Smrg{ 191871d7fec4Smrg /*//int errc; */ 191971d7fec4Smrg unsigned long write, read; 192071d7fec4Smrg 192171d7fec4Smrg TRACE(("houston_init()\n")) 192271d7fec4Smrg 192371d7fec4Smrg /*initialize I2C */ 192471d7fec4Smrg /*errc = I2C_init(); 192571d7fec4Smrg * if (errc) 192671d7fec4Smrg * return errc; 192771d7fec4Smrg */ 192871d7fec4Smrg /*Before we begin, we must enable power to the TFT */ 192971d7fec4Smrg read = READ_VID32(CS5530_DISPLAY_CONFIG); 193071d7fec4Smrg read |= CS5530_DCFG_FP_PWR_EN | CS5530_DCFG_FP_DATA_EN; 193171d7fec4Smrg WRITE_VID32(CS5530_DISPLAY_CONFIG, read); 193271d7fec4Smrg 193371d7fec4Smrg /*simple w/r test. */ 193471d7fec4Smrg write = 0x0055; 193571d7fec4Smrg read = 0; 193671d7fec4Smrg 193771d7fec4Smrg houston_WriteReg(HOUSTON_IHO, write, 2); 193871d7fec4Smrg houston_ReadReg(HOUSTON_IHO, &read, 2); 193971d7fec4Smrg if (read != write) { 194071d7fec4Smrg houston_WriteReg(HOUSTON_IHO, write, 2); 194171d7fec4Smrg houston_ReadReg(HOUSTON_IHO, &read, 2); 194271d7fec4Smrg if (read != write) { 194371d7fec4Smrg /*chip is not there, do something appropriate? */ 194471d7fec4Smrg TRACE(("wrote HOUSTON_IHO=0x0055, read 0x%04x\n", read)) 194571d7fec4Smrg return ERR_DEVICE_NOT_FOUND; 194671d7fec4Smrg } 194771d7fec4Smrg } 194871d7fec4Smrg 194971d7fec4Smrg /*read chip revision. */ 195071d7fec4Smrg houston_ReadReg(HOUSTON_REV, &read, 2); 195171d7fec4Smrg g_houston_rev = (int)read; 195271d7fec4Smrg 195371d7fec4Smrg /*ok. */ 195471d7fec4Smrg return 0; 195571d7fec4Smrg} 195671d7fec4Smrg 195771d7fec4Smrgstatic int 195871d7fec4Smrghouston_Rev(void) 195971d7fec4Smrg{ 196071d7fec4Smrg return g_houston_rev; 196171d7fec4Smrg} 196271d7fec4Smrg 196371d7fec4Smrgstatic S_TIMING_SPECS g_specs; 196471d7fec4Smrg 196571d7fec4Smrgstatic const S_TIMING_SPECS * 196671d7fec4Smrgp_specs(void) 196771d7fec4Smrg{ 196871d7fec4Smrg return &g_specs; 196971d7fec4Smrg} 197071d7fec4Smrg 197171d7fec4Smrg/*//==========================================================================*/ 197271d7fec4Smrg/****/ 197371d7fec4Smrg/*FS450 configuration functions.*/ 197471d7fec4Smrg/****/ 197571d7fec4Smrg/*//==========================================================================*/ 197671d7fec4Smrgstatic int 197771d7fec4Smrgconfig_init(void) 197871d7fec4Smrg{ 197971d7fec4Smrg int err; 198071d7fec4Smrg 198171d7fec4Smrg TRACE(("config_init()\n")) 198271d7fec4Smrg 198371d7fec4Smrg err = houston_init(); 198471d7fec4Smrg if (err) 198571d7fec4Smrg return err; 198671d7fec4Smrg 198771d7fec4Smrg return 0; 198871d7fec4Smrg} 198971d7fec4Smrg 199071d7fec4Smrg/*==========================================================================*/ 199171d7fec4Smrg/****/ 199271d7fec4Smrg/*convert word to encoder 10 bit value.*/ 199371d7fec4Smrg 199471d7fec4Smrgstatic unsigned short 199571d7fec4Smrgw10bit2z(unsigned short w) 199671d7fec4Smrg{ 199771d7fec4Smrg return (w >> 2) | ((w & 0x03) << 8); 199871d7fec4Smrg} 199971d7fec4Smrg 200071d7fec4Smrgstatic unsigned short 200171d7fec4Smrgz2w10bit(unsigned short z) 200271d7fec4Smrg{ 200371d7fec4Smrg return (0x03 & (z >> 8)) | ((0xFF & z) << 2); 200471d7fec4Smrg} 200571d7fec4Smrg 200671d7fec4Smrg/*==========================================================================*/ 200771d7fec4Smrg/****/ 200871d7fec4Smrg/*// TV Standards*/ 200971d7fec4Smrg 201071d7fec4Smrgstatic const struct 201171d7fec4Smrg{ 201271d7fec4Smrg unsigned long standard; 201371d7fec4Smrg int tvsetup_index; 201471d7fec4Smrg} 201571d7fec4Smrgg_tv_standards[] = 201671d7fec4Smrg{ 201771d7fec4Smrg { 201871d7fec4Smrg GFX_TV_STANDARD_NTSC_M, 0} 201971d7fec4Smrg , { 202071d7fec4Smrg GFX_TV_STANDARD_NTSC_M_J, 2} 202171d7fec4Smrg , { 202271d7fec4Smrg GFX_TV_STANDARD_PAL_B, 1} 202371d7fec4Smrg , { 202471d7fec4Smrg GFX_TV_STANDARD_PAL_D, 1} 202571d7fec4Smrg , { 202671d7fec4Smrg GFX_TV_STANDARD_PAL_H, 1} 202771d7fec4Smrg , { 202871d7fec4Smrg GFX_TV_STANDARD_PAL_I, 1} 202971d7fec4Smrg , { 203071d7fec4Smrg GFX_TV_STANDARD_PAL_M, 3} 203171d7fec4Smrg , { 203271d7fec4Smrg GFX_TV_STANDARD_PAL_N, 4} 203371d7fec4Smrg , { 203471d7fec4Smrg GFX_TV_STANDARD_PAL_G, 1} 203571d7fec4Smrg,}; 203671d7fec4Smrg 203771d7fec4Smrgstatic int 203871d7fec4Smrgmap_tvstd_to_index(unsigned long tv_std) 203971d7fec4Smrg{ 204071d7fec4Smrg unsigned int i; 204171d7fec4Smrg 204271d7fec4Smrg for (i = 0; i < sizeof(g_tv_standards) / sizeof(*g_tv_standards); i++) { 204371d7fec4Smrg if (tv_std == g_tv_standards[i].standard) 204471d7fec4Smrg return g_tv_standards[i].tvsetup_index; 204571d7fec4Smrg } 204671d7fec4Smrg 204771d7fec4Smrg return -1; 204871d7fec4Smrg} 204971d7fec4Smrg 205071d7fec4Smrgstatic unsigned long 205171d7fec4Smrgsupported_standards(void) 205271d7fec4Smrg{ 205371d7fec4Smrg unsigned long standards = 0; 205471d7fec4Smrg unsigned int i; 205571d7fec4Smrg 205671d7fec4Smrg for (i = 0; i < sizeof(g_tv_standards) / sizeof(*g_tv_standards); i++) { 205771d7fec4Smrg if (g_tv_standards[i].tvsetup_index >= 0) 205871d7fec4Smrg standards |= g_tv_standards[i].standard; 205971d7fec4Smrg } 206071d7fec4Smrg 206171d7fec4Smrg return standards; 206271d7fec4Smrg} 206371d7fec4Smrg 206471d7fec4Smrg/*==========================================================================*/ 206571d7fec4Smrg 206671d7fec4Smrgstatic void 206771d7fec4Smrgconfig_power(int on) 206871d7fec4Smrg{ 206971d7fec4Smrg unsigned long reg; 207071d7fec4Smrg 207171d7fec4Smrg if (houston_Rev() < HOUSTON_REV_B) { 207271d7fec4Smrg /*no power down supported, but still turn of clock in off mode */ 207371d7fec4Smrg if (on) { 207471d7fec4Smrg houston_ReadReg(HOUSTON_CR, ®, 2); 207571d7fec4Smrg reg &= ~(CR_CLKOFF | CR_RESET); 207671d7fec4Smrg houston_WriteReg(HOUSTON_CR, reg, 2); 207771d7fec4Smrg reg |= CR_RESET; 207871d7fec4Smrg houston_WriteReg(HOUSTON_CR, reg, 2); 207971d7fec4Smrg reg &= ~CR_RESET; 208071d7fec4Smrg houston_WriteReg(HOUSTON_CR, reg, 2); 208171d7fec4Smrg } else { 208271d7fec4Smrg houston_ReadReg(HOUSTON_CR, ®, 2); 208371d7fec4Smrg reg |= CR_CLKOFF; 208471d7fec4Smrg houston_WriteReg(HOUSTON_CR, reg, 2); 208571d7fec4Smrg } 208671d7fec4Smrg 208771d7fec4Smrg return; 208871d7fec4Smrg } 208971d7fec4Smrg 209071d7fec4Smrg if (on) { 209171d7fec4Smrg /*!CLKOFF, !COMPOFF, !YCOFF */ 209271d7fec4Smrg /*and reset Houston */ 209371d7fec4Smrg houston_ReadReg(HOUSTON_CR, ®, 2); 209471d7fec4Smrg reg &= ~(CR_CLKOFF | CR_RESET | CR_COMPOFF | CR_YCOFF); 209571d7fec4Smrg houston_WriteReg(HOUSTON_CR, reg, 2); 209671d7fec4Smrg reg |= CR_RESET; 209771d7fec4Smrg houston_WriteReg(HOUSTON_CR, reg, 2); 209871d7fec4Smrg reg &= ~CR_RESET; 209971d7fec4Smrg houston_WriteReg(HOUSTON_CR, reg, 2); 210071d7fec4Smrg 210171d7fec4Smrg /*!GTLIO_PD */ 210271d7fec4Smrg houston_ReadReg(HOUSTON_MISC, ®, 2); 210371d7fec4Smrg reg &= ~MISC_GTLIO_PD; 210471d7fec4Smrg houston_WriteReg(HOUSTON_MISC, reg, 2); 210571d7fec4Smrg } else { 210671d7fec4Smrg /*CLKOFF, COMPOFF, YCOFF */ 210771d7fec4Smrg houston_ReadReg(HOUSTON_CR, ®, 2); 210871d7fec4Smrg reg |= (CR_CLKOFF | CR_COMPOFF | CR_YCOFF); 210971d7fec4Smrg houston_WriteReg(HOUSTON_CR, reg, 2); 211071d7fec4Smrg 211171d7fec4Smrg /*GTLIO_PD */ 211271d7fec4Smrg houston_ReadReg(HOUSTON_MISC, ®, 2); 211371d7fec4Smrg reg |= MISC_GTLIO_PD; 211471d7fec4Smrg houston_WriteReg(HOUSTON_MISC, reg, 2); 211571d7fec4Smrg } 211671d7fec4Smrg} 211771d7fec4Smrg 211871d7fec4Smrg/*==========================================================================*/ 211971d7fec4Smrg/****/ 212071d7fec4Smrg/*// VGA mode*/ 212171d7fec4Smrg 212271d7fec4Smrgstatic void 212371d7fec4Smrgconfig_vga_mode(unsigned long vga_mode) 212471d7fec4Smrg{ 212571d7fec4Smrg /*h_total must be evenly divisible by 32? */ 212671d7fec4Smrg 212771d7fec4Smrg static struct 212871d7fec4Smrg { 212971d7fec4Smrg unsigned long mode; 213071d7fec4Smrg int width; 213171d7fec4Smrg int lines; 213271d7fec4Smrg int h_total; 213371d7fec4Smrg } 213471d7fec4Smrg vgaparams[] = 213571d7fec4Smrg { 213671d7fec4Smrg { 213771d7fec4Smrg GFX_VGA_MODE_640X480, 640, 480, 1056} 213871d7fec4Smrg , { 213971d7fec4Smrg GFX_VGA_MODE_720X487, 720, 487, 1056} 214071d7fec4Smrg , { 214171d7fec4Smrg GFX_VGA_MODE_720X576, 720, 576, 1056} 214271d7fec4Smrg , { 214371d7fec4Smrg GFX_VGA_MODE_800X600, 800, 600, 1056} 214471d7fec4Smrg , { 214571d7fec4Smrg GFX_VGA_MODE_1024X768, 1024, 768, 1344} 214671d7fec4Smrg ,}; 214771d7fec4Smrg 214871d7fec4Smrg unsigned long cr, misc, byp; 214971d7fec4Smrg unsigned int i; 215071d7fec4Smrg 215171d7fec4Smrg g_specs.vga_width = 0; 215271d7fec4Smrg g_specs.vga_lines = 0; 215371d7fec4Smrg g_specs.h_total = 0; 215471d7fec4Smrg 215571d7fec4Smrg for (i = 0; i < sizeof(vgaparams) / sizeof(*vgaparams); i++) { 215671d7fec4Smrg if (vga_mode == vgaparams[i].mode) { 215771d7fec4Smrg g_specs.vga_width = vgaparams[i].width; 215871d7fec4Smrg g_specs.vga_lines = vgaparams[i].lines; 215971d7fec4Smrg g_specs.h_total = vgaparams[i].h_total; 216071d7fec4Smrg break; 216171d7fec4Smrg } 216271d7fec4Smrg } 216371d7fec4Smrg if (!g_specs.h_total) 216471d7fec4Smrg return; 216571d7fec4Smrg 216671d7fec4Smrg /*clock mux decimator and vga dual. */ 216771d7fec4Smrg houston_ReadReg(HOUSTON_CR, &cr, 2); 216871d7fec4Smrg houston_ReadReg(HOUSTON_MISC, &misc, 2); 216971d7fec4Smrg houston_ReadReg(HOUSTON_BYP, &byp, 2); 217071d7fec4Smrg 217171d7fec4Smrg if (vga_mode == GFX_VGA_MODE_1024X768) { 217271d7fec4Smrg /*XGA*/ cr |= CR_UIM_DEC; 217371d7fec4Smrg misc |= MISC_VGACKDIV; 217471d7fec4Smrg byp |= (BYP_HDS_BYPASS | BYP_CAC_BYPASS); 217571d7fec4Smrg } else { 217671d7fec4Smrg /*VGA,SVGA */ 217771d7fec4Smrg cr &= ~CR_UIM_DEC; 217871d7fec4Smrg misc &= ~MISC_VGACKDIV; 217971d7fec4Smrg byp &= ~(BYP_HDS_BYPASS | BYP_CAC_BYPASS); 218071d7fec4Smrg } 218171d7fec4Smrg 218271d7fec4Smrg houston_WriteReg(HOUSTON_CR, cr, 2); 218371d7fec4Smrg houston_WriteReg(HOUSTON_MISC, misc, 2); 218471d7fec4Smrg houston_WriteReg(HOUSTON_BYP, byp, 2); 218571d7fec4Smrg} 218671d7fec4Smrg 218771d7fec4Smrg/*==========================================================================*/ 218871d7fec4Smrg/****/ 218971d7fec4Smrg/*// Write settings for TV standard to device*/ 219071d7fec4Smrg 219171d7fec4Smrgstatic void 219271d7fec4Smrgconfig_tv_std(unsigned long tv_std, unsigned int trigger_bits) 219371d7fec4Smrg{ 219471d7fec4Smrg int k; 219571d7fec4Smrg unsigned short reg34; 219671d7fec4Smrg unsigned long cr, w; 219771d7fec4Smrg unsigned long l; 219871d7fec4Smrg 219971d7fec4Smrg /*verify supported standard. */ 220071d7fec4Smrg k = map_tvstd_to_index(tv_std); 220171d7fec4Smrg if (k < 0) 220271d7fec4Smrg return; 220371d7fec4Smrg 220471d7fec4Smrg /*store tv width and lines */ 220571d7fec4Smrg g_specs.tv_width = tvsetup.tv_width[k]; 220671d7fec4Smrg g_specs.tv_lines = tvsetup.tv_lines[k]; 220771d7fec4Smrg 220871d7fec4Smrg /*houston CR register. */ 220971d7fec4Smrg houston_ReadReg(HOUSTON_CR, &cr, 2); 221071d7fec4Smrg cr &= ~CR_656_PAL_NTSC; 221171d7fec4Smrg cr |= tvsetup.houston_cr[k]; 221271d7fec4Smrg houston_WriteReg(HOUSTON_CR, cr, 2); 221371d7fec4Smrg 221471d7fec4Smrg /*setup the encoder. */ 221571d7fec4Smrg l = tvsetup.chroma_freq[k]; 221671d7fec4Smrg houston_WriteReg(ENC_CHROMA_FREQ, (int)(l & 0x00ff), 1); 221771d7fec4Smrg houston_WriteReg(ENC_CHROMA_FREQ + 1, (int)((l >> 8) & 0x00ff), 1); 221871d7fec4Smrg houston_WriteReg(ENC_CHROMA_FREQ + 2, (int)((l >> 16) & 0x00ff), 1); 221971d7fec4Smrg houston_WriteReg(ENC_CHROMA_FREQ + 3, (int)((l >> 24) & 0x00ff), 1); 222071d7fec4Smrg 222171d7fec4Smrg houston_WriteReg(ENC_CHROMA_PHASE, tvsetup.chroma_phase[k], 1); 222271d7fec4Smrg houston_WriteReg(ENC_REG05, 0x00, 1); /*reg 0x05 */ 222371d7fec4Smrg houston_WriteReg(ENC_REG06, 0x89, 1); /*reg 0x06 */ 222471d7fec4Smrg houston_WriteReg(ENC_REG07, 0x00, 1); /*reg 0x07 */ 222571d7fec4Smrg houston_WriteReg(ENC_HSYNC_WIDTH, tvsetup.hsync_width[k], 1); 222671d7fec4Smrg houston_WriteReg(ENC_BURST_WIDTH, tvsetup.burst_width[k], 1); 222771d7fec4Smrg houston_WriteReg(ENC_BACK_PORCH, tvsetup.back_porch[k], 1); 222871d7fec4Smrg houston_WriteReg(ENC_CB_BURST_LEVEL, tvsetup.cb_burst_level[k], 1); 222971d7fec4Smrg houston_WriteReg(ENC_CR_BURST_LEVEL, tvsetup.cr_burst_level[k], 1); 223071d7fec4Smrg houston_WriteReg(ENC_SLAVE_MODE, 0x01, 1); /*slave mode */ 223171d7fec4Smrg if (trigger_bits == 0) 223271d7fec4Smrg w = w10bit2z(tvsetup.blank_level[k]); /*blank level */ 223371d7fec4Smrg else 223471d7fec4Smrg w = w10bit2z((unsigned short)(tvsetup.blank_level[k] - 223571d7fec4Smrg tvsetup.hamp_offset[k])); 223671d7fec4Smrg houston_WriteReg(ENC_BLANK_LEVEL, w & 0x00ff, 1); 223771d7fec4Smrg houston_WriteReg(ENC_BLANK_LEVEL + 1, w >> 8, 1); 223871d7fec4Smrg w = w10bit2z(tvsetup.tv_lines[k]); /*num_lines */ 223971d7fec4Smrg houston_WriteReg(ENC_NUM_LINES, w & 0x00ff, 1); 224071d7fec4Smrg houston_WriteReg(ENC_NUM_LINES + 1, w >> 8, 1); 224171d7fec4Smrg 224271d7fec4Smrg houston_WriteReg(ENC_TINT, 0x00, 1); /*tint */ 224371d7fec4Smrg houston_WriteReg(ENC_BREEZE_WAY, tvsetup.breeze_way[k], 1); 224471d7fec4Smrg houston_WriteReg(ENC_FRONT_PORCH, tvsetup.front_porch[k], 1); 224571d7fec4Smrg houston_WriteReg(ENC_ACTIVELINE, tvsetup.activeline[k], 1); 224671d7fec4Smrg houston_WriteReg(ENC_FIRST_LINE, 0x15, 1); /*firstvideoline */ 224771d7fec4Smrg reg34 = 224871d7fec4Smrg 0x80 | 224971d7fec4Smrg (tvsetup.pal_mode[k] << 6) | 225071d7fec4Smrg (tvsetup.sys625_50[k] << 3) | 225171d7fec4Smrg (tvsetup.cphase_rst[k] << 1) | (tvsetup.vsync5[k]); 225271d7fec4Smrg houston_WriteReg(ENC_REG34, reg34, 1); /*reg 0x34 */ 225371d7fec4Smrg houston_WriteReg(ENC_SYNC_LEVEL, tvsetup.sync_level[k], 1); 225471d7fec4Smrg if (trigger_bits == 0) 225571d7fec4Smrg w = w10bit2z(tvsetup.vbi_blank_level[k]); /*blank level */ 225671d7fec4Smrg else 225771d7fec4Smrg w = w10bit2z((unsigned short)(tvsetup.vbi_blank_level[k] - 1)); 225871d7fec4Smrg houston_WriteReg(ENC_VBI_BLANK_LEVEL, w & 0x00ff, 1); 225971d7fec4Smrg houston_WriteReg(ENC_VBI_BLANK_LEVEL + 1, w >> 8, 1); 226071d7fec4Smrg} 226171d7fec4Smrg 226271d7fec4Smrgstatic void 226371d7fec4Smrgconget_tv_std(unsigned long *p_tv_standard) 226471d7fec4Smrg{ 226571d7fec4Smrg unsigned long cr; 226671d7fec4Smrg 226771d7fec4Smrg if (!p_tv_standard) 226871d7fec4Smrg return; 226971d7fec4Smrg 227071d7fec4Smrg /*just pick between NTSC and PAL */ 227171d7fec4Smrg houston_ReadReg(HOUSTON_CR, &cr, 2); 227271d7fec4Smrg if (CR_656_PAL_NTSC & cr) 227371d7fec4Smrg *p_tv_standard = GFX_TV_STANDARD_PAL_B; 227471d7fec4Smrg else 227571d7fec4Smrg *p_tv_standard = GFX_TV_STANDARD_NTSC_M; 227671d7fec4Smrg} 227771d7fec4Smrg 227871d7fec4Smrg/*==========================================================================*/ 227971d7fec4Smrg/****/ 228071d7fec4Smrg/*// TVout mode*/ 228171d7fec4Smrg 228271d7fec4Smrgstatic void 228371d7fec4Smrgconfig_tvout_mode(unsigned long tvout_mode) 228471d7fec4Smrg{ 228571d7fec4Smrg unsigned long cr; 228671d7fec4Smrg 228771d7fec4Smrg houston_ReadReg(HOUSTON_CR, &cr, 2); 228871d7fec4Smrg 228971d7fec4Smrg /*all dacs off */ 229071d7fec4Smrg cr |= (CR_COMPOFF | CR_YCOFF); 229171d7fec4Smrg /*not rgb */ 229271d7fec4Smrg cr &= ~CR_OFMT; 229371d7fec4Smrg 229471d7fec4Smrg /*turn on requested output */ 229571d7fec4Smrg if (GFX_TVOUT_MODE_CVBS & tvout_mode) 229671d7fec4Smrg cr &= ~CR_COMPOFF; 229771d7fec4Smrg if (GFX_TVOUT_MODE_YC & tvout_mode) 229871d7fec4Smrg cr &= ~CR_YCOFF; 229971d7fec4Smrg if (GFX_TVOUT_MODE_RGB & tvout_mode) { 230071d7fec4Smrg cr &= ~(CR_COMPOFF | CR_YCOFF); 230171d7fec4Smrg cr |= CR_OFMT; 230271d7fec4Smrg } 230371d7fec4Smrg 230471d7fec4Smrg houston_WriteReg(HOUSTON_CR, cr, 2); 230571d7fec4Smrg} 230671d7fec4Smrg 230771d7fec4Smrgstatic void 230871d7fec4Smrgconget_tvout_mode(unsigned long *p_tvout_mode) 230971d7fec4Smrg{ 231071d7fec4Smrg unsigned long cr; 231171d7fec4Smrg 231271d7fec4Smrg if (!p_tvout_mode) 231371d7fec4Smrg return; 231471d7fec4Smrg 231571d7fec4Smrg houston_ReadReg(HOUSTON_CR, &cr, 2); 231671d7fec4Smrg 231771d7fec4Smrg if (CR_OFMT & cr) 231871d7fec4Smrg *p_tvout_mode = GFX_TVOUT_MODE_RGB; 231971d7fec4Smrg else { 232071d7fec4Smrg *p_tvout_mode = 0; 232171d7fec4Smrg if (!(CR_YCOFF & cr)) 232271d7fec4Smrg *p_tvout_mode |= GFX_TVOUT_MODE_YC; 232371d7fec4Smrg if (!(CR_COMPOFF & cr)) 232471d7fec4Smrg *p_tvout_mode |= GFX_TVOUT_MODE_CVBS; 232571d7fec4Smrg } 232671d7fec4Smrg} 232771d7fec4Smrg 232871d7fec4Smrg/*==========================================================================*/ 232971d7fec4Smrg/****/ 233071d7fec4Smrg/*// Size & Position*/ 233171d7fec4Smrg 233271d7fec4Smrg#define IS_NTSC(tv_std) (tv_std & ( \ 233371d7fec4Smrg GFX_TV_STANDARD_NTSC_M | \ 233471d7fec4Smrg GFX_TV_STANDARD_NTSC_M_J | \ 233571d7fec4Smrg GFX_TV_STANDARD_PAL_M)) 233671d7fec4Smrg#define IS_PAL(tv_std) (tv_std & ( \ 233771d7fec4Smrg GFX_TV_STANDARD_PAL_B | \ 233871d7fec4Smrg GFX_TV_STANDARD_PAL_D | \ 233971d7fec4Smrg GFX_TV_STANDARD_PAL_H | \ 234071d7fec4Smrg GFX_TV_STANDARD_PAL_I | \ 234171d7fec4Smrg GFX_TV_STANDARD_PAL_N | \ 234271d7fec4Smrg GFX_TV_STANDARD_PAL_G)) 234371d7fec4Smrg 234471d7fec4Smrg/*return fifo delay setting for mode, std, and total lines.*/ 234571d7fec4Smrg 234671d7fec4Smrgstatic void 234771d7fec4Smrgget_ffolat_ivo(unsigned long vga_mode, 234871d7fec4Smrg unsigned long tv_std, 234971d7fec4Smrg long i, unsigned short *ffolat, unsigned short *ivo) 235071d7fec4Smrg{ 235171d7fec4Smrg switch (vga_mode) { 235271d7fec4Smrg case GFX_VGA_MODE_640X480: 235371d7fec4Smrg if (IS_NTSC(tv_std)) { 235471d7fec4Smrg if (i > SIZE6X4NTSC - 1) 235571d7fec4Smrg i = SIZE6X4NTSC - 1; 235671d7fec4Smrg *ffolat = ffo6x4ntsc[i].ffolat; 235771d7fec4Smrg *ivo = 0x20; 235871d7fec4Smrg } else { 235971d7fec4Smrg if (i > SIZE6X4PAL - 1) 236071d7fec4Smrg i = SIZE6X4PAL - 1; 236171d7fec4Smrg *ffolat = ffo6x4pal[i].ffolat; 236271d7fec4Smrg *ivo = 0x28; 236371d7fec4Smrg } 236471d7fec4Smrg break; 236571d7fec4Smrg 236671d7fec4Smrg case GFX_VGA_MODE_800X600: 236771d7fec4Smrg if (IS_NTSC(tv_std)) { 236871d7fec4Smrg if (i > SIZE8X6NTSC - 1) 236971d7fec4Smrg i = SIZE8X6NTSC - 1; 237071d7fec4Smrg *ffolat = ffo8x6ntsc[i].ffolat; 237171d7fec4Smrg *ivo = 0x3a; 237271d7fec4Smrg } else { 237371d7fec4Smrg if (i > SIZE8X6PAL - 1) 237471d7fec4Smrg i = SIZE8X6PAL - 1; 237571d7fec4Smrg *ffolat = ffo8x6pal[i].ffolat; 237671d7fec4Smrg *ivo = 0x39; 237771d7fec4Smrg } 237871d7fec4Smrg break; 237971d7fec4Smrg 238071d7fec4Smrg case GFX_VGA_MODE_720X487: 238171d7fec4Smrg *ffolat = 0x40; /*//FFO7x4; */ 238271d7fec4Smrg *ivo = 0x1a; 238371d7fec4Smrg break; 238471d7fec4Smrg 238571d7fec4Smrg case GFX_VGA_MODE_720X576: 238671d7fec4Smrg *ffolat = 0x40; /*//FFO7x5; */ 238771d7fec4Smrg *ivo = 0x1a; 238871d7fec4Smrg break; 238971d7fec4Smrg 239071d7fec4Smrg case GFX_VGA_MODE_1024X768: 239171d7fec4Smrg default: 239271d7fec4Smrg if (IS_NTSC(tv_std)) { 239371d7fec4Smrg if (i > SIZE10X7NTSC - 1) 239471d7fec4Smrg i = SIZE10X7NTSC - 1; 239571d7fec4Smrg *ffolat = ffo10x7ntsc[i].ffolat; 239671d7fec4Smrg *ivo = ffo10x7ntsc[i].ivo; 239771d7fec4Smrg } else { 239871d7fec4Smrg if (i > SIZE10X7PAL - 1) 239971d7fec4Smrg i = SIZE10X7PAL - 1; 240071d7fec4Smrg *ffolat = ffo10x7pal[i].ffolat; 240171d7fec4Smrg *ivo = ffo10x7pal[i].ivo; 240271d7fec4Smrg } 240371d7fec4Smrg break; 240471d7fec4Smrg } 240571d7fec4Smrg} 240671d7fec4Smrg 240771d7fec4Smrg/*get vertical line min and max for mode and std.*/ 240871d7fec4Smrg 240971d7fec4Smrgstatic void 241071d7fec4Smrgget_vtotal_min_max(unsigned long vga_mode, 241171d7fec4Smrg unsigned long tv_std, 241271d7fec4Smrg int *v_total_min, int *v_total_max, int *v_step) 241371d7fec4Smrg{ 241471d7fec4Smrg int k = map_tvstd_to_index(tv_std); 241571d7fec4Smrg 241671d7fec4Smrg switch (vga_mode) { 241771d7fec4Smrg case GFX_VGA_MODE_640X480: 241871d7fec4Smrg if (IS_NTSC(tv_std)) { 241971d7fec4Smrg *v_total_min = ffo6x4ntsc[0].v_total; 242071d7fec4Smrg *v_total_max = ffo6x4ntsc[SIZE6X4NTSC - 1].v_total; 242171d7fec4Smrg } else { 242271d7fec4Smrg *v_total_min = ffo6x4pal[0].v_total; 242371d7fec4Smrg *v_total_max = ffo6x4pal[SIZE6X4PAL - 1].v_total; 242471d7fec4Smrg } 242571d7fec4Smrg *v_step = 4; 242671d7fec4Smrg break; 242771d7fec4Smrg 242871d7fec4Smrg case GFX_VGA_MODE_800X600: 242971d7fec4Smrg if (IS_NTSC(tv_std)) { 243071d7fec4Smrg *v_total_min = ffo8x6ntsc[0].v_total; 243171d7fec4Smrg *v_total_max = ffo8x6ntsc[SIZE8X6NTSC - 1].v_total; 243271d7fec4Smrg } else { 243371d7fec4Smrg *v_total_min = ffo8x6pal[0].v_total; 243471d7fec4Smrg *v_total_max = ffo8x6pal[SIZE8X6PAL - 1].v_total; 243571d7fec4Smrg } 243671d7fec4Smrg *v_step = 5; 243771d7fec4Smrg break; 243871d7fec4Smrg 243971d7fec4Smrg case GFX_VGA_MODE_720X487: 244071d7fec4Smrg case GFX_VGA_MODE_720X576: 244171d7fec4Smrg *v_total_min = tvsetup.tv_lines[k]; 244271d7fec4Smrg *v_total_max = tvsetup.tv_lines[k]; 244371d7fec4Smrg *v_step = 4; 244471d7fec4Smrg break; 244571d7fec4Smrg 244671d7fec4Smrg case GFX_VGA_MODE_1024X768: 244771d7fec4Smrg if (IS_NTSC(tv_std)) { 244871d7fec4Smrg *v_total_min = ffo10x7ntsc[0].v_total; 244971d7fec4Smrg *v_total_max = ffo10x7ntsc[SIZE10X7NTSC - 1].v_total; 245071d7fec4Smrg } else { 245171d7fec4Smrg *v_total_min = ffo10x7pal[0].v_total; 245271d7fec4Smrg *v_total_max = ffo10x7pal[SIZE10X7PAL - 1].v_total; 245371d7fec4Smrg } 245471d7fec4Smrg *v_step = 6; 245571d7fec4Smrg break; 245671d7fec4Smrg } 245771d7fec4Smrg} 245871d7fec4Smrg 245971d7fec4Smrgstatic void 246071d7fec4Smrgconfig_overscan_xy(unsigned long tv_std, 246171d7fec4Smrg unsigned long vga_mode, 246271d7fec4Smrg int overscan_x, int overscan_y, int pos_x, int pos_y) 246371d7fec4Smrg{ 246471d7fec4Smrg unsigned int vga_index; 246571d7fec4Smrg unsigned long reg; 246671d7fec4Smrg double vsc; 246771d7fec4Smrg int k; 246871d7fec4Smrg unsigned short ffolat, ivo; 246971d7fec4Smrg int base_v_total, range, v_offset; 247071d7fec4Smrg int v_total_min, v_total_max, v_step; 247171d7fec4Smrg float r, f; 247271d7fec4Smrg int vga_pixels, pre_pixels; 247371d7fec4Smrg float hscale, hscale_min, hscale_max; 247471d7fec4Smrg int hsc; 247571d7fec4Smrg int iho, iho_max, ihw; 247671d7fec4Smrg 247771d7fec4Smrg /*tv_std is valid. */ 247871d7fec4Smrg k = map_tvstd_to_index(tv_std); 247971d7fec4Smrg 248071d7fec4Smrg /*store tv width and lines */ 248171d7fec4Smrg g_specs.tv_width = tvsetup.tv_width[k]; 248271d7fec4Smrg g_specs.tv_lines = tvsetup.tv_lines[k]; 248371d7fec4Smrg 248471d7fec4Smrg /*determine vga mode index */ 248571d7fec4Smrg for (vga_index = 0; vga_index < SCANTABLE_ENTRIES; vga_index++) { 248671d7fec4Smrg if (scantable[vga_index].mode == vga_mode) 248771d7fec4Smrg break; 248871d7fec4Smrg } 248971d7fec4Smrg if (vga_index >= SCANTABLE_ENTRIES) 249071d7fec4Smrg return; 249171d7fec4Smrg 249271d7fec4Smrg /****/ 249371d7fec4Smrg /*vertical scaling (v_total setup). */ 249471d7fec4Smrg /****/ 249571d7fec4Smrg /*calculate vertical range. */ 249671d7fec4Smrg get_vtotal_min_max(vga_mode, tv_std, &v_total_min, &v_total_max, &v_step); 249771d7fec4Smrg TRACE(("v_total min=%d, max=%d\n", v_total_min, v_total_max)) 249871d7fec4Smrg base_v_total = scantable[vga_index].v_total[k]; 249971d7fec4Smrg range = fsmax(base_v_total - v_total_min, v_total_max - base_v_total); 250071d7fec4Smrg TRACE(("v_total range = %d\n", range)) 250171d7fec4Smrg 250271d7fec4Smrg /*map +/-1000 overscan y into +/-range. */ 250371d7fec4Smrg v_offset = (int)((((float)overscan_y * range) / 1000.f) + .5f); 250471d7fec4Smrg TRACE(("v_offset = %d\n", v_offset)) 250571d7fec4Smrg 250671d7fec4Smrg /*range limit v_total. */ 250771d7fec4Smrg g_specs.v_total = 250871d7fec4Smrg range_limit(base_v_total + v_offset, v_total_min, v_total_max); 250971d7fec4Smrg 251071d7fec4Smrg /*round to calibrated value. */ 251171d7fec4Smrg v_offset = (g_specs.v_total - v_total_min + (v_step / 2)) / v_step; 251271d7fec4Smrg g_specs.v_total = v_total_min + v_offset * v_step; 251371d7fec4Smrg TRACE(("desired v_total=%d\n", g_specs.v_total)) 251471d7fec4Smrg 251571d7fec4Smrg /****/ 251671d7fec4Smrg /*vertical positioning (vsync setup). */ 251771d7fec4Smrg /****/ 251871d7fec4Smrg get_ffolat_ivo(vga_mode, tv_std, v_offset, &ffolat, &ivo); 251971d7fec4Smrg houston_WriteReg(HOUSTON_IVO, ivo, 2); 252071d7fec4Smrg 252171d7fec4Smrg /*scale base sync offset by scaling ratio. */ 252271d7fec4Smrg r = (float)g_specs.v_total / (float)base_v_total; 252371d7fec4Smrg v_offset = (int)(r * (float)scantable[vga_index].v_sync[k]); 252471d7fec4Smrg 252571d7fec4Smrg /*scale ivo. */ 252671d7fec4Smrg f = (float)ivo; 252771d7fec4Smrg v_offset -= (int)(f - f / r); 252871d7fec4Smrg 252971d7fec4Smrg /*compensate for center screen. */ 253071d7fec4Smrg f = (float)tvsetup.tv_active_lines[k] / 2.f; 253171d7fec4Smrg v_offset += (int)(f * r - f); 253271d7fec4Smrg 253371d7fec4Smrg /*calculate vsync. */ 253471d7fec4Smrg g_specs.v_sync = g_specs.v_total - v_offset + pos_y; 253571d7fec4Smrg TRACE(("desired v_total=%d, desired v_sync=%d\n", g_specs.v_total, 253671d7fec4Smrg g_specs.v_sync)) 253771d7fec4Smrg if (g_specs.v_sync < g_specs.vga_lines + 10) { 253871d7fec4Smrg TRACE(("vsync too low\n")) 253971d7fec4Smrg /*//d.v_total += d.vga_lines+10-d.v_sync; */ 254071d7fec4Smrg g_specs.v_sync = g_specs.vga_lines + 10; 254171d7fec4Smrg } else if (g_specs.v_sync > g_specs.v_total - 10) { 254271d7fec4Smrg TRACE(("vsync too high\n")) 254371d7fec4Smrg g_specs.v_sync = g_specs.v_total - 10; 254471d7fec4Smrg } 254571d7fec4Smrg TRACE(("v_total=%d v_sync=%d\n", g_specs.v_total, g_specs.v_sync)) 254671d7fec4Smrg 254771d7fec4Smrg /*FFOLAT. */ 254871d7fec4Smrg houston_WriteReg(HOUSTON_FFO_LAT, ffolat, 2); 254971d7fec4Smrg 255071d7fec4Smrg /*VSC. */ 255171d7fec4Smrg vsc = (65536.0f * 255271d7fec4Smrg (1.0f - (double)g_specs.tv_lines / (double)g_specs.v_total)) + 0.5f; 255371d7fec4Smrg reg = ((unsigned long)-vsc) & 0xffff; 255471d7fec4Smrg TRACE(("vsc=%04x, tv_lines=%d, v_total=%d\n", reg, g_specs.tv_lines, 255571d7fec4Smrg g_specs.v_total)) 255671d7fec4Smrg houston_WriteReg(HOUSTON_VSC, (int)reg, 2); 255771d7fec4Smrg 255871d7fec4Smrg /****/ 255971d7fec4Smrg /*horizontal scaling. */ 256071d7fec4Smrg /****/ 256171d7fec4Smrg 256271d7fec4Smrg /*vga pixels is vga width, except in 1024x768, where it's half that. */ 256371d7fec4Smrg vga_pixels = g_specs.vga_width; 256471d7fec4Smrg if (1024 == vga_pixels) 256571d7fec4Smrg vga_pixels /= 2; 256671d7fec4Smrg 256771d7fec4Smrg /*maximum scaling coefficient is tv_width / vga_pixels */ 256871d7fec4Smrg /*minimum is about 1/2, but that is quite small. arbitrarily set minimum at 75% maximum. */ 256971d7fec4Smrg hscale_max = (720.0f / vga_pixels); 257071d7fec4Smrg hscale_min = fsmax((0.75f * hscale_max), (1.0f - (63.0f / 128.0f))); 257171d7fec4Smrg TRACE(("hscale_min = %u.%u, hscale_max = %u.%u\n", 257271d7fec4Smrg (int)hscale_min, 257371d7fec4Smrg (int)((hscale_min - (int)hscale_min) * 1000), 257471d7fec4Smrg (int)hscale_max, (int)((hscale_max - (int)hscale_max) * 1000))) 257571d7fec4Smrg 257671d7fec4Smrg /*map overscan_x into min to max. */ 257771d7fec4Smrg hscale = 257871d7fec4Smrg hscale_min + ((overscan_x + 1000.0f) / 2000.0f) * (hscale_max - 257971d7fec4Smrg hscale_min); 258071d7fec4Smrg TRACE(("hscale = %u.%u\n", (int)hscale, 258171d7fec4Smrg (int)((hscale - (int)hscale) * 1000))) 258271d7fec4Smrg 258371d7fec4Smrg /*determine hsc where hscale = (1 + hsc/128) */ 258471d7fec4Smrg if (hscale >= 1.0f) 258571d7fec4Smrg hsc = (int)(128.f * (hscale - 1.0f) + .5f); 258671d7fec4Smrg else 258771d7fec4Smrg hsc = (int)(128.f * (hscale - 1.0f) - .5f); 258871d7fec4Smrg TRACE(("hsc = %d\n", hsc)) 258971d7fec4Smrg if (hsc >= 0) 259071d7fec4Smrg houston_WriteReg(HOUSTON_HSC, hsc << 8, 2); 259171d7fec4Smrg else 259271d7fec4Smrg houston_WriteReg(HOUSTON_HSC, hsc & 0xFF, 2); 259371d7fec4Smrg 259471d7fec4Smrg /*recalculate hscale for future formulas */ 259571d7fec4Smrg hscale = 1.0f + (hsc / 128.0f); 259671d7fec4Smrg TRACE(("recalculated hscale = %u.%u\n", (int)hscale, 259771d7fec4Smrg (int)((hscale - (int)hscale) * 1000))) 259871d7fec4Smrg 259971d7fec4Smrg /****/ 260071d7fec4Smrg /*horizontal offset. */ 260171d7fec4Smrg /****/ 260271d7fec4Smrg /*place hsync 40 before halfway from vga_width to htotal */ 260371d7fec4Smrg /*but not less than vga_width + 10 */ 260471d7fec4Smrg g_specs.h_sync = 260571d7fec4Smrg fsmax((g_specs.h_total + g_specs.vga_width) / 2 - 40, 260671d7fec4Smrg g_specs.vga_width + 10); 260771d7fec4Smrg /*also, make it even */ 260871d7fec4Smrg g_specs.h_sync &= ~1; 260971d7fec4Smrg TRACE(("hsync = %u\n", g_specs.h_sync)) 261071d7fec4Smrg 261171d7fec4Smrg /*iho range is 0 to iho_max. */ 261271d7fec4Smrg /*iho_max is 2 * iho_center. */ 261371d7fec4Smrg /*iho_center is pre_pixels - (tvwidth / hscale - vga pixels) / 2. */ 261471d7fec4Smrg /*pre_pixels = (htotal - hsync) * (vga_pixels / vga_width) */ 261571d7fec4Smrg /*note that the range is inverted also, because it specifies the number of pixels */ 261671d7fec4Smrg /*to skip, or subtract. iho=0 maps to farthest right. */ 261771d7fec4Smrg /*map -pos_x = +/-1000 into (0 to iho_max) */ 261871d7fec4Smrg pre_pixels = 261971d7fec4Smrg (int)((long)(g_specs.h_total - g_specs.h_sync) * vga_pixels / 262071d7fec4Smrg g_specs.vga_width); 262171d7fec4Smrg iho_max = (2 * pre_pixels) - ((int)(720.0f / hscale + 0.5f) - vga_pixels); 262271d7fec4Smrg TRACE(("iho_max = %u\n", iho_max)) 262371d7fec4Smrg iho = 262471d7fec4Smrg (int)range_limit(((long)(1000 - pos_x) * iho_max / 2000) + 262571d7fec4Smrg scantable[vga_index].iho[k], 0, iho_max); 262671d7fec4Smrg TRACE(("iho = %u\n", iho)) 262771d7fec4Smrg houston_WriteReg(HOUSTON_IHO, iho, 2); 262871d7fec4Smrg 262971d7fec4Smrg /****/ 263071d7fec4Smrg /*input horizontal width. */ 263171d7fec4Smrg /****/ 263271d7fec4Smrg 263371d7fec4Smrg /*input horizontal width is vga pixels + pre_pixels - iho */ 263471d7fec4Smrg /*additionally, ihw cannot exceed tv width / hscale */ 263571d7fec4Smrg /*and if hsc is negative, (ihw)(-hsc/128) cannot exceed ~250. */ 263671d7fec4Smrg /*and ihw should be even. */ 263771d7fec4Smrg ihw = fsmin(vga_pixels + pre_pixels - iho, (int)(720.0f / hscale)); 263871d7fec4Smrg if (hsc < 0) 263971d7fec4Smrg ihw = (int)fsmin(ihw, 253L * 128 / (-hsc)); 264071d7fec4Smrg ihw &= ~1; 264171d7fec4Smrg TRACE(("ihw = %u\n", ihw)) 264271d7fec4Smrg houston_WriteReg(HOUSTON_IHA, ihw, 2); 264371d7fec4Smrg 264471d7fec4Smrg f = (((float)g_specs.h_total * g_specs.v_total) * 27.f) / 264571d7fec4Smrg ((float)g_specs.tv_width * g_specs.tv_lines); 264671d7fec4Smrg 264771d7fec4Smrg TRACE(("freq=%u.%uMHz\n", (int)f, (int)((f - (int)f) * 1000))) 264871d7fec4Smrg} 264971d7fec4Smrg 265071d7fec4Smrg/*==========================================================================*/ 265171d7fec4Smrg/****/ 265271d7fec4Smrg/*configure houston nco.*/ 265371d7fec4Smrg 265471d7fec4Smrgstatic void 265571d7fec4Smrgconfig_nco(unsigned long tv_std, unsigned long vga_mode) 265671d7fec4Smrg{ 265771d7fec4Smrg unsigned long cr, misc; 265871d7fec4Smrg unsigned long reg; 265971d7fec4Smrg int k = map_tvstd_to_index(tv_std); 266071d7fec4Smrg 266171d7fec4Smrg /*read and store CR. */ 266271d7fec4Smrg houston_ReadReg(HOUSTON_CR, &cr, 2); 266371d7fec4Smrg 266471d7fec4Smrg /*make sure NCO_EN (enable latch) bit is clear */ 266571d7fec4Smrg cr &= ~CR_NCO_EN; 266671d7fec4Smrg houston_WriteReg(HOUSTON_CR, cr, 2); 266771d7fec4Smrg 266871d7fec4Smrg /*clear NCO_LOADX. */ 266971d7fec4Smrg houston_ReadReg(HOUSTON_MISC, &misc, 2); 267071d7fec4Smrg misc &= ~(MISC_NCO_LOAD1 + MISC_NCO_LOAD0); 267171d7fec4Smrg houston_WriteReg(HOUSTON_MISC, misc, 2); 267271d7fec4Smrg 267371d7fec4Smrg if (vga_mode == GFX_VGA_MODE_1024X768) { 267471d7fec4Smrg /*setup for M and N load (Nco_load=1). */ 267571d7fec4Smrg misc |= (MISC_NCO_LOAD0); 267671d7fec4Smrg houston_WriteReg(HOUSTON_MISC, misc, 2); 267771d7fec4Smrg 267871d7fec4Smrg /*M and N. */ 267971d7fec4Smrg houston_WriteReg(HOUSTON_NCONL, 1024 - 2, 2); 268071d7fec4Smrg houston_WriteReg(HOUSTON_NCODL, 128 - 1, 2); 268171d7fec4Smrg 268271d7fec4Smrg /*latch M/N in. */ 268371d7fec4Smrg cr |= CR_NCO_EN; 268471d7fec4Smrg houston_WriteReg(HOUSTON_CR, cr, 2); 268571d7fec4Smrg cr &= ~CR_NCO_EN; 268671d7fec4Smrg houston_WriteReg(HOUSTON_CR, cr, 2); 268771d7fec4Smrg 268871d7fec4Smrg /*setup ncon and ncod load (Nco_load=0). */ 268971d7fec4Smrg misc &= ~(MISC_NCO_LOAD1 + MISC_NCO_LOAD0); 269071d7fec4Smrg houston_WriteReg(HOUSTON_MISC, misc, 2); 269171d7fec4Smrg 269271d7fec4Smrg /*NCON. */ 269371d7fec4Smrg reg = ((unsigned long)g_specs.v_total * g_specs.h_total) / 2; 269471d7fec4Smrg houston_WriteReg(HOUSTON_NCONH, reg >> 16, 2); 269571d7fec4Smrg houston_WriteReg(HOUSTON_NCONL, reg & 0xffff, 2); 269671d7fec4Smrg 269771d7fec4Smrg /*NCOD. */ 269871d7fec4Smrg houston_WriteReg(HOUSTON_NCODL, tvsetup.houston_ncodl[k], 2); 269971d7fec4Smrg houston_WriteReg(HOUSTON_NCODH, tvsetup.houston_ncodh[k], 2); 270071d7fec4Smrg } else { 270171d7fec4Smrg /*setup for M and N load (Nco_load=2). */ 270271d7fec4Smrg misc |= (MISC_NCO_LOAD1); 270371d7fec4Smrg houston_WriteReg(HOUSTON_MISC, misc, 2); 270471d7fec4Smrg 270571d7fec4Smrg /*NCON. */ 270671d7fec4Smrg reg = (unsigned long)g_specs.v_total * g_specs.h_total; 270771d7fec4Smrg houston_WriteReg(HOUSTON_NCONH, reg >> 16, 2); 270871d7fec4Smrg houston_WriteReg(HOUSTON_NCONL, reg & 0xffff, 2); 270971d7fec4Smrg 271071d7fec4Smrg /*NCOD. */ 271171d7fec4Smrg houston_WriteReg(HOUSTON_NCODL, tvsetup.houston_ncodl[k], 2); 271271d7fec4Smrg houston_WriteReg(HOUSTON_NCODH, tvsetup.houston_ncodh[k], 2); 271371d7fec4Smrg 271471d7fec4Smrg TRACE(("NCON = %lu (0x%08lx), NCOD = %lu (0x%08lx)\n", 271571d7fec4Smrg reg, 271671d7fec4Smrg reg, 271771d7fec4Smrg ((unsigned long)tvsetup.houston_ncodh[k] << 16) + 271871d7fec4Smrg tvsetup.houston_ncodl[k], 271971d7fec4Smrg ((unsigned long)tvsetup.houston_ncodh[k] << 16) + 272071d7fec4Smrg tvsetup.houston_ncodl[k])) 272171d7fec4Smrg } 272271d7fec4Smrg 272371d7fec4Smrg /*latch M/N and NCON/NCOD in. */ 272471d7fec4Smrg cr |= CR_NCO_EN; 272571d7fec4Smrg houston_WriteReg(HOUSTON_CR, cr, 2); 272671d7fec4Smrg cr &= ~CR_NCO_EN; 272771d7fec4Smrg houston_WriteReg(HOUSTON_CR, cr, 2); 272871d7fec4Smrg} 272971d7fec4Smrg 273071d7fec4Smrg/*==========================================================================*/ 273171d7fec4Smrg/****/ 273271d7fec4Smrg/*// Write sharpness settings to device*/ 273371d7fec4Smrg 273471d7fec4Smrgstatic void 273571d7fec4Smrgconfig_sharpness(int sharpness) 273671d7fec4Smrg{ 273771d7fec4Smrg unsigned int shp; 273871d7fec4Smrg 273971d7fec4Smrg /*map 0-1000 to 0-20. */ 274071d7fec4Smrg shp = (unsigned int)(0.5f + ((float)sharpness * 20.0f / 1000.0f)); 274171d7fec4Smrg shp = range_limit(shp, 0, 20); 274271d7fec4Smrg 274371d7fec4Smrg houston_WriteReg(HOUSTON_SHP, shp, 2); 274471d7fec4Smrg} 274571d7fec4Smrg 274671d7fec4Smrgstatic void 274771d7fec4Smrgconget_sharpness(int *p_sharpness) 274871d7fec4Smrg{ 274971d7fec4Smrg unsigned long shp; 275071d7fec4Smrg 275171d7fec4Smrg if (!p_sharpness) 275271d7fec4Smrg return; 275371d7fec4Smrg 275471d7fec4Smrg houston_ReadReg(HOUSTON_SHP, &shp, 2); 275571d7fec4Smrg 275671d7fec4Smrg /*map 0-20 to 0-1000. */ 275771d7fec4Smrg *p_sharpness = (int)(0.5f + ((float)shp * 1000.0f / 20.0f)); 275871d7fec4Smrg} 275971d7fec4Smrg 276071d7fec4Smrg/*==========================================================================*/ 276171d7fec4Smrg/****/ 276271d7fec4Smrg/*// Write flicker settings to device*/ 276371d7fec4Smrg 276471d7fec4Smrgstatic void 276571d7fec4Smrgconfig_flicker(int flicker) 276671d7fec4Smrg{ 276771d7fec4Smrg unsigned int flk; 276871d7fec4Smrg 276971d7fec4Smrg /*map 0-1000 to 0-16. */ 277071d7fec4Smrg flk = (unsigned int)(0.5f + ((float)flicker * 16.0f / 1000.0f)); 277171d7fec4Smrg flk = range_limit(flk, 0, 16); 277271d7fec4Smrg 277371d7fec4Smrg houston_WriteReg(HOUSTON_FLK, flk, 2); 277471d7fec4Smrg} 277571d7fec4Smrg 277671d7fec4Smrgstatic void 277771d7fec4Smrgconget_flicker(int *p_flicker) 277871d7fec4Smrg{ 277971d7fec4Smrg unsigned long flk; 278071d7fec4Smrg 278171d7fec4Smrg if (!p_flicker) 278271d7fec4Smrg return; 278371d7fec4Smrg 278471d7fec4Smrg houston_ReadReg(HOUSTON_FLK, &flk, 2); 278571d7fec4Smrg 278671d7fec4Smrg /*map 0-16 to 0-1000. */ 278771d7fec4Smrg *p_flicker = (int)(0.5f + ((float)flk * 1000.0f / 16.0f)); 278871d7fec4Smrg} 278971d7fec4Smrg 279071d7fec4Smrg/*==========================================================================*/ 279171d7fec4Smrg/****/ 279271d7fec4Smrg/*// Write color settings to device*/ 279371d7fec4Smrg 279471d7fec4Smrgstatic void 279571d7fec4Smrgconfig_color(int color) 279671d7fec4Smrg{ 279771d7fec4Smrg unsigned long clr; 279871d7fec4Smrg 279971d7fec4Smrg /*map 0-100 to 0-255. */ 280071d7fec4Smrg /*montreal production test needs 169 to be mappable, so */ 280171d7fec4Smrg /*use .8 rounding factor, 169=(int)(66.*2.55+.8). */ 280271d7fec4Smrg clr = (unsigned long)(0.8f + ((float)color * 255.0f / 100.0f)); 280371d7fec4Smrg clr = range_limit(clr, 0, 255); 280471d7fec4Smrg 280571d7fec4Smrg houston_WriteReg(ENC_CR_GAIN, clr, 1); 280671d7fec4Smrg houston_WriteReg(ENC_CB_GAIN, clr, 1); 280771d7fec4Smrg} 280871d7fec4Smrg 280971d7fec4Smrgstatic void 281071d7fec4Smrgconget_color(int *p_color) 281171d7fec4Smrg{ 281271d7fec4Smrg unsigned long cr_gain; 281371d7fec4Smrg 281471d7fec4Smrg if (!p_color) 281571d7fec4Smrg return; 281671d7fec4Smrg 281771d7fec4Smrg /*just get CR GAIN, CB GAIN should match. */ 281871d7fec4Smrg houston_ReadReg(ENC_CR_GAIN, &cr_gain, 1); 281971d7fec4Smrg 282071d7fec4Smrg /*map 0-255 to 0-100. */ 282171d7fec4Smrg *p_color = (int)(0.5f + ((float)cr_gain * 100.0f / 255.0f)); 282271d7fec4Smrg} 282371d7fec4Smrg 282471d7fec4Smrg/*==========================================================================*/ 282571d7fec4Smrg/****/ 282671d7fec4Smrg/*// Write brightness and contrast settings to device*/ 282771d7fec4Smrg 282871d7fec4Smrg#define NTSC_BLANK_LEVEL 240 282971d7fec4Smrg 283071d7fec4Smrgstatic const int min_black_level = NTSC_BLANK_LEVEL + 1; 283171d7fec4Smrgstatic const int max_white_level = 1023; 283271d7fec4Smrg 283371d7fec4Smrgstatic void 283471d7fec4Smrgconfig_brightness_contrast(unsigned long tv_std, unsigned int trigger_bits, 283571d7fec4Smrg int brightness, int contrast) 283671d7fec4Smrg{ 283771d7fec4Smrg int brightness_off; 283871d7fec4Smrg float contrast_mult; 283971d7fec4Smrg int black, white; 284071d7fec4Smrg unsigned short w; 284171d7fec4Smrg int k = map_tvstd_to_index(tv_std); 284271d7fec4Smrg 284371d7fec4Smrg /*0-100 maps to +/-220. */ 284471d7fec4Smrg brightness_off = (int)(0.5f + ((float)brightness * 440.0f / 100.0f)) - 220; 284571d7fec4Smrg 284671d7fec4Smrg /*0-100 maps to .75-1.25. */ 284771d7fec4Smrg contrast_mult = ((float)contrast * 0.5f / 100.0f) + 0.75f; 284871d7fec4Smrg 284971d7fec4Smrg black = tvsetup.black_level[k]; 285071d7fec4Smrg if (trigger_bits != 0) 285171d7fec4Smrg black -= tvsetup.hamp_offset[k]; 285271d7fec4Smrg 285371d7fec4Smrg white = tvsetup.white_level[k]; 285471d7fec4Smrg if (trigger_bits != 0) 285571d7fec4Smrg white -= tvsetup.hamp_offset[k]; 285671d7fec4Smrg 285771d7fec4Smrg black = (int)((float)(black + brightness_off) * contrast_mult); 285871d7fec4Smrg white = (int)((float)(white + brightness_off) * contrast_mult); 285971d7fec4Smrg if (black < min_black_level) 286071d7fec4Smrg black = min_black_level; 286171d7fec4Smrg if (white > max_white_level) 286271d7fec4Smrg white = max_white_level; 286371d7fec4Smrg 286471d7fec4Smrg w = w10bit2z((unsigned short)black); 286571d7fec4Smrg houston_WriteReg(ENC_BLACK_LEVEL, w & 0x00ff, 1); 286671d7fec4Smrg houston_WriteReg(ENC_BLACK_LEVEL + 1, w >> 8, 1); 286771d7fec4Smrg w = w10bit2z((unsigned short)white); 286871d7fec4Smrg houston_WriteReg(ENC_WHITE_LEVEL, w & 0x00ff, 1); 286971d7fec4Smrg houston_WriteReg(ENC_WHITE_LEVEL + 1, w >> 8, 1); 287071d7fec4Smrg} 287171d7fec4Smrg 287271d7fec4Smrgstatic void 287371d7fec4Smrgconget_brightness_contrast(unsigned long tv_std, unsigned int trigger_bits, 287471d7fec4Smrg int *p_brightness, int *p_contrast) 287571d7fec4Smrg{ 287671d7fec4Smrg int brightness_off; 287771d7fec4Smrg float contrast_mult; 287871d7fec4Smrg unsigned short black, white; 287971d7fec4Smrg unsigned long zh, zl; 288071d7fec4Smrg int k; 288171d7fec4Smrg 288271d7fec4Smrg if (!p_brightness || !p_contrast) 288371d7fec4Smrg return; 288471d7fec4Smrg 288571d7fec4Smrg k = map_tvstd_to_index(tv_std); 288671d7fec4Smrg 288771d7fec4Smrg houston_ReadReg(ENC_BLACK_LEVEL, &zl, 1); 288871d7fec4Smrg houston_ReadReg(ENC_BLACK_LEVEL + 1, &zh, 1); 288971d7fec4Smrg black = z2w10bit((unsigned short)(zl + (zh << 8))); 289071d7fec4Smrg if (trigger_bits != 0) 289171d7fec4Smrg black += tvsetup.hamp_offset[k]; 289271d7fec4Smrg houston_ReadReg(ENC_WHITE_LEVEL, &zl, 1); 289371d7fec4Smrg houston_ReadReg(ENC_WHITE_LEVEL + 1, &zh, 1); 289471d7fec4Smrg white = z2w10bit((unsigned short)(zl + (zh << 8))); 289571d7fec4Smrg if (trigger_bits != 0) 289671d7fec4Smrg white += tvsetup.hamp_offset[k]; 289771d7fec4Smrg 289871d7fec4Smrg /*this reverse computation does not account for clipping, but should */ 289971d7fec4Smrg /*provide somewhat reasonable numbers */ 290071d7fec4Smrg contrast_mult = 290171d7fec4Smrg ((float)white - (float)black) / ((float)tvsetup.white_level[k] - 290271d7fec4Smrg (float)tvsetup.black_level[k]); 290371d7fec4Smrg brightness_off = 290471d7fec4Smrg (int)(((float)black / contrast_mult) - tvsetup.black_level[k]); 290571d7fec4Smrg 290671d7fec4Smrg /*+/-220 maps to 0-100. */ 290771d7fec4Smrg *p_brightness = 290871d7fec4Smrg range_limit((int) 290971d7fec4Smrg (0.5f + 291071d7fec4Smrg ((float)(brightness_off + 220) * 100.0f / 440.0f)), 0, 291171d7fec4Smrg 100); 291271d7fec4Smrg 291371d7fec4Smrg /*.75-1.25 maps to 0-100. */ 291471d7fec4Smrg *p_contrast = 291571d7fec4Smrg range_limit((int) 291671d7fec4Smrg (0.5f + 291771d7fec4Smrg ((float)(contrast_mult - 0.75f) * 100.0f / 0.5f)), 0, 291871d7fec4Smrg 100); 291971d7fec4Smrg} 292071d7fec4Smrg 292171d7fec4Smrg/*==========================================================================*/ 292271d7fec4Smrg/****/ 292371d7fec4Smrg/*configure luma/chroma filters.*/ 292471d7fec4Smrg 292571d7fec4Smrgstatic void 292671d7fec4Smrgconfig_yc_filter(unsigned long tv_std, int luma_filter, int chroma_filter) 292771d7fec4Smrg{ 292871d7fec4Smrg unsigned long reg, reg07, reg34; 292971d7fec4Smrg 293071d7fec4Smrg if (houston_Rev() < HOUSTON_REV_B) 293171d7fec4Smrg return; 293271d7fec4Smrg 293371d7fec4Smrg /*luma filter. */ 293471d7fec4Smrg if (luma_filter) 293571d7fec4Smrg reg = tvsetup.notch_filter[map_tvstd_to_index(tv_std)]; 293671d7fec4Smrg else 293771d7fec4Smrg reg = 0; 293871d7fec4Smrg houston_WriteReg(ENC_NOTCH_FILTER, reg, 1); 293971d7fec4Smrg 294071d7fec4Smrg /*chroma filter. */ 294171d7fec4Smrg houston_ReadReg(ENC_REG07, ®07, 1); 294271d7fec4Smrg houston_ReadReg(ENC_REG34, ®34, 1); 294371d7fec4Smrg if (chroma_filter) { 294471d7fec4Smrg reg07 &= ~0x08; 294571d7fec4Smrg reg34 &= ~0x20; 294671d7fec4Smrg } else { 294771d7fec4Smrg reg07 |= 0x08; 294871d7fec4Smrg reg34 |= 0x20; 294971d7fec4Smrg } 295071d7fec4Smrg houston_WriteReg(ENC_REG07, reg07, 1); 295171d7fec4Smrg houston_WriteReg(ENC_REG34, reg34, 1); 295271d7fec4Smrg} 295371d7fec4Smrg 295471d7fec4Smrgstatic void 295571d7fec4Smrgconget_yc_filter(int *p_luma_filter, int *p_chroma_filter) 295671d7fec4Smrg{ 295771d7fec4Smrg unsigned long reg, reg07, reg34; 295871d7fec4Smrg 295971d7fec4Smrg if (!p_luma_filter || !p_chroma_filter) 296071d7fec4Smrg return; 296171d7fec4Smrg 296271d7fec4Smrg if (houston_Rev() < HOUSTON_REV_B) { 296371d7fec4Smrg *p_luma_filter = 0; 296471d7fec4Smrg *p_chroma_filter = 0; 296571d7fec4Smrg return; 296671d7fec4Smrg } 296771d7fec4Smrg 296871d7fec4Smrg /*luma filter. */ 296971d7fec4Smrg houston_ReadReg(ENC_NOTCH_FILTER, ®, 1); 297071d7fec4Smrg *p_luma_filter = (reg ? 1 : 0); 297171d7fec4Smrg 297271d7fec4Smrg /*chroma filter. */ 297371d7fec4Smrg houston_ReadReg(ENC_REG07, ®07, 1); 297471d7fec4Smrg houston_ReadReg(ENC_REG34, ®34, 1); 297571d7fec4Smrg *p_chroma_filter = !((0x08 & reg07) || (0x20 & reg34)); 297671d7fec4Smrg} 297771d7fec4Smrg 297871d7fec4Smrg/*==========================================================================*/ 297971d7fec4Smrg/****/ 298071d7fec4Smrg/*// Macrovision*/ 298171d7fec4Smrg 298271d7fec4Smrgstatic void 298371d7fec4Smrgconfig_macrovision(unsigned long tv_std, unsigned int trigger_bits) 298471d7fec4Smrg{ 298571d7fec4Smrg/****/ 298671d7fec4Smrg/*Constants to index into mvsetup columns.*/ 298771d7fec4Smrg/****/ 298871d7fec4Smrg#define nNTSC_APS00 0 /*ntsc mv off. */ 298971d7fec4Smrg#define nNTSC_APS01 1 /*ntsc AGC only. */ 299071d7fec4Smrg#define nNTSC_APS10 2 /*ntsc AGC + 2-line CS. */ 299171d7fec4Smrg#define nNTSC_APS11 3 /*ntsc AGC + 4-line CS. */ 299271d7fec4Smrg#define nPAL_APS00 4 /*pal mv off. */ 299371d7fec4Smrg#define nPAL_APSXX 5 /*pal mv on. */ 299471d7fec4Smrg#define nMVModes 6 299571d7fec4Smrg 299671d7fec4Smrg/****/ 299771d7fec4Smrg/*Macrovision setup table.*/ 299871d7fec4Smrg/****/ 299971d7fec4Smrg static const struct mvparms 300071d7fec4Smrg { 300171d7fec4Smrg unsigned short n0[nMVModes]; 300271d7fec4Smrg unsigned short n1[nMVModes]; 300371d7fec4Smrg unsigned short n2[nMVModes]; 300471d7fec4Smrg unsigned short n3[nMVModes]; 300571d7fec4Smrg unsigned short n4[nMVModes]; 300671d7fec4Smrg unsigned short n5[nMVModes]; 300771d7fec4Smrg unsigned short n6[nMVModes]; 300871d7fec4Smrg unsigned short n7[nMVModes]; 300971d7fec4Smrg unsigned short n8[nMVModes]; 301071d7fec4Smrg unsigned short n9[nMVModes]; 301171d7fec4Smrg unsigned short n10[nMVModes]; 301271d7fec4Smrg unsigned short n11[nMVModes]; 301371d7fec4Smrg unsigned short n12[nMVModes]; 301471d7fec4Smrg unsigned short n13[nMVModes]; 301571d7fec4Smrg unsigned short n14[nMVModes]; 301671d7fec4Smrg unsigned short n15[nMVModes]; 301771d7fec4Smrg unsigned short n16[nMVModes]; 301871d7fec4Smrg unsigned short n17[nMVModes]; 301971d7fec4Smrg unsigned short n18[nMVModes]; 302071d7fec4Smrg unsigned short n19[nMVModes]; 302171d7fec4Smrg unsigned short n20[nMVModes]; 302271d7fec4Smrg unsigned short n21[nMVModes]; 302371d7fec4Smrg unsigned short n22[nMVModes]; 302471d7fec4Smrg unsigned short agc_pulse_level[nMVModes]; 302571d7fec4Smrg unsigned short bp_pulse_level[nMVModes]; 302671d7fec4Smrg } 302771d7fec4Smrg 302871d7fec4Smrg mvsetup = 302971d7fec4Smrg { /*// ntsc ntsc ntsc ntsc pal pal */ 303071d7fec4Smrg /*// MV AGC AGC + AGC + MV MV */ 303171d7fec4Smrg /*// off. only 2-line 4-line off. on. */ 303271d7fec4Smrg /*// CS. CS. */ 303371d7fec4Smrg { 303471d7fec4Smrg 0x00, 0x36, 0x3e, 0x3e, 0x00, 0x3e} 303571d7fec4Smrg , /*n0 */ 303671d7fec4Smrg { 303771d7fec4Smrg 0x1d, 0x1d, 0x1d, 0x17, 0x1a, 0x1a} 303871d7fec4Smrg , /*n1 */ 303971d7fec4Smrg { 304071d7fec4Smrg 0x11, 0x11, 0x11, 0x15, 0x22, 0x22} 304171d7fec4Smrg , /*n2 */ 304271d7fec4Smrg { 304371d7fec4Smrg 0x25, 0x25, 0x25, 0x21, 0x2a, 0x2a} 304471d7fec4Smrg , /*n3 */ 304571d7fec4Smrg { 304671d7fec4Smrg 0x11, 0x11, 0x11, 0x15, 0x22, 0x22} 304771d7fec4Smrg , /*n4 */ 304871d7fec4Smrg { 304971d7fec4Smrg 0x01, 0x01, 0x01, 0x05, 0x05, 0x05} 305071d7fec4Smrg , /*n5 */ 305171d7fec4Smrg { 305271d7fec4Smrg 0x07, 0x07, 0x07, 0x05, 0x02, 0x02} 305371d7fec4Smrg , /*n6 */ 305471d7fec4Smrg { 305571d7fec4Smrg 0x00, 0x00, 0x00, 0x02, 0x00, 0x00} 305671d7fec4Smrg , /*n7 */ 305771d7fec4Smrg { 305871d7fec4Smrg 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c} 305971d7fec4Smrg , /*n8 */ 306071d7fec4Smrg { 306171d7fec4Smrg 0x1b, 0x1b, 0x1b, 0x1b, 0x3d, 0x3d} 306271d7fec4Smrg , /*n9 */ 306371d7fec4Smrg { 306471d7fec4Smrg 0x24, 0x24, 0x24, 0x24, 0x14, 0x14} 306571d7fec4Smrg , /*n10 */ 306671d7fec4Smrg { 306771d7fec4Smrg 0x780f, 0x780f, 0x780f, 0x780f, 0x7e07, 0x7e07} 306871d7fec4Smrg , /*n11 */ 306971d7fec4Smrg { 307071d7fec4Smrg 0x0000, 0x0000, 0x0000, 0x0000, 0x5402, 0x5402} 307171d7fec4Smrg , /*n12 */ 307271d7fec4Smrg { 307371d7fec4Smrg 0x0f, 0x0f, 0x0f, 0x0f, 0xfe, 0xfe} 307471d7fec4Smrg , /*n13 */ 307571d7fec4Smrg { 307671d7fec4Smrg 0x0f, 0x0f, 0x0f, 0x0f, 0x7e, 0x7e} 307771d7fec4Smrg , /*n14 */ 307871d7fec4Smrg { 307971d7fec4Smrg 0x60, 0x60, 0x60, 0x60, 0x60, 0x60} 308071d7fec4Smrg , /*n15 */ 308171d7fec4Smrg { 308271d7fec4Smrg 0x01, 0x01, 0x01, 0x01, 0x00, 0x00} 308371d7fec4Smrg , /*n16 */ 308471d7fec4Smrg { 308571d7fec4Smrg 0x0a, 0x0a, 0x0a, 0x0a, 0x08, 0x08} 308671d7fec4Smrg , /*n17 */ 308771d7fec4Smrg { 308871d7fec4Smrg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 308971d7fec4Smrg , /*n18 */ 309071d7fec4Smrg { 309171d7fec4Smrg 0x05, 0x05, 0x05, 0x05, 0x04, 0x04} 309271d7fec4Smrg , /*n19 */ 309371d7fec4Smrg { 309471d7fec4Smrg 0x04, 0x04, 0x04, 0x04, 0x07, 0x07} 309571d7fec4Smrg , /*n20 */ 309671d7fec4Smrg { 309771d7fec4Smrg 0x03ff, 0x03ff, 0x03ff, 0x03ff, 0x0155, 0x0155} 309871d7fec4Smrg , /*n21 */ 309971d7fec4Smrg { 310071d7fec4Smrg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 310171d7fec4Smrg , /*n22 */ 310271d7fec4Smrg { 310371d7fec4Smrg 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3} 310471d7fec4Smrg , /*agc_pulse_level */ 310571d7fec4Smrg { 310671d7fec4Smrg 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8} 310771d7fec4Smrg , /*bp_pulse_level */ 310871d7fec4Smrg }; 310971d7fec4Smrg 311071d7fec4Smrg int nMode; 311171d7fec4Smrg unsigned long misc; 311271d7fec4Smrg unsigned short n0; 311371d7fec4Smrg 311471d7fec4Smrg trigger_bits &= 0x3; 311571d7fec4Smrg 311671d7fec4Smrg /*Determine the OEM Macrovision Program Mode and Register 0 Data. */ 311771d7fec4Smrg if (IS_NTSC(tv_std)) { 311871d7fec4Smrg /*NTSC TV Standard. */ 311971d7fec4Smrg if (trigger_bits == 0) { 312071d7fec4Smrg /*turn Macrovision OFF. */ 312171d7fec4Smrg nMode = nNTSC_APS00; 312271d7fec4Smrg } else if (trigger_bits == 1) { 312371d7fec4Smrg /*AGC Only. */ 312471d7fec4Smrg nMode = nNTSC_APS01; 312571d7fec4Smrg } else if (trigger_bits == 2) { 312671d7fec4Smrg /*AGC + 2-line CS. */ 312771d7fec4Smrg nMode = nNTSC_APS10; 312871d7fec4Smrg } else { 312971d7fec4Smrg /*AGC + 4-line CS. */ 313071d7fec4Smrg nMode = nNTSC_APS11; 313171d7fec4Smrg } 313271d7fec4Smrg } else { 313371d7fec4Smrg /*PAL TV Standard. */ 313471d7fec4Smrg if (trigger_bits == 0) { 313571d7fec4Smrg /*turn Macrovision OFF. */ 313671d7fec4Smrg nMode = nPAL_APS00; 313771d7fec4Smrg } else { 313871d7fec4Smrg /*APS 01, 10, or 11. */ 313971d7fec4Smrg nMode = nPAL_APSXX; 314071d7fec4Smrg } 314171d7fec4Smrg } 314271d7fec4Smrg 314371d7fec4Smrg /*Retrieve the Macrovision Program Mode Data */ 314471d7fec4Smrg if (tv_std != GFX_TV_STANDARD_PAL_M) 314571d7fec4Smrg n0 = mvsetup.n0[nMode]; 314671d7fec4Smrg else { 314771d7fec4Smrg /*PAL-M sets up like NTSC except for n0. */ 314871d7fec4Smrg if ((trigger_bits & 0x03) == 0) 314971d7fec4Smrg n0 = mvsetup.n0[nPAL_APS00]; 315071d7fec4Smrg else 315171d7fec4Smrg n0 = mvsetup.n0[nPAL_APSXX]; 315271d7fec4Smrg } 315371d7fec4Smrg 315471d7fec4Smrg /*download settings now. */ 315571d7fec4Smrg houston_WriteReg(MV_N0, n0, 1); 315671d7fec4Smrg houston_WriteReg(MV_N1, mvsetup.n1[nMode], 1); 315771d7fec4Smrg houston_WriteReg(MV_N2, mvsetup.n2[nMode], 1); 315871d7fec4Smrg houston_WriteReg(MV_N3, mvsetup.n3[nMode], 1); 315971d7fec4Smrg houston_WriteReg(MV_N4, mvsetup.n4[nMode], 1); 316071d7fec4Smrg houston_WriteReg(MV_N5, mvsetup.n5[nMode], 1); 316171d7fec4Smrg houston_WriteReg(MV_N6, mvsetup.n6[nMode], 1); 316271d7fec4Smrg houston_WriteReg(MV_N7, mvsetup.n7[nMode], 1); 316371d7fec4Smrg houston_WriteReg(MV_N8, mvsetup.n8[nMode], 1); 316471d7fec4Smrg houston_WriteReg(MV_N9, mvsetup.n9[nMode], 1); 316571d7fec4Smrg houston_WriteReg(MV_N10, mvsetup.n10[nMode], 1); 316671d7fec4Smrg houston_WriteReg(MV_N11, mvsetup.n11[nMode] & 0xff, 1); 316771d7fec4Smrg houston_WriteReg(MV_N11 + 1, mvsetup.n11[nMode] >> 8, 1); 316871d7fec4Smrg houston_WriteReg(MV_N12, mvsetup.n12[nMode] & 0xff, 1); 316971d7fec4Smrg houston_WriteReg(MV_N12 + 1, mvsetup.n12[nMode] >> 8, 1); 317071d7fec4Smrg houston_WriteReg(MV_N13, mvsetup.n13[nMode], 1); 317171d7fec4Smrg houston_WriteReg(MV_N14, mvsetup.n14[nMode], 1); 317271d7fec4Smrg houston_WriteReg(MV_N15, mvsetup.n15[nMode], 1); 317371d7fec4Smrg houston_WriteReg(MV_N16, mvsetup.n16[nMode], 1); 317471d7fec4Smrg houston_WriteReg(MV_N17, mvsetup.n17[nMode], 1); 317571d7fec4Smrg houston_WriteReg(MV_N18, mvsetup.n18[nMode], 1); 317671d7fec4Smrg houston_WriteReg(MV_N19, mvsetup.n19[nMode], 1); 317771d7fec4Smrg houston_WriteReg(MV_N20, mvsetup.n20[nMode], 1); 317871d7fec4Smrg houston_WriteReg(MV_N21, mvsetup.n21[nMode] & 0xff, 1); 317971d7fec4Smrg houston_WriteReg(MV_N21 + 1, mvsetup.n21[nMode] >> 8, 1); 318071d7fec4Smrg houston_WriteReg(MV_N22, mvsetup.n22[nMode], 1); 318171d7fec4Smrg houston_WriteReg(MV_AGC_PULSE_LEVEL, mvsetup.agc_pulse_level[nMode], 1); 318271d7fec4Smrg houston_WriteReg(MV_BP_PULSE_LEVEL, mvsetup.bp_pulse_level[nMode], 1); 318371d7fec4Smrg 318471d7fec4Smrg houston_ReadReg(HOUSTON_MISC, &misc, 2); 318571d7fec4Smrg if (trigger_bits == 0) 318671d7fec4Smrg misc &= ~MISC_MV_SOFT_EN; 318771d7fec4Smrg else 318871d7fec4Smrg misc |= MISC_MV_SOFT_EN; 318971d7fec4Smrg houston_WriteReg(HOUSTON_MISC, misc, 2); 319071d7fec4Smrg} 319171d7fec4Smrg 319271d7fec4Smrgstatic void 319371d7fec4Smrgconget_macrovision(unsigned long tv_std, unsigned int *p_cp_trigger_bits) 319471d7fec4Smrg{ 319571d7fec4Smrg unsigned long n0, n1; 319671d7fec4Smrg 319771d7fec4Smrg if (!p_cp_trigger_bits) 319871d7fec4Smrg return; 319971d7fec4Smrg 320071d7fec4Smrg houston_ReadReg(MV_N0, &n0, 1); 320171d7fec4Smrg houston_ReadReg(MV_N1, &n1, 1); 320271d7fec4Smrg 320371d7fec4Smrg *p_cp_trigger_bits = 0; 320471d7fec4Smrg 320571d7fec4Smrg if (IS_NTSC(tv_std)) { 320671d7fec4Smrg switch (n0) { 320771d7fec4Smrg case 0: 320871d7fec4Smrg *p_cp_trigger_bits = 0; 320971d7fec4Smrg break; 321071d7fec4Smrg 321171d7fec4Smrg case 0x36: 321271d7fec4Smrg *p_cp_trigger_bits = 1; 321371d7fec4Smrg break; 321471d7fec4Smrg 321571d7fec4Smrg case 0x3E: 321671d7fec4Smrg { 321771d7fec4Smrg if (0x1D == n1) 321871d7fec4Smrg *p_cp_trigger_bits = 2; 321971d7fec4Smrg else 322071d7fec4Smrg *p_cp_trigger_bits = 3; 322171d7fec4Smrg } 322271d7fec4Smrg break; 322371d7fec4Smrg } 322471d7fec4Smrg } else if (IS_PAL(tv_std)) { 322571d7fec4Smrg if (0 == n0) 322671d7fec4Smrg *p_cp_trigger_bits = 0; 322771d7fec4Smrg else { 322871d7fec4Smrg /*don't know here what the non-zero trigger bits were */ 322971d7fec4Smrg *p_cp_trigger_bits = 1; 323071d7fec4Smrg } 323171d7fec4Smrg } 323271d7fec4Smrg} 323371d7fec4Smrg 323471d7fec4Smrg/*// PLAL_MediaGX.cpp*/ 323571d7fec4Smrg/*//==========================================================================*/ 323671d7fec4Smrg/****/ 323771d7fec4Smrg/*These functions provides implementation of platform-specific functions*/ 323871d7fec4Smrg/*MediaGX platform.*/ 323971d7fec4Smrg/****/ 324071d7fec4Smrg/*//==========================================================================*/ 324171d7fec4Smrg 324271d7fec4Smrg/*MediaGX control registers.*/ 324371d7fec4Smrg#define CCR3 0xC3 324471d7fec4Smrg#define GCR 0xb8 324571d7fec4Smrg 324671d7fec4Smrg/*Media GX registers*/ 324771d7fec4Smrg/* 324871d7fec4Smrg#define DC_UNLOCK 0x8300 324971d7fec4Smrg#define DC_GENERAL_CFG 0x8304 325071d7fec4Smrg#define DC_TIMING_CFG 0x8308 325171d7fec4Smrg#define DC_OUTPUT_CFG 0x830c 325271d7fec4Smrg#define DC_H_TIMING_1 0X8330 325371d7fec4Smrg#define DC_H_TIMING_2 0X8334 325471d7fec4Smrg#define DC_H_TIMING_3 0X8338 325571d7fec4Smrg#define DC_FP_H_TIMING 0X833c 325671d7fec4Smrg#define DC_V_TIMING_1 0X8340 325771d7fec4Smrg#define DC_V_TIMING_2 0X8344 325871d7fec4Smrg#define DC_V_TIMING_3 0X8348 325971d7fec4Smrg#define DC_FP_V_TIMING 0X834c 326071d7fec4Smrg*/ 326171d7fec4Smrg/*Media GX general config register.*/ 326271d7fec4Smrg#define GX_DCLK_MUL 0x00c0 326371d7fec4Smrg#define GX_DCLKx1 0x0040 326471d7fec4Smrg#define GX_DCLKx2 0x0080 326571d7fec4Smrg#define GX_DCLKx4 0x00c0 326671d7fec4Smrg 326771d7fec4Smrg/*Media GX timing config register.*/ 326871d7fec4Smrg#define GX_TGEN 0x0020 326971d7fec4Smrg 327071d7fec4Smrg/*Cx5530 register offsets (from GX_BASE).*/ 327171d7fec4Smrg#define CX_DISPLAY_CONFIG 0x10004 327271d7fec4Smrg#define CX_DOT_CLK 0x10024 327371d7fec4Smrg#define CX_TV_CONFIG 0x10028 327471d7fec4Smrg 327571d7fec4Smrg/*Cx5530 display configuration register.*/ 327671d7fec4Smrg#define CX_FPVSYNC_POL 0x0800 327771d7fec4Smrg#define CX_FPHSYNC_POL 0x0400 327871d7fec4Smrg#define CX_FPDATA_ENB 0x0080 327971d7fec4Smrg#define CX_FPPOWER_ENB 0x0040 328071d7fec4Smrg#define CX_CRTVSYNC_POL 0x0200 328171d7fec4Smrg#define CX_CRTHSYNC_POL 0x0100 328271d7fec4Smrg 328371d7fec4Smrg/*Cx5530 dot clock configuration register.*/ 328471d7fec4Smrg#define CX_TVCLK_SELECT 0x0400 328571d7fec4Smrg 328671d7fec4Smrg/*Cx5530 tv configuration register*/ 328771d7fec4Smrg#define CX_INVERT_FPCLK (1 << 6) 328871d7fec4Smrg 328971d7fec4Smrg/*//==========================================================================*/ 329071d7fec4Smrg/****/ 329171d7fec4Smrg/*// FS450 I2C Address*/ 329271d7fec4Smrg/****/ 329371d7fec4Smrg/*// There are two possible 7-bit addresses, 0x4A and 0x6A.*/ 329471d7fec4Smrg/*// The address if selectable via pins on the FS450.*/ 329571d7fec4Smrg/*// There are also two possible 10-bit addresses, 0x224 and 0x276, but this*/ 329671d7fec4Smrg/*// source is not designed to use them.*/ 329771d7fec4Smrg/****/ 329871d7fec4Smrg 329971d7fec4Smrg#define FS450_I2C_ADDRESS (0x4A) 330071d7fec4Smrg 330171d7fec4Smrgstatic unsigned char 330271d7fec4SmrgPLAL_FS450_i2c_address(void) 330371d7fec4Smrg{ 330471d7fec4Smrg return FS450_I2C_ADDRESS; 330571d7fec4Smrg} 330671d7fec4Smrg 330771d7fec4Smrg/*//==========================================================================*/ 330871d7fec4Smrg/****/ 330971d7fec4Smrg/*// FS450 UIM mode*/ 331071d7fec4Smrg/****/ 331171d7fec4Smrg/*// This mode is programmed in the FS450 command register when enabling TV*/ 331271d7fec4Smrg/*// out.*/ 331371d7fec4Smrg 331471d7fec4Smrgstatic int 331571d7fec4SmrgPLAL_FS450_UIM_mode(void) 331671d7fec4Smrg{ 331771d7fec4Smrg return 3; 331871d7fec4Smrg} 331971d7fec4Smrg 332071d7fec4Smrg/*//==========================================================================*/ 332171d7fec4Smrg/****/ 332271d7fec4Smrg/*// Read and Write MediaGX registers*/ 332371d7fec4Smrg 332471d7fec4Smrgstatic unsigned long 332571d7fec4SmrgReadGx(unsigned long inRegAddr) 332671d7fec4Smrg{ 332771d7fec4Smrg unsigned long data; 332871d7fec4Smrg 332971d7fec4Smrg DMAL_ReadUInt32(inRegAddr, &data); 333071d7fec4Smrg 333171d7fec4Smrg return data; 333271d7fec4Smrg} 333371d7fec4Smrg 333471d7fec4Smrgstatic void 333571d7fec4SmrgWriteGx(unsigned long inRegAddr, unsigned long inData) 333671d7fec4Smrg{ 333771d7fec4Smrg int is_timing_register; 333871d7fec4Smrg unsigned long reg_timing_cfg; 333971d7fec4Smrg 334071d7fec4Smrg /*because the unlock register for the MediaGx video registers may not */ 334171d7fec4Smrg /*persist, we will write the unlock code before every write. */ 334271d7fec4Smrg DMAL_WriteUInt32(DC_UNLOCK, 0x4758); 334371d7fec4Smrg 334471d7fec4Smrg /*see if register is a timing register */ 334571d7fec4Smrg is_timing_register = 334671d7fec4Smrg (DC_H_TIMING_1 == inRegAddr) || 334771d7fec4Smrg (DC_H_TIMING_2 == inRegAddr) || 334871d7fec4Smrg (DC_H_TIMING_3 == inRegAddr) || 334971d7fec4Smrg (DC_FP_H_TIMING == inRegAddr) || 335071d7fec4Smrg (DC_V_TIMING_1 == inRegAddr) || 335171d7fec4Smrg (DC_V_TIMING_2 == inRegAddr) || 335271d7fec4Smrg (DC_V_TIMING_3 == inRegAddr) || (DC_FP_V_TIMING == inRegAddr); 335371d7fec4Smrg 335471d7fec4Smrg /*if the register is a timing register, clear the TGEN bit to allow modification */ 335571d7fec4Smrg if (is_timing_register) { 335671d7fec4Smrg DMAL_ReadUInt32(DC_TIMING_CFG, ®_timing_cfg); 335771d7fec4Smrg DMAL_WriteUInt32(DC_TIMING_CFG, reg_timing_cfg & ~GX_TGEN); 335871d7fec4Smrg } 335971d7fec4Smrg 336071d7fec4Smrg /*write the requested register */ 336171d7fec4Smrg DMAL_WriteUInt32(inRegAddr, inData); 336271d7fec4Smrg 336371d7fec4Smrg /*reset the TGEN bit to previous state */ 336471d7fec4Smrg if (is_timing_register) { 336571d7fec4Smrg DMAL_WriteUInt32(DC_TIMING_CFG, reg_timing_cfg); 336671d7fec4Smrg } 336771d7fec4Smrg} 336871d7fec4Smrg 336971d7fec4Smrg#ifdef FS450_DIRECTREG 337071d7fec4Smrg 337171d7fec4Smrg/*//==========================================================================*/ 337271d7fec4Smrg/****/ 337371d7fec4Smrg/*// Platform-specific processing for a Read or Write Register calls.*/ 337471d7fec4Smrg/*// The functions should return true if the specified register belongs to*/ 337571d7fec4Smrg/*// this platform.*/ 337671d7fec4Smrg 337771d7fec4Smrgstatic int 337871d7fec4SmrgPLAL_ReadRegister(S_REG_INFO * p_reg) 337971d7fec4Smrg{ 338071d7fec4Smrg if (!p_reg) 338171d7fec4Smrg return 0; 338271d7fec4Smrg 338371d7fec4Smrg if (SOURCE_GCC == p_reg->source) { 338471d7fec4Smrg p_reg->value = ReadGx(p_reg->offset); 338571d7fec4Smrg 338671d7fec4Smrg return 1; 338771d7fec4Smrg } 338871d7fec4Smrg 338971d7fec4Smrg return 0; 339071d7fec4Smrg} 339171d7fec4Smrg 339271d7fec4Smrgstatic int 339371d7fec4SmrgPLAL_WriteRegister(const S_REG_INFO * p_reg) 339471d7fec4Smrg{ 339571d7fec4Smrg if (!p_reg) 339671d7fec4Smrg return 0; 339771d7fec4Smrg 339871d7fec4Smrg if (SOURCE_GCC == p_reg->source) { 339971d7fec4Smrg WriteGx(p_reg->offset, p_reg->value); 340071d7fec4Smrg 340171d7fec4Smrg return 1; 340271d7fec4Smrg } 340371d7fec4Smrg 340471d7fec4Smrg return 0; 340571d7fec4Smrg} 340671d7fec4Smrg 340771d7fec4Smrg#endif 340871d7fec4Smrg 340971d7fec4Smrg/*//==========================================================================*/ 341071d7fec4Smrg/****/ 341171d7fec4Smrg/*// Determine if TV is on*/ 341271d7fec4Smrg 341371d7fec4Smrgstatic int 341471d7fec4SmrgPLAL_IsTVOn(void) 341571d7fec4Smrg{ 341671d7fec4Smrg unsigned long reg; 341771d7fec4Smrg 341871d7fec4Smrg /*check Cx5530 dot clock */ 341971d7fec4Smrg reg = ReadGx(CX_DOT_CLK); 342071d7fec4Smrg return (reg & CX_TVCLK_SELECT) ? 1 : 0; 342171d7fec4Smrg} 342271d7fec4Smrg 342371d7fec4Smrg/*//==========================================================================*/ 342471d7fec4Smrg/****/ 342571d7fec4Smrg/*// Platform-specific actions to reset to VGA mode*/ 342671d7fec4Smrg 342771d7fec4Smrgstatic int 342871d7fec4SmrgPLAL_EnableVga(void) 342971d7fec4Smrg{ 343071d7fec4Smrg unsigned long reg; 343171d7fec4Smrg 343271d7fec4Smrg /*2 x dclk */ 343371d7fec4Smrg reg = ReadGx(DC_GENERAL_CFG); 343471d7fec4Smrg reg &= ~GX_DCLK_MUL; 343571d7fec4Smrg reg |= GX_DCLKx2; 343671d7fec4Smrg WriteGx(DC_GENERAL_CFG, reg); 343771d7fec4Smrg 343871d7fec4Smrg /*select pll dot clock. */ 343971d7fec4Smrg reg = ReadGx(CX_DOT_CLK); 344071d7fec4Smrg reg &= ~CX_TVCLK_SELECT; 344171d7fec4Smrg WriteGx(CX_DOT_CLK, reg); 344271d7fec4Smrg 344371d7fec4Smrg /*timing config, reset everything on dclk. */ 344471d7fec4Smrg reg = ReadGx(DC_TIMING_CFG); 344571d7fec4Smrg reg &= ~GX_TGEN; 344671d7fec4Smrg WriteGx(DC_TIMING_CFG, reg); 344771d7fec4Smrg reg |= GX_TGEN; 344871d7fec4Smrg WriteGx(DC_TIMING_CFG, reg); 344971d7fec4Smrg 345071d7fec4Smrg /*un-invert FP clock */ 345171d7fec4Smrg reg = ReadGx(CX_TV_CONFIG); 345271d7fec4Smrg reg &= ~CX_INVERT_FPCLK; 345371d7fec4Smrg WriteGx(CX_TV_CONFIG, reg); 345471d7fec4Smrg 345571d7fec4Smrg return 0; 345671d7fec4Smrg} 345771d7fec4Smrg 345871d7fec4Smrg/*//==========================================================================*/ 345971d7fec4Smrg/****/ 346071d7fec4Smrg/*// Platform-specific actions to enter TVout mode*/ 346171d7fec4Smrg 346271d7fec4Smrgstatic int 346371d7fec4SmrgPLAL_PrepForTVout(void) 346471d7fec4Smrg{ 346571d7fec4Smrg unsigned int reg; 346671d7fec4Smrg 346771d7fec4Smrg /*Cx5530 tv config. */ 346871d7fec4Smrg reg = 0; 346971d7fec4Smrg WriteGx(CX_TV_CONFIG, reg); 347071d7fec4Smrg 347171d7fec4Smrg /*invert FP clock */ 347271d7fec4Smrg reg = (int)ReadGx(CX_TV_CONFIG); 347371d7fec4Smrg reg |= CX_INVERT_FPCLK; 347471d7fec4Smrg WriteGx(CX_TV_CONFIG, reg); 347571d7fec4Smrg 347671d7fec4Smrg return 0; 347771d7fec4Smrg} 347871d7fec4Smrg 347971d7fec4Smrgstatic int 348071d7fec4SmrgPLAL_SetTVTimingRegisters(const S_TIMING_SPECS * p_specs) 348171d7fec4Smrg{ 348271d7fec4Smrg unsigned long reg; 348371d7fec4Smrg 348471d7fec4Smrg /*timing config, reset everything on dclk. */ 348571d7fec4Smrg reg = ReadGx(DC_TIMING_CFG); 348671d7fec4Smrg reg &= ~GX_TGEN; 348771d7fec4Smrg WriteGx(DC_TIMING_CFG, reg); 348871d7fec4Smrg 348971d7fec4Smrg /*htotal and hactive. */ 349071d7fec4Smrg reg = ((p_specs->h_total - 1) << 16) | (p_specs->vga_width - 1); 349171d7fec4Smrg WriteGx(DC_H_TIMING_1, reg); 349271d7fec4Smrg 349371d7fec4Smrg /*hblank. */ 349471d7fec4Smrg reg = ((p_specs->h_total - 1) << 16) | (p_specs->vga_width - 1); 349571d7fec4Smrg WriteGx(DC_H_TIMING_2, reg); 349671d7fec4Smrg 349771d7fec4Smrg /*hsync. */ 349871d7fec4Smrg reg = ((p_specs->h_sync + 63) << 16) | p_specs->h_sync; 349971d7fec4Smrg WriteGx(DC_H_TIMING_3, reg); 350071d7fec4Smrg 350171d7fec4Smrg /*fp hsync. */ 350271d7fec4Smrg WriteGx(DC_FP_H_TIMING, reg); 350371d7fec4Smrg 350471d7fec4Smrg /*vtotal and vactive. */ 350571d7fec4Smrg reg = ((p_specs->v_total - 1) << 16) | (p_specs->vga_lines - 1); 350671d7fec4Smrg WriteGx(DC_V_TIMING_1, reg); 350771d7fec4Smrg 350871d7fec4Smrg /*vblank. */ 350971d7fec4Smrg reg = ((p_specs->v_total - 1) << 16) | (p_specs->vga_lines - 1); 351071d7fec4Smrg WriteGx(DC_V_TIMING_2, reg); 351171d7fec4Smrg 351271d7fec4Smrg /*vsync. */ 351371d7fec4Smrg reg = ((p_specs->v_sync) << 16) | (p_specs->v_sync - 1); 351471d7fec4Smrg WriteGx(DC_V_TIMING_3, reg); 351571d7fec4Smrg 351671d7fec4Smrg /*fp vsync. */ 351771d7fec4Smrg reg = ((p_specs->v_sync - 1) << 16) | (p_specs->v_sync - 2); 351871d7fec4Smrg WriteGx(DC_FP_V_TIMING, reg); 351971d7fec4Smrg 352071d7fec4Smrg /*timing config, reenable all dclk stuff. */ 352171d7fec4Smrg reg = ReadGx(DC_TIMING_CFG); 352271d7fec4Smrg reg |= GX_TGEN; 352371d7fec4Smrg WriteGx(DC_TIMING_CFG, reg); 352471d7fec4Smrg 352571d7fec4Smrg return 0; 352671d7fec4Smrg} 352771d7fec4Smrg 352871d7fec4Smrgstatic int 352971d7fec4SmrgPLAL_FinalEnableTVout(unsigned long vga_mode) 353071d7fec4Smrg{ 353171d7fec4Smrg unsigned int reg; 353271d7fec4Smrg 353371d7fec4Smrg /*Cx5530 select tv dot clock. */ 353471d7fec4Smrg reg = (int)ReadGx(CX_DOT_CLK); 353571d7fec4Smrg reg |= CX_TVCLK_SELECT; 353671d7fec4Smrg WriteGx(CX_DOT_CLK, reg); 353771d7fec4Smrg 353871d7fec4Smrg /*2 x dclk (actually 1x) */ 353971d7fec4Smrg reg = (int)ReadGx(DC_GENERAL_CFG); 354071d7fec4Smrg reg &= ~GX_DCLK_MUL; 354171d7fec4Smrg WriteGx(DC_GENERAL_CFG, reg); 354271d7fec4Smrg 354371d7fec4Smrg reg |= GX_DCLKx2; 354471d7fec4Smrg WriteGx(DC_GENERAL_CFG, reg); 354571d7fec4Smrg 354671d7fec4Smrg /*Cx5530 display configuration register. */ 354771d7fec4Smrg reg = (int)ReadGx(CX_DISPLAY_CONFIG); 354871d7fec4Smrg reg |= (CX_FPVSYNC_POL | CX_FPHSYNC_POL | CX_FPDATA_ENB | CX_FPPOWER_ENB); 354971d7fec4Smrg WriteGx(CX_DISPLAY_CONFIG, reg); 355071d7fec4Smrg 355171d7fec4Smrg/*disable, shouldn't be necessary*/ 355271d7fec4Smrg#if 0 355371d7fec4Smrg /*kick MediaGX clock multiplier to clean up clock */ 355471d7fec4Smrg reg = ReadGx(DC_GENERAL_CFG); 355571d7fec4Smrg reg &= ~GX_DCLK_MUL; 355671d7fec4Smrg WriteGx(DC_GENERAL_CFG, reg); 355771d7fec4Smrg reg |= GX_DCLKx2; 355871d7fec4Smrg WriteGx(DC_GENERAL_CFG, reg); 355971d7fec4Smrg#endif 356071d7fec4Smrg 356171d7fec4Smrg return 0; 356271d7fec4Smrg} 3563