[PATCH 2/5] viafb: Framebuffer driver for VIA UniChrome/Chrome9 HC
STALE7094d
From: <hidden>
Date: 2007-04-28 02:42:45
diff -Nur linux-2.6.21-rc7/drivers/video/via/hwcfig.h linux-2.6.21-rc7.viafb/drivers/video/via/hwcfig.h
--- linux-2.6.21-rc7/drivers/video/via/hwcfig.h 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.21-rc7.viafb/drivers/video/via/hwcfig.h 2007-04-26 19:52:32.000000000 -0400@@ -0,0 +1,399 @@ + /* + * Copyright 1998-2007 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2007 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + + +#ifndef __HWCFIG_H__ +#define __HWCFIG_H__ + +#include <linux/ioport.h> +#include <asm/io.h> + +#include "share.h" +#include "hw.h" + +static struct pll_map pll_value[] = { + {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M, CX700_25_175M}, + {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M, CX700_29_581M}, + {CLK_26_880M, CLE266_PLL_26_880M, K800_PLL_26_880M, CX700_26_880M}, + {CLK_31_490M, CLE266_PLL_31_490M, K800_PLL_31_490M, CX700_31_490M}, + {CLK_31_500M, CLE266_PLL_31_500M, K800_PLL_31_500M, CX700_31_500M}, + {CLK_31_728M, CLE266_PLL_31_728M, K800_PLL_31_728M, CX700_31_728M}, + {CLK_32_668M, CLE266_PLL_32_668M, K800_PLL_32_668M, CX700_32_668M}, + {CLK_36_000M, CLE266_PLL_36_000M, K800_PLL_36_000M, CX700_36_000M}, + {CLK_40_000M, CLE266_PLL_40_000M, K800_PLL_40_000M, CX700_40_000M}, + {CLK_41_291M, CLE266_PLL_41_291M, K800_PLL_41_291M, CX700_41_291M}, + {CLK_43_163M, CLE266_PLL_43_163M, K800_PLL_43_163M, CX700_43_163M}, + {CLK_48_875M, CLE266_PLL_48_875M, K800_PLL_48_875M, CX700_48_875M}, + {CLK_49_500M, CLE266_PLL_49_500M, K800_PLL_49_500M, CX700_49_500M}, + {CLK_52_406M, CLE266_PLL_52_406M, K800_PLL_52_406M, CX700_52_406M}, + {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M, CX700_56_250M}, + {CLK_65_000M, CLE266_PLL_65_000M, K800_PLL_65_000M, CX700_65_000M}, + {CLK_68_179M, CLE266_PLL_68_179M, K800_PLL_68_179M, CX700_68_179M}, + {CLK_78_750M, CLE266_PLL_78_750M, K800_PLL_78_750M, CX700_78_750M}, + {CLK_80_136M, CLE266_PLL_80_136M, K800_PLL_80_136M, CX700_80_136M}, + {CLK_83_375M, CLE266_PLL_83_375M, K800_PLL_83_375M, CX700_83_375M}, + {CLK_83_950M, CLE266_PLL_83_950M, K800_PLL_83_950M, CX700_83_950M}, + {CLK_85_860M, CLE266_PLL_85_860M, K800_PLL_85_860M, CX700_85_860M}, + {CLK_94_500M, CLE266_PLL_94_500M, K800_PLL_94_500M, CX700_94_500M}, + {CLK_108_000M, CLE266_PLL_108_000M, K800_PLL_108_000M, CX700_108_000M}, + {CLK_125_104M, CLE266_PLL_125_104M, K800_PLL_125_104M, CX700_125_104M}, + {CLK_133_308M, CLE266_PLL_133_308M, K800_PLL_133_308M, CX700_133_308M}, + {CLK_135_000M, CLE266_PLL_135_000M, K800_PLL_135_000M, CX700_135_000M}, + {CLK_157_500M, CLE266_PLL_157_500M, K800_PLL_157_500M, CX700_157_500M}, + {CLK_162_000M, CLE266_PLL_162_000M, K800_PLL_162_000M, CX700_162_000M}, + {CLK_202_500M, CLE266_PLL_202_500M, K800_PLL_202_500M, CX700_202_500M}, + {CLK_234_000M, CLE266_PLL_234_000M, K800_PLL_234_000M, CX700_234_000M}, + {CLK_297_500M, CLE266_PLL_297_500M, K800_PLL_297_500M, CX700_297_500M}, + {CLK_74_481M, CLE266_PLL_74_481M, K800_PLL_74_481M, CX700_74_481M}, + {CLK_172_798M, CLE266_PLL_172_798M, K800_PLL_172_798M, CX700_172_798M}, + {CLK_122_614M, CLE266_PLL_122_614M, K800_PLL_122_614M, CX700_122_614M} + +}; + +#define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value) + +static struct fifo_depth_select display_fifo_depth_reg= { + /* IGA1 FIFO Depth_Select */ + {IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17,0,7}}}, + /* IGA2 FIFO Depth_Select */ + {IGA2_FIFO_DEPTH_SELECT_REG_NUM, {{CR68,4,7}, {CR94,7,7}, {CR95,7,7}}} +}; + +static struct fifo_threshold_select fifo_threshold_select_reg= { + /* IGA1 FIFO Threshold Select */ + {IGA1_FIFO_THRESHOLD_REG_NUM, {{SR16,0,5},{SR16,7,7}}}, + /* IGA2 FIFO Threshold Select */ + {IGA2_FIFO_THRESHOLD_REG_NUM, {{CR68,0,3}, {CR95,4,6}}} +}; + +static struct fifo_high_threshold_select fifo_high_threshold_select_reg= { + /* IGA1 FIFO High Threshold Select */ + {IGA1_FIFO_HIGH_THRESHOLD_REG_NUM, {{SR18,0,5},{SR18,7,7}}}, + /* IGA2 FIFO High Threshold Select */ + {IGA2_FIFO_HIGH_THRESHOLD_REG_NUM, {{CR92,0,3}, {CR95,0,2}}} +}; + +static struct display_queue_expire_num display_queue_expire_num_reg= { + /* IGA1 Display Queue Expire Num */ + {IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{SR22,0,4}}}, + /* IGA2 Display Queue Expire Num */ + {IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{CR94,0,6}}} +}; + +/* Definition Offset Registers */ +static struct offset offset_reg = { + /* IGA1 Offset Register */ + {IGA1_OFFSET_REG_NUM, {{CR13,0,7},{CR35,5,7}}}, + /* IGA2 Offset Register */ + {IGA2_OFFSET_REG_NUM, {{CR66,0,7},{CR67,0,1}}} +}; + +/* Definition Fetch Count Registers */ +static struct fetch_count fetch_count_reg = { + /* IGA1 Fetch Count Register */ + {IGA1_FETCH_COUNT_REG_NUM, {{SR1C,0,7},{SR1D,0,1}}}, + /* IGA2 Fetch Count Register */ + {IGA2_FETCH_COUNT_REG_NUM, {{CR65,0,7},{CR67,2,3}}} +}; + +#define IGA1_STARTING_ADDR_REG_NUM 4 /* location: {CR0C,0,7},{CR0D,0,7},{CR34,0,7},{CR48,0,1} */ +#define IGA2_STARTING_ADDR_REG_NUM 3 /* location: {CR62,1,7},{CR63,0,7},{CR64,0,7} */ + +static struct iga1_crtc_timing iga1_crtc_reg = { + /* IGA1 Horizontal Total */ + {IGA1_HOR_TOTAL_REG_NUM, {{CR00,0,7}, {CR36,3,3}}}, + /* IGA1 Horizontal Addressable Video */ + {IGA1_HOR_ADDR_REG_NUM, {{CR01,0,7}}}, + /* IGA1 Horizontal Blank Start */ + {IGA1_HOR_BLANK_START_REG_NUM, {{CR02,0,7}}}, + /* IGA1 Horizontal Blank End */ + {IGA1_HOR_BLANK_END_REG_NUM, {{CR03,0,4}, {CR05,7,7}, {CR33,5,5}}}, + /* IGA1 Horizontal Sync Start */ + {IGA1_HOR_SYNC_START_REG_NUM, {{CR04,0,7}, {CR33,4,4}}}, + /* IGA1 Horizontal Sync End */ + {IGA1_HOR_SYNC_END_REG_NUM, {{CR05,0,4}}}, + /* IGA1 Vertical Total */ + {IGA1_VER_TOTAL_REG_NUM, {{CR06,0,7}, {CR07,0,0}, {CR07,5,5}, {CR35,0,0}}}, + /* IGA1 Vertical Addressable Video */ + {IGA1_VER_ADDR_REG_NUM, {{CR12,0,7}, {CR07,1,1}, {CR07,6,6}, {CR35,2,2}}}, + /* IGA1 Vertical Blank Start */ + {IGA1_VER_BLANK_START_REG_NUM, {{CR15,0,7}, {CR07,3,3}, {CR09,5,5}, {CR35,3,3}}}, + /* IGA1 Vertical Blank End */ + {IGA1_VER_BLANK_END_REG_NUM, {{CR16,0,7}}}, + /* IGA1 Vertical Sync Start */ + {IGA1_VER_SYNC_START_REG_NUM, {{CR10,0,7}, {CR07,2,2}, {CR07,7,7}, {CR35,1,1}}}, + /* IGA1 Vertical Sync End */ + {IGA1_VER_SYNC_END_REG_NUM, {{CR11,0,3}}} +}; + +static struct iga2_shadow_crtc_timing iga2_shadow_crtc_reg = { + /* IGA2 Shadow Horizontal Total */ + {IGA2_SHADOW_HOR_TOTAL_REG_NUM, {{CR6D,0,7}, {CR71,3,3}}}, + /* IGA2 Shadow Horizontal Blank End */ + {IGA2_SHADOW_HOR_BLANK_END_REG_NUM, {{CR6E,0,7}}}, + /* IGA2 Shadow Vertical Total */ + {IGA2_SHADOW_VER_TOTAL_REG_NUM, {{CR6F,0,7}, {CR71,0,2}}}, + /* IGA2 Shadow Vertical Addressable Video */ + {IGA2_SHADOW_VER_ADDR_REG_NUM, {{CR70,0,7}, {CR71,4,6}}}, + /* IGA2 Shadow Vertical Blank Start */ + {IGA2_SHADOW_VER_BLANK_START_REG_NUM, {{CR72,0,7}, {CR74,4,6}}}, + /* IGA2 Shadow Vertical Blank End */ + {IGA2_SHADOW_VER_BLANK_END_REG_NUM, {{CR73,0,7}, {CR74,0,2}}}, + /* IGA2 Shadow Vertical Sync Start */ + {IGA2_SHADOW_VER_SYNC_START_REG_NUM, {{CR75,0,7}, {CR76,4,6}}}, + /* IGA2 Shadow Vertical Sync End */ + {IGA2_SHADOW_VER_SYNC_END_REG_NUM, {{CR76,0,3}}} +}; + +static struct iga2_crtc_timing iga2_crtc_reg = { + /* IGA2 Horizontal Total */ + {IGA2_HOR_TOTAL_REG_NUM, {{CR50,0,7}, {CR55,0,3}}}, + /* IGA2 Horizontal Addressable Video */ + {IGA2_HOR_ADDR_REG_NUM, {{CR51,0,7}, {CR55,4,6}}}, + /* IGA2 Horizontal Blank Start */ + {IGA2_HOR_BLANK_START_REG_NUM, {{CR52,0,7}, {CR54,0,2}}}, + /* IGA2 Horizontal Blank End */ + {IGA2_HOR_BLANK_END_REG_NUM, {{CR53,0,7}, {CR54,3,5}, {CR5D,6,6}}}, + /* IGA2 Horizontal Sync Start */ + {IGA2_HOR_SYNC_START_REG_NUM, {{CR56,0,7}, {CR54,6,7}, {CR5C,7,7}, {CR5D,7,7}}}, + /* IGA2 Horizontal Sync End */ + {IGA2_HOR_SYNC_END_REG_NUM, {{CR57,0,7}, {CR5C,6,6}}}, + /* IGA2 Vertical Total */ + {IGA2_VER_TOTAL_REG_NUM, {{CR58,0,7}, {CR5D,0,2}}}, + /* IGA2 Vertical Addressable Video */ + {IGA2_VER_ADDR_REG_NUM, {{CR59,0,7}, {CR5D,3,5}}}, + /* IGA2 Vertical Blank Start */ + {IGA2_VER_BLANK_START_REG_NUM, {{CR5A,0,7}, {CR5C,0,2}}}, + /* IGA2 Vertical Blank End */ + {IGA2_VER_BLANK_END_REG_NUM, {{CR5B,0,7}, {CR5C,3,5}}}, + /* IGA2 Vertical Sync Start */ + {IGA2_VER_SYNC_START_REG_NUM, {{CR5E,0,7}, {CR5F,5,7}}}, + /* IGA2 Vertical Sync End */ + {IGA2_VER_SYNC_END_REG_NUM, {{CR5F,0,4}}} +}; + +static struct _lcd_scaling_factor lcd_scaling_factor = { + /* LCD Horizontal Scaling Factor Register */ + {LCD_HOR_SCALING_FACTOR_REG_NUM, {{CR9F,0,1}, {CR77,0,7}, {CR79,4,5}}}, + /* LCD Vertical Scaling Factor Register */ + {LCD_VER_SCALING_FACTOR_REG_NUM, {{CR79,3,3}, {CR78,0,7}, {CR79,6,7}}} +}; +static struct _lcd_scaling_factor lcd_scaling_factor_CLE = { + /* LCD Horizontal Scaling Factor Register */ + {LCD_HOR_SCALING_FACTOR_REG_NUM_CLE, {{CR77,0,7}, {CR79,4,5}}}, + /* LCD Vertical Scaling Factor Register */ + {LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78,0,7}, {CR79,6,7}}} +}; + +static struct rgbLUT palLUT_table[]= { + /* {R,G,B} */ + /* Index 0x00~0x03 */ + {0x00, 0x00, 0x00}, {0x00, 0x00, 0x2A}, {0x00, 0x2A, 0x00}, {0x00, 0x2A, 0x2A}, + /* Index 0x04~0x07 */ + {0x2A, 0x00, 0x00}, {0x2A, 0x00, 0x2A}, {0x2A, 0x15, 0x00}, {0x2A, 0x2A, 0x2A}, + /* Index 0x08~0x0B */ + {0x15, 0x15, 0x15}, {0x15, 0x15, 0x3F}, {0x15, 0x3F, 0x15}, {0x15, 0x3F, 0x3F}, + /* Index 0x0C~0x0F */ + {0x3F, 0x15, 0x15}, {0x3F, 0x15, 0x3F}, {0x3F, 0x3F, 0x15}, {0x3F, 0x3F, 0x3F}, + /* Index 0x10~0x13 */ + {0x00, 0x00, 0x00}, {0x05, 0x05, 0x05}, {0x08, 0x08, 0x08}, {0x0B, 0x0B, 0x0B}, + /* Index 0x14~0x17 */ + {0x0E, 0x0E, 0x0E}, {0x11, 0x11, 0x11}, {0x14, 0x14, 0x14}, {0x18, 0x18, 0x18}, + /* Index 0x18~0x1B */ + {0x1C, 0x1C, 0x1C}, {0x20, 0x20, 0x20}, {0x24, 0x24, 0x24}, {0x28, 0x28, 0x28}, + /* Index 0x1C~0x1F */ + {0x2D, 0x2D, 0x2D}, {0x32, 0x32, 0x32}, {0x38, 0x38, 0x38}, {0x3F, 0x3F, 0x3F}, + /* Index 0x20~0x23 */ + {0x00, 0x00, 0x3F}, {0x10, 0x00, 0x3F}, {0x1F, 0x00, 0x3F}, {0x2F, 0x00, 0x3F}, + /* Index 0x24~0x27 */ + {0x3F, 0x00, 0x3F}, {0x3F, 0x00, 0x2F}, {0x3F, 0x00, 0x1F}, {0x3F, 0x00, 0x10}, + /* Index 0x28~0x2B */ + {0x3F, 0x00, 0x00}, {0x3F, 0x10, 0x00}, {0x3F, 0x1F, 0x00}, {0x3F, 0x2F, 0x00}, + /* Index 0x2C~0x2F */ + {0x3F, 0x3F, 0x00}, {0x2F, 0x3F, 0x00}, {0x1F, 0x3F, 0x00}, {0x10, 0x3F, 0x00}, + /* Index 0x30~0x33 */ + {0x00, 0x3F, 0x00}, {0x00, 0x3F, 0x10}, {0x00, 0x3F, 0x1F}, {0x00, 0x3F, 0x2F}, + /* Index 0x34~0x37 */ + {0x00, 0x3F, 0x3F}, {0x00, 0x2F, 0x3F}, {0x00, 0x1F, 0x3F}, {0x00, 0x10, 0x3F}, + /* Index 0x38~0x3B */ + {0x1F, 0x1F, 0x3F}, {0x27, 0x1F, 0x3F}, {0x2F, 0x1F, 0x3F}, {0x37, 0x1F, 0x3F}, + /* Index 0x3C~0x3F */ + {0x3F, 0x1F, 0x3F}, {0x3F, 0x1F, 0x37}, {0x3F, 0x1F, 0x2F}, {0x3F, 0x1F, 0x27}, + /* Index 0x40~0x43 */ + {0x3F, 0x1F, 0x1F}, {0x3F, 0x27, 0x1F}, {0x3F, 0x2F, 0x1F}, {0x3F, 0x3F, 0x1F}, + /* Index 0x44~0x47 */ + {0x3F, 0x3F, 0x1F}, {0x37, 0x3F, 0x1F}, {0x2F, 0x3F, 0x1F}, {0x27, 0x3F, 0x1F}, + /* Index 0x48~0x4B */ + {0x1F, 0x3F, 0x1F}, {0x1F, 0x3F, 0x27}, {0x1F, 0x3F, 0x2F}, {0x1F, 0x3F, 0x37}, + /* Index 0x4C~0x4F */ + {0x1F, 0x3F, 0x3F}, {0x1F, 0x37, 0x3F}, {0x1F, 0x2F, 0x3F}, {0x1F, 0x27, 0x3F}, + /* Index 0x50~0x53 */ + {0x2D, 0x2D, 0x3F}, {0x31, 0x2D, 0x3F}, {0x36, 0x2D, 0x3F}, {0x3A, 0x2D, 0x3F}, + /* Index 0x54~0x57 */ + {0x3F, 0x2D, 0x3F}, {0x3F, 0x2D, 0x3A}, {0x3F, 0x2D, 0x36}, {0x3F, 0x2D, 0x31}, + /* Index 0x58~0x5B */ + {0x3F, 0x2D, 0x2D}, {0x3F, 0x31, 0x2D}, {0x3F, 0x36, 0x2D}, {0x3F, 0x3A, 0x2D}, + /* Index 0x5C~0x5F */ + {0x3F, 0x3F, 0x2D}, {0x3A, 0x3F, 0x2D}, {0x36, 0x3F, 0x2D}, {0x31, 0x3F, 0x2D}, + /* Index 0x60~0x63 */ + {0x2D, 0x3F, 0x2D}, {0x2D, 0x3F, 0x31}, {0x2D, 0x3F, 0x36}, {0x2D, 0x3F, 0x3A}, + /* Index 0x64~0x67 */ + {0x2D, 0x3F, 0x3F}, {0x2D, 0x3A, 0x3F}, {0x2D, 0x36, 0x3F}, {0x2D, 0x31, 0x3F}, + /* Index 0x68~0x6B */ + {0x00, 0x00, 0x1C}, {0x07, 0x00, 0x1C}, {0x0E, 0x00, 0x1C}, {0x15, 0x00, 0x1C}, + /* Index 0x6C~0x6F */ + {0x1C, 0x00, 0x1C}, {0x1C, 0x00, 0x15}, {0x1C, 0x00, 0x0E}, {0x1C, 0x00, 0x07}, + /* Index 0x70~0x73 */ + {0x1C, 0x00, 0x00}, {0x1C, 0x07, 0x00}, {0x1C, 0x0E, 0x00}, {0x1C, 0x15, 0x00}, + /* Index 0x74~0x77 */ + {0x1C, 0x1C, 0x00}, {0x15, 0x1C, 0x00}, {0x0E, 0x1C, 0x00}, {0x07, 0x1C, 0x00}, + /* Index 0x78~0x7B */ + {0x00, 0x1C, 0x00}, {0x00, 0x1C, 0x07}, {0x00, 0x1C, 0x0E}, {0x00, 0x1C, 0x15}, + /* Index 0x7C~0x7F */ + {0x00, 0x1C, 0x1C}, {0x00, 0x15, 0x1C}, {0x00, 0x0E, 0x1C}, {0x00, 0x07, 0x1C}, + /* Index 0x80~0x83 */ + {0x0E, 0x0E, 0x1C}, {0x11, 0x0E, 0x1C}, {0x15, 0x0E, 0x1C}, {0x18, 0x0E, 0x1C}, + /* Index 0x84~0x87 */ + {0x1C, 0x0E, 0x1C}, {0x1C, 0x0E, 0x18}, {0x1C, 0x0E, 0x15}, {0x1C, 0x0E, 0x11}, + /* Index 0x88~0x8B */ + {0x1C, 0x0E, 0x0E}, {0x1C, 0x11, 0x0E}, {0x1C, 0x15, 0x0E}, {0x1C, 0x18, 0x0E}, + /* Index 0x8C~0x8F */ + {0x1C, 0x1C, 0x0E}, {0x18, 0x1C, 0x0E}, {0x15, 0x1C, 0x0E}, {0x11, 0x1C, 0x0E}, + /* Index 0x90~0x93 */ + {0x0E, 0x1C, 0x0E}, {0x0E, 0x1C, 0x11}, {0x0E, 0x1C, 0x15}, {0x0E, 0x1C, 0x18}, + /* Index 0x94~0x97 */ + {0x0E, 0x1C, 0x1C}, {0x0E, 0x18, 0x1C}, {0x0E, 0x15, 0x1C}, {0x0E, 0x11, 0x1C}, + /* Index 0x98~0x9B */ + {0x14, 0x14, 0x1C}, {0x16, 0x14, 0x1C}, {0x18, 0x14, 0x1C}, {0x1A, 0x14, 0x1C}, + /* Index 0x9C~0x9F */ + {0x1C, 0x14, 0x1C}, {0x1C, 0x14, 0x1A}, {0x1C, 0x14, 0x18}, {0x1C, 0x14, 0x16}, + /* Index 0xA0~0xA3 */ + {0x1C, 0x14, 0x14}, {0x1C, 0x16, 0x14}, {0x1C, 0x18, 0x14}, {0x1C, 0x1A, 0x14}, + /* Index 0xA4~0xA7 */ + {0x1C, 0x1C, 0x14}, {0x1A, 0x1C, 0x14}, {0x18, 0x1C, 0x14}, {0x16, 0x1C, 0x14}, + /* Index 0xA8~0xAB */ + {0x14, 0x1C, 0x14}, {0x14, 0x1C, 0x16}, {0x14, 0x1C, 0x18}, {0x14, 0x1C, 0x1A}, + /* Index 0xAC~0xAF */ + {0x14, 0x1C, 0x1C}, {0x14, 0x1A, 0x1C}, {0x14, 0x18, 0x1C}, {0x14, 0x16, 0x1C}, + /* Index 0xB0~0xB3 */ + {0x00, 0x00, 0x10}, {0x04, 0x00, 0x10}, {0x08, 0x00, 0x10}, {0x0C, 0x00, 0x10}, + /* Index 0xB4~0xB7 */ + {0x10, 0x00, 0x10}, {0x10, 0x00, 0x0C}, {0x10, 0x00, 0x08}, {0x10, 0x00, 0x04}, + /* Index 0xB8~0xBB */ + {0x10, 0x00, 0x00}, {0x10, 0x04, 0x00}, {0x10, 0x08, 0x00}, {0x10, 0x0C, 0x00}, + /* Index 0xBC~0xBF */ + {0x10, 0x10, 0x00}, {0x0C, 0x10, 0x00}, {0x08, 0x10, 0x00}, {0x04, 0x10, 0x00}, + /* Index 0xC0~0xC3 */ + {0x00, 0x10, 0x00}, {0x00, 0x10, 0x04}, {0x00, 0x10, 0x08}, {0x00, 0x10, 0x0C}, + /* Index 0xC4~0xC7 */ + {0x00, 0x10, 0x10}, {0x00, 0x0C, 0x10}, {0x00, 0x08, 0x10}, {0x00, 0x04, 0x10}, + /* Index 0xC8~0xCB */ + {0x08, 0x08, 0x10}, {0x0A, 0x08, 0x10}, {0x0C, 0x08, 0x10}, {0x0E, 0x08, 0x10}, + /* Index 0xCC~0xCF */ + {0x10, 0x08, 0x10}, {0x10, 0x08, 0x0E}, {0x10, 0x08, 0x0C}, {0x10, 0x08, 0x0A}, + /* Index 0xD0~0xD3 */ + {0x10, 0x08, 0x08}, {0x10, 0x0A, 0x08}, {0x10, 0x0C, 0x08}, {0x10, 0x0E, 0x08}, + /* Index 0xD4~0xD7 */ + {0x10, 0x10, 0x08}, {0x0E, 0x10, 0x08}, {0x0C, 0x10, 0x08}, {0x0A, 0x10, 0x08}, + /* Index 0xD8~0xDB */ + {0x08, 0x10, 0x08}, {0x08, 0x10, 0x0A}, {0x08, 0x10, 0x0C}, {0x08, 0x10, 0x0E}, + /* Index 0xDC~0xDF */ + {0x08, 0x10, 0x10}, {0x08, 0x0E, 0x10}, {0x08, 0x0C, 0x10}, {0x08, 0x0A, 0x10}, + /* Index 0xE0~0xE3 */ + {0x0B, 0x0B, 0x10}, {0x0C, 0x0B, 0x10}, {0x0D, 0x0B, 0x10}, {0x0F, 0x0B, 0x10}, + /* Index 0xE4~0xE7 */ + {0x10, 0x0B, 0x10}, {0x10, 0x0B, 0x0F}, {0x10, 0x0B, 0x0D}, {0x10, 0x0B, 0x0C}, + /* Index 0xE8~0xEB */ + {0x10, 0x0B, 0x0B}, {0x10, 0x0C, 0x0B}, {0x10, 0x0D, 0x0B}, {0x10, 0x0F, 0x0B}, + /* Index 0xEC~0xEF */ + {0x10, 0x10, 0x0B}, {0x0F, 0x10, 0x0B}, {0x0D, 0x10, 0x0B}, {0x0C, 0x10, 0x0B}, + /* Index 0xF0~0xF3 */ + {0x0B, 0x10, 0x0B}, {0x0B, 0x10, 0x0C}, {0x0B, 0x10, 0x0D}, {0x0B, 0x10, 0x0F}, + /* Index 0xF4~0xF7 */ + {0x0B, 0x10, 0x10}, {0x0B, 0x0F, 0x10}, {0x0B, 0x0D, 0x10}, {0x0B, 0x0C, 0x10}, + /* Index 0xF8~0xFB */ + {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, + /* Index 0xFC~0xFF */ + {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00} +}; + +static u16 red256[] = { +0x0 ,0x0 ,0x0 ,0x0 ,0xa800,0xa800,0xa800,0xa800,0x5400,0x5400,0x5400,0x5400,0xfc00,0xfc00,0xfc00,0xfc00, +0x0 ,0x1400,0x2000,0x2c00,0x3800,0x4400,0x5000,0x6000,0x7000,0x8000,0x9000,0xa000,0xb400,0xc800,0xe000,0xfc00, +0x0 ,0x4000,0x7c00,0xbc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xbc00,0x7c00,0x4000, +0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x7c00,0x9c00,0xbc00,0xdc00,0xfc00,0xfc00,0xfc00,0xfc00, +0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xdc00,0xbc00,0x9c00,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00, +0xb400,0xc400,0xd800,0xe800,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xe800,0xd800,0xc400, +0xb400,0xb400,0xb400,0xb400,0xb400,0xb400,0xb400,0xb400,0x0 ,0x1c00,0x3800,0x5400,0x7000,0x7000,0x7000,0x7000, +0x7000,0x7000,0x7000,0x7000,0x7000,0x5400,0x3800,0x1c00,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , +0x3800,0x4400,0x5400,0x6000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x6000,0x5400,0x4400, +0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x5000,0x5800,0x6000,0x6800,0x7000,0x7000,0x7000,0x7000, +0x7000,0x7000,0x7000,0x7000,0x7000,0x6800,0x6000,0x5800,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000, +0x0 ,0x1000,0x2000,0x3000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x3000,0x2000,0x1000, +0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2000,0x2800,0x3000,0x3800,0x4000,0x4000,0x4000,0x4000, +0x4000,0x4000,0x4000,0x4000,0x4000,0x3800,0x3000,0x2800,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, +0x2c00,0x3000,0x3400,0x3c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x3c00,0x3400,0x3000, +0x2c00,0x2c00,0x2c00,0x2c00,0x2c00,0x2c00,0x2c00,0x2c00,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 +}; +static u16 green256[] = { +0x0 ,0x0 ,0xa800,0xa800,0x0 ,0x0 ,0x5400,0xa800,0x5400,0x5400,0xfc00,0xfc00,0x5400,0x5400,0xfc00,0xfc00, +0x0 ,0x1400,0x2000,0x2c00,0x3800,0x4400,0x5000,0x6000,0x7000,0x8000,0x9000,0xa000,0xb400,0xc800,0xe000,0xfc00, +0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x7c00,0xbc00,0xfc00,0xfc00,0xfc00,0xfc00, +0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xbc00,0x7c00,0x4000,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00, +0x7c00,0x9c00,0xbc00,0xdc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xdc00,0xbc00,0x9c00, +0xb400,0xb400,0xb400,0xb400,0xb400,0xb400,0xb400,0xb400,0xb400,0xc400,0xd800,0xe800,0xfc00,0xfc00,0xfc00,0xfc00, +0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xe800,0xd800,0xc400,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , +0x0 ,0x1c00,0x3800,0x5400,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x5400,0x3800,0x1c00, +0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x4400,0x5400,0x6000,0x7000,0x7000,0x7000,0x7000, +0x7000,0x7000,0x7000,0x7000,0x7000,0x6000,0x5400,0x4400,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000, +0x5000,0x5800,0x6000,0x6800,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x6800,0x6000,0x5800, +0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1000,0x2000,0x3000,0x4000,0x4000,0x4000,0x4000, +0x4000,0x4000,0x4000,0x4000,0x4000,0x3000,0x2000,0x1000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, +0x2000,0x2800,0x3000,0x3800,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x3800,0x3000,0x2800, +0x2c00,0x2c00,0x2c00,0x2c00,0x2c00,0x2c00,0x2c00,0x2c00,0x2c00,0x3000,0x3400,0x3c00,0x4000,0x4000,0x4000,0x4000, +0x4000,0x4000,0x4000,0x4000,0x4000,0x3c00,0x3400,0x3000,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 +}; +static u16 blue256[] = { +0x0 ,0xa800,0x0 ,0xa800,0x0 ,0xa800,0x0 ,0xa800,0x5400,0xfc00,0x5400,0xfc00,0x5400,0xfc00,0x5400,0xfc00, +0x0 ,0x1400,0x2000,0x2c00,0x3800,0x4400,0x5000,0x6000,0x7000,0x8000,0x9000,0xa000,0xb400,0xc800,0xe000,0xfc00, +0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xbc00,0x7c00,0x4000,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , +0x0 ,0x4000,0x7c00,0xbc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xdc00,0xbc00,0x9c00, +0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x9c00,0xbc00,0xdc00,0xfc00,0xfc00,0xfc00,0xfc00, +0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xe800,0xd800,0xc400,0xb400,0xb400,0xb400,0xb400,0xb400,0xb400,0xb400,0xb400, +0xb400,0xc400,0xd800,0xe800,0xfc00,0xfc00,0xfc00,0xfc00,0x7000,0x7000,0x7000,0x7000,0x7000,0x5400,0x3800,0x1c00, +0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1c00,0x3800,0x5400,0x7000,0x7000,0x7000,0x7000, +0x7000,0x7000,0x7000,0x7000,0x7000,0x6000,0x5400,0x4400,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, +0x3800,0x4400,0x5400,0x6000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x6800,0x6000,0x5800, +0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5800,0x6000,0x6800,0x7000,0x7000,0x7000,0x7000, +0x4000,0x4000,0x4000,0x4000,0x4000,0x3000,0x2000,0x1000,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , +0x0 ,0x1000,0x2000,0x3000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x3800,0x3000,0x2800, +0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2800,0x3000,0x3800,0x4000,0x4000,0x4000,0x4000, +0x4000,0x4000,0x4000,0x4000,0x4000,0x3c00,0x3400,0x3000,0x2c00,0x2c00,0x2c00,0x2c00,0x2c00,0x2c00,0x2c00,0x2c00, +0x2c00,0x3000,0x3400,0x3c00,0x4000,0x4000,0x4000,0x4000,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 +}; +#endif /* __HWCFIG_H__ */ + + + +
diff -Nur linux-2.6.21-rc7/drivers/video/via/hw.h linux-2.6.21-rc7.viafb/drivers/video/via/hw.h
--- linux-2.6.21-rc7/drivers/video/via/hw.h 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.21-rc7.viafb/drivers/video/via/hw.h 2007-04-26 19:52:32.000000000 -0400@@ -0,0 +1,749 @@ + /* + * Copyright 1998-2007 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2007 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + + +#ifndef __HW_H__ +#define __HW_H__ + +#include <linux/ioport.h> +#include <asm/io.h> + +#include "share.h" + + +/***************************************************/ +/* Definition IGA1 Design Method of CRTC Registers */ +/***************************************************/ +#define IGA1_HOR_TOTAL_FORMULA(x) ((x)/8)-5 +#define IGA1_HOR_ADDR_FORMULA(x) ((x)/8)-1 +#define IGA1_HOR_BLANK_START_FORMULA(x) ((x)/8)-1 +#define IGA1_HOR_BLANK_END_FORMULA(x,y) ((x+y)/8)-1 +#define IGA1_HOR_SYNC_START_FORMULA(x) ((x)/8) +#define IGA1_HOR_SYNC_END_FORMULA(x,y) ((x+y)/8) + +#define IGA1_VER_TOTAL_FORMULA(x) (x)-2 +#define IGA1_VER_ADDR_FORMULA(x) (x)-1 +#define IGA1_VER_BLANK_START_FORMULA(x) (x)-1 +#define IGA1_VER_BLANK_END_FORMULA(x,y) (x+y)-1 +#define IGA1_VER_SYNC_START_FORMULA(x) (x)-1 +#define IGA1_VER_SYNC_END_FORMULA(x,y) (x+y)-1 + +/***************************************************/ +/* Definition IGA2 Design Method of CRTC Registers */ +/***************************************************/ +#define IGA2_HOR_TOTAL_FORMULA(x) (x)-1 +#define IGA2_HOR_ADDR_FORMULA(x) (x)-1 +#define IGA2_HOR_BLANK_START_FORMULA(x) (x)-1 +#define IGA2_HOR_BLANK_END_FORMULA(x,y) (x+y)-1 +#define IGA2_HOR_SYNC_START_FORMULA(x) (x)-1 +#define IGA2_HOR_SYNC_END_FORMULA(x,y) (x+y)-1 + +#define IGA2_VER_TOTAL_FORMULA(x) (x)-1 +#define IGA2_VER_ADDR_FORMULA(x) (x)-1 +#define IGA2_VER_BLANK_START_FORMULA(x) (x)-1 +#define IGA2_VER_BLANK_END_FORMULA(x,y) (x+y)-1 +#define IGA2_VER_SYNC_START_FORMULA(x) (x)-1 +#define IGA2_VER_SYNC_END_FORMULA(x,y) (x+y)-1 + +/**********************************************************/ +/* Definition IGA2 Design Method of CRTC Shadow Registers */ +/**********************************************************/ +#define IGA2_HOR_TOTAL_SHADOW_FORMULA(x) (x/8)-5 +#define IGA2_HOR_BLANK_END_SHADOW_FORMULA(x,y) ((x+y)/8)-1 +#define IGA2_VER_TOTAL_SHADOW_FORMULA(x) (x)-2 +#define IGA2_VER_ADDR_SHADOW_FORMULA(x) (x)-1 +#define IGA2_VER_BLANK_START_SHADOW_FORMULA(x) (x)-1 +#define IGA2_VER_BLANK_END_SHADOW_FORMULA(x,y) (x+y)-1 +#define IGA2_VER_SYNC_START_SHADOW_FORMULA(x) (x) +#define IGA2_VER_SYNC_END_SHADOW_FORMULA(x,y) (x+y) + +/* Define Register Number for IGA1 CRTC Timing */ +#define IGA1_HOR_TOTAL_REG_NUM 2 /* location: {CR00,0,7},{CR36,3,3} */ +#define IGA1_HOR_ADDR_REG_NUM 1 /* location: {CR01,0,7} */ +#define IGA1_HOR_BLANK_START_REG_NUM 1 /* location: {CR02,0,7} */ +#define IGA1_HOR_BLANK_END_REG_NUM 3 /* location: {CR03,0,4},{CR05,7,7},{CR33,5,5} */ +#define IGA1_HOR_SYNC_START_REG_NUM 2 /* location: {CR04,0,7},{CR33,4,4} */ +#define IGA1_HOR_SYNC_END_REG_NUM 1 /* location: {CR05,0,4} */ +#define IGA1_VER_TOTAL_REG_NUM 4 /* location: {CR06,0,7},{CR07,0,0},{CR07,5,5},{CR35,0,0} */ +#define IGA1_VER_ADDR_REG_NUM 4 /* location: {CR12,0,7},{CR07,1,1},{CR07,6,6},{CR35,2,2} */ +#define IGA1_VER_BLANK_START_REG_NUM 4 /* location: {CR15,0,7},{CR07,3,3},{CR09,5,5},{CR35,3,3} */ +#define IGA1_VER_BLANK_END_REG_NUM 1 /* location: {CR16,0,7} */ +#define IGA1_VER_SYNC_START_REG_NUM 4 /* location: {CR10,0,7},{CR07,2,2},{CR07,7,7},{CR35,1,1} */ +#define IGA1_VER_SYNC_END_REG_NUM 1 /* location: {CR11,0,3} */ + +/* Define Register Number for IGA2 Shadow CRTC Timing */ +#define IGA2_SHADOW_HOR_TOTAL_REG_NUM 2 /* location: {CR6D,0,7},{CR71,3,3} */ +#define IGA2_SHADOW_HOR_BLANK_END_REG_NUM 1 /* location: {CR6E,0,7} */ +#define IGA2_SHADOW_VER_TOTAL_REG_NUM 2 /* location: {CR6F,0,7},{CR71,0,2} */ +#define IGA2_SHADOW_VER_ADDR_REG_NUM 2 /* location: {CR70,0,7},{CR71,4,6} */ +#define IGA2_SHADOW_VER_BLANK_START_REG_NUM 2 /* location: {CR72,0,7},{CR74,4,6} */ +#define IGA2_SHADOW_VER_BLANK_END_REG_NUM 2 /* location: {CR73,0,7},{CR74,0,2} */ +#define IGA2_SHADOW_VER_SYNC_START_REG_NUM 2 /* location: {CR75,0,7},{CR76,4,6} */ +#define IGA2_SHADOW_VER_SYNC_END_REG_NUM 1 /* location: {CR76,0,3} */ + +/* Define Register Number for IGA2 CRTC Timing */ +#define IGA2_HOR_TOTAL_REG_NUM 2 /* location: {CR50,0,7},{CR55,0,3} */ +#define IGA2_HOR_ADDR_REG_NUM 2 /* location: {CR51,0,7},{CR55,4,6} */ +#define IGA2_HOR_BLANK_START_REG_NUM 2 /* location: {CR52,0,7},{CR54,0,2} */ +#define IGA2_HOR_BLANK_END_REG_NUM 3 /* location: CLE266: {CR53,0,7},{CR54,3,5} => CLE266's CR5D[6] is reserved, so it may have problem to set 1600x1200 on IGA2. */ + /* Others: {CR53,0,7},{CR54,3,5},{CR5D,6,6} */ +#define IGA2_HOR_SYNC_START_REG_NUM 4 /* location: {CR56,0,7},{CR54,6,7},{CR5C,7,7} */ + /* VT3314 and Later: {CR56,0,7},{CR54,6,7},{CR5C,7,7}, {CR5D,7,7} */ +#define IGA2_HOR_SYNC_END_REG_NUM 2 /* location: {CR57,0,7},{CR5C,6,6} */ +#define IGA2_VER_TOTAL_REG_NUM 2 /* location: {CR58,0,7},{CR5D,0,2} */ +#define IGA2_VER_ADDR_REG_NUM 2 /* location: {CR59,0,7},{CR5D,3,5} */ +#define IGA2_VER_BLANK_START_REG_NUM 2 /* location: {CR5A,0,7},{CR5C,0,2} */ +#define IGA2_VER_BLANK_END_REG_NUM 2 /* location: {CR5E,0,7},{CR5C,3,5} */ +#define IGA2_VER_SYNC_START_REG_NUM 2 /* location: {CR5E,0,7},{CR5F,5,7} */ +#define IGA2_VER_SYNC_END_REG_NUM 1 /* location: {CR5F,0,4} */ + +/* Define Offset and Fetch Count Register*/ +#define IGA1_OFFSET_REG_NUM 2 /* location: {CR13,0,7},{CR35,5,7} */ +#define IGA1_OFFSER_ALIGN_BYTE 8 /* 8 bytes alignment. */ +#define IGA1_OFFSET_FORMULA(x,y) (x*y)/IGA1_OFFSER_ALIGN_BYTE /* x: H resolution, y: color depth */ + +#define IGA1_FETCH_COUNT_REG_NUM 2 /* location: {SR1C,0,7},{SR1D,0,1} */ +#define IGA1_FETCH_COUNT_ALIGN_BYTE 16 /* 16 bytes alignment. */ +#define IGA1_FETCH_COUNT_PATCH_VALUE 4 /* x: H resolution, y: color depth */ +#define IGA1_FETCH_COUNT_FORMULA(x,y) ((x*y)/IGA1_FETCH_COUNT_ALIGN_BYTE)+ IGA1_FETCH_COUNT_PATCH_VALUE + +#define IGA2_OFFSET_REG_NUM 2 /* location: {CR66,0,7},{CR67,0,1} */ +#define IGA2_OFFSET_ALIGN_BYTE 8 +#define IGA2_OFFSET_FORMULA(x,y) (x*y)/IGA2_OFFSET_ALIGN_BYTE /* x: H resolution, y: color depth */ + +#define IGA2_FETCH_COUNT_REG_NUM 2 /* location: {CR65,0,7},{CR67,2,3} */ +#define IGA2_FETCH_COUNT_ALIGN_BYTE 16 +#define IGA2_FETCH_COUNT_PATCH_VALUE 0 +#define IGA2_FETCH_COUNT_FORMULA(x,y) ((x*y)/IGA2_FETCH_COUNT_ALIGN_BYTE)+ IGA2_FETCH_COUNT_PATCH_VALUE + +/* Staring Address */ +#define IGA1_STARTING_ADDR_REG_NUM 4 /* location: {CR0C,0,7},{CR0D,0,7},{CR34,0,7},{CR48,0,1} */ +#define IGA2_STARTING_ADDR_REG_NUM 3 /* location: {CR62,1,7},{CR63,0,7},{CR64,0,7} */ + +/* Define Display OFFSET */ +/* These value are by HW suggested value */ +#define K800_IGA1_FIFO_MAX_DEPTH 384 /* location: {SR17,0,7} */ +#define K800_IGA1_FIFO_THRESHOLD 328 /* location: {SR16,0,5},{SR16,7,7} */ +#define K800_IGA1_FIFO_HIGH_THRESHOLD 296 /* location: {SR18,0,5},{SR18,7,7} */ +#define K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0 /* location: {SR22,0,4}. (128/4) =64, K800 must be set zero, */ + /* because HW only 5 bits */ + +#define K800_IGA2_FIFO_MAX_DEPTH 384 /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */ +#define K800_IGA2_FIFO_THRESHOLD 328 /* location: {CR68,0,3},{CR95,4,6} */ +#define K800_IGA2_FIFO_HIGH_THRESHOLD 296 /* location: {CR92,0,3},{CR95,0,2} */ +#define K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128 /* location: {CR94,0,6} */ + +#define P880_IGA1_FIFO_MAX_DEPTH 192 /* location: {SR17,0,7} */ +#define P880_IGA1_FIFO_THRESHOLD 128 /* location: {SR16,0,5},{SR16,7,7} */ +#define P880_IGA1_FIFO_HIGH_THRESHOLD 64 /* location: {SR18,0,5},{SR18,7,7} */ +#define P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0 /* location: {SR22,0,4}. (128/4) =64, K800 must be set zero, */ + /* because HW only 5 bits */ + +#define P880_IGA2_FIFO_MAX_DEPTH 96 /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */ +#define P880_IGA2_FIFO_THRESHOLD 64 /* location: {CR68,0,3},{CR95,4,6} */ +#define P880_IGA2_FIFO_HIGH_THRESHOLD 32 /* location: {CR92,0,3},{CR95,0,2} */ +#define P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128 /* location: {CR94,0,6} */ + +/* VT3314 chipset*/ +#define CN900_IGA1_FIFO_MAX_DEPTH 96 /* location: {SR17,0,7}*/ +#define CN900_IGA1_FIFO_THRESHOLD 80 /* location: {SR16,0,5},{SR16,7,7}*/ +#define CN900_IGA1_FIFO_HIGH_THRESHOLD 64 /* location: {SR18,0,5},{SR18,7,7}*/ +#define CN900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0 /* location: {SR22,0,4}. (128/4) =64, P800 must be set zero, because HW only 5 bits*/ + +#define CN900_IGA2_FIFO_MAX_DEPTH 96 /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7}*/ +#define CN900_IGA2_FIFO_THRESHOLD 80 /* location: {CR68,0,3},{CR95,4,6}*/ +#define CN900_IGA2_FIFO_HIGH_THRESHOLD 32 /* location: {CR92,0,3},{CR95,0,2}*/ +#define CN900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128 /* location: {CR94,0,6}*/ + +/* For VT3324, these values are suggested by HW */ +#define CX700_IGA1_FIFO_MAX_DEPTH 192 /* location: {SR17,0,7}*/ +#define CX700_IGA1_FIFO_THRESHOLD 128 /* location: {SR16,0,5},{SR16,7,7}*/ +#define CX700_IGA1_FIFO_HIGH_THRESHOLD 128 /* location: {SR18,0,5},{SR18,7,7} */ +#define CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 124 /* location: {SR22,0,4} */ + +#define CX700_IGA2_FIFO_MAX_DEPTH 96 /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7}*/ +#define CX700_IGA2_FIFO_THRESHOLD 64 /* location: {CR68,0,3},{CR95,4,6}*/ +#define CX700_IGA2_FIFO_HIGH_THRESHOLD 32 /* location: {CR92,0,3},{CR95,0,2} */ +#define CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128 /* location: {CR94,0,6}*/ + +/* VT3336 chipset*/ +#define K8M890_IGA1_FIFO_MAX_DEPTH 360 /* location: {SR17,0,7}*/ +#define K8M890_IGA1_FIFO_THRESHOLD 328 /* location: {SR16,0,5},{SR16,7,7}*/ +#define K8M890_IGA1_FIFO_HIGH_THRESHOLD 296 /* location: {SR18,0,5},{SR18,7,7}*/ +#define K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 124 /* location: {SR22,0,4}.*/ + +#define K8M890_IGA2_FIFO_MAX_DEPTH 360 /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7}*/ +#define K8M890_IGA2_FIFO_THRESHOLD 328 /* location: {CR68,0,3},{CR95,4,6}*/ +#define K8M890_IGA2_FIFO_HIGH_THRESHOLD 296 /* location: {CR92,0,3},{CR95,0,2}*/ +#define K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 124 /* location: {CR94,0,6}*/ + +/* VT3327 chipset*/ +#define P4M890_IGA1_FIFO_MAX_DEPTH 96 /* location: {SR17,0,7}*/ +#define P4M890_IGA1_FIFO_THRESHOLD 76 /* location: {SR16,0,5},{SR16,7,7}*/ +#define P4M890_IGA1_FIFO_HIGH_THRESHOLD 64 /* location: {SR18,0,5},{SR18,7,7}*/ +#define P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 32 /* location: {SR22,0,4}. (32/4) =8*/ + +#define P4M890_IGA2_FIFO_MAX_DEPTH 96 /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7}*/ +#define P4M890_IGA2_FIFO_THRESHOLD 76 /* location: {CR68,0,3},{CR95,4,6}*/ +#define P4M890_IGA2_FIFO_HIGH_THRESHOLD 64 /* location: {CR92,0,3},{CR95,0,2}*/ +#define P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 32 /* location: {CR94,0,6}*/ + +/* VT3364 chipset*/ +#define P4M900_IGA1_FIFO_MAX_DEPTH 96 /* location: {SR17,0,7}*/ +#define P4M900_IGA1_FIFO_THRESHOLD 76 /* location: {SR16,0,5},{SR16,7,7}*/ +#define P4M900_IGA1_FIFO_HIGH_THRESHOLD 76 /* location: {SR18,0,5},{SR18,7,7}*/ +#define P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 32 /* location: {SR22,0,4}.*/ + +#define P4M900_IGA2_FIFO_MAX_DEPTH 96 /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7}*/ +#define P4M900_IGA2_FIFO_THRESHOLD 76 /* location: {CR68,0,3},{CR95,4,6}*/ +#define P4M900_IGA2_FIFO_HIGH_THRESHOLD 76 /* location: {CR92,0,3},{CR95,0,2}*/ +#define P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 32 /* location: {CR94,0,6}*/ + +#define IGA1_FIFO_DEPTH_SELECT_REG_NUM 1 +#define IGA1_FIFO_THRESHOLD_REG_NUM 2 +#define IGA1_FIFO_HIGH_THRESHOLD_REG_NUM 2 +#define IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM 1 + +#define IGA2_FIFO_DEPTH_SELECT_REG_NUM 3 +#define IGA2_FIFO_THRESHOLD_REG_NUM 2 +#define IGA2_FIFO_HIGH_THRESHOLD_REG_NUM 2 +#define IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM 1 + + +#define IGA1_FIFO_DEPTH_SELECT_FORMULA(x) (x/2)-1 +#define IGA1_FIFO_THRESHOLD_FORMULA(x) (x/4) +#define IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA(x) (x/4) +#define IGA1_FIFO_HIGH_THRESHOLD_FORMULA(x) (x/4) +#define IGA2_FIFO_DEPTH_SELECT_FORMULA(x) ((x/2)/4)-1 +#define IGA2_FIFO_THRESHOLD_FORMULA(x) (x/4) +#define IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA(x) (x/4) +#define IGA2_FIFO_HIGH_THRESHOLD_FORMULA(x) (x/4) + +/************************************************************************/ +/* LCD Timing */ +/************************************************************************/ +#define LCD_POWER_SEQ_TD0 500000 /* 500 ms = 500000 us */ +#define LCD_POWER_SEQ_TD1 50000 /* 50 ms = 50000 us */ +#define LCD_POWER_SEQ_TD2 0 /* 0 us */ +#define LCD_POWER_SEQ_TD3 210000 /* 210 ms = 210000 us */ + +#define CLE266_POWER_SEQ_UNIT 71 /* 2^10 * (1/14.31818M) = 71.475 us (K400.revA) */ +#define K800_POWER_SEQ_UNIT 142 /* 2^11 * (1/14.31818M) = 142.95 us (K400.revB) */ +#define P880_POWER_SEQ_UNIT 572 /* 2^13 * (1/14.31818M) = 572.1 us */ + +#define CLE266_POWER_SEQ_FORMULA(x) (x)/CLE266_POWER_SEQ_UNIT +#define K800_POWER_SEQ_FORMULA(x) (x)/K800_POWER_SEQ_UNIT +#define P880_POWER_SEQ_FORMULA(x) (x)/P880_POWER_SEQ_UNIT + + +#define LCD_POWER_SEQ_TD0_REG_NUM 2 /* location: {CR8B,0,7},{CR8F,0,3} */ +#define LCD_POWER_SEQ_TD1_REG_NUM 2 /* location: {CR8C,0,7},{CR8F,4,7} */ +#define LCD_POWER_SEQ_TD2_REG_NUM 2 /* location: {CR8D,0,7},{CR90,0,3} */ +#define LCD_POWER_SEQ_TD3_REG_NUM 2 /* location: {CR8E,0,7},{CR90,4,7} */ + + +/* LCD Scaling factor */ +/* x: indicate setting horizontal size */ +/* y: indicate panel horizontal size */ + +#define CLE266_LCD_HOR_SCF_FORMULA(x,y) (((x-1)*1024)/(y-1)) /* Horizontal scaling factor 10 bits (2^10) */ +#define CLE266_LCD_VER_SCF_FORMULA(x,y) (((x-1)*1024)/(y-1)) /* Vertical scaling factor 10 bits (2^10) */ +#define K800_LCD_HOR_SCF_FORMULA(x,y) (((x-1)*4096)/(y-1)) /* Horizontal scaling factor 10 bits (2^12) */ +#define K800_LCD_VER_SCF_FORMULA(x,y) (((x-1)*2048)/(y-1)) /* Vertical scaling factor 10 bits (2^11) */ + +#define LCD_HOR_SCALING_FACTOR_REG_NUM 3 /* location: {CR9F,0,1},{CR77,0,7},{CR79,4,5} */ +#define LCD_VER_SCALING_FACTOR_REG_NUM 3 /* location: {CR79,3,3},{CR78,0,7},{CR79,6,7} */ +#define LCD_HOR_SCALING_FACTOR_REG_NUM_CLE 2 /* location: {CR77,0,7},{CR79,4,5} */ +#define LCD_VER_SCALING_FACTOR_REG_NUM_CLE 2 /* location: {CR78,0,7},{CR79,6,7} */ + + + +/************************************************/ +/* Define IGA1 Display Timing */ +/************************************************/ +struct io_register { + u8 io_addr; + u8 start_bit; + u8 end_bit; +}; + + +/* IGA1 Horizontal Total */ +struct iga1_hor_total +{ + int reg_num; + struct io_register reg[IGA1_HOR_TOTAL_REG_NUM]; +}; + +/* IGA1 Horizontal Addressable Video */ +struct iga1_hor_addr { + int reg_num; + struct io_register reg[IGA1_HOR_ADDR_REG_NUM]; +}; + +/* IGA1 Horizontal Blank Start */ +struct iga1_hor_blank_start { + int reg_num; + struct io_register reg[IGA1_HOR_BLANK_START_REG_NUM]; +}; + +/* IGA1 Horizontal Blank End */ +struct iga1_hor_blank_end { + int reg_num; + struct io_register reg[IGA1_HOR_BLANK_END_REG_NUM]; +}; + +/* IGA1 Horizontal Sync Start */ +struct iga1_hor_sync_start { + int reg_num; + struct io_register reg[IGA1_HOR_SYNC_START_REG_NUM]; +}; + +/* IGA1 Horizontal Sync End */ +struct iga1_hor_sync_end { + int reg_num; + struct io_register reg[IGA1_HOR_SYNC_END_REG_NUM]; +}; + +/* IGA1 Vertical Total */ +struct iga1_ver_total { + int reg_num; + struct io_register reg[IGA1_VER_TOTAL_REG_NUM]; +}; + +/* IGA1 Vertical Addressable Video */ +struct iga1_ver_addr { + int reg_num; + struct io_register reg[IGA1_VER_ADDR_REG_NUM]; +}; + +/* IGA1 Vertical Blank Start */ +struct iga1_ver_blank_start { + int reg_num; + struct io_register reg[IGA1_VER_BLANK_START_REG_NUM]; +}; + +/* IGA1 Vertical Blank End */ +struct iga1_ver_blank_end { + int reg_num; + struct io_register reg[IGA1_VER_BLANK_END_REG_NUM]; +}; + +/* IGA1 Vertical Sync Start */ +struct iga1_ver_sync_start { + int reg_num; + struct io_register reg[IGA1_VER_SYNC_START_REG_NUM]; +}; + +/* IGA1 Vertical Sync End */ +struct iga1_ver_sync_end { + int reg_num; + struct io_register reg[IGA1_VER_SYNC_END_REG_NUM]; +}; + +/************************************************/ +/* Define IGA2 Shadow Display Timing */ +/************************************************/ + +/* IGA2 Shadow Horizontal Total */ +struct iga2_shadow_hor_total +{ + int reg_num; + struct io_register reg[IGA2_SHADOW_HOR_TOTAL_REG_NUM]; +}; + +/* IGA2 Shadow Horizontal Blank End */ +struct iga2_shadow_hor_blank_end { + int reg_num; + struct io_register reg[IGA2_SHADOW_HOR_BLANK_END_REG_NUM]; +}; + + +/* IGA2 Shadow Vertical Total */ +struct iga2_shadow_ver_total { + int reg_num; + struct io_register reg[IGA2_SHADOW_VER_TOTAL_REG_NUM]; +}; + +/* IGA2 Shadow Vertical Addressable Video */ +struct iga2_shadow_ver_addr { + int reg_num; + struct io_register reg[IGA2_SHADOW_VER_ADDR_REG_NUM]; +}; + +/* IGA2 Shadow Vertical Blank Start */ +struct iga2_shadow_ver_blank_start { + int reg_num; + struct io_register reg[IGA2_SHADOW_VER_BLANK_START_REG_NUM]; +}; + +/* IGA2 Shadow Vertical Blank End */ +struct iga2_shadow_ver_blank_end { + int reg_num; + struct io_register reg[IGA2_SHADOW_VER_BLANK_END_REG_NUM]; +}; + +/* IGA2 Shadow Vertical Sync Start */ +struct iga2_shadow_ver_sync_start { + int reg_num; + struct io_register reg[IGA2_SHADOW_VER_SYNC_START_REG_NUM]; +}; + +/* IGA2 Shadow Vertical Sync End */ +struct iga2_shadow_ver_sync_end { + int reg_num; + struct io_register reg[IGA2_SHADOW_VER_SYNC_END_REG_NUM]; +}; + +/************************************************/ +/* Define IGA2 Display Timing */ +/************************************************/ + +/* IGA2 Horizontal Total */ +struct iga2_hor_total { + int reg_num; + struct io_register reg[IGA2_HOR_TOTAL_REG_NUM]; +}; + +/* IGA2 Horizontal Addressable Video */ +struct iga2_hor_addr { + int reg_num; + struct io_register reg[IGA2_HOR_ADDR_REG_NUM]; +}; + +/* IGA2 Horizontal Blank Start */ +struct iga2_hor_blank_start { + int reg_num; + struct io_register reg[IGA2_HOR_BLANK_START_REG_NUM]; +}; + +/* IGA2 Horizontal Blank End */ +struct iga2_hor_blank_end { + int reg_num; + struct io_register reg[IGA2_HOR_BLANK_END_REG_NUM]; +}; + +/* IGA2 Horizontal Sync Start */ +struct iga2_hor_sync_start { + int reg_num; + struct io_register reg[IGA2_HOR_SYNC_START_REG_NUM]; +}; + +/* IGA2 Horizontal Sync End */ +struct iga2_hor_sync_end { + int reg_num; + struct io_register reg[IGA2_HOR_SYNC_END_REG_NUM]; +}; + +/* IGA2 Vertical Total */ +struct iga2_ver_total { + int reg_num; + struct io_register reg[IGA2_VER_TOTAL_REG_NUM]; +}; + +/* IGA2 Vertical Addressable Video */ +struct iga2_ver_addr { + int reg_num; + struct io_register reg[IGA2_VER_ADDR_REG_NUM]; +}; + +/* IGA2 Vertical Blank Start */ +struct iga2_ver_blank_start { + int reg_num; + struct io_register reg[IGA2_VER_BLANK_START_REG_NUM]; +}; + +/* IGA2 Vertical Blank End */ +struct iga2_ver_blank_end { + int reg_num; + struct io_register reg[IGA2_VER_BLANK_END_REG_NUM]; +}; + +/* IGA2 Vertical Sync Start */ +struct iga2_ver_sync_start { + int reg_num; + struct io_register reg[IGA2_VER_SYNC_START_REG_NUM]; +}; + +/* IGA2 Vertical Sync End */ +struct iga2_ver_sync_end { + int reg_num; + struct io_register reg[IGA2_VER_SYNC_END_REG_NUM]; +}; + +/* IGA1 Offset Register */ +struct iga1_offset { + int reg_num; + struct io_register reg[IGA1_OFFSET_REG_NUM]; +}; + +/* IGA2 Offset Register */ +struct iga2_offset { + int reg_num; + struct io_register reg[IGA2_OFFSET_REG_NUM]; +}; + +struct offset{ + struct iga1_offset iga1_offset_reg; + struct iga2_offset iga2_offset_reg; +}; + +/* IGA1 Fetch Count Register */ +struct iga1_fetch_count { + int reg_num; + struct io_register reg[IGA1_FETCH_COUNT_REG_NUM]; +}; + +/* IGA2 Fetch Count Register */ +struct iga2_fetch_count { + int reg_num; + struct io_register reg[IGA2_FETCH_COUNT_REG_NUM]; +}; + +struct fetch_count{ + struct iga1_fetch_count iga1_fetch_count_reg; + struct iga2_fetch_count iga2_fetch_count_reg; +}; + +/* Starting Address Register */ +struct iga1_starting_addr { + int reg_num; + struct io_register reg[IGA1_STARTING_ADDR_REG_NUM]; +}; + +struct iga2_starting_addr { + int reg_num; + struct io_register reg[IGA2_STARTING_ADDR_REG_NUM]; +}; + +struct starting_addr { + struct iga1_starting_addr iga1_starting_addr_reg; + struct iga2_starting_addr iga2_starting_addr_reg; +}; + +/* LCD Power Sequence Timer */ +struct lcd_pwd_seq_td0{ + int reg_num; + struct io_register reg[LCD_POWER_SEQ_TD0_REG_NUM]; +}; + +struct lcd_pwd_seq_td1{ + int reg_num; + struct io_register reg[LCD_POWER_SEQ_TD1_REG_NUM]; +}; + +struct lcd_pwd_seq_td2{ + int reg_num; + struct io_register reg[LCD_POWER_SEQ_TD2_REG_NUM]; +}; + +struct lcd_pwd_seq_td3{ + int reg_num; + struct io_register reg[LCD_POWER_SEQ_TD3_REG_NUM]; +}; + +struct _lcd_pwd_seq_timer{ + struct lcd_pwd_seq_td0 td0; + struct lcd_pwd_seq_td1 td1; + struct lcd_pwd_seq_td2 td2; + struct lcd_pwd_seq_td3 td3; +}; + +/* LCD Scaling Factor */ +struct _lcd_hor_scaling_factor{ + int reg_num; + struct io_register reg[LCD_HOR_SCALING_FACTOR_REG_NUM]; +}; + +struct _lcd_ver_scaling_factor{ + int reg_num; + struct io_register reg[LCD_VER_SCALING_FACTOR_REG_NUM]; +}; + + +struct _lcd_scaling_factor{ + struct _lcd_hor_scaling_factor lcd_hor_scaling_factor; + struct _lcd_ver_scaling_factor lcd_ver_scaling_factor; +}; + +struct pll_map { + u32 clk; + u32 cle266_pll; + u32 k800_pll; + u32 cx700_pll; +}; + +struct rgbLUT { + u8 red; + u8 green; + u8 blue; +}; + +struct lcd_pwd_seq_timer { + u16 td0; + u16 td1; + u16 td2; + u16 td3; +}; + + +/* Display FIFO Relation Registers */ +struct iga1_fifo_depth_select { + int reg_num; + struct io_register reg[IGA1_FIFO_DEPTH_SELECT_REG_NUM]; +}; + +struct iga1_fifo_threshold_select { + int reg_num; + struct io_register reg[IGA1_FIFO_THRESHOLD_REG_NUM]; +}; + +struct iga1_fifo_high_threshold_select { + int reg_num; + struct io_register reg[IGA1_FIFO_HIGH_THRESHOLD_REG_NUM]; +}; + +struct iga1_display_queue_expire_num { + int reg_num; + struct io_register reg[IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM]; +}; + +struct iga2_fifo_depth_select { + int reg_num; + struct io_register reg[IGA2_FIFO_DEPTH_SELECT_REG_NUM]; +}; + +struct iga2_fifo_threshold_select { + int reg_num; + struct io_register reg[IGA2_FIFO_THRESHOLD_REG_NUM]; +}; + +struct iga2_fifo_high_threshold_select { + int reg_num; + struct io_register reg[IGA2_FIFO_HIGH_THRESHOLD_REG_NUM]; +}; + +struct iga2_display_queue_expire_num { + int reg_num; + struct io_register reg[IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM]; +}; + +struct fifo_depth_select { + struct iga1_fifo_depth_select iga1_fifo_depth_select_reg; + struct iga2_fifo_depth_select iga2_fifo_depth_select_reg; +}; + +struct fifo_threshold_select { + struct iga1_fifo_threshold_select iga1_fifo_threshold_select_reg; + struct iga2_fifo_threshold_select iga2_fifo_threshold_select_reg; +}; + +struct fifo_high_threshold_select { + struct iga1_fifo_high_threshold_select iga1_fifo_high_threshold_select_reg; + struct iga2_fifo_high_threshold_select iga2_fifo_high_threshold_select_reg; +}; + +struct display_queue_expire_num { + struct iga1_display_queue_expire_num iga1_display_queue_expire_num_reg; + struct iga2_display_queue_expire_num iga2_display_queue_expire_num_reg; +}; + + + +struct iga1_crtc_timing { + struct iga1_hor_total hor_total; + struct iga1_hor_addr hor_addr; + struct iga1_hor_blank_start hor_blank_start; + struct iga1_hor_blank_end hor_blank_end; + struct iga1_hor_sync_start hor_sync_start; + struct iga1_hor_sync_end hor_sync_end; + struct iga1_ver_total ver_total; + struct iga1_ver_addr ver_addr; + struct iga1_ver_blank_start ver_blank_start; + struct iga1_ver_blank_end ver_blank_end; + struct iga1_ver_sync_start ver_sync_start; + struct iga1_ver_sync_end ver_sync_end; +}; + +struct iga2_shadow_crtc_timing { + struct iga2_shadow_hor_total hor_total_shadow; + struct iga2_shadow_hor_blank_end hor_blank_end_shadow; + struct iga2_shadow_ver_total ver_total_shadow; + struct iga2_shadow_ver_addr ver_addr_shadow; + struct iga2_shadow_ver_blank_start ver_blank_start_shadow; + struct iga2_shadow_ver_blank_end ver_blank_end_shadow; + struct iga2_shadow_ver_sync_start ver_sync_start_shadow; + struct iga2_shadow_ver_sync_end ver_sync_end_shadow; +}; + +struct iga2_crtc_timing { + struct iga2_hor_total hor_total; + struct iga2_hor_addr hor_addr; + struct iga2_hor_blank_start hor_blank_start; + struct iga2_hor_blank_end hor_blank_end; + struct iga2_hor_sync_start hor_sync_start; + struct iga2_hor_sync_end hor_sync_end; + struct iga2_ver_total ver_total; + struct iga2_ver_addr ver_addr; + struct iga2_ver_blank_start ver_blank_start; + struct iga2_ver_blank_end ver_blank_end; + struct iga2_ver_sync_start ver_sync_start; + struct iga2_ver_sync_end ver_sync_end; +}; + +/* Copied from X driver code */ +/* used by get video memory size */ +/* device ID */ +#define CLE266 0x3123 +#define KM400 0x3205 +#define CN400_FUNCTION2 0x2259 +#define CN400_FUNCTION3 0x3259 +/* support VT3314 chipset */ +#define CN900_FUNCTION2 0x2314 +#define CN900_FUNCTION3 0x3208 +/* VT3324 chipset */ +#define CX700_FUNCTION2 0x2324 +#define CX700_FUNCTION3 0x3324 +/* VT3204 chipset*/ +#define KM800_FUNCTION3 0x3204 +/* VT3336 chipset*/ +#define KM890_FUNCTION3 0x3336 +/* VT3327 chipset*/ +#define P4M890_FUNCTION3 0x3327 +/* VT3293 chipset*/ +#define CN750_FUNCTION3 0x3208 +/* VT3364 chipset*/ +#define P4M900_FUNCTION3 0x3364 + +typedef struct IODATA { + u8 Index; + u8 Mask; + u8 Data; +}IODATA, *IODATAPTR; + +#endif /* __HW_H__ */ + + + +
diff -Nur linux-2.6.21-rc7/drivers/video/via/iface.c linux-2.6.21-rc7.viafb/drivers/video/via/iface.c
--- linux-2.6.21-rc7/drivers/video/via/iface.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.21-rc7.viafb/drivers/video/via/iface.c 2007-04-26 19:52:32.000000000 -0400@@ -0,0 +1,90 @@ + /* + * Copyright 1998-2007 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2007 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + + +#include <linux/ioport.h> +#include <linux/pci.h> +#include <asm/io.h> + +#include "iface.h" +#include "debug.h" +#include "share.h" + +/* Get frame buffer size from VGA BIOS */ +extern inline u8 read_reg(int io_port, u8 index); +extern int memsize; + +unsigned int get_memsize(void) +{ + unsigned int m; + + /* If memory size provided by user */ + if (memsize) + m = memsize * Mb; + else + { + m = (unsigned int) read_reg(VIASR, SR39); + m = m*(4*Mb); + + if((m < (16*Mb)) || (m > (64*Mb))) + m = 16*Mb; + } + DEBUG_MSG(KERN_INFO "framebuffer size = %d Mb\n", m/Mb); + return m; +} + +/* Get Video Buffer Starting Physical Address(back door) */ + +unsigned long get_videobuf_addr(void) +{ + struct pci_dev *pdev=NULL; + unsigned char sys_mem; + unsigned char video_mem; + unsigned long sys_mem_size; + unsigned long video_mem_size; + unsigned long vmem_starting_adr = 0x0C000000; /* system memory = 256 MB, video memory 64 MB */ + + pdev = (struct pci_dev *)pci_find_device(VIA_K800_BRIDGE_VID, VIA_K800_BRIDGE_DID, NULL); + if (pdev != NULL) + { + pci_read_config_byte(pdev, VIA_K800_SYSTEM_MEMORY_REG, &sys_mem); + pci_read_config_byte(pdev, VIA_K800_VIDEO_MEMORY_REG, &video_mem); + video_mem = (video_mem & 0x70) >> 4; + sys_mem_size = ((unsigned long)sys_mem) << 24; + if (video_mem != 0) + video_mem_size = (1 << (video_mem)) *1024*1024; + else + video_mem_size = 0; + + vmem_starting_adr = sys_mem_size - video_mem_size; + + } + + DEBUG_MSG(KERN_INFO "Video Memory Starting Address = %lx \n", vmem_starting_adr); + return vmem_starting_adr; +} + + + +
diff -Nur linux-2.6.21-rc7/drivers/video/via/iface.h linux-2.6.21-rc7.viafb/drivers/video/via/iface.h
--- linux-2.6.21-rc7/drivers/video/via/iface.h 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.21-rc7.viafb/drivers/video/via/iface.h 2007-04-26 19:52:32.000000000 -0400@@ -0,0 +1,15 @@ +#ifndef __IFACE_H__ +#define __IFACE_H__ + +#define Kb (1024) +#define Mb (Kb*Kb) + +#define VIA_K800_BRIDGE_VID 0x1106 +#define VIA_K800_BRIDGE_DID 0x3204 + +#define VIA_K800_SYSTEM_MEMORY_REG 0x47 +#define VIA_K800_VIDEO_MEMORY_REG 0xA1 + +#endif /* __IFACE_H__ */ + +
diff -Nur linux-2.6.21-rc7/drivers/video/via/IntegratedTV.c linux-2.6.21-rc7.viafb/drivers/video/via/IntegratedTV.c
--- linux-2.6.21-rc7/drivers/video/via/IntegratedTV.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.21-rc7.viafb/drivers/video/via/IntegratedTV.c 2007-04-26 19:52:32.000000000 -0400@@ -0,0 +1,1448 @@ +/* + * Copyright 1998-2007 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2007 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <linux/ioport.h> +#include <asm/io.h> +#include <linux/fb.h> + +#include "viafbdev.h" +#include "tv.h" +#include "share.h" +#include "chip.h" +#include "debug.h" +#include "tblIntegratedTV.h" +#include "IntegratedTV.h" +#include "ioctl.h" + +extern struct tv_setting_information tv_setting_info; +extern struct chip_information chip_info; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +extern struct viafb_info viafbinfo; +#else +extern struct viafb_par parinfo; +#endif + +extern inline void write_reg(u8 index, u16 io_port, u8 data); +extern inline u8 read_reg(int io_port, u8 index); +extern void write_reg_mask(u8 index, int io_port, u8 data, u8 mask); +extern void enable_second_display_channel(void); +extern void plus_vck_to_iga1_timing(unsigned long h_total); +extern void delays(int count); +extern void load_crtc_timing(struct display_timing device_timing, int set_iga); + +bool g_first_time_to_sense = TRUE; + +void enable_integrated_tv_shadow_reg(void) +{ + int i; + + /* Enable integrated TV shadow register. */ + /* Only for A0000 now, we may modify this if need other TV shadow memory. */ + write_reg(SR52, VIASR, 0x01); + + /* Wait data ready. */ + for (i=0; i<10; i++) + { + if (read_reg(VIASR, SR52) & BIT0) + { + break; + } + } +} + + +void disable_integrated_tv_shadow_reg(void) +{ + write_reg(SR52, VIASR, 0x00); +} + + +void write_integrated_tv_reg8(unsigned char* mmio_base, u8 offset, u8 data) +{ + *(volatile u8 *)(mmio_base + offset) = data; + DEBUG_MSG(KERN_INFO "Write Integrated TV Reg (byte): Offset 0x%2x, Value 0x%2x!\n", offset, data); +} + + +void write_integrated_tv_reg32(unsigned char* mmio_base, u8 offset, u32 data) +{ + *(volatile u32 *)(mmio_base + offset) = data; + DEBUG_MSG(KERN_INFO "Write Integrated TV Reg: Offset 0x%2x, Value 0x%8x!\n", offset, data); +} + + +void write_integrated_tv_reg_mask32(unsigned char* mmio_base, u8 offset, u32 mask, u32 data) +{ + u32 old_data, new_data; + + old_data = *(volatile u32 *)(mmio_base + offset); + new_data = (data & mask) | (old_data & (~mask)); + *(volatile u32 *)(mmio_base + offset) = new_data; + + DEBUG_MSG(KERN_INFO "Write Integrated TV Reg Mask: Offset 0x%2x, Value 0x%8x!\n", offset, new_data); +} + + +u32 read_integrated_tv_reg32(unsigned char* mmio_base, u8 offset) +{ + u32 data; + + data = *(volatile u32 *)(mmio_base + offset); + + return data; +} + + +void write_integrated_tv_general_table(unsigned short *tv_reg_offset_table, unsigned long *tv_reg_table) +{ + int i = 0; + unsigned char* mmio_base; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + mmio_base = (unsigned char*)viafbinfo.integrated_tv_map_base; +#else + mmio_base = (unsigned char*)parinfo.integrated_tv_map_base; +#endif + + while(tv_reg_offset_table[i] != 0xFFFF) + { + write_integrated_tv_reg32(mmio_base, GET_LOW_BYTE(tv_reg_offset_table[i]), tv_reg_table[i]); + i++; + } +} + + +void write_integrated_tv_patch_table(u16 *tv_reg_table) +{ + int i = 0; + unsigned char* mmio_base; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + mmio_base = (unsigned char*)viafbinfo.integrated_tv_map_base; +#else + mmio_base = (unsigned char*)parinfo.integrated_tv_map_base; +#endif + + while(tv_reg_table[i] != 0xFFFF) + { + write_integrated_tv_reg8(mmio_base, GET_LOW_BYTE(tv_reg_table[i]), GET_HIGH_BYTE(tv_reg_table[i])); + i++; + } +} + + +u32 access_integrated_tv_regs(int reg_id, u32 value, int cmd) +{ + u8 offset; + u32 mask, set_data, get_data, shift_bits, tmp1, tmp2; + unsigned char* mmio_base; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + mmio_base = (unsigned char*)viafbinfo.integrated_tv_map_base; +#else + mmio_base = (unsigned char*)parinfo.integrated_tv_map_base; +#endif + + /* Note: It's better to call enable_integrated_tv_shadow_reg() to enable integrated TV shadow register */ + /* before access the following registers, or it may fail to access them. */ + + switch (reg_id) + { + case ITV_REG_ID_PK_ENABLE: + { + /* 00[0] */ + offset = 0x00; + mask = 0x00000001; + shift_bits = 0; + + break; + } + + case ITV_REG_ID_SRC_SEL: + { + /* 00[18] */ + offset = 0x00; + mask = 0x00040000; + shift_bits = 18; + + break; + } + + case ITV_REG_ID_SW_RESET: + { + /* 00[20] */ + offset = 0x00; + mask = 0x00100000; + shift_bits = 20; + + break; + } + + case ITV_REG_ID_SYNC_BUF_MODE: + { + /* 00[30] */ + offset = 0x00; + mask = 0x40000000; + shift_bits = 30; + + break; + } + + case ITV_REG_ID_SD_ENABLE: + { + /* 00[31] */ + offset = 0x00; + mask = 0x80000000; + shift_bits = 31; + + break; + } + + case ITV_REG_ID_SRC_VSIZE: + { + /* 18[10:0] */ + offset = 0x18; + mask = 0x000007FF; + shift_bits = 0; + + break; + } + + case ITV_REG_ID_SRC_HSIZE: + { + /* 18[21:11] */ + offset = 0x18; + mask = 0x003FF800; + shift_bits = 11; + + break; + } + + case ITV_REG_ID_DE_FLK_THRESHOLD: + { + /* 20[31:27] + 20[15:11] */ + offset = 0x20; + + if (cmd == ITV_CMD_WRITE) + { + tmp1 = value & 0x1F; /* bit4-bit0 */ + tmp2 = (value >> 5) & 0x1F; /* bit9-bit5 */ + set_data = (tmp2 << 27) | (tmp1 << 11); + write_integrated_tv_reg_mask32(mmio_base, offset, 0xF800F800, set_data); + + return 0; /* 0 means nothing, just for return. */ + } + else + { + get_data = read_integrated_tv_reg32(mmio_base, offset); + tmp1 = (get_data & 0x0000F800) >> 11; /* bit4-bit0 */ + tmp2 = (get_data & 0xF8000000) >> 27; /* bit9-bit5 */ + get_data = (tmp2 << 5) | tmp1; + + return get_data; + } + } + + case ITV_REG_ID_SCL_VFAC: + { + /* 24[12:0] */ + offset = 0x24; + mask = 0x00001FFF; + shift_bits = 0; + + break; + } + + case ITV_REG_ID_DE_FLK_NUM: + { + /* 24[13] */ + offset = 0x24; + mask = 0x00002000; + shift_bits = 13; + + break; + } + + case ITV_REG_ID_DF_WT_SEL: + { + /* 24[14] */ + offset = 0x24; + mask = 0x00004000; + shift_bits = 14; + + break; + } + + case ITV_REG_ID_DF_TYPE: + { + /* 24[15] */ + offset = 0x24; + mask = 0x00008000; + shift_bits = 15; + + break; + } + + case ITV_REG_ID_DE_FLICKER_ENABLE: + { + /* 24[29] */ + offset = 0x24; + mask = 0x20000000; + shift_bits = 29; + + break; + } + + case ITV_REG_ID_SCL_HFAC: + { + /* 24[28:16] */ + offset = 0x24; + mask = 0x1FFF0000; + shift_bits = 16; + + break; + } + + case ITV_REG_ID_DST_VSIZE: + { + /* 28[10:0] */ + offset = 0x28; + mask = 0x000007FF; + shift_bits = 0; + + break; + } + + case ITV_REG_ID_DST_HSIZE: + { + /* 28[21:11] */ + offset = 0x28; + mask = 0x003FF800; + shift_bits = 11; + + break; + } + + case ITV_REG_ID_TV_ENABLE: + { + /* 38[0] */ + offset = 0x38; + mask = 0x00000001; + shift_bits = 0; + + break; + } + + case ITV_REG_ID_OUTPUT_SEL: + { + /* 38[29:28] */ + offset = 0x38; + mask = 0x30000000; + shift_bits = 28; + + break; + } + + case ITV_REG_ID_TV_SENSE: + { + /* 3C[15:14] */ + offset = 0x3C; + mask = 0x0000C000; + shift_bits = 14; + + break; + } + + case ITV_REG_ID_TV_SENSE_DATA: + { + /* 3C[31:24] */ + offset = 0x3C; + mask = 0xFF000000; + shift_bits = 24; + + break; + } + + case ITV_REG_ID_DST_HSD: + { + /* 48[30:21] */ + offset = 0x48; + mask = 0x7FE00000; + shift_bits = 21; + + break; + } + + case ITV_REG_ID_DST_VSD: + { + /* 4C[31:23] */ + offset = 0x4C; + mask = 0xFF800000; + shift_bits = 23; + + break; + } + + case ITV_REG_ID_SATURATION: + { + /* 50[8:0] + 50[24:16] */ + offset = 0x50; + + if (cmd == ITV_CMD_WRITE) + { + tmp1 = value & 0x1FF; /* bit8-bit0 */ + tmp2 = (value >> 9) & 0x1FF; /* bit24-bit16 */ + set_data = ((tmp2 << 16) | (tmp1)); + write_integrated_tv_reg_mask32(mmio_base, offset, 0x01FF01FF, set_data); + + return 0; /* 0 means nothing, just for return. */ + } + else + { + get_data = read_integrated_tv_reg32(mmio_base, offset); + tmp1 = (get_data & 0x000001FF); /* bit8-bit0 */ + tmp2 = (get_data & 0x01FF0000) >> 16; /* bit24-bit16 */ + get_data = (tmp2 << 9) | tmp1; + + return get_data; + } + } + + case ITV_REG_ID_CONTRAST: + { + /* 54[8:0] */ + offset = 0x54; + mask = 0x000001FF; + shift_bits = 0; + break; + } + + case ITV_REG_ID_BLACK_LEVEL: + { + /* 54[30:23] */ + offset = 0x54; + mask = 0x7F800000; + shift_bits = 23; + break; + } + + case ITV_REG_ID_HUE: + { + /* 60[10:0] */ + offset = 0x60; + mask = 0x000007FF; + shift_bits = 0; + break; + } + + case ITV_REG_ID_PRI_DAC_SEL: + { + /* 6C[12] */ + offset = 0x6C; + mask = 0x00001000; + shift_bits = 12; + + break; + } + + case ITV_REG_ID_TV_SENSE_STATUS: + { + /* E4[2] */ + offset = 0xE4; + mask = 0x00000004; + shift_bits = 2; + + break; + } + + case ITV_REG_ID_PBPR_BLANK_LEVEL: + { + /* E8[8:0] */ + offset = 0xE8; + mask = 0x000000FF; + shift_bits = 0; + break; + } + + case ITV_REG_ID_TV_SENSE_RGB_STATUS: + { + /* E8[30:28] */ + offset = 0xE8; + mask = 0x70000000; + shift_bits = 28; + + break; + } + + default: + { + return 0; /* 0 means nothing, just for return. */ + } + } + + if (cmd == ITV_CMD_WRITE) + { + set_data = value << shift_bits; + write_integrated_tv_reg_mask32(mmio_base, offset, mask, set_data); + + return 0; /* 0 means nothing, just for return. */ + } + else + { + get_data = read_integrated_tv_reg32(mmio_base, offset); + get_data = (get_data & mask) >> shift_bits; + + return get_data; + } +} + + +void set_integrated_tv_output_signal(void) +{ + u8 sr5e; + + /* HDTV only can use RGB or YPbPr output. */ + if ((tv_setting_info.system == TVTYPE_480P) || (tv_setting_info.system == TVTYPE_576P) || + (tv_setting_info.system == TVTYPE_720P) || (tv_setting_info.system == TVTYPE_1080I)) + + { + if ((tv_setting_info.out_signal != TV_OUTPUT_RGB) && + (tv_setting_info.out_signal != TV_OUTPUT_YPBPR)) + { + tv_setting_info.out_signal = TV_OUTPUT_RGB; + } + } + + DEBUG_MSG(KERN_INFO "set_integrated_tv_output_signal: TVOutput = %d\n", tv_setting_info.out_signal); + + /* We could separate Composite and S-Video by controlling DAC R/G/B. */ + sr5e = read_reg(VIASR, SR5E) & 0xF1; /* Turn on DAC R/G/B. */ + + switch (tv_setting_info.out_signal) + { + case TV_OUTPUT_COMPOSITE: + { + access_integrated_tv_regs(ITV_REG_ID_OUTPUT_SEL, ITV_VALUE_OUTPUT_SC, ITV_CMD_WRITE); + + /* Turn off DAC R and G, turn on DAC B. */ + write_reg(SR5E, VIASR, sr5e | (BIT1+BIT2)); + break; + } + + case TV_OUTPUT_SVIDEO: + { + access_integrated_tv_regs(ITV_REG_ID_OUTPUT_SEL, ITV_VALUE_OUTPUT_SC, ITV_CMD_WRITE); + + /* Turn on DAC R and G, turn off DAC B. */ + write_reg(SR5E, VIASR, sr5e | BIT3); + break; + } + + case TV_OUTPUT_COMPOSITE_SVIDEO: + { + access_integrated_tv_regs(ITV_REG_ID_OUTPUT_SEL, ITV_VALUE_OUTPUT_SC, ITV_CMD_WRITE); + + /* Turn on DAC R/G/B. */ + write_reg(SR5E, VIASR, sr5e); + break; + } + + case TV_OUTPUT_RGB: + { + access_integrated_tv_regs(ITV_REG_ID_OUTPUT_SEL, ITV_VALUE_OUTPUT_RGB, ITV_CMD_WRITE); + + /* Turn on DAC R/G/B. */ + write_reg(SR5E, VIASR, sr5e); + break; + } + + case TV_OUTPUT_YPBPR: + { + access_integrated_tv_regs(ITV_REG_ID_OUTPUT_SEL, ITV_VALUE_OUTPUT_YPbPr, ITV_CMD_WRITE); + + /* Turn on DAC R/G/B. */ + write_reg(SR5E, VIASR, sr5e); + break; + } + + default: + { + access_integrated_tv_regs(ITV_REG_ID_OUTPUT_SEL, ITV_VALUE_OUTPUT_SC, ITV_CMD_WRITE); + + /* Turn off DAC R and G, turn on DAC B. */ + write_reg(SR5E, VIASR, sr5e | (BIT1+BIT2)); + break; + } + } +} + + +void write_gfx_crtc_timing_for_tv(unsigned long *tv_crtc_table) +{ + int i; + struct display_timing tv_crtc_reg; + + for (i=0; i< NUM_CRTC_TIMING; i++) + { + switch(i) + { + case H_TOTAL_INDEX: + tv_crtc_reg.hor_total = tv_crtc_table[i]; + DEBUG_MSG(KERN_INFO "H_Total: %d!\n", tv_crtc_reg.hor_total); + break; + + case H_ADDR_INDEX: + tv_crtc_reg.hor_addr = tv_crtc_table[i]; + DEBUG_MSG(KERN_INFO "H_Addr: %d!\n", tv_crtc_reg.hor_addr); + break; + + case H_BLANK_START_INDEX: + tv_crtc_reg.hor_blank_start = tv_crtc_table[i]; + DEBUG_MSG(KERN_INFO "H_Blank_Start: %d!\n", tv_crtc_reg.hor_blank_start); + break; + + case H_BLANK_END_INDEX: + tv_crtc_reg.hor_blank_end = tv_crtc_table[i]; + DEBUG_MSG(KERN_INFO "H_Blank_End: %d!\n", tv_crtc_reg.hor_blank_end); + break; + + case H_SYNC_START_INDEX: + tv_crtc_reg.hor_sync_start = tv_crtc_table[i]; + DEBUG_MSG(KERN_INFO "H_Sync_Start: %d!\n", tv_crtc_reg.hor_sync_start); + break; + + case H_SYNC_END_INDEX: + tv_crtc_reg.hor_sync_end = tv_crtc_table[i]; + DEBUG_MSG(KERN_INFO "H_Sync_End: %d!\n", tv_crtc_reg.hor_sync_end); + break; + + case V_TOTAL_INDEX: + tv_crtc_reg.ver_total = tv_crtc_table[i]; + break; + + case V_ADDR_INDEX: + tv_crtc_reg.ver_addr = tv_crtc_table[i]; + break; + + case V_BLANK_START_INDEX: + tv_crtc_reg.ver_blank_start = tv_crtc_table[i]; + break; + + case V_BLANK_END_INDEX: + tv_crtc_reg.ver_blank_end = tv_crtc_table[i]; + break; + + case V_SYNC_START_INDEX: + tv_crtc_reg.ver_sync_start = tv_crtc_table[i]; + break; + + case V_SYNC_END_INDEX: + tv_crtc_reg.ver_sync_end = tv_crtc_table[i]; + break; + + } + } + + load_crtc_timing(tv_crtc_reg, tv_setting_info.iga_path); +} + + +void update_scaling_factor(void) +{ + u32 dst_hsize, dst_vsize, src_hsize, src_vsize, scal_factor = 0; + + dst_hsize = access_integrated_tv_regs(ITV_REG_ID_DST_HSIZE, 0, ITV_CMD_READ) + 1; + dst_vsize = access_integrated_tv_regs(ITV_REG_ID_DST_VSIZE, 0, ITV_CMD_READ) + 1; + src_hsize = access_integrated_tv_regs(ITV_REG_ID_SRC_HSIZE, 0, ITV_CMD_READ) + 1; + src_vsize = access_integrated_tv_regs(ITV_REG_ID_SRC_VSIZE, 0, ITV_CMD_READ) + 1; + + if ((tv_setting_info.system == TVTYPE_480P) || + (tv_setting_info.system == TVTYPE_576P) || + (tv_setting_info.system == TVTYPE_1080I)) + { + scal_factor = (src_hsize * 2048) / dst_hsize; + } + else if (tv_setting_info.system == TVTYPE_720P) + { + /* The two modes 720x480 and 720x576 have alignment issue (alignment to 4), + so the value of SRC_LINE_PITCH, DST_DQW_NUM and DST_LINE_PITCH + we set are greater than the desired ones, and this may cause the problem about + having garbage line on the right side, so we reduce the scaling factor to avoid + this problem. */ + if (((src_hsize == 720) && (src_vsize == 480)) || + ((src_hsize == 720) && (src_vsize == 576))) + { + scal_factor = ((src_hsize * 2048) / dst_hsize) - 3; + } + else + { + scal_factor = (src_hsize * 2048) / dst_hsize; + } + } + else + { + scal_factor = (src_hsize * 2048) / (dst_hsize * 2); + } + + access_integrated_tv_regs(ITV_REG_ID_SCL_HFAC, scal_factor, ITV_CMD_WRITE); + + scal_factor = (src_vsize * 2048) / dst_vsize; + access_integrated_tv_regs(ITV_REG_ID_SCL_VFAC, scal_factor, ITV_CMD_WRITE); +} + + +void set_hdtv_patch_table(int mode_index) +{ + switch(tv_setting_info.system) + { + case TVTYPE_480P: + write_integrated_tv_patch_table(ITV_HDTV_PATCH_TABLE[mode_index].std_480p); + break; + + case TVTYPE_576P: + write_integrated_tv_patch_table(ITV_HDTV_PATCH_TABLE[mode_index].std_576p); + break; + + case TVTYPE_720P: + write_integrated_tv_patch_table(ITV_HDTV_PATCH_TABLE[mode_index].std_720p); + break; + + case TVTYPE_1080I: + write_integrated_tv_patch_table(ITV_HDTV_PATCH_TABLE[mode_index].std_1080i); + break; + + default: + break; + } +} + + +void set_tv_output_patch_table(void) +{ + if (tv_setting_info.out_signal == TV_OUTPUT_RGB) + { + if (tv_setting_info.system == TVTYPE_NTSC) + { + write_integrated_tv_patch_table(ITV_PATCH_TABLE_RGB_NTSC); + } + else if (tv_setting_info.system == TVTYPE_PAL) + { + write_integrated_tv_patch_table(ITV_PATCH_TABLE_RGB_PAL); + } + } + else if (tv_setting_info.out_signal == TV_OUTPUT_YPBPR) + { + if (tv_setting_info.system == TVTYPE_NTSC) + { + write_integrated_tv_patch_table(ITV_PATCH_TABLE_YPBPR_NTSC); + } + else if (tv_setting_info.system == TVTYPE_PAL) + { + write_integrated_tv_patch_table(ITV_PATCH_TABLE_YPBPR_PAL); + } + } +} + +void patch_for_macrovision(void) +{ + /* We should do this patch for this issue: */ + /* The H-sync cycle of VT3324A3 integrated TV disappeared when disable TV macrovision. */ + if (CX700_REVISION_700M2 != chip_info.gfx_chip_revision) /* Macrovision disable. */ + { + switch (tv_setting_info.system) + { + case TVTYPE_NTSC: + case TVTYPE_480P: + access_integrated_tv_regs(ITV_REG_ID_PBPR_BLANK_LEVEL, 0x6D, ITV_CMD_WRITE); + break; + + case TVTYPE_PAL: + case TVTYPE_576P: + access_integrated_tv_regs(ITV_REG_ID_PBPR_BLANK_LEVEL, 0x71, ITV_CMD_WRITE); + break; + + case TVTYPE_720P: + case TVTYPE_1080I: + access_integrated_tv_regs(ITV_REG_ID_PBPR_BLANK_LEVEL, 0x72, ITV_CMD_WRITE); + break; + } + } +} + + +void set_integrated_tv_mode(int tv_mode_index) +{ + int i, mode_index; + unsigned long *tv_mode_table = NULL; + unsigned long *tv_crtc_table = NULL; + + DEBUG_MSG(KERN_INFO "set_integrated_tv_mode!\n"); + DEBUG_MSG(KERN_INFO "TV Mode = %d.\n", tv_mode_index); + DEBUG_MSG(KERN_INFO "TV Type = %d\n", tv_setting_info.system); + DEBUG_MSG(KERN_INFO "TV Output = %d\n", tv_setting_info.out_signal); + DEBUG_MSG(KERN_INFO "TV IGA = %d\n", tv_setting_info.iga_path); + + /* Try to get the suitable mode table. */ + for (i=0; i<NUM_TOTAL_INTEGRATEDTV_MODE_TABLE; i++) + { + mode_index = i; + + if (ITV_MODE_TABLE[i].mode_index == tv_mode_index) + { + break; + } + } + + DEBUG_MSG(KERN_INFO "TV Mode Index to use is: %d.\n" , mode_index); + + switch (tv_setting_info.system) + { + case TVTYPE_NTSC: + { + tv_mode_table = ITV_MODE_TABLE[mode_index].std_ntsc; + tv_crtc_table = ITV_CRTC_TABLE[mode_index].std_ntsc; + break; + } + + case TVTYPE_PAL: + { + tv_mode_table = ITV_MODE_TABLE[mode_index].std_pal; + tv_crtc_table = ITV_CRTC_TABLE[mode_index].std_pal; + break; + } + + case TVTYPE_480P: + { + /* For 480P, we use NTSC's mode table, and then do some patches later. */ + tv_mode_table = ITV_MODE_TABLE[mode_index].std_ntsc; + tv_crtc_table = ITV_CRTC_TABLE[mode_index].std_ntsc; + break; + } + + case TVTYPE_576P: + { + /* For 576P, we use PAL's mode table, and then do some patches later. */ + tv_mode_table = ITV_MODE_TABLE[mode_index].std_pal; + tv_crtc_table = ITV_CRTC_TABLE[mode_index].std_pal; + break; + } + + case TVTYPE_720P: + { + tv_mode_table = ITV_MODE_TABLE[mode_index].std_720p; + tv_crtc_table = ITV_CRTC_TABLE[mode_index].std_720p; + break; + } + + case TVTYPE_1080I: + { + tv_mode_table = ITV_MODE_TABLE[mode_index].std_1080i; + tv_crtc_table = ITV_CRTC_TABLE[mode_index].std_1080i; + break; + } + + default: + { + tv_mode_table = ITV_MODE_TABLE[mode_index].std_ntsc; + tv_crtc_table = ITV_CRTC_TABLE[mode_index].std_ntsc; + break; + } + } + + enable_integrated_tv_shadow_reg(); + + /* Write TV Encoder Regsiters: */ + + /* Common settings by mode: */ + write_integrated_tv_general_table(ITV_MODE_TABLE_OFFSET, tv_mode_table); + + /* Write GFX CRTC timing by TV mode. */ + write_gfx_crtc_timing_for_tv(tv_crtc_table); + + if (tv_setting_info.iga_path == IGA2) + { + access_integrated_tv_regs(ITV_REG_ID_SRC_SEL, ITV_VALUE_SRC_FROM_IGA2, ITV_CMD_WRITE); + + write_reg_mask(CR6A, VIACR, 0, BIT2); + + enable_second_display_channel(); + } + else + { + access_integrated_tv_regs(ITV_REG_ID_SRC_SEL, ITV_VALUE_SRC_FROM_IGA1, ITV_CMD_WRITE); + + /* For the case: TV IGA1 horizontal total can't be divided by 8. */ + plus_vck_to_iga1_timing(tv_crtc_table[H_TOTAL_INDEX]); + } + + /* Set TV output signal: */ + set_integrated_tv_output_signal(); + + /* Patch for HDTV: */ + set_hdtv_patch_table(mode_index); + + /* We should modify some settings if use RGB/YPbPr output. */ + set_tv_output_patch_table(); + + /* Update scaling factor: */ + update_scaling_factor(); + + /* Ported from X to support A3*/ + patch_for_macrovision(); + + disable_integrated_tv_shadow_reg(); +} + + +void integrated_tv_sw_reset(void) +{ + enable_integrated_tv_shadow_reg(); + + access_integrated_tv_regs(ITV_REG_ID_SD_ENABLE, ITV_VALUE_DISABLE, ITV_CMD_WRITE); + access_integrated_tv_regs(ITV_REG_ID_SW_RESET, ITV_VALUE_ENABLE, ITV_CMD_WRITE); + access_integrated_tv_regs(ITV_REG_ID_SW_RESET, ITV_VALUE_DISABLE, ITV_CMD_WRITE); + + delays(50000); /* We should delay to wait IGA1's VSync. */ + + access_integrated_tv_regs(ITV_REG_ID_SD_ENABLE, ITV_VALUE_ENABLE, ITV_CMD_WRITE); + + disable_integrated_tv_shadow_reg(); +} + + +void integrated_tv_enable(void) +{ + /* Turn on DPMS. */ + write_reg_mask(CR36, VIACR, 0, BIT4+BIT5); + + enable_integrated_tv_shadow_reg(); + + /* For the problem TV may crash when we repeat to switch TV type */ + /* (NTSC->PAL->NTSC->PAL->...), to do the following sequence can help avoiding this problem. */ + /* 1. Disable Sync Buffer Mode before set mode and disable TV. */ + /* 2. Enable Sync Buffer Mode before enable TV. */ + /* Suggested by HW team. */ + + /* Enable Sync Buffer Mode: */ + access_integrated_tv_regs(ITV_REG_ID_SYNC_BUF_MODE, ITV_VALUE_ENABLE, ITV_CMD_WRITE); + + /* Enable PK. */ + access_integrated_tv_regs(ITV_REG_ID_PK_ENABLE, ITV_VALUE_ENABLE, ITV_CMD_WRITE); + + /* Enable SD. */ + access_integrated_tv_regs(ITV_REG_ID_SD_ENABLE, ITV_VALUE_ENABLE, ITV_CMD_WRITE); + + /* Enable TV encoder. */ + access_integrated_tv_regs(ITV_REG_ID_TV_ENABLE, ITV_VALUE_ENABLE, ITV_CMD_WRITE); + + /* Change DAC usage. */ + access_integrated_tv_regs(ITV_REG_ID_PRI_DAC_SEL, ITV_VALUE_DAC_FOR_TV, ITV_CMD_WRITE); + + /* Disable SW Reset. */ + access_integrated_tv_regs(ITV_REG_ID_SW_RESET, ITV_VALUE_DISABLE, ITV_CMD_WRITE); + + disable_integrated_tv_shadow_reg(); + + integrated_tv_sw_reset(); +} + + +void integrated_tv_disable(void) +{ + enable_integrated_tv_shadow_reg(); + + /* For the problem TV may crash when we repeat to switch TV type */ + /* (NTSC->PAL->NTSC->PAL->...), to do the following sequence can help avoiding this problem. */ + /* 1. Disable Sync Buffer Mode before set mode and disable TV. */ + /* 2. Enable Sync Buffer Mode before enable TV. */ + /* Suggested by HW team. */ + + /* Enable SW Reset. */ + access_integrated_tv_regs(ITV_REG_ID_SW_RESET, ITV_VALUE_ENABLE, ITV_CMD_WRITE); + + /* Disable Sync Buffer Mode: */ + access_integrated_tv_regs(ITV_REG_ID_SYNC_BUF_MODE, ITV_VALUE_DISABLE, ITV_CMD_WRITE); + + /* Disable PK. */ + access_integrated_tv_regs(ITV_REG_ID_PK_ENABLE, ITV_VALUE_DISABLE, ITV_CMD_WRITE); + + /* Disable SD. */ + access_integrated_tv_regs(ITV_REG_ID_SD_ENABLE, ITV_VALUE_DISABLE, ITV_CMD_WRITE); + + /* Disable TV encoder. */ + access_integrated_tv_regs(ITV_REG_ID_TV_ENABLE, ITV_VALUE_DISABLE, ITV_CMD_WRITE); + + /* Change DAC usage. */ + access_integrated_tv_regs(ITV_REG_ID_PRI_DAC_SEL, ITV_VALUE_DAC_FOR_CRT, ITV_CMD_WRITE); + + disable_integrated_tv_shadow_reg(); +} + + +void get_integrated_tv_default_status(void) +{ + static int scale_value_initialized; + enable_integrated_tv_shadow_reg(); + + /* Size: */ + /* The scaling factor level and default value here are not absolute, they can change by request. */ + tv_setting_info.ScalHLevel = 21; + tv_setting_info.ScalVLevel = 15; + tv_setting_info.DefaultScalH = 10; + tv_setting_info.DefaultScalV = 7; + if(!scale_value_initialized) { + tv_setting_info.CurrentScalH = tv_setting_info.DefaultScalH; + tv_setting_info.CurrentScalV = tv_setting_info.DefaultScalV; + scale_value_initialized=1; + } + tv_setting_info.ScalDegreeH = 5; + tv_setting_info.ScalDegreeV = 5; + + /* Positoin: */ + /* The position level and default value here are not absolute, they can change by request. */ + tv_setting_info.PositionHLevel = 17; + tv_setting_info.PositionVLevel = 13; + tv_setting_info.DefaultPositionH = 9; + tv_setting_info.DefaultPositionV = 7; + tv_setting_info.CurrentPositionH = tv_setting_info.DefaultPositionH; + tv_setting_info.CurrentPositionV = tv_setting_info.DefaultPositionV; + + tv_setting_info.DefaultFFilter = 0; + tv_setting_info.FFilterLevel = 1; + tv_setting_info.CurrentFFilter = tv_setting_info.DefaultFFilter; + + tv_setting_info.DefaultAFFilter = 0; + tv_setting_info.AFFilterLevel = 1023; + + /* Brightness: */ + tv_setting_info.DefaultBrightness = access_integrated_tv_regs(ITV_REG_ID_BLACK_LEVEL, 0, ITV_CMD_READ); + tv_setting_info.BrightnessLevel = 255; /* 8 bits. */ + tv_setting_info.CurrentBrightness = tv_setting_info.DefaultBrightness; + + /* Contrast: */ + tv_setting_info.DefaultContrast= access_integrated_tv_regs(ITV_REG_ID_CONTRAST, 0, ITV_CMD_READ); + tv_setting_info.ContrastLevel = 512; /* 9 bits. */ + tv_setting_info.CurrentContrast= tv_setting_info.DefaultContrast; + + /* Saturation: */ + tv_setting_info.DefaultSaturation= access_integrated_tv_regs(ITV_REG_ID_SATURATION, 0, ITV_CMD_READ); + tv_setting_info.SaturationLevel = 0x3FFFF; /* 9+9 bits. */ + tv_setting_info.CurrentSaturation= tv_setting_info.DefaultSaturation; + + /* Hue: */ + tv_setting_info.DefaultTINT = access_integrated_tv_regs(ITV_REG_ID_HUE, 0, ITV_CMD_READ); + tv_setting_info.TINTLevel = 2047; /* 11 bits. */ + tv_setting_info.CurrentTINT = tv_setting_info.DefaultTINT; + + disable_integrated_tv_shadow_reg(); +} + + +int get_integrated_tv_ffilter_status(int filter_type, int* filter_state) +{ + int value = 0; + int tmp_filter_state = 0; + int tmp_filter_type =0; + + enable_integrated_tv_shadow_reg(); + + /* check if filter is enable */ + tmp_filter_state = access_integrated_tv_regs(ITV_REG_ID_DE_FLICKER_ENABLE, 0, ITV_CMD_READ); + + /* get current filter type */ + tmp_filter_type = access_integrated_tv_regs(ITV_REG_ID_DE_FLK_NUM, 0, ITV_CMD_READ); + + if (filter_type == ITV_FILTER_TYPE_NORMAL) + { + if ((tmp_filter_state == STATE_ON) && (tmp_filter_type == ITV_VALUE_FLK_NUM_WHOLE_IMAGE)) + { + *filter_state = STATE_ON; + } + else + { + *filter_state = STATE_OFF; + } + value = access_integrated_tv_regs(ITV_REG_ID_DF_WT_SEL, 0, ITV_CMD_READ); + } + else if (filter_type == ITV_FILTER_TYPE_ADAPTIVE) + { + if ((tmp_filter_state == STATE_ON) && (tmp_filter_type == ITV_VALUE_FLK_NUM_ONE_POINT)) + { + *filter_state = STATE_ON; + } + else + { + *filter_state = STATE_OFF; + } + value = access_integrated_tv_regs(ITV_REG_ID_DE_FLK_THRESHOLD, 0, ITV_CMD_READ); + } + + disable_integrated_tv_shadow_reg(); + + return value; +} + + + +void get_integrated_tv_pos(u32* current_hpos, u32* current_vpos) +{ + enable_integrated_tv_shadow_reg(); + + *current_hpos = access_integrated_tv_regs(ITV_REG_ID_DST_HSD, 0, ITV_CMD_READ); + *current_vpos = access_integrated_tv_regs(ITV_REG_ID_DST_VSD, 0, ITV_CMD_READ); + + disable_integrated_tv_shadow_reg(); +} + + +void set_integrated_tv_ffilter_status(int filter_type, int filter_on_off, u32 desired_value) +{ + enable_integrated_tv_shadow_reg(); + + if (filter_type == ITV_FILTER_TYPE_NORMAL) + { + if (filter_on_off == ITV_FILTER_ON) + { + /* Turn on FFilter: */ + access_integrated_tv_regs(ITV_REG_ID_DE_FLICKER_ENABLE, ITV_VALUE_ENABLE, ITV_CMD_WRITE); + access_integrated_tv_regs(ITV_REG_ID_DF_TYPE, ITV_FILTER_TYPE_NORMAL, ITV_CMD_WRITE); + + /* Set the weighting of FFilter : */ + if (desired_value < 0) + { + desired_value = 0; + } + + if (desired_value > tv_setting_info.FFilterLevel) + { + desired_value = tv_setting_info.FFilterLevel; + } + + access_integrated_tv_regs(ITV_REG_ID_DF_WT_SEL, desired_value, ITV_CMD_WRITE); + + tv_setting_info.CurrentFFilter = desired_value; + } + else + { + /* Turn off FFilter: */ + access_integrated_tv_regs(ITV_REG_ID_DE_FLICKER_ENABLE, ITV_VALUE_DISABLE, ITV_CMD_WRITE); + } + } + else if (filter_type == ITV_FILTER_TYPE_ADAPTIVE) + { + if (filter_on_off == ITV_FILTER_ON) + { + /* Turn on AFFilter: */ + access_integrated_tv_regs(ITV_REG_ID_DE_FLICKER_ENABLE, ITV_VALUE_ENABLE, ITV_CMD_WRITE); + access_integrated_tv_regs(ITV_REG_ID_DE_FLK_NUM, ITV_VALUE_FLK_NUM_ONE_POINT, ITV_CMD_WRITE); + + /* Set threshold of AFFilter : */ + if (desired_value < 0) + { + desired_value = 0; + } + + if (desired_value > tv_setting_info.AFFilterLevel) + { + desired_value = tv_setting_info.AFFilterLevel; + } + + access_integrated_tv_regs(ITV_REG_ID_DE_FLK_THRESHOLD, desired_value, ITV_CMD_WRITE); + } + else + { + /* Turn off AFFilter: */ + access_integrated_tv_regs(ITV_REG_ID_DE_FLK_NUM, ITV_VALUE_FLK_NUM_WHOLE_IMAGE, ITV_CMD_WRITE); + access_integrated_tv_regs(ITV_REG_ID_DE_FLK_THRESHOLD, 0, ITV_CMD_WRITE); + access_integrated_tv_regs(ITV_REG_ID_DE_FLICKER_ENABLE, ITV_VALUE_DISABLE, ITV_CMD_WRITE); + } + } + + disable_integrated_tv_shadow_reg(); +} + + +void set_integrated_tv_hue(u32 desired_value) +{ + enable_integrated_tv_shadow_reg(); + access_integrated_tv_regs(ITV_REG_ID_HUE, desired_value, ITV_CMD_WRITE); + tv_setting_info.CurrentTINT = desired_value; + disable_integrated_tv_shadow_reg(); +} + + +void set_integrated_tv_brightness(u32 desired_value) +{ + enable_integrated_tv_shadow_reg(); + access_integrated_tv_regs(ITV_REG_ID_BLACK_LEVEL, desired_value, ITV_CMD_WRITE); + tv_setting_info.CurrentBrightness = desired_value; + disable_integrated_tv_shadow_reg(); +} + + +void set_integrated_tv_contrast(u32 desired_value) +{ + enable_integrated_tv_shadow_reg(); + access_integrated_tv_regs(ITV_REG_ID_CONTRAST, desired_value, ITV_CMD_WRITE); + tv_setting_info.CurrentContrast = desired_value; + disable_integrated_tv_shadow_reg(); +} + + +void set_integrated_tv_saturation(u32 desired_value) +{ + enable_integrated_tv_shadow_reg(); + access_integrated_tv_regs(ITV_REG_ID_SATURATION, desired_value, ITV_CMD_WRITE); + tv_setting_info.CurrentSaturation = desired_value; + disable_integrated_tv_shadow_reg(); +} + + +void set_integrated_tv_pos(u32 desired_hpos, u32 desired_vpos) +{ + u32 dst_hpos, dst_vpos; + + enable_integrated_tv_shadow_reg(); + + dst_hpos = access_integrated_tv_regs(ITV_REG_ID_DST_HSD, 0, ITV_CMD_READ); + dst_vpos = access_integrated_tv_regs(ITV_REG_ID_DST_VSD, 0, ITV_CMD_READ); + + dst_hpos = dst_hpos + (desired_hpos - tv_setting_info.CurrentPositionH); + dst_vpos = dst_vpos - (desired_vpos - tv_setting_info.CurrentPositionV); + + access_integrated_tv_regs(ITV_REG_ID_DST_HSD, dst_hpos, ITV_CMD_WRITE); + access_integrated_tv_regs(ITV_REG_ID_DST_VSD, dst_vpos, ITV_CMD_WRITE); + + tv_setting_info.CurrentPositionH = desired_hpos; + tv_setting_info.CurrentPositionV = desired_vpos; + + disable_integrated_tv_shadow_reg(); +} + + +void set_integrated_tv_size(u32 desired_hsize, u32 desired_vsize) +{ + u32 dst_hsize, dst_vsize; + DEBUG_MSG("set integrated TV H:%d V:%d", desired_hsize, desired_vsize); + + enable_integrated_tv_shadow_reg(); + + dst_hsize = access_integrated_tv_regs(ITV_REG_ID_DST_HSIZE, 0, ITV_CMD_READ); + dst_vsize = access_integrated_tv_regs(ITV_REG_ID_DST_VSIZE, 0, ITV_CMD_READ); + + dst_hsize = dst_hsize + tv_setting_info.ScalDegreeH * (desired_hsize - tv_setting_info.CurrentScalH); + dst_vsize = dst_vsize + tv_setting_info.ScalDegreeV * (desired_vsize - tv_setting_info.CurrentScalV); + + access_integrated_tv_regs(ITV_REG_ID_DST_HSIZE, dst_hsize, ITV_CMD_WRITE); + access_integrated_tv_regs(ITV_REG_ID_DST_VSIZE, dst_vsize, ITV_CMD_WRITE); + + /* Update scaling factor: */ + update_scaling_factor(); + + tv_setting_info.CurrentScalH = desired_hsize; + tv_setting_info.CurrentScalV = desired_vsize; + disable_integrated_tv_shadow_reg(); +} + + +int integrated_tv_sense(void) +{ + u8 cr30, cr37, cr43, rgb_dac_status; + u32 tv3f, rgb_status, tv_encoder_status, dac_status; + int sense_status; + + enable_integrated_tv_shadow_reg(); + + if (g_first_time_to_sense) + { + /* Set TV mode (arbitrary) at least once before sense TV. */ + write_integrated_tv_general_table(ITV_INIT_TABLE_OFFSET, ITV_INIT_TABLE_VALUE); + write_integrated_tv_general_table(ITV_MODE_TABLE_OFFSET, ITV_MODE_TABLE_NTSC_640x480); + g_first_time_to_sense = FALSE; + } + + /* Saved for restore later: */ + cr30 = read_reg(VIACR, CR30); + cr37 = read_reg(VIACR, CR37); + cr43 = read_reg(VIACR, CR43); + rgb_dac_status = read_reg(VIASR, SR5E); + tv3f = access_integrated_tv_regs(ITV_REG_ID_TV_SENSE_DATA, 0, ITV_CMD_READ); + tv_encoder_status = access_integrated_tv_regs(ITV_REG_ID_TV_ENABLE, 0, ITV_CMD_READ); + dac_status = access_integrated_tv_regs(ITV_REG_ID_PRI_DAC_SEL, 0, ITV_CMD_READ); + + /* To sense TV, we should: */ + /* 1. Set CR30[4:3]=01, CR37[2:0]=100, CR37[3]=0, CR43[5:4]=01 and TV.3F[7:0]=42h. */ + /* 2. Enable TV DAC R/G/B. */ + /* 3. Enable TV encoder. */ + /* 4. Change primary DAC to TV. */ + write_reg_mask(CR30, VIACR, BIT3, BIT4+BIT3); + write_reg_mask(CR37, VIACR, BIT2, BIT3+BIT2+BIT1+BIT0); + write_reg_mask(CR43, VIACR, BIT4, BIT5+BIT4); + write_reg_mask(SR5E, VIASR, 0, BIT3+BIT2+BIT1); + access_integrated_tv_regs(ITV_REG_ID_TV_SENSE_DATA, 0x42, ITV_CMD_WRITE); + access_integrated_tv_regs(ITV_REG_ID_TV_ENABLE, ITV_VALUE_ENABLE, ITV_CMD_WRITE); + access_integrated_tv_regs(ITV_REG_ID_PRI_DAC_SEL, ITV_VALUE_DAC_FOR_TV, ITV_CMD_WRITE); + + /* Start to sense: */ + access_integrated_tv_regs(ITV_REG_ID_TV_SENSE, ITV_VALUE_MANUAL_SENSE, ITV_CMD_WRITE); + access_integrated_tv_regs(ITV_REG_ID_TV_SENSE, ITV_VALUE_NO_SENSE, ITV_CMD_WRITE); + + /* Restore: */ + access_integrated_tv_regs(ITV_REG_ID_PRI_DAC_SEL, dac_status, ITV_CMD_WRITE); + access_integrated_tv_regs(ITV_REG_ID_TV_ENABLE, tv_encoder_status, ITV_CMD_WRITE); + access_integrated_tv_regs(ITV_REG_ID_TV_SENSE_DATA, tv3f, ITV_CMD_WRITE); + write_reg(CR30, VIACR, cr30); + write_reg(CR37, VIACR, cr37); + write_reg(CR43, VIACR, cr43); + write_reg(SR5E, VIASR, rgb_dac_status); + + /* Get sense result: */ + sense_status = access_integrated_tv_regs(ITV_REG_ID_TV_SENSE_STATUS, 0, ITV_CMD_READ); + rgb_status = access_integrated_tv_regs(ITV_REG_ID_TV_SENSE_RGB_STATUS, 0, ITV_CMD_READ); + + /* Check connected TV output: */ + if (!tv_setting_info.out_signal) + { + switch(rgb_status) + { + case ITV_VALUE_DAC_R | ITV_VALUE_DAC_G: + { + tv_setting_info.out_signal= TV_OUTPUT_SVIDEO; + break; + } + + case ITV_VALUE_DAC_B: + { + tv_setting_info.out_signal = TV_OUTPUT_COMPOSITE; + break; + } + + case ITV_VALUE_DAC_R | ITV_VALUE_DAC_G | ITV_VALUE_DAC_B: + { + tv_setting_info.out_signal = TV_OUTPUT_RGB; + break; + } + + default: + { + tv_setting_info.out_signal = TV_OUTPUT_COMPOSITE; + break; + } + } + } + + disable_integrated_tv_shadow_reg(); + + return sense_status; +} + + +int init_integrated_tv_regs(void) +{ + u32 mask = 0x1FFFFFF0; /* [28:4] */ + u32 buf_start_address; + u32 buffer_size = 0x80000; + u8 offset = 0; + unsigned char* mmio_base; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + buf_start_address = viafbinfo.memsize - INTEGRATED_TV_BUFFER_SIZE; + + viafbinfo.integrated_tv_map_base = (unsigned int)ioremap_nocache(viafbinfo.mmio_base + VIA_MMIO_INTEGRATED_TV_BASE, VIA_MMIO_INTEGRATED_TV_SIZE); + + if (!viafbinfo.integrated_tv_map_base) + { + return FAIL; + } + + mmio_base = (unsigned char*)viafbinfo.integrated_tv_map_base; +#else + buf_start_address = parinfo.fbmem_free - INTEGRATED_TV_BUFFER_SIZE; + parinfo.fbmem_free = parinfo.fbmem_free - INTEGRATED_TV_BUFFER_SIZE; + parinfo.fbmem_used += INTEGRATED_TV_BUFFER_SIZE; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) + parinfo.integrated_tv_map_base = ioremap_nocache(parinfo.mmio_base + VIA_MMIO_INTEGRATED_TV_BASE, VIA_MMIO_INTEGRATED_TV_SIZE); +#else + parinfo.integrated_tv_map_base = (unsigned int)ioremap_nocache(parinfo.mmio_base + VIA_MMIO_INTEGRATED_TV_BASE, VIA_MMIO_INTEGRATED_TV_SIZE); +#endif + + if (!parinfo.integrated_tv_map_base) + { + return FAIL; + } + + mmio_base = (unsigned char*)parinfo.integrated_tv_map_base; +#endif + + enable_integrated_tv_shadow_reg(); + + /* Clear all: */ + while (offset < 0xF0) + { + write_integrated_tv_reg32(mmio_base, offset, 0); + offset = offset + 4; + } + + /* Write Source Buffer 0~3 Base Address: */ + write_integrated_tv_reg_mask32(mmio_base, 0x04, mask, buf_start_address); + + buf_start_address = buf_start_address + buffer_size; + write_integrated_tv_reg_mask32(mmio_base, 0x08, mask, buf_start_address); + + buf_start_address = buf_start_address + buffer_size; + write_integrated_tv_reg_mask32(mmio_base, 0x0C, mask, buf_start_address); + + buf_start_address = buf_start_address + buffer_size; + write_integrated_tv_reg_mask32(mmio_base, 0x10, mask, buf_start_address); + + /* Write Destination Even and Odd Buffer Base Address: */ + buf_start_address = buf_start_address + buffer_size; + write_integrated_tv_reg_mask32(mmio_base, 0x2C, mask, buf_start_address); + + buf_start_address = buf_start_address + buffer_size; + write_integrated_tv_reg_mask32(mmio_base, 0x30, mask, buf_start_address); + + /* Other initialize: */ + write_integrated_tv_general_table(ITV_INIT_TABLE_OFFSET, ITV_INIT_TABLE_VALUE); + + disable_integrated_tv_shadow_reg(); + + return OK; +} + + +int integrated_tv_encoder_identify(void) +{ + if (chip_info.gfx_chip_name == UNICHROME_CX700) + { + return OK; + } + else + { + return FAIL; + } +} +
diff -Nur linux-2.6.21-rc7/drivers/video/via/IntegratedTV.h linux-2.6.21-rc7.viafb/drivers/video/via/IntegratedTV.h
--- linux-2.6.21-rc7/drivers/video/via/IntegratedTV.h 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.21-rc7.viafb/drivers/video/via/IntegratedTV.h 2007-04-26 19:52:32.000000000 -0400@@ -0,0 +1,107 @@ +/* + * Copyright 1998-2007 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2007 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _INTEGRATEDTV_H_ +#define _INTEGRATEDTV_H_ 1 + + +/* Registers IDs: */ +/* The definition value has 4 bits: 2 bits IO address + 2 bits offset. */ +/* ex. 0x0018 means bits 18 of IO Address 00, it is TV source selection. */ +#define ITV_REG_ID_PK_ENABLE 0x0000 /* PK enable. */ +#define ITV_REG_ID_SRC_SEL 0x0018 /* Source from IGA1 or IGA2. */ +#define ITV_REG_ID_SW_RESET 0x0020 /* SW reset. */ +#define ITV_REG_ID_SYNC_BUF_MODE 0x0030 /* Synchronous mode. */ +#define ITV_REG_ID_SD_ENABLE 0x0031 /* Scaler and Deflicker enable. */ +#define ITV_REG_ID_SRC_VSIZE 0x1800 /* Source image vertical pixels. */ +#define ITV_REG_ID_SRC_HSIZE 0x1811 /* Source image horizontal pixels. */ +#define ITV_REG_ID_DE_FLK_THRESHOLD 0x2011 /* Adative flicker filter threshold. */ +#define ITV_REG_ID_SCL_VFAC 0x2400 /* Vertical scaling factor. */ +#define ITV_REG_ID_DE_FLK_NUM 0x2413 /* Adative flicker filter. */ +#define ITV_REG_ID_DF_WT_SEL 0x2414 /* De-flicker weighting selection. */ +#define ITV_REG_ID_DF_TYPE 0x2415 /* De-flicker type. */ +#define ITV_REG_ID_SCL_HFAC 0x2416 /* Horizontal scaling factor. */ +#define ITV_REG_ID_DE_FLICKER_ENABLE 0x2429 /* De-flicker enable. */ +#define ITV_REG_ID_DST_VSIZE 0x2800 /* Destination image vertical pixels. */ +#define ITV_REG_ID_DST_HSIZE 0x2811 /* Destination image horizontal pixels. */ +#define ITV_REG_ID_TV_ENABLE 0x3800 /* TV enable. */ +#define ITV_REG_ID_OUTPUT_SEL 0x3828 /* TV DAC output selection. */ +#define ITV_REG_ID_TV_SENSE 0x3C14 /* TV sense enable. */ +#define ITV_REG_ID_TV_SENSE_DATA 0x3C24 /* TV sense data. */ +#define ITV_REG_ID_DST_HSD 0x4821 /* Destination image horizontal start display */ +#define ITV_REG_ID_DST_VSD 0x4C23 /* Destination image vertical start display */ +#define ITV_REG_ID_SATURATION 0x5000 /* Saturation adjustment. */ +#define ITV_REG_ID_CONTRAST 0x5400 /* Contrast adjustment. */ +#define ITV_REG_ID_BLACK_LEVEL 0x5423 /* Brightness adjustment. */ +#define ITV_REG_ID_HUE 0x6000 /* Hue adjustment. */ +#define ITV_REG_ID_PRI_DAC_SEL 0x6C12 /* Primary DAC for CRT or TV. */ +#define ITV_REG_ID_TV_SENSE_STATUS 0xE402 /* TV sense status. */ +#define ITV_REG_ID_PBPR_BLANK_LEVEL 0xE800 /* Blank Level for Pb and Pr. For VT3324 A3. */ +#define ITV_REG_ID_TV_SENSE_RGB_STATUS 0xE828 /* TV sense R/G/B status. */ + +#define ITV_CMD_READ 0 +#define ITV_CMD_WRITE 1 + +#define ITV_VALUE_DISABLE 0 +#define ITV_VALUE_ENABLE 1 + +#define ITV_VALUE_SRC_FROM_IGA1 0 +#define ITV_VALUE_SRC_FROM_IGA2 1 + +#define ITV_VALUE_DAC_FOR_CRT 0 +#define ITV_VALUE_DAC_FOR_TV 1 + +#define ITV_VALUE_OUTPUT_SC 0x00 /* S-Video or Composite */ +#define ITV_VALUE_OUTPUT_RGB 0x02 /* RGB */ +#define ITV_VALUE_OUTPUT_YPbPr 0x03 /* YPbPr */ + +#define ITV_VALUE_FLK_NUM_WHOLE_IMAGE 0 +#define ITV_VALUE_FLK_NUM_ONE_POINT 1 + +#define ITV_VALUE_NO_SENSE 0x00 +#define ITV_VALUE_MANUAL_SENSE 0x02 +#define ITV_VALUE_AUTO_SENSE 0x03 + +#define ITV_VALUE_TV_UNCONNECTED 0 +#define ITV_VALUE_TV_CONNECTED 1 + +#define ITV_VALUE_DAC_R 4 +#define ITV_VALUE_DAC_G 2 +#define ITV_VALUE_DAC_B 1 + +#define ITV_FILTER_TYPE_NORMAL 0 +#define ITV_FILTER_TYPE_IIR 1 +#define ITV_FILTER_TYPE_ADAPTIVE 2 +#define ITV_FILTER_TYPE_NONE 3 + +#define ITV_FILTER_OFF 0 +#define ITV_FILTER_ON 1 + +#define INTEGRATED_TV_BUFFER_SIZE 0x300000 /* bytes */ /* We reserve 3MB now. */ + +#define VIA_MMIO_INTEGRATED_TV_BASE 0xC000 +#define VIA_MMIO_INTEGRATED_TV_SIZE 256 + +#endif +
diff -Nur linux-2.6.21-rc7/drivers/video/via/ioctl.c linux-2.6.21-rc7.viafb/drivers/video/via/ioctl.c
--- linux-2.6.21-rc7/drivers/video/via/ioctl.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.21-rc7.viafb/drivers/video/via/ioctl.c 2007-04-26 19:52:32.000000000 -0400@@ -0,0 +1,213 @@ +/* + * Copyright 1998-2007 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2007 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <linux/fb.h> +#include <asm/uaccess.h> + +#include "viafbdev.h" +#include "chip.h" +#include "debug.h" +#include "ioctl.h" +#include "share.h" + +extern int dvi_sense(void); +extern int tv_sense(void); +extern int tv_auto_sense(void); +extern inline u8 read_reg(int io_port, u8 index); + +extern struct chip_information chip_info; +extern struct tv_setting_information tv_setting_info; +extern struct viafb_info viafbinfo; +extern int CRT_ON, TV_ON, DVI_ON, LCD_ON; +extern int DeviceStatus; +extern int HotPlug_TV; +extern int refresh; + +int HotPlug_Xres = 640, HotPlug_Yres = 480, HotPlug_bpp = 32, HotPlug_refresh = 60, HotPlug_TVType = TVTYPE_NTSC; + +int ioctl_get_viafb_info(u_long arg) +{ + struct viafb_ioctl_info viainfo; + + viainfo.viafb_id = VIAID; + viainfo.vendor_id = PCI_VIA_VENDOR_ID; + + switch(chip_info.gfx_chip_name) { + case UNICHROME_CLE266: + viainfo.device_id = UNICHROME_CLE266_DID; + break; + + case UNICHROME_K400: + viainfo.device_id = UNICHROME_K400_DID; + break; + + case UNICHROME_K800: + viainfo.device_id = UNICHROME_K800_DID; + break; + + case UNICHROME_P880: + viainfo.device_id = UNICHROME_P880_DID; + break; + + case UNICHROME_CN900: + viainfo.device_id = UNICHROME_CN900_DID; + break; + + /* Add for VT3324. */ + case UNICHROME_CX700: + viainfo.device_id = UNICHROME_CX700_DID; + break; + + /* Add for VT3327 VT3336 VT3364 */ + case UNICHROME_K8M890: + viainfo.device_id = UNICHROME_K8M890_DID; + break; + + case UNICHROME_P4M890: + viainfo.device_id = UNICHROME_P4M890_DID; + break; + + case UNICHROME_P4M900: + viainfo.device_id = UNICHROME_P4M900_DID; + break; + } + + viainfo.version = VERSION_MAJOR; + viainfo.revision = VERSION_MINOR; + + if(copy_to_user((void __user *)arg, &viainfo, sizeof(viainfo))) { + return -EFAULT; + } + + return 0; +} + +/* Hot-Plug Priority: DVI > TV > CRT */ +int ioctl_hotplug(int hres, int vres, int bpp) +{ + int TVsense, DVIsense, status = 0; + u8 TVType = 0; + + DEBUG_MSG(KERN_INFO "ioctl_hotplug!!\n"); + + if(chip_info.tmds_chip_info.tmds_chip_name != NON_TMDS_TRANSMITTER) { + DVIsense = dvi_sense(); + + if(DVIsense) { + DEBUG_MSG(KERN_INFO "DVI Attached...\n"); + if(DeviceStatus != DVI_Device) { + DVI_ON = 1; + CRT_ON = TV_ON = LCD_ON = 0; + + if(DeviceStatus == TV_Device) { + tv_setting_info.system = HotPlug_TVType; + } + + DeviceStatus = DVI_Device; + return DeviceStatus; + } + status = 1; + } + else + DEBUG_MSG(KERN_INFO "DVI De-attached...\n"); + } + + if((chip_info.tv_chip_info.tv_chip_name != NON_TV_ENCODER)&&(status == 0)) { + /* If TV not ON, using TV manual sense function. + If TV ON, using TV auto sense function. + This is avoid the display flick to use TV manual sense function when TV ON. */ + if(DeviceStatus != TV_Device) { + TVsense = tv_sense(); + } + else { + TVsense = tv_auto_sense(); + } + + if(TVsense != TV_OUTPUT_NONE) { + DEBUG_MSG(KERN_INFO "TV Attached: TVsense = %d\n", TVsense); + + if(DeviceStatus != TV_Device) { + TV_ON = 1; + CRT_ON = DVI_ON = LCD_ON = 0; + + HotPlug_TVType = tv_setting_info.system; + + if((chip_info.gfx_chip_name == UNICHROME_CLE266) && (chip_info.gfx_chip_revision == CLE266_REVISION_AX)) { + TVType = read_reg(VIACR, 0x3C) & 0x0F; + } + else { + TVType = read_reg(VIACR, 0x4E) & 0x0F; + } + + if(!TVType) { + tv_setting_info.system = TVTYPE_NTSC; + } + else { + tv_setting_info.system = TVTYPE_PAL; + } + + tv_setting_info.out_signal = TVsense; + + HotPlug_TV = 1; + DeviceStatus = TV_Device; + return DeviceStatus; + } + status = 1; + } + else { + DEBUG_MSG(KERN_INFO "TV De-attached...\n"); + HotPlug_TV = 0; + } + } + + if((DeviceStatus != CRT_Device)&&(status == 0)) { + CRT_ON = 1; + TV_ON = DVI_ON = LCD_ON = 0; + + if(DeviceStatus == TV_Device) { + tv_setting_info.system = HotPlug_TVType; + } + + DeviceStatus = CRT_Device; + return DeviceStatus; + } + + return 0; +} + +int ioctl_get_tv_type(u_long arg) +{ + u8 TVType = 0; + u32 __user *argp = (u32 __user *)arg; + + if((chip_info.gfx_chip_name == UNICHROME_CLE266) && (chip_info.gfx_chip_revision == CLE266_REVISION_AX)) { + TVType = read_reg(VIACR, 0x3C) & 0x0F; + } + else { + TVType = read_reg(VIACR, 0x4E) & 0x0F; + } + + return put_user((u32)TVType, argp); +} +
diff -Nur linux-2.6.21-rc7/drivers/video/via/ioctl.h linux-2.6.21-rc7.viafb/drivers/video/via/ioctl.h
--- linux-2.6.21-rc7/drivers/video/via/ioctl.h 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.21-rc7.viafb/drivers/video/via/ioctl.h 2007-04-26 19:52:32.000000000 -0400@@ -0,0 +1,264 @@ +/* + * Copyright 1998-2007 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2007 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __IOCTL_H__ +#define __IOCTL_H__ + +#ifndef __user +#define __user +#endif + +/* VIAFB IOCTL definition */ +#define VIAFB_GET_INFO_SIZE 0x56494101 /* 'VIA\01' */ +#define VIAFB_GET_INFO 0x56494102 /* 'VIA\02' */ +#define VIAFB_HOTPLUG 0x56494103 /* 'VIA\03' */ +#define VIAFB_SET_HOTPLUG_FLAG 0x56494104 /* 'VIA\04' */ +#define VIAFB_GET_RESOLUTION 0x56494105 /* 'VIA\05' */ +#define VIAFB_GET_TV_TYPE 0x56494106 /* 'VIA\06' */ +#define VIAFB_GET_SAMM_INFO 0x56494107 /* 'VIA\07' */ +#define VIAFB_TURN_ON_OUTPUT_DEVICE 0x56494108 /* 'VIA\08' */ +#define VIAFB_TURN_OFF_OUTPUT_DEVICE 0x56494109 /* 'VIA\09' */ +#define VIAFB_SET_DEVICE 0x5649410A +#define VIAFB_GET_DEVICE 0x5649410B +#define VIAFB_SET_TV_COLOR_DEFAULT 0x5649410C /* 'VIA\0C' */ +#define VIAFB_SET_TV_BRIGHTNESS 0x5649410D /* 'VIA\0D' */ +#define VIAFB_SET_TV_CONTRAST 0x5649410E /* 'VIA\0E' */ +#define VIAFB_SET_TV_SATURATION 0x5649410F /* 'VIA\0F' */ +#define VIAFB_SET_TV_TINT 0x56494110 /* 'VIA\10' */ +#define VIAFB_SET_TV_FFILTER 0x56494111 /* 'VIA\11' */ +#define VIAFB_GET_DRIVER_VERSION 0x56494112 /* 'VIA\12' */ +#define VIAFB_GET_CHIP_INFO 0x56494113 /* 'VIA\13' */ +#define VIAFB_SET_DEVICE_INFO 0x56494114 /* 'VIA\14' */ +#define VIAFB_GET_DEVICE_INFO 0x56494115 /* 'VIA\15' */ +#define VIAFB_SET_TV_POSITION 0x56494116 +#define VIAFB_SET_TV_SIZE 0x56494117 +#define VIAFB_GET_DEVICE_SUPPORT 0x56494118 +#define VIAFB_GET_DEVICE_CONNECT 0x56494119 +#define VIAFB_GET_PANEL_SUPPORT_EXPAND 0x5649411A +#define VIAFB_GET_TV_SUPPORT_SIGNAL 0x5649411B +#define VIAFB_GET_TV_SUPPORT_STANDARD 0x5649411C +#define VIAFB_GET_TV_MAX_SIZE 0x5649411D +#define VIAFB_GET_TV_MAX_POSITION 0x5649411E +#define VIAFB_GET_TV_SUPPORT_TUNING_ITEM 0x5649411F +#define VIAFB_GET_TV_MAX_TUNING_VALUE 0x56494120 +#define VIAFB_GET_TV_SUPPORT_SETTING_ITEM 0x56494121 +#define VIAFB_GET_DRIVER_NAME 0x56494122 +#define VIAFB_GET_DEVICE_SUPPORT_STATE 0x56494123 +#define VIAFB_GET_GAMMA_LUT 0x56494124 +#define VIAFB_SET_GAMMA_LUT 0x56494125 +#define VIAFB_GET_GAMMA_SUPPORT_STATE 0x56494126 +#define VIAFB_SET_VIDEO_DEVICE 0x56494127 +#define VIAFB_GET_VIDEO_DEVICE 0x56494128 +#define VIAFB_SET_SECOND_MODE 0x56494129 + +/* Re-define value to sync with xserver driver. (Bitwise) */ +#define None_Device 0x00 +#define CRT_Device 0x01 +#define LCD_Device 0x02 +#define TV_Device 0x04 +#define DVI_Device 0x08 +#define CRT2_Device 0x10 +#define HDTV_Device 0x20 +#define LCD2_Device 0x40 + +/* Flags which are used to control operations of TV. (Bitwise) */ +#define OP_TV_SYSTEM 0x0001 +#define OP_TV_LEVEL 0x0002 +#define OP_TV_OUT_SIGNAL 0x0004 +#define OP_TV_DEDOTCRAWL 0x0008 +#define OP_TV_BRIGHTNESS 0x0010 +#define OP_TV_CONTRAST 0x0020 +#define OP_TV_SATURATION 0x0040 +#define OP_TV_TINT 0x0080 +#define OP_TV_POSITION 0x0100 +#define OP_TV_SETTING_FFILTER 0x0200 +#define OP_TV_TUNING_FFILTER 0x0400 +#define OP_TV_SETTING_ADAPTIVE_FFILTER 0x0800 +#define OP_TV_TUNING_ADAPTIVE_FFILTER 0x1000 + + + +/* Flags which are used to control operations of LCD. (Bitwise) */ +#define OP_LCD_CENTERING 0x01 +#define OP_LCD_PANEL_ID 0x02 +#define OP_LCD_MODE 0x03 + +/* SAMM operation flag */ +#define OP_SAMM 0x80 + +/* Define maximum value of tv/lcd items. */ +/* The setting value of tv/lcd must be smaller than corresponding maximum value */ +#define TV_STANDARD_MAXIMUM 0x20 +#define TV_SIZE_LEVEL_MAXIMUM 0x02 +#define TV_OUT_SIGNAL_MAXIMUM 0x100 +#define TV_FFILTER_MAXIMUM 3 +#define TV_BRIGHTNESS_MAXIMUM 255 +#define TV_CONTRAST_MAXIMUM 255 +#define TV_ADAPTIVE_FFILTER_MAXIMUM 255 +#define TV_SATURATION_MAXIMUM 65535 +#define TV_TINT_MAXIMUM 2047 +#define TV_HOR_POSITION_MAXIMUM 15 +#define TV_VER_POSITION_MAXIMUM 15 +#define LCD_PANEL_ID_MAXIMUM 19 + + +#define STATE_ON 0x1 +#define STATE_OFF 0x0 +#define STATE_DEFAULT 0xFFFF + +#define MAX_ACTIVE_DEV_NUM 2 + + +typedef struct{ + unsigned short crt:1; + unsigned short dvi:1; + unsigned short tv:1; + unsigned short lcd:1; + unsigned short samm:1; + unsigned short primary_dev; + + unsigned short lcd_dsp_cent:1; + unsigned char lcd_panel_id; + unsigned char lcd_mode:1; + + unsigned char tv_out_sig; + unsigned short tv_level:2; + unsigned short tv_system; + unsigned short tv_dedotcrawl:1; + unsigned short xres,yres; + unsigned short xres1,yres1; + unsigned short refresh; + unsigned short bpp; + unsigned short refresh1; + unsigned short bpp1; + unsigned short sequence; + + unsigned short epia_dvi:1; + unsigned short lcd_dual_edge:1; + unsigned short bus_width; + unsigned short lcd2:1; +} device_t; + + +struct viafb_ioctl_info { + u32 viafb_id; /* for identifying viafb */ +#define VIAID 0x56494146 /* Identify myself with 'VIAF' */ + u16 vendor_id; + u16 device_id; + u8 version; + u8 revision; + u8 reserved[246]; /* for future use */ +}; + +struct viafb_ioctl_mode { + u32 xres; + u32 yres; + u32 refresh; + u32 bpp; + u32 xres_sec; + u32 yres_sec; + u32 virtual_xres_sec; + u32 virtual_yres_sec; + u32 refresh_sec; + u32 bpp_sec; +}; +struct viafb_ioctl_samm { + u32 samm_status; + u32 size_prim; + u32 size_sec; + u32 mem_base; + u32 offset_sec; +}; + +struct viafb_driver_version { + int iMajorNum; + int iKernelNum; + int iOSNum; + int iMinorNum; +}; + +/* This structure contains variable attributes of TV. */ +struct viafb_ioctl_tv_attribute { + unsigned int system; + unsigned int level; + unsigned int out_signal; + unsigned int dedotcrawl; + unsigned int ffilter; + unsigned int adaptive_ffilter; + unsigned int brightness; + unsigned int contrast; + unsigned int saturation; + unsigned int tint; + unsigned int horizontal_pos; + unsigned int vertical_pos; + unsigned int CurrentScalH; + unsigned int CurrentScalV; + unsigned int ScalHLevel; + unsigned int ScalVLevel; + unsigned int DefaultScalH; + unsigned int DefaultScalV; + unsigned int PositionHLevel; + unsigned int PositionVLevel; + unsigned int DefaultPositionH; + unsigned int DefaultPositionV; + unsigned int ffilter_state; + unsigned int adaptive_ffilter_state; +}; + +/* This structure contains variable attributes of LCD. */ +struct viafb_ioctl_lcd_attribute { + unsigned int panel_id; + unsigned int display_center; + unsigned int lcd_mode; +}; + +/* This structure contains all setting information of devices. */ +struct viafb_ioctl_setting { + unsigned short device_flag; /* Enable or disable active devices */ + unsigned short device_status; /* Indicate which device should be turn on or turn off. */ + unsigned int tv_operation_flag; /* Indicate which TV's attribute can be changed. */ + unsigned short lcd_operation_flag; /* Indicate which LCD's attribute can be changed. */ + unsigned short samm_status; /* 1: SAMM ON 0: SAMM OFF */ + + unsigned short first_dev_hor_res; /* horizontal resolution of first device */ + unsigned short first_dev_ver_res; /* vertical resolution of first device */ + unsigned short second_dev_hor_res; /* horizontal resolution of second device */ + unsigned short second_dev_ver_res; /* vertical resolution of second device */ + unsigned short first_dev_refresh; /* refresh rate of first device */ + unsigned short first_dev_bpp; /* bpp of first device */ + unsigned short second_dev_refresh; /* refresh rate of second device */ + unsigned short second_dev_bpp; /* bpp of second device */ + + unsigned int primary_device; /* Indicate which device are primary display device. */ + unsigned int video_device_status; /* Indicate which device will show video. only valid in duoview mode */ + struct viafb_ioctl_tv_attribute tv_attributes; + struct viafb_ioctl_lcd_attribute lcd_attributes; +}; + +typedef struct _POSITIONVALUE +{ + unsigned int dwX; + unsigned int dwY; +}POSITIONVALUE; +#endif /* __IOCTL_H__ */
diff -Nur linux-2.6.21-rc7/drivers/video/via/lcd.c linux-2.6.21-rc7.viafb/drivers/video/via/lcd.c
--- linux-2.6.21-rc7/drivers/video/via/lcd.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.21-rc7.viafb/drivers/video/via/lcd.c 2007-04-26 19:52:32.000000000 -0400@@ -0,0 +1,1630 @@ +/* + * Copyright 1998-2007 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2007 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include <linux/version.h> +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +#include <linux/config.h> +#endif +#include <linux/ioport.h> +#include <asm/io.h> + +#include "debug.h" +#include "lcd.h" +#include "lcdtbl.h" +#include "chip.h" +#include "share.h" +#include "hw.h" +#include "viamode.h" +#include "hwcfig.h" +#include "via_i2c.h" + +/* extern function */ +extern int i2cWriteByte(u8 slave_addr, u8 index, u8 data); +extern int i2cReadByte(u8 slave_addr, u8 index, u8 *pData); +extern void set_output_path(int device, int set_iga, int output_interface); +extern void fill_crtc_timing(struct crt_mode_table *crt_table, int mode_index, int bpp_byte, int set_iga); +extern void write_reg_mask(u8 index, int io_port, u8 data, u8 mask); +extern void load_reg(int timing_value, int load_reg_num, struct io_register *reg, int io_type); +extern struct display_timing get_timing_value(struct crt_mode_table *crt_table, int mode_index); +extern void load_offset_reg(int h_addr, int bpp_byte, int set_iga); +extern void load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); +extern void write_regx(struct io_reg RegTable[],int ItemNum); +extern int get_mode_index(int hres, int vres,int flag); +extern void delays(int count); +extern inline void lock_crt(void); +extern inline void unlock_crt(void); +extern inline u8 read_reg(int io_port, u8 index); +extern inline void write_reg(u8 index, u16 io_port, u8 data); +extern int SearchModeSetting(int ModeInfoIndex); +extern void load_FIFO_reg(int set_iga, int hor_active, int ver_active); +extern u32 get_clk_value(int clk); +extern void SetVCLK(u32 CLK, int set_iga); +extern void load_crtc_timing(struct display_timing device_timing, int set_iga); +extern void set_color_depth(int bpp_byte, int set_iga); +extern bool lvds_identify_vt1636(void); +extern void init_lvds_vt1636(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); +void disable_lvds_vt1636(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); +void enable_lvds_vt1636(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); +extern void vt1636_patch_skew_on_vt3324(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); +extern void vt1636_patch_skew_on_vt3327(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); +extern void vt1636_patch_skew_on_vt3364(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); + + +/* extern struct */ +extern struct chip_information chip_info; +extern struct lvds_setting_information lvds_setting_info; +extern struct lvds_setting_information lvds_setting_info2; +extern struct _lcd_scaling_factor lcd_scaling_factor; +extern struct iga1_crtc_timing iga1_crtc_reg; +extern struct iga1_shadow_crtc_timing iga1_shadow_crtc_reg; +extern struct iga2_crtc_timing iga2_crtc_reg; + +extern int lcd_panel_id; + +extern int SAMM_ON, LCD2_ON, LCD_ON; +extern int display_hardware_layout; + +int lvds_register_read(int index); +int fp_id_to_vindex(int panel_id); +void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, int panel_vres); +void load_lcd_k400_patch_tbl(int set_hres, int set_vres, int panel_id); +void load_lcd_p880_patch_tbl(int set_hres, int set_vres, int panel_id); +void load_lcd_patch_regs(int set_hres, int set_vres, int panel_id, int set_iga); +void VIAPitchAlignmentPatchLCD(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); +void lcd_disable(void); +void lcd_enable(void); +void LCDPowerSequenceOff(void); +void LCDPowerSequenceOn(void); +void fill_lcd_format(void); +void init_lvds_output_interface(struct lvds_chip_information *plvds_chip_info, struct lvds_setting_information* plvds_setting_info); +struct display_timing lcd_centering_timging(struct display_timing mode_crt_reg, struct display_timing panel_crt_reg); +void load_crtc_shadow_timing(struct display_timing mode_timing, struct display_timing panel_timing); +void load_scaling_factor_for_p4m900(int set_hres, int set_vres, int panel_hres, int panel_vres); + + + +int check_lvds_chip(int device_id_subaddr, int device_id) +{ + if (lvds_register_read(device_id_subaddr) == device_id) + return(OK); + else + return(FAIL); +} + +void init_lcd_size(void) +{ + DEBUG_MSG(KERN_INFO "init_lcd_size()\n"); + DEBUG_MSG(KERN_INFO "lvds_setting_info.get_lcd_size_method %d\n", lvds_setting_info.get_lcd_size_method); + + switch(lvds_setting_info.get_lcd_size_method) { + case GET_LCD_SIZE_BY_SYSTEM_BIOS: + break; + case GET_LCD_SZIE_BY_HW_STRAPPING: + break; + case GET_LCD_SIZE_BY_VGA_BIOS: + DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n"); + lvds_setting_info.lcd_panel_size = fp_id_to_vindex(lcd_panel_id); + DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n", lvds_setting_info.lcd_panel_id); + DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n", lvds_setting_info.lcd_panel_size); + break; + case GET_LCD_SIZE_BY_USER_SETTING: + DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n"); + lvds_setting_info.lcd_panel_size = fp_id_to_vindex(lcd_panel_id); + DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n", lvds_setting_info.lcd_panel_id); + DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n", lvds_setting_info.lcd_panel_size); + break; + default: + DEBUG_MSG(KERN_INFO "init_lcd_size fail\n"); + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID1_800X600; + lvds_setting_info.lcd_panel_size = fp_id_to_vindex(LCD_PANEL_ID1_800X600); + } + lvds_setting_info2.lcd_panel_id = lvds_setting_info.lcd_panel_id; + lvds_setting_info2.lcd_panel_size = lvds_setting_info.lcd_panel_size; + lvds_setting_info2.lcd_panel_hres = lvds_setting_info.lcd_panel_hres; + lvds_setting_info2.lcd_panel_vres = lvds_setting_info.lcd_panel_vres; + lvds_setting_info2.LCDDualEdge = lvds_setting_info.LCDDualEdge; + lvds_setting_info2.LCDDithering = lvds_setting_info.LCDDithering; +} + +bool lvds_identify_integratedlvds(void) +{ + if (display_hardware_layout == HW_LAYOUT_LCD_EXTERNAL_LCD2) + { + /* Two dual channel LCD (Internal LVDS + External LVDS): */ + /* If we have an external LVDS, such as VT1636, we should have its chip ID already. */ + if (chip_info.lvds_chip_info.lvds_chip_name) + { + chip_info.lvds_chip_info2.lvds_chip_name = INTEGRATED_LVDS; + DEBUG_MSG(KERN_INFO "Support two dual channel LVDS! (Internal LVDS + External LVDS)\n"); + } + else + { + chip_info.lvds_chip_info.lvds_chip_name = INTEGRATED_LVDS; + DEBUG_MSG(KERN_INFO "Not found external LVDS, so can't support two dual channel LVDS!\n"); + } + } + else if (display_hardware_layout == HW_LAYOUT_LCD1_LCD2) + { + /* Two single channel LCD (Internal LVDS + Internal LVDS): */ + chip_info.lvds_chip_info.lvds_chip_name = INTEGRATED_LVDS; + chip_info.lvds_chip_info2.lvds_chip_name = INTEGRATED_LVDS; + DEBUG_MSG(KERN_INFO "Support two single channel LVDS! (Internal LVDS + Internal LVDS)\n"); + } + else if (display_hardware_layout != HW_LAYOUT_DVI_ONLY) + { + /* If we have found external LVDS, just use it, otherwise, we will use internal LVDS as default. */ + if (!chip_info.lvds_chip_info.lvds_chip_name) + { + chip_info.lvds_chip_info.lvds_chip_name = INTEGRATED_LVDS; + DEBUG_MSG(KERN_INFO "Found Integrated LVDS!\n"); + } + } + else + { + chip_info.lvds_chip_info.lvds_chip_name = NON_LVDS_TRANSMITTER; + DEBUG_MSG(KERN_INFO "Do not support LVDS!\n"); + return FALSE; + } + + return TRUE; +} + +int lvds_trasmitter_identify(void) +{ + u8 tmp; + tmp = chip_info.tv_chip_info.tv_chip_on_slot; + chip_info.tv_chip_info.tv_chip_on_slot = TV_ON_AMR; + if(lvds_identify_vt1636()) + { + chip_info.lvds_chip_info.i2c_port = TVI2CPORTINDEX; + DEBUG_MSG(KERN_INFO "Found VIA VT1636 LVDS on port i2c 0x31 \n"); + }else + { + chip_info.tv_chip_info.tv_chip_on_slot = TV_ON_AGP; + if(lvds_identify_vt1636()) + { + chip_info.lvds_chip_info.i2c_port = TVGPIOPORTINDEX; + DEBUG_MSG(KERN_INFO "Found VIA VT1636 LVDS on port gpio 0x2c \n"); + } + } + chip_info.tv_chip_info.tv_chip_on_slot = tmp; + + if (chip_info.gfx_chip_name == UNICHROME_CX700) + { + lvds_identify_integratedlvds(); + } + + if(chip_info.lvds_chip_info.lvds_chip_name) + { + return TRUE; + } + /* Check for VT1631: */ + chip_info.lvds_chip_info.lvds_chip_name = VT1631_LVDS; + chip_info.lvds_chip_info.lvds_chip_slave_addr = VT1631_LVDS_I2C_ADDR; + + if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID)!= FAIL) + { + DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n"); + DEBUG_MSG(KERN_INFO "\n %2d", chip_info.lvds_chip_info.lvds_chip_name); + DEBUG_MSG(KERN_INFO "\n %2d", chip_info.lvds_chip_info.lvds_chip_name); + return(OK); + } + + + chip_info.lvds_chip_info.lvds_chip_name = NON_LVDS_TRANSMITTER; + chip_info.lvds_chip_info.lvds_chip_slave_addr = VT1631_LVDS_I2C_ADDR; + return(FAIL); +} + +int fp_id_to_vindex(int panel_id) +{ + DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n"); + + if(panel_id > 0x13) + lcd_panel_id = panel_id= read_reg(VIACR, CR3F) & 0x0F; + + switch(panel_id) { + case 0x0: + lvds_setting_info.lcd_panel_hres = 640; + lvds_setting_info.lcd_panel_vres = 480; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID0_640X480; + lvds_setting_info.LCDDualEdge = 0; + lvds_setting_info.LCDDithering = 1; + return(VIA_RES_640X480); + break; + case 0x1: + lvds_setting_info.lcd_panel_hres = 800; + lvds_setting_info.lcd_panel_vres = 600; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID1_800X600; + lvds_setting_info.LCDDualEdge = 0; + lvds_setting_info.LCDDithering = 1; + return(VIA_RES_800X600); + break; + case 0x2: + lvds_setting_info.lcd_panel_hres = 1024; + lvds_setting_info.lcd_panel_vres = 768; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID2_1024X768; + lvds_setting_info.LCDDualEdge = 0; + lvds_setting_info.LCDDithering = 1; + return(VIA_RES_1024X768); + break; + case 0x3: + lvds_setting_info.lcd_panel_hres = 1280; + lvds_setting_info.lcd_panel_vres = 768; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID3_1280X768; + lvds_setting_info.LCDDualEdge = 0; + lvds_setting_info.LCDDithering = 1; + return(VIA_RES_1280X768); + break; + case 0x4: + lvds_setting_info.lcd_panel_hres = 1280; + lvds_setting_info.lcd_panel_vres = 1024; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID4_1280X1024; + lvds_setting_info.LCDDualEdge = 1; + lvds_setting_info.LCDDithering = 1; + return(VIA_RES_1280X1024); + break; + case 0x5: + lvds_setting_info.lcd_panel_hres = 1400; + lvds_setting_info.lcd_panel_vres = 1050; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID5_1400X1050; + lvds_setting_info.LCDDualEdge = 1; + lvds_setting_info.LCDDithering = 1; + return(VIA_RES_1400X1050); + break; + case 0x6: + lvds_setting_info.lcd_panel_hres = 1600; + lvds_setting_info.lcd_panel_vres = 1200; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID6_1600X1200; + lvds_setting_info.LCDDualEdge = 1; + lvds_setting_info.LCDDithering = 1; + return(VIA_RES_1600X1200); + break; + case 0x9: + lvds_setting_info.lcd_panel_hres = 1024; + lvds_setting_info.lcd_panel_vres = 768; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID2_1024X768; + lvds_setting_info.LCDDualEdge = 1; + lvds_setting_info.LCDDithering = 1; + return(VIA_RES_1024X768); + break; + case 0xA: + lvds_setting_info.lcd_panel_hres = 1024; + lvds_setting_info.lcd_panel_vres = 768; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID2_1024X768; + lvds_setting_info.LCDDualEdge = 0; + lvds_setting_info.LCDDithering = 0; + return(VIA_RES_1024X768); + break; + case 0xB: + lvds_setting_info.lcd_panel_hres = 1024; + lvds_setting_info.lcd_panel_vres = 768; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID2_1024X768; + lvds_setting_info.LCDDualEdge = 1; + lvds_setting_info.LCDDithering = 0; + return(VIA_RES_1024X768); + break; + case 0xC: + lvds_setting_info.lcd_panel_hres = 1280; + lvds_setting_info.lcd_panel_vres = 768; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID3_1280X768; + lvds_setting_info.LCDDualEdge = 0; + lvds_setting_info.LCDDithering = 0; + return(VIA_RES_1280X768); + break; + case 0xD: + lvds_setting_info.lcd_panel_hres = 1280; + lvds_setting_info.lcd_panel_vres = 1024; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID4_1280X1024; + lvds_setting_info.LCDDualEdge = 1; + lvds_setting_info.LCDDithering = 0; + return(VIA_RES_1280X1024); + break; + case 0xE: + lvds_setting_info.lcd_panel_hres = 1400; + lvds_setting_info.lcd_panel_vres = 1050; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID5_1400X1050; + lvds_setting_info.LCDDualEdge = 1; + lvds_setting_info.LCDDithering = 0; + return(VIA_RES_1400X1050); + break; + case 0xF: + lvds_setting_info.lcd_panel_hres = 1600; + lvds_setting_info.lcd_panel_vres = 1200; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID6_1600X1200; + lvds_setting_info.LCDDualEdge = 1; + lvds_setting_info.LCDDithering = 0; + return(VIA_RES_1600X1200); + break; + case 0x10: + lvds_setting_info.lcd_panel_hres = 1366; + lvds_setting_info.lcd_panel_vres = 768; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID7_1366X768; + lvds_setting_info.LCDDualEdge = 0; + lvds_setting_info.LCDDithering = 0; + return(VIA_RES_1368X768); + break; + case 0x11: + lvds_setting_info.lcd_panel_hres = 1024; + lvds_setting_info.lcd_panel_vres = 600; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID8_1024X600; + lvds_setting_info.LCDDualEdge = 0; + lvds_setting_info.LCDDithering = 1; + return(VIA_RES_1024X600); + break; + case 0x12: + lvds_setting_info.lcd_panel_hres = 1280; + lvds_setting_info.lcd_panel_vres = 768; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID3_1280X768; + lvds_setting_info.LCDDualEdge = 1; + lvds_setting_info.LCDDithering = 1; + return(VIA_RES_1280X768); + break; + case 0x13: + lvds_setting_info.lcd_panel_hres = 1280; + lvds_setting_info.lcd_panel_vres = 800; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID9_1280X800; + lvds_setting_info.LCDDualEdge = 0; + lvds_setting_info.LCDDithering = 1; + return(VIA_RES_1280X800); + break; + default: + lvds_setting_info.lcd_panel_hres = 800; + lvds_setting_info.lcd_panel_vres = 600; + lvds_setting_info.lcd_panel_id = LCD_PANEL_ID1_800X600; + lvds_setting_info.LCDDualEdge = 0; + lvds_setting_info.LCDDithering = 1; + return(VIA_RES_800X600); + } +} + +void lvds_register_write(int index, u8 data) +{ + u8 tmp; + + tmp = chip_info.tv_chip_info.tv_chip_on_slot; + + chip_info.tv_chip_info.tv_chip_on_slot = TV_ON_AGP; + + i2cWriteByte(chip_info.lvds_chip_info.lvds_chip_slave_addr, index, data); + + chip_info.tv_chip_info.tv_chip_on_slot = tmp; + +} + +int lvds_register_read(int index) +{ + u8 data; + int status; + u8 tmp; + + tmp = chip_info.tv_chip_info.tv_chip_on_slot; + + chip_info.tv_chip_info.tv_chip_on_slot = TV_ON_AGP; + status = i2cReadByte((u8)chip_info.lvds_chip_info.lvds_chip_slave_addr, (u8)index, &data); + + chip_info.tv_chip_info.tv_chip_on_slot = tmp; + return(data); +} + +void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, int panel_vres) +{ + int reg_value = 0; + int load_reg_num; + struct io_register *reg = NULL; + + DEBUG_MSG(KERN_INFO "load_lcd_scaling()!!\n"); + + /* LCD Scaling Enable */ + write_reg_mask(CR79, VIACR, 0x07, BIT0+BIT1+BIT2); + + /* Modified form X driver code.P4M900_A0's scaling register has a + little problem on reading it. So we use another method to access it. */ + if (UNICHROME_P4M900 == chip_info.gfx_chip_name) + { + load_scaling_factor_for_p4m900(set_hres, set_vres, panel_hres, panel_vres); + return; + } + + + /* Check if expansion for horizontal */ + if(set_hres != panel_hres) + { + /* Load Horizontal Scaling Factor */ + switch(chip_info.gfx_chip_name) + { + case UNICHROME_CLE266: + case UNICHROME_K400: + reg_value = CLE266_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); + load_reg_num = lcd_scaling_factor_CLE.lcd_hor_scaling_factor.reg_num; + reg = lcd_scaling_factor_CLE.lcd_hor_scaling_factor.reg; + load_reg(reg_value, load_reg_num, reg, VIACR); + break; + case UNICHROME_K800: + case UNICHROME_P880: + case UNICHROME_CN900: + case UNICHROME_CX700: + case UNICHROME_K8M890: + case UNICHROME_P4M890: + reg_value = K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); + write_reg_mask(CRA2, VIACR, 0xC0, BIT7+BIT6); /* Horizontal scaling enabled */ + load_reg_num = lcd_scaling_factor.lcd_hor_scaling_factor.reg_num; + reg = lcd_scaling_factor.lcd_hor_scaling_factor.reg; + load_reg(reg_value, load_reg_num, reg, VIACR); + break; + } + + DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d", reg_value); + } + else + { + write_reg_mask(CRA2, VIACR, 0x00, BIT7); /* Horizontal scaling disabled */ + } + + /* Check if expansion for vertical */ + if(set_vres != panel_vres) + { + /* Load Vertical Scaling Factor */ + switch(chip_info.gfx_chip_name) + { + case UNICHROME_CLE266: + case UNICHROME_K400: + reg_value = CLE266_LCD_VER_SCF_FORMULA(set_vres, panel_vres); + load_reg_num = lcd_scaling_factor_CLE.lcd_ver_scaling_factor.reg_num; + reg = lcd_scaling_factor_CLE.lcd_ver_scaling_factor.reg; + load_reg(reg_value, load_reg_num, reg, VIACR); + break; + case UNICHROME_K800: + case UNICHROME_P880: + case UNICHROME_CN900: + case UNICHROME_CX700: + case UNICHROME_K8M890: + case UNICHROME_P4M890: + reg_value = K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres); + write_reg_mask(CRA2, VIACR, 0x08, BIT3); /* Vertical scaling enabled */ + load_reg_num = lcd_scaling_factor.lcd_ver_scaling_factor.reg_num; + reg = lcd_scaling_factor.lcd_ver_scaling_factor.reg; + load_reg(reg_value, load_reg_num, reg, VIACR); + break; + } + + DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d", reg_value); + } + else + { + write_reg_mask(CRA2, VIACR, 0x00, BIT3); /* Vertical scaling disabled */ + } +} + +void load_lcd_k400_patch_tbl(int set_hres, int set_vres, int panel_id) +{ + int vmode_index; + int reg_num=0; + struct io_reg *lcd_patch_reg=NULL; + + if(lvds_setting_info.iga_path==IGA2) + vmode_index = get_mode_index(set_hres, set_vres,1); + else + vmode_index = get_mode_index(set_hres, set_vres,0); + switch(panel_id) { + /* LCD 800x600 */ + case LCD_PANEL_ID1_800X600: + switch(vmode_index) { + case VIA_RES_640X400: + case VIA_RES_640X480: + reg_num = NUM_TOTAL_K400_LCD_RES_6X4_8X6; + lcd_patch_reg = K400_LCD_RES_6X4_8X6; + break; + case VIA_RES_720X480: + case VIA_RES_720X576: + reg_num = NUM_TOTAL_K400_LCD_RES_7X4_8X6; + lcd_patch_reg = K400_LCD_RES_7X4_8X6; + break; + } + break; + + /* LCD 1024x768 */ + case LCD_PANEL_ID2_1024X768: + switch(vmode_index) { + case VIA_RES_640X400: + case VIA_RES_640X480: + reg_num = NUM_TOTAL_K400_LCD_RES_6X4_10X7; + lcd_patch_reg = K400_LCD_RES_6X4_10X7; + break; + case VIA_RES_720X480: + case VIA_RES_720X576: + reg_num = NUM_TOTAL_K400_LCD_RES_7X4_10X7; + lcd_patch_reg = K400_LCD_RES_7X4_10X7; + break; + case VIA_RES_800X600: + reg_num = NUM_TOTAL_K400_LCD_RES_8X6_10X7; + lcd_patch_reg = K400_LCD_RES_8X6_10X7; + break; + } + break; + + /* LCD 1280x1024 */ + case LCD_PANEL_ID4_1280X1024: + switch(vmode_index) { + case VIA_RES_640X400: + case VIA_RES_640X480: + reg_num = NUM_TOTAL_K400_LCD_RES_6X4_12X10; + lcd_patch_reg = K400_LCD_RES_6X4_12X10; + break; + case VIA_RES_720X480: + case VIA_RES_720X576: + reg_num = NUM_TOTAL_K400_LCD_RES_7X4_12X10; + lcd_patch_reg = K400_LCD_RES_7X4_12X10; + break; + case VIA_RES_800X600: + reg_num = NUM_TOTAL_K400_LCD_RES_8X6_12X10; + lcd_patch_reg = K400_LCD_RES_8X6_12X10; + break; + case VIA_RES_1024X768: + reg_num = NUM_TOTAL_K400_LCD_RES_10X7_12X10; + lcd_patch_reg = K400_LCD_RES_10X7_12X10; + break; + + } + break; + + /* LCD 1400x1050 */ + case LCD_PANEL_ID5_1400X1050: + switch(vmode_index) + { + case VIA_RES_640X480: + reg_num = NUM_TOTAL_K400_LCD_RES_6X4_14X10; + lcd_patch_reg = K400_LCD_RES_6X4_14X10; + break; + case VIA_RES_800X600: + reg_num = NUM_TOTAL_K400_LCD_RES_8X6_14X10; + lcd_patch_reg = K400_LCD_RES_8X6_14X10; + break; + case VIA_RES_1024X768: + reg_num = NUM_TOTAL_K400_LCD_RES_10X7_14X10; + lcd_patch_reg = K400_LCD_RES_10X7_14X10; + break; + case VIA_RES_1280X768: + case VIA_RES_1280X960: + case VIA_RES_1280X1024: + reg_num = NUM_TOTAL_K400_LCD_RES_12X10_14X10; + lcd_patch_reg = K400_LCD_RES_12X10_14X10; + break; + } + break; + + /* LCD 1600x1200 */ + case LCD_PANEL_ID6_1600X1200: + switch(vmode_index) { + case VIA_RES_640X400: + case VIA_RES_640X480: + reg_num = NUM_TOTAL_K400_LCD_RES_6X4_16X12; + lcd_patch_reg = K400_LCD_RES_6X4_16X12; + break; + case VIA_RES_720X480: + case VIA_RES_720X576: + reg_num = NUM_TOTAL_K400_LCD_RES_7X4_16X12; + lcd_patch_reg = K400_LCD_RES_7X4_16X12; + break; + case VIA_RES_800X600: + reg_num = NUM_TOTAL_K400_LCD_RES_8X6_16X12; + lcd_patch_reg = K400_LCD_RES_8X6_16X12; + break; + case VIA_RES_1024X768: + reg_num = NUM_TOTAL_K400_LCD_RES_10X7_16X12; + lcd_patch_reg = K400_LCD_RES_10X7_16X12; + break; + case VIA_RES_1280X768: + case VIA_RES_1280X960: + case VIA_RES_1280X1024: + reg_num = NUM_TOTAL_K400_LCD_RES_12X10_16X12; + lcd_patch_reg = K400_LCD_RES_12X10_16X12; + break; + } + break; + + } + if (reg_num != 0) + { + /* H.W. Reset : ON */ + write_reg_mask(CR17, VIACR, 0x00, BIT7); + + write_regx(lcd_patch_reg, reg_num); + + /* H.W. Reset : OFF */ + write_reg_mask(CR17, VIACR, 0x80, BIT7); + + /* Reset PLL */ + write_reg_mask(SR40, VIASR, 0x02, BIT1); + write_reg_mask(SR40, VIASR, 0x00, BIT1); + + /* Fire! */ + outb(inb(VIARMisc) | (BIT2+BIT3), VIAWMisc); + } +} + +void load_lcd_p880_patch_tbl(int set_hres, int set_vres, int panel_id) +{ + int vmode_index; + int reg_num=0; + struct io_reg *lcd_patch_reg=NULL; + + if(lvds_setting_info.iga_path==IGA2) + vmode_index = get_mode_index(set_hres, set_vres,1); + else + vmode_index = get_mode_index(set_hres, set_vres,0); + + switch(panel_id) { + case LCD_PANEL_ID5_1400X1050: + switch(vmode_index) + { + case VIA_RES_640X480: + reg_num = NUM_TOTAL_P880_LCD_RES_6X4_14X10; + lcd_patch_reg = P880_LCD_RES_6X4_14X10; + break; + case VIA_RES_800X600: + reg_num = NUM_TOTAL_P880_LCD_RES_8X6_14X10; + lcd_patch_reg = P880_LCD_RES_8X6_14X10; + break; + } + break; + case LCD_PANEL_ID6_1600X1200: + switch(vmode_index) { + case VIA_RES_640X400: + case VIA_RES_640X480: + reg_num = NUM_TOTAL_P880_LCD_RES_6X4_16X12; + lcd_patch_reg = P880_LCD_RES_6X4_16X12; + break; + case VIA_RES_720X480: + case VIA_RES_720X576: + reg_num = NUM_TOTAL_P880_LCD_RES_7X4_16X12; + lcd_patch_reg = P880_LCD_RES_7X4_16X12; + break; + case VIA_RES_800X600: + reg_num = NUM_TOTAL_P880_LCD_RES_8X6_16X12; + lcd_patch_reg = P880_LCD_RES_8X6_16X12; + break; + case VIA_RES_1024X768: + reg_num = NUM_TOTAL_P880_LCD_RES_10X7_16X12; + lcd_patch_reg = P880_LCD_RES_10X7_16X12; + break; + case VIA_RES_1280X768: + case VIA_RES_1280X960: + case VIA_RES_1280X1024: + reg_num = NUM_TOTAL_P880_LCD_RES_12X10_16X12; + lcd_patch_reg = P880_LCD_RES_12X10_16X12; + break; + } + break; + + } + if (reg_num != 0) + { + /* H.W. Reset : ON */ + write_reg_mask(CR17, VIACR, 0x00, BIT7); + + write_regx(lcd_patch_reg, reg_num); + + /* H.W. Reset : OFF */ + write_reg_mask(CR17, VIACR, 0x80, BIT7); + + /* Reset PLL */ + write_reg_mask(SR40, VIASR, 0x02, BIT1); + write_reg_mask(SR40, VIASR, 0x00, BIT1); + + /* Fire! */ + outb(inb(VIARMisc) | (BIT2+BIT3), VIAWMisc); + } +} + +void load_lcd_patch_regs(int set_hres, int set_vres, int panel_id, int set_iga) +{ + int vmode_index; + + if(lvds_setting_info.iga_path==IGA2) + vmode_index = get_mode_index(set_hres, set_vres,1); + else + vmode_index = get_mode_index(set_hres, set_vres,0); + + unlock_crt(); + + /* Patch for simultaneous & Expansion */ + if((set_iga == IGA1_IGA2) && (lvds_setting_info.display_method == LCD_EXPANDSION)) + { + switch(chip_info.gfx_chip_name) { + case UNICHROME_CLE266: + case UNICHROME_K400: + load_lcd_k400_patch_tbl(set_hres, set_vres, panel_id); + break; + case UNICHROME_K800: + break; + case UNICHROME_P880: + case UNICHROME_CN900: + case UNICHROME_CX700: + load_lcd_p880_patch_tbl(set_hres, set_vres, panel_id); + } + } + + lock_crt(); +} + +void VIAPitchAlignmentPatchLCD(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) +{ + unsigned char cr13, cr35, cr65, cr66, cr67; + unsigned long dwScreenPitch= 0; + unsigned long dwPitch; + + dwPitch = plvds_setting_info->h_active * (plvds_setting_info->bpp >> 3); + if (dwPitch & 0x1F) + { /* Is 32 Byte Alignment ? */ + dwScreenPitch = ((dwPitch + 31) & ~31) >> 3; + if ( plvds_setting_info->iga_path==IGA2) + { + if(plvds_setting_info->bpp>8) { + /* When 8bpp 720xX,848xX will not do 32Byte alignment. */ + cr66 = (unsigned char)(dwScreenPitch & 0xFF); + write_reg(CR66, VIACR, cr66); + cr67 = read_reg(VIACR, CR67) & 0xFC; + cr67 |= (unsigned char)((dwScreenPitch & 0x300) >> 8); + write_reg(CR67, VIACR, cr67); + } + + /* Fetch Count */ + cr67 = read_reg(VIACR, CR67) & 0xF3; + cr67 |= (unsigned char)((dwScreenPitch & 0x600) >> 7); + write_reg(CR67, VIACR, cr67); + cr65 = (unsigned char)((dwScreenPitch >> 1) & 0xFF); + cr65 += 2; + write_reg(CR65, VIACR, cr65); + } + else + { + if(plvds_setting_info->bpp>8) { + /* When 8bpp 720xX,848xX will not do 32Byte alignment. */ + cr13 = (unsigned char)(dwScreenPitch & 0xFF); + write_reg(CR13, VIACR, cr13); + cr35 = read_reg(VIACR, CR35) & 0x1F; + cr35 |= (unsigned char)((dwScreenPitch & 0x700) >> 3); + write_reg(CR35, VIACR, cr35); + } + } + } +} +void lcd_patch_skew_dvp0(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) +{ + if(VT1636_LVDS == plvds_chip_info->lvds_chip_name) + { + switch(chip_info.gfx_chip_name) + { + case UNICHROME_P4M900: + vt1636_patch_skew_on_vt3364(plvds_setting_info, plvds_chip_info); + break; + case UNICHROME_P4M890: + vt1636_patch_skew_on_vt3327(plvds_setting_info, plvds_chip_info); + break; + } + } +} +void lcd_patch_skew_dvp1(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) +{ + if(VT1636_LVDS == plvds_chip_info->lvds_chip_name) + { + switch(chip_info.gfx_chip_name) + { + case UNICHROME_CX700: + vt1636_patch_skew_on_vt3324(plvds_setting_info, plvds_chip_info); + break; + } + } +} +void lcd_patch_skew(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) +{ + DEBUG_MSG(KERN_INFO "lcd_patch_skew\n"); + switch (plvds_chip_info->output_interface) + { + case INTERFACE_DVP0: + lcd_patch_skew_dvp0(plvds_setting_info, plvds_chip_info); + break; + case INTERFACE_DVP1: + lcd_patch_skew_dvp1(plvds_setting_info, plvds_chip_info); + break; + case INTERFACE_DFP_LOW: + if (UNICHROME_P4M900 == chip_info.gfx_chip_name) + { + write_reg_mask(CR99, VIACR, 0x08, BIT0+BIT1+BIT2+BIT3); + } + break; + } +} + +/* LCD Set Mode */ +void lcd_set_mode(struct crt_mode_table *mode_crt_table, struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) +{ + int video_index = plvds_setting_info->lcd_panel_size; + int set_iga = plvds_setting_info->iga_path; + int mode_bpp = plvds_setting_info->bpp; + int load_reg_num=0; + int reg_value=0; + int set_hres, set_vres; + int panel_hres, panel_vres; + u32 pll_D_N; + int offset; + struct io_register *reg = NULL; + struct display_timing mode_crt_reg, panel_crt_reg; + struct crt_mode_table *panel_crt_table; + struct VideoModeTable *vmode_tbl; + + DEBUG_MSG(KERN_INFO "LCD_Set_Mode!, expansion:%d\n", plvds_setting_info->display_method); + + mode_crt_reg = mode_crt_table->crtc; /* Get mode table */ + + vmode_tbl = &CLE266Modes[SearchModeSetting(video_index)]; /* Get panel table */ + panel_crt_table = vmode_tbl->crtc; + panel_crt_reg = panel_crt_table->crtc; + + set_hres = plvds_setting_info->h_active; + set_vres = plvds_setting_info->v_active; + panel_hres = plvds_setting_info->lcd_panel_hres; + panel_vres = plvds_setting_info->lcd_panel_vres; + if(VT1636_LVDS == plvds_chip_info->lvds_chip_name) + { + init_lvds_vt1636(plvds_setting_info, plvds_chip_info); + } + plvds_setting_info->vclk = panel_crt_table->clk; + if (set_iga == IGA1) + { + /* IGA1 doesn't have LCD scaling, so set it as centering. */ + load_crtc_timing(lcd_centering_timging(mode_crt_reg, panel_crt_reg), IGA1); + } + else + { + /* Expansion */ + if ((plvds_setting_info->display_method == LCD_EXPANDSION) & + ((set_hres != panel_hres ) || (set_vres != panel_vres))) + { + /* expansion timing IGA2 always loaded panel set timing */ + load_crtc_timing(panel_crt_reg, IGA2); + load_lcd_scaling(set_hres, set_vres, panel_hres, panel_vres); + } + else /* Centering */ + { + /* centering timing IGA2 always loaded panel and mode releative timing */ + load_crtc_timing(lcd_centering_timging(mode_crt_reg, panel_crt_reg), IGA2); + write_reg_mask(CR79, VIACR, 0x00, BIT0+BIT1+BIT2); /* LCD scaling disabled */ + } + } + + if (set_iga == IGA1_IGA2) + { + load_crtc_shadow_timing(mode_crt_reg, panel_crt_reg); /* Fill shadow registers */ + + switch(plvds_setting_info->lcd_panel_id) + { + case LCD_PANEL_ID0_640X480: + offset = 80; + break; + case LCD_PANEL_ID1_800X600: + offset = 110; + break; + case LCD_PANEL_ID2_1024X768: + offset = 150; + break; + case LCD_PANEL_ID3_1280X768: + case LCD_PANEL_ID4_1280X1024: + case LCD_PANEL_ID5_1400X1050: + offset = 190; + break; + case LCD_PANEL_ID6_1600X1200: + offset = 250; + break; + case LCD_PANEL_ID7_1366X768: + offset = 212; + break; + default: + offset = 140; + break; + } + + /* Offset for simultaneous */ + reg_value = offset; + load_reg_num = offset_reg.iga2_offset_reg.reg_num; + reg = offset_reg.iga2_offset_reg.reg; + load_reg(reg_value, load_reg_num, reg, VIACR); + + load_fetch_count_reg(set_hres, 4, IGA2); /* Fetch count for simultaneous*/ + } + else /* SAMM */ + { + load_offset_reg(set_hres, mode_bpp/8, set_iga); /* Offset for IGA2 only */ + load_fetch_count_reg(set_hres, mode_bpp/8, set_iga); /* Fetch count for IGA2 only */ + + if((chip_info.gfx_chip_name != UNICHROME_CLE266) && (chip_info.gfx_chip_name != UNICHROME_K400)) + load_FIFO_reg(set_iga, set_hres, set_vres); + + set_color_depth(mode_bpp/8, set_iga); + } + + fill_lcd_format(); + + pll_D_N = get_clk_value(panel_crt_table[0].clk); + DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); + SetVCLK(pll_D_N, set_iga); + + set_output_path(DEVICE_LCD, set_iga, plvds_chip_info->output_interface); + lcd_patch_skew(plvds_setting_info, plvds_chip_info); + + /* If K8M800, enable LCD Prefetch Mode. */ + if((chip_info.gfx_chip_name == UNICHROME_K800) || (UNICHROME_K8M890 == chip_info.gfx_chip_name)) + { + write_reg_mask(CR6A, VIACR, 0x01, BIT0); + } + + load_lcd_patch_regs(set_hres, set_vres, plvds_setting_info->lcd_panel_id, set_iga); + + /* Patch for non 32bit alignment mode */ + VIAPitchAlignmentPatchLCD(plvds_setting_info, plvds_chip_info); +} + +void integrated_lvds_disable(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) +{ + bool turn_off_first_powersequence = FALSE; + bool turn_off_second_powersequence = FALSE; + if(INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface) + { + turn_off_first_powersequence = TRUE; + } + if(INTERFACE_LVDS0 == plvds_chip_info->output_interface) + { + turn_off_first_powersequence = TRUE; + } + if(INTERFACE_LVDS1 == plvds_chip_info->output_interface) + { + turn_off_second_powersequence = TRUE; + } + if (turn_off_second_powersequence) + { + /* Use second power sequence control: */ + + /* Turn off power sequence. */ + write_reg_mask(CRD4, VIACR, 0, BIT1); + + /* Turn off back light. */ + write_reg_mask(CRD3, VIACR, 0xC0, BIT6+BIT7); + } + if(turn_off_first_powersequence) + { + /* Use first power sequence control: */ + + /* Turn off power sequence. */ + write_reg_mask(CR6A, VIACR, 0, BIT3); + + /* Turn off back light. */ + write_reg_mask(CR91, VIACR, 0xC0, BIT6+BIT7); + } + + /* Turn DFP High/Low Pad off. */ + write_reg_mask(SR2A, VIASR, 0, BIT0+BIT1+BIT2+BIT3); + + /* Power off LVDS channel. */ + switch (plvds_chip_info->output_interface) + { + case INTERFACE_LVDS0: + { + write_reg_mask(CRD2, VIACR, 0x80, BIT7); + break; + } + + case INTERFACE_LVDS1: + { + write_reg_mask(CRD2, VIACR, 0x40, BIT6); + break; + } + + case INTERFACE_LVDS0LVDS1: + { + write_reg_mask(CRD2, VIACR, 0xC0, BIT6+BIT7); + break; + } + } +} + +void integrated_lvds_enable(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) +{ + bool turn_on_first_powersequence = FALSE; + bool turn_on_second_powersequence = FALSE; + DEBUG_MSG(KERN_INFO "integrated_lvds_enable, out_interface:%d\n", plvds_chip_info->output_interface); + /* Panel mode for VT3324 integrated LVDS. */ + if (plvds_setting_info->lcd_mode == LCD_SPWG) + { + write_reg_mask(CRD2, VIACR, 0x00, BIT0+BIT1); + } + else /* lcd_mode == OPEN LDI */ + { + write_reg_mask(CRD2, VIACR, 0x03, BIT0+BIT1); + } + if(INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface) + { + turn_on_first_powersequence = TRUE; + } + if(INTERFACE_LVDS0 == plvds_chip_info->output_interface) + { + turn_on_first_powersequence = TRUE; + } + if(INTERFACE_LVDS1 == plvds_chip_info->output_interface) + { + turn_on_second_powersequence = TRUE; + } + + if (turn_on_second_powersequence) + { + /* Use second power sequence control: */ + + /* Use hardware control power sequence. */ + write_reg_mask(CRD3, VIACR, 0, BIT0); + + /* Turn on back light. */ + write_reg_mask(CRD3, VIACR, 0, BIT6+BIT7); + + /* Turn on hardware power sequence. */ + write_reg_mask(CRD4, VIACR, 0x02, BIT1); + } + if(turn_on_first_powersequence) + { + /* Use first power sequence control: */ + + /* Use hardware control power sequence. */ + write_reg_mask(CR91, VIACR, 0, BIT0); + + /* Turn on back light. */ + write_reg_mask(CR91, VIACR, 0, BIT6+BIT7); + + /* Turn on hardware power sequence. */ + write_reg_mask(CR6A, VIACR, 0x08, BIT3); + } + + /* Turn DFP High/Low pad on. */ + write_reg_mask(SR2A, VIASR, 0x0F, BIT0+BIT1+BIT2+BIT3); + + /* Power on LVDS channel. */ + switch (plvds_chip_info->output_interface) + { + case INTERFACE_LVDS0: + { + write_reg_mask(CRD2, VIACR, 0, BIT7); + break; + } + + case INTERFACE_LVDS1: + { + write_reg_mask(CRD2, VIACR, 0, BIT6); + break; + } + + case INTERFACE_LVDS0LVDS1: + { + write_reg_mask(CRD2, VIACR, 0, BIT6+BIT7); + break; + } + } +} + +void lcd_disable(void) +{ + + if (chip_info.gfx_chip_name == UNICHROME_CLE266) + { + LCDPowerSequenceOff(); + write_reg_mask(SR1E, VIASR, 0x00, 0x30); /* DI1 pad off */ + } + else if(chip_info.gfx_chip_name == UNICHROME_CX700) + { + if (LCD2_ON && (INTEGRATED_LVDS == chip_info.lvds_chip_info2.lvds_chip_name)) + { + integrated_lvds_disable(&lvds_setting_info2, &chip_info.lvds_chip_info2); + } + if (INTEGRATED_LVDS == chip_info.lvds_chip_info.lvds_chip_name) + { + integrated_lvds_disable(&lvds_setting_info, &chip_info.lvds_chip_info); + } + if (VT1636_LVDS == chip_info.lvds_chip_info.lvds_chip_name) + { + disable_lvds_vt1636(&lvds_setting_info, &chip_info.lvds_chip_info); + } + } + else if(VT1636_LVDS == chip_info.lvds_chip_info.lvds_chip_name) + { + disable_lvds_vt1636(&lvds_setting_info, &chip_info.lvds_chip_info); + } + else + { + write_reg_mask(SR2A, VIASR, 0x00, 0x0F); /* DFP-HL pad off */ + write_reg_mask(SR3D, VIASR, 0x00, 0x20); /* Backlight off */ + write_reg_mask(CR91, VIACR, 0x80, 0x80); /* 24 bit DI data paht off */ + write_reg_mask(CR6B, VIACR, 0x00, 0x08); /* Simultaneout disabled */ + } + + write_reg_mask(CR79, VIACR, 0x00, 0x01); /* Disable expansion bit */ + write_reg_mask(SR16, VIASR, 0x00, 0x40); /* CRT path set to IGA1 */ + write_reg_mask(CR6B, VIACR, 0x00, 0x08); /* Simultaneout disabled */ + write_reg_mask(CR6A, VIACR, 0x00, 0x80); /* IGA2 path disabled */ + +} + +void lcd_enable(void) +{ + if (chip_info.gfx_chip_name == UNICHROME_CLE266) + { + write_reg_mask(SR1E, VIASR, 0x30, 0x30); /* DI1 pad on */ + LCDPowerSequenceOn(); + } + else if(chip_info.gfx_chip_name == UNICHROME_CX700) + { + if (LCD2_ON && (INTEGRATED_LVDS == chip_info.lvds_chip_info2.lvds_chip_name)) + { + integrated_lvds_enable(&lvds_setting_info2, &chip_info.lvds_chip_info2); + } + if (INTEGRATED_LVDS == chip_info.lvds_chip_info.lvds_chip_name) + { + integrated_lvds_enable(&lvds_setting_info, &chip_info.lvds_chip_info); + } + if (VT1636_LVDS == chip_info.lvds_chip_info.lvds_chip_name) + { + enable_lvds_vt1636(&lvds_setting_info, &chip_info.lvds_chip_info); + } + } + else if(VT1636_LVDS == chip_info.lvds_chip_info.lvds_chip_name) + { + enable_lvds_vt1636(&lvds_setting_info, &chip_info.lvds_chip_info); + } + else + { + write_reg_mask(SR2A, VIASR, 0x0F, 0x0F); /* DFP-HL pad on */ + write_reg_mask(SR3D, VIASR, 0x20, 0x20); /* Backlight on */ + write_reg_mask(CR91, VIACR, 0x00, 0x80); /* 24 bit DI data paht on */ + + /* Set data source selection bit by iga path */ + if (lvds_setting_info.iga_path == IGA1) + { + write_reg_mask(CR97, VIACR, 0x00, 0x10); /* DFP-H set to IGA1 */ + write_reg_mask(CR99, VIACR, 0x00, 0x10); /* DFP-L set to IGA1 */ + } + else + { + write_reg_mask(CR97, VIACR, 0x10, 0x10); /* DFP-H set to IGA2 */ + write_reg_mask(CR99, VIACR, 0x10, 0x10); /* DFP-L set to IGA2 */ + } + + write_reg_mask(CR6A, VIACR, 0x48, 0x48); /* LCD enabled */ + } + + if ((lvds_setting_info.iga_path == IGA1)||(lvds_setting_info.iga_path == IGA1_IGA2)) + { + write_reg_mask(SR16, VIASR, 0x40, 0x40); /* CRT path set to IGA2 */ + write_reg_mask(CR6A, VIACR, 0x00, 0x80); /* IGA2 path disabled */ + } + else /* IGA2 */ + { + write_reg_mask(CR6A, VIACR, 0x80, 0x80); /* IGA2 path enabled */ + } + +} + +void LCDPowerSequenceOff(void) +{ + int i, mask, data; + + /* Software control power sequence */ + write_reg_mask(CR91, VIACR, 0x11, 0x11); + + for (i = 0; i < 3; i++) + { + mask = PowerSequenceOff[0][i]; + data = PowerSequenceOff[1][i] & mask; + write_reg_mask(CR91, VIACR, (u8)data, (u8)mask); + delays(PowerSequenceOff[2][i]); + } + + /* Disable LCD */ + write_reg_mask(CR6A, VIACR, 0x00, 0x08); +} + +void LCDPowerSequenceOn(void) +{ + int i, mask, data; + + /* Software control power sequence */ + write_reg_mask(CR91, VIACR, 0x11, 0x11); + + /* Enable LCD */ + write_reg_mask(CR6A, VIACR, 0x08, 0x08); + + for (i = 0; i < 3; i++) + { + mask = PowerSequenceOn[0][i]; + data = PowerSequenceOn[1][i] & mask; + write_reg_mask(CR91, VIACR, (u8)data, (u8)mask); + delays(PowerSequenceOn[2][i]); + } + + delays(1); +} + +void fill_lcd_format(void) +{ + u8 bdithering = 0, bdual = 0; + + if(lvds_setting_info.LCDDualEdge) + { + bdual = BIT4; + } + if(lvds_setting_info.LCDDithering) + { + bdithering = BIT0; + } + + write_reg_mask(CR88, VIACR, (bdithering | bdual), BIT4+BIT0); /* Dual & Dithering */ +} + +void check_diport_of_integrated_lvds(struct lvds_chip_information *plvds_chip_info, struct lvds_setting_information* plvds_setting_info) +{ + /* Determine LCD DI Port by hardware layout. */ + switch (display_hardware_layout) + { + case HW_LAYOUT_LCD_ONLY: + { + if (plvds_setting_info->LCDDualEdge) + { + plvds_chip_info->output_interface = INTERFACE_LVDS0LVDS1; + } + else + { + plvds_chip_info->output_interface = INTERFACE_LVDS0; + } + + break; + } + + case HW_LAYOUT_DVI_ONLY: + { + plvds_chip_info->output_interface = INTERFACE_NONE; + break; + } + + case HW_LAYOUT_LCD1_LCD2: + case HW_LAYOUT_LCD_EXTERNAL_LCD2: + { + plvds_chip_info->output_interface = INTERFACE_LVDS0LVDS1; + break; + } + + case HW_LAYOUT_LCD_DVI: + { + plvds_chip_info->output_interface = INTERFACE_LVDS1; + break; + } + + default: + { + plvds_chip_info->output_interface = INTERFACE_LVDS1; + break; + } + } + + DEBUG_MSG(KERN_INFO "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n", display_hardware_layout, plvds_chip_info->output_interface); +} + +void init_lvds_output_interface(struct lvds_chip_information *plvds_chip_info, struct lvds_setting_information* plvds_setting_info) +{ + if(INTERFACE_NONE != plvds_chip_info->output_interface) + { + /* Do nothing, lcd port is specified by module parameter */ + return; + } + switch(plvds_chip_info->lvds_chip_name) + { + + case VT1636_LVDS: + switch(chip_info.gfx_chip_name) + { + case UNICHROME_CX700: + plvds_chip_info->output_interface = INTERFACE_DVP1; + break; + case UNICHROME_CN900: + plvds_chip_info->output_interface = INTERFACE_DFP_LOW; + break; + default: + plvds_chip_info->output_interface = INTERFACE_DVP0; + break; + } + break; + + /* Add for VT3324 integrated LVDS. */ + case INTEGRATED_LVDS: + check_diport_of_integrated_lvds(plvds_chip_info, plvds_setting_info); + break; + + default: + switch(chip_info.gfx_chip_name) + { + /* Modified from X driver. For the case VT1637 (PCIE LVDS Transmitter) + on VT3336/VT3327, we should use DFP Low to enable LCD. + FixMe!! We should find a better method to do this. */ + case UNICHROME_K8M890: + case UNICHROME_P4M900: + case UNICHROME_P4M890: + plvds_chip_info->output_interface = INTERFACE_DFP_LOW; + break; + default: + plvds_chip_info->output_interface = INTERFACE_DFP; + break; + } + break; + } +} + +struct display_timing lcd_centering_timging(struct display_timing mode_crt_reg, struct display_timing panel_crt_reg) +{ + struct display_timing crt_reg; + + crt_reg.hor_total = panel_crt_reg.hor_total; + crt_reg.hor_addr = mode_crt_reg.hor_addr; + crt_reg.hor_blank_start = (panel_crt_reg.hor_addr - mode_crt_reg.hor_addr)/2 + crt_reg.hor_addr; + crt_reg.hor_blank_end = panel_crt_reg.hor_blank_end; + crt_reg.hor_sync_start = (panel_crt_reg.hor_sync_start - panel_crt_reg.hor_blank_start) + crt_reg.hor_blank_start; + crt_reg.hor_sync_end = panel_crt_reg.hor_sync_end; + + crt_reg.ver_total = panel_crt_reg.ver_total; + crt_reg.ver_addr = mode_crt_reg.ver_addr; + crt_reg.ver_blank_start = (panel_crt_reg.ver_addr - mode_crt_reg.ver_addr)/2 + crt_reg.ver_addr; + crt_reg.ver_blank_end = panel_crt_reg.ver_blank_end; + crt_reg.ver_sync_start = (panel_crt_reg.ver_sync_start - panel_crt_reg.ver_blank_start) + crt_reg.ver_blank_start; + crt_reg.ver_sync_end = panel_crt_reg.ver_sync_end; + + return crt_reg; +} + +void load_crtc_shadow_timing(struct display_timing mode_timing, struct display_timing panel_timing) +{ + struct io_register *reg = NULL; + int i; + int load_reg_Num = 0; + int reg_value = 0; + + if(lvds_setting_info.display_method == LCD_EXPANDSION) /* Expansion */ + { + for(i=12;i<20;i++) + { + switch(i) + { + case H_TOTAL_SHADOW_INDEX: + reg_value = IGA2_HOR_TOTAL_SHADOW_FORMULA(panel_timing.hor_total); + load_reg_Num = iga2_shadow_crtc_reg.hor_total_shadow.reg_num; + reg = iga2_shadow_crtc_reg.hor_total_shadow.reg; + break; + case H_BLANK_END_SHADOW_INDEX: + reg_value = IGA2_HOR_BLANK_END_SHADOW_FORMULA(panel_timing.hor_blank_start, panel_timing.hor_blank_end); + load_reg_Num = iga2_shadow_crtc_reg.hor_blank_end_shadow.reg_num; + reg = iga2_shadow_crtc_reg.hor_blank_end_shadow.reg; + break; + case V_TOTAL_SHADOW_INDEX: + reg_value = IGA2_VER_TOTAL_SHADOW_FORMULA(panel_timing.ver_total); + load_reg_Num = iga2_shadow_crtc_reg.ver_total_shadow.reg_num; + reg = iga2_shadow_crtc_reg.ver_total_shadow.reg; + break; + case V_ADDR_SHADOW_INDEX: + reg_value = IGA2_VER_ADDR_SHADOW_FORMULA(panel_timing.ver_addr); + load_reg_Num = iga2_shadow_crtc_reg.ver_addr_shadow.reg_num; + reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg; + break; + case V_BLANK_SATRT_SHADOW_INDEX: + reg_value = IGA2_VER_BLANK_START_SHADOW_FORMULA(panel_timing.ver_blank_start); + load_reg_Num = iga2_shadow_crtc_reg.ver_blank_start_shadow.reg_num; + reg = iga2_shadow_crtc_reg.ver_blank_start_shadow.reg; + break; + case V_BLANK_END_SHADOW_INDEX: + reg_value = IGA2_VER_BLANK_END_SHADOW_FORMULA(panel_timing.ver_blank_start, panel_timing.ver_blank_end); + load_reg_Num = iga2_shadow_crtc_reg.ver_blank_end_shadow.reg_num; + reg = iga2_shadow_crtc_reg.ver_blank_end_shadow.reg; + break; + case V_SYNC_SATRT_SHADOW_INDEX: + reg_value = IGA2_VER_SYNC_START_SHADOW_FORMULA(panel_timing.ver_sync_start); + load_reg_Num = iga2_shadow_crtc_reg.ver_sync_start_shadow.reg_num; + reg = iga2_shadow_crtc_reg.ver_sync_start_shadow.reg; + break; + case V_SYNC_END_SHADOW_INDEX: + reg_value = IGA2_VER_SYNC_END_SHADOW_FORMULA(panel_timing.ver_sync_start, panel_timing.ver_sync_end); + load_reg_Num = iga2_shadow_crtc_reg.ver_sync_end_shadow.reg_num; + reg = iga2_shadow_crtc_reg.ver_sync_end_shadow.reg; + break; + } + load_reg(reg_value, load_reg_Num, reg, VIACR); + } + } + else /* Centering */ + { + for(i=12;i<20;i++) + { + switch(i) + { + case H_TOTAL_SHADOW_INDEX: + reg_value = IGA2_HOR_TOTAL_SHADOW_FORMULA(panel_timing.hor_total); + load_reg_Num = iga2_shadow_crtc_reg.hor_total_shadow.reg_num; + reg = iga2_shadow_crtc_reg.hor_total_shadow.reg; + break; + case H_BLANK_END_SHADOW_INDEX: + reg_value = IGA2_HOR_BLANK_END_SHADOW_FORMULA(panel_timing.hor_blank_start, panel_timing.hor_blank_end); + load_reg_Num = iga2_shadow_crtc_reg.hor_blank_end_shadow.reg_num; + reg = iga2_shadow_crtc_reg.hor_blank_end_shadow.reg; + break; + case V_TOTAL_SHADOW_INDEX: + reg_value = IGA2_VER_TOTAL_SHADOW_FORMULA(panel_timing.ver_total); + load_reg_Num = iga2_shadow_crtc_reg.ver_total_shadow.reg_num; + reg = iga2_shadow_crtc_reg.ver_total_shadow.reg; + break; + case V_ADDR_SHADOW_INDEX: + reg_value = IGA2_VER_ADDR_SHADOW_FORMULA(mode_timing.ver_addr); + load_reg_Num = iga2_shadow_crtc_reg.ver_addr_shadow.reg_num; + reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg; + break; + case V_BLANK_SATRT_SHADOW_INDEX: + reg_value = IGA2_VER_BLANK_START_SHADOW_FORMULA(mode_timing.ver_blank_start); + load_reg_Num = iga2_shadow_crtc_reg.ver_blank_start_shadow.reg_num; + reg = iga2_shadow_crtc_reg.ver_blank_start_shadow.reg; + break; + case V_BLANK_END_SHADOW_INDEX: + reg_value = IGA2_VER_BLANK_END_SHADOW_FORMULA(panel_timing.ver_blank_start, panel_timing.ver_blank_end); + load_reg_Num = iga2_shadow_crtc_reg.ver_blank_end_shadow.reg_num; + reg = iga2_shadow_crtc_reg.ver_blank_end_shadow.reg; + break; + case V_SYNC_SATRT_SHADOW_INDEX: + reg_value = IGA2_VER_SYNC_START_SHADOW_FORMULA((panel_timing.ver_sync_start - panel_timing.ver_blank_start) + (panel_timing.ver_addr - mode_timing.ver_addr)/2 + mode_timing.ver_addr); + load_reg_Num = iga2_shadow_crtc_reg.ver_sync_start_shadow.reg_num; + reg = iga2_shadow_crtc_reg.ver_sync_start_shadow.reg; + break; + case V_SYNC_END_SHADOW_INDEX: + reg_value = IGA2_VER_SYNC_END_SHADOW_FORMULA((panel_timing.ver_sync_start - panel_timing.ver_blank_start) + (panel_timing.ver_addr - mode_timing.ver_addr)/2 + mode_timing.ver_addr, panel_timing.ver_sync_end); + load_reg_Num = iga2_shadow_crtc_reg.ver_sync_end_shadow.reg_num; + reg = iga2_shadow_crtc_reg.ver_sync_end_shadow.reg; + break; + } + load_reg(reg_value, load_reg_Num, reg, VIACR); + } + } +} + + + +/* Purpose: + * To know if current chip are mobile. + * Parameter: + * mobile: a pointer to a boolean value which is used to received the mobile status. + */ +bool lcd_get_mobile_state(bool* mobile) +{ + unsigned char *romptr, *tableptr; + u8 core_base; + unsigned char* biosptr; + u32 romaddr = 0x000C0000; /* Rom address */ + u16 start_pattern = (u16)NULL; + + biosptr=ioremap(romaddr,0x10000); + + memcpy(&start_pattern, biosptr, 2); + if (start_pattern == 0xAA55) /* Compare pattern */ + { + /* Get the start of Table */ + romptr = biosptr + 0x1B; /* 0x1B means BIOS offset position */ + tableptr = biosptr + *((u16 *)romptr); + + /* Get the start of biosver structure */ + romptr = tableptr + 18; /* 18 means BIOS version position. */ + romptr = biosptr + *((u16 *)romptr); + + /* The offset should be 44, but the actual image is less three char. */ + romptr += 41; + + core_base = *romptr++; + + if (core_base & 0x8) + { + *mobile = FALSE; + } + else + { + *mobile = TRUE; + } + + iounmap(biosptr); /* release memory */ + + return TRUE; + } + else + { + iounmap(biosptr); + return FALSE; + } +} + +/* Modified form X driver code to support P4M900 */ +void load_scaling_factor_for_p4m900(int set_hres, int set_vres, int panel_hres, int panel_vres) +{ + int h_scaling_factor; + int v_scaling_factor; + u8 cra2 = 0; + u8 cr77 = 0; + u8 cr78 = 0; + u8 cr79 = 0; + u8 cr9f = 0; + /* Check if expansion for horizontal */ + if(set_hres < panel_hres) + { + /* Load Horizontal Scaling Factor */ + + /* For VIA_K8M800 or later chipsets. */ + h_scaling_factor = K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); + cr9f = h_scaling_factor & 0x0003; /* HSCaleFactor[1:0] at CR9F[1:0] */ + cr77 = (h_scaling_factor & 0x03FC)>>2; /* HSCaleFactor[9:2] at CR77[7:0] */ + cr79 = (h_scaling_factor & 0x0C00)>>10; /* HSCaleFactor[11:10] at CR79[5:4] */ + cr79 <<= 4; + + /* Horizontal scaling enabled */ + cra2 = 0xC0; + + DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d\n", h_scaling_factor); + } + else + { + /* Horizontal scaling disabled */ + cra2 = 0x00; + } + + + /* Check if expansion for vertical */ + if(set_vres < panel_vres) + { + /* Load Vertical Scaling Factor */ + + /* For VIA_K8M800 or later chipsets. */ + v_scaling_factor = K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres); + + /* Vertical scaling enabled */ + cra2 |= 0x08; + cr79 |= ((v_scaling_factor & 0x0001)<<3); /* VSCaleFactor[0] at CR79[3] */ + cr78 |= (v_scaling_factor & 0x01FE) >> 1; /* VSCaleFactor[8:1] at CR78[7:0] */ + cr79 |= ((v_scaling_factor & 0x0600) >> 9) << 6; /* VSCaleFactor[10:9] at CR79[7:6] */ + + DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d\n", v_scaling_factor); + } + else + { + /* Vertical scaling disabled */ + cra2 |= 0x00; + } + + write_reg_mask(CRA2, VIACR, cra2, BIT3+BIT6+BIT7); + write_reg_mask(CR77, VIACR, cr77, 0xFF); + write_reg_mask(CR78, VIACR, cr78, 0xFF); + write_reg_mask(CR79, VIACR, cr79, 0xF8); + write_reg_mask(CR9F, VIACR, cr9f, BIT0+BIT1); +} +
diff -Nur linux-2.6.21-rc7/drivers/video/via/lcd.h linux-2.6.21-rc7.viafb/drivers/video/via/lcd.h
--- linux-2.6.21-rc7/drivers/video/via/lcd.h 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.21-rc7.viafb/drivers/video/via/lcd.h 2007-04-26 19:52:32.000000000 -0400@@ -0,0 +1,57 @@ + /* + * Copyright 1998-2007 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2007 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + + +#ifndef __LCD_H__ +#define __LCD_H__ + +/* Definition TMDS Device ID register */ +#define VT1631_DEVICE_ID_REG 0x02 +#define VT1631_DEVICE_ID 0x92 + + +#define VT3271_DEVICE_ID_REG 0x02 +#define VT3271_DEVICE_ID 0x71 + + +#define GET_LCD_SIZE_BY_SYSTEM_BIOS 0x01 +#define GET_LCD_SIZE_BY_VGA_BIOS 0x02 +#define GET_LCD_SZIE_BY_HW_STRAPPING 0x03 +#define GET_LCD_SIZE_BY_USER_SETTING 0x04 + + + +/* Definition DVI Panel ID */ +#define LCD_PANEL_ID0_640X480 0x00 /* Resolution: 640x480, Channel: single, Dithering: Enable */ +#define LCD_PANEL_ID1_800X600 0x01 /* Resolution: 800x600, Channel: single, Dithering: Enable */ +#define LCD_PANEL_ID2_1024X768 0x02 /* Resolution: 1024x768, Channel: single, Dithering: Enable */ +#define LCD_PANEL_ID3_1280X768 0x03 /* Resolution: 1280x768, Channel: single, Dithering: Enable */ +#define LCD_PANEL_ID4_1280X1024 0x04 /* Resolution: 1280x1024, Channel: dual, Dithering: Enable */ +#define LCD_PANEL_ID5_1400X1050 0x05 /* Resolution: 1400x1050, Channel: dual, Dithering: Enable */ +#define LCD_PANEL_ID6_1600X1200 0x06 /* Resolution: 1600x1200, Channel: dual, Dithering: Enable */ +#define LCD_PANEL_ID7_1366X768 0x07 /* Resolution: 1366x768, Channel: single, Dithering: Disable */ +#define LCD_PANEL_ID8_1024X600 0x08 /* Resolution: 1024x600, Channel: single, Dithering: Enable */ +#define LCD_PANEL_ID9_1280X800 0x09 /* Resolution: 1280x800, Channel: single, Dithering: Enable */ + +#endif /* __LCD_H__ */
diff -Nur linux-2.6.21-rc7/drivers/video/via/lcdtbl.h linux-2.6.21-rc7.viafb/drivers/video/via/lcdtbl.h
--- linux-2.6.21-rc7/drivers/video/via/lcdtbl.h 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.21-rc7.viafb/drivers/video/via/lcdtbl.h 2007-04-26 19:52:32.000000000 -0400@@ -0,0 +1,303 @@ + /* + * Copyright 1998-2007 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2007 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + + +#ifndef __LCDTBL_H__ +#define __LCDTBL_H__ + +#include "share.h" + +/* CLE266 Software Power Sequence */ +/* {Mask}, {Data}, {Delay} */ +int PowerSequenceOn[3][3] = {{0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, {0x19, 0x1FE, 0x01}}; +int PowerSequenceOff[3][3] = {{0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, {0xD2, 0x19, 0x01}}; + +/* ++++++ P880 ++++++ */ +/* Panel 1600x1200 */ +struct io_reg P880_LCD_RES_6X4_16X12[] = { + {VIACR,CR50,0xFF,0x73},{VIACR,CR55,0x0F,0x08}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x73},{VIACR,CR54,0x38,0x00},{VIACR,CR5D,0x40,0x40},/* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x5A},{VIACR,CR71,0x08,0x00}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x5E}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xD6},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR44,0xFF,0x7D},{VIASR,SR45,0xFF,0x8C},{VIASR,SR46,0xFF,0x02} /* VCLK */ +}; +#define NUM_TOTAL_P880_LCD_RES_6X4_16X12 ARRAY_SIZE(P880_LCD_RES_6X4_16X12) + +struct io_reg P880_LCD_RES_7X4_16X12[] = { + {VIACR,CR50,0xFF,0x67},{VIACR,CR55,0x0F,0x08}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x67},{VIACR,CR54,0x38,0x00},{VIACR,CR5D,0x40,0x40},/* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x74},{VIACR,CR71,0x08,0x00}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x78}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xF5},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR44,0xFF,0x78},{VIASR,SR45,0xFF,0x8C},{VIASR,SR46,0xFF,0x01} /* VCLK */ +}; +#define NUM_TOTAL_P880_LCD_RES_7X4_16X12 ARRAY_SIZE(P880_LCD_RES_7X4_16X12) + +struct io_reg P880_LCD_RES_8X6_16X12[] = { + {VIACR,CR50,0xFF,0x65},{VIACR,CR55,0x0F,0x08}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x65},{VIACR,CR54,0x38,0x00},{VIACR,CR5D,0x40,0x40},/* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x7F},{VIACR,CR71,0x08,0x00}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x83}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xE1},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR44,0xFF,0x6D},{VIASR,SR45,0xFF,0x88},{VIASR,SR46,0xFF,0x03} /* VCLK */ +}; +#define NUM_TOTAL_P880_LCD_RES_8X6_16X12 ARRAY_SIZE(P880_LCD_RES_8X6_16X12) + +struct io_reg P880_LCD_RES_10X7_16X12[] = { + {VIACR,CR50,0xFF,0x65},{VIACR,CR55,0x0F,0x08}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x65},{VIACR,CR54,0x38,0x00},{VIACR,CR5D,0x40,0x40},/* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0xAB},{VIACR,CR71,0x08,0x00}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0xAF}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xF0},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR44,0xFF,0x92},{VIASR,SR45,0xFF,0x88},{VIASR,SR46,0xFF,0x03} /* VCLK */ +}; +#define NUM_TOTAL_P880_LCD_RES_10X7_16X12 ARRAY_SIZE(P880_LCD_RES_10X7_16X12) + +struct io_reg P880_LCD_RES_12X10_16X12[] = { + {VIACR,CR50,0xFF,0x7D},{VIACR,CR55,0x0F,0x08}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x7D},{VIACR,CR54,0x38,0x00},{VIACR,CR5D,0x40,0x40},/* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0xD0},{VIACR,CR71,0x08,0x00}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0xD4}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xFA},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR44,0xFF,0xF6},{VIASR,SR45,0xFF,0x88},{VIASR,SR46,0xFF,0x05} /* VCLK */ +}; +#define NUM_TOTAL_P880_LCD_RES_12X10_16X12 ARRAY_SIZE(P880_LCD_RES_12X10_16X12) + +/* Panel 1400x1050 */ +static struct io_reg P880_LCD_RES_6X4_14X10[] = { /* 640x480 */ + {VIACR,CR50,0xFF,0x9D},{VIACR,CR55,0x0F,0x56}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x9D},{VIACR,CR54,0x38,0x75},{VIACR,CR5D,0x40,0x24}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x5F},{VIACR,CR71,0x08,0x44}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x63}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xB4},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR44,0xFF,0xC6},{VIASR,SR45,0xFF,0x8C},{VIASR,SR46,0xFF,0x05} /* VCLK */ +}; +#define NUM_TOTAL_P880_LCD_RES_6X4_14X10 ARRAY_SIZE(P880_LCD_RES_6X4_14X10) + +static struct io_reg P880_LCD_RES_8X6_14X10[] = { /* 800x600 */ + {VIACR,CR50,0xFF,0x9D},{VIACR,CR55,0x0F,0x56}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x9D},{VIACR,CR54,0x38,0x75},{VIACR,CR5D,0x40,0x24}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x7F},{VIACR,CR71,0x08,0x44}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x83}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xBE},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR44,0xFF,0x06},{VIASR,SR45,0xFF,0x8D},{VIASR,SR46,0xFF,0x05} /* VCLK */ +}; +#define NUM_TOTAL_P880_LCD_RES_8X6_14X10 ARRAY_SIZE(P880_LCD_RES_8X6_14X10) + + +/* ++++++ K400 ++++++ */ +/* Panel 1600x1200 */ +struct io_reg K400_LCD_RES_6X4_16X12[] = { + {VIACR,CR50,0xFF,0x73},{VIACR,CR55,0x0F,0x08}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x73},{VIACR,CR54,0x38,0x00},{VIACR,CR5D,0x40,0x40}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x5A},{VIACR,CR71,0x08,0x00}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x5E}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xDA},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0xC4},{VIASR,SR47,0xFF,0x7F} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_6X4_16X12 ARRAY_SIZE(K400_LCD_RES_6X4_16X12) + +struct io_reg K400_LCD_RES_7X4_16X12[] = { + {VIACR,CR50,0xFF,0x67},{VIACR,CR55,0x0F,0x08}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x67},{VIACR,CR54,0x38,0x00},{VIACR,CR5D,0x40,0x40}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x74},{VIACR,CR71,0x08,0x00}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x78}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xF5},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x46},{VIASR,SR47,0xFF,0x3D} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_7X4_16X12 ARRAY_SIZE(K400_LCD_RES_7X4_16X12) + +struct io_reg K400_LCD_RES_8X6_16X12[] = { + {VIACR,CR50,0xFF,0x65},{VIACR,CR55,0x0F,0x08}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x65},{VIACR,CR54,0x38,0x00},{VIACR,CR5D,0x40,0x40}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x7F},{VIACR,CR71,0x08,0x00}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x83}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xE1},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x85},{VIASR,SR47,0xFF,0x6F} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_8X6_16X12 ARRAY_SIZE(K400_LCD_RES_8X6_16X12) + +struct io_reg K400_LCD_RES_10X7_16X12[] = { + {VIACR,CR50,0xFF,0x65},{VIACR,CR55,0x0F,0x08}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x65},{VIACR,CR54,0x38,0x00},{VIACR,CR5D,0x40,0x40}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0xAB},{VIACR,CR71,0x08,0x00}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0xAF}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xF0},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x45},{VIASR,SR47,0xFF,0x4A} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_10X7_16X12 ARRAY_SIZE(K400_LCD_RES_10X7_16X12) + +struct io_reg K400_LCD_RES_12X10_16X12[] = { + {VIACR,CR50,0xFF,0x7D},{VIACR,CR55,0x0F,0x08}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x7D},{VIACR,CR54,0x38,0x00},{VIACR,CR5D,0x40,0x40}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0xD0},{VIACR,CR71,0x08,0x00}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0xD4}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xFA},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x47},{VIASR,SR47,0xFF,0x7C} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_12X10_16X12 ARRAY_SIZE(K400_LCD_RES_12X10_16X12) + +/* Panel 1400x1050 */ +static struct io_reg K400_LCD_RES_6X4_14X10[] = { /* 640x400 */ + {VIACR,CR50,0xFF,0x9D},{VIACR,CR55,0x0F,0x56}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x9D},{VIACR,CR54,0x38,0x75},{VIACR,CR5D,0x40,0x24}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x5F},{VIACR,CR71,0x08,0x44}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x63}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xB4},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x07},{VIASR,SR47,0xFF,0x19} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_6X4_14X10 ARRAY_SIZE(K400_LCD_RES_6X4_14X10) + +static struct io_reg K400_LCD_RES_8X6_14X10[] = { /* 800x600 */ + {VIACR,CR50,0xFF,0x9D},{VIACR,CR55,0x0F,0x56}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x9D},{VIACR,CR54,0x38,0x75},{VIACR,CR5D,0x40,0x24}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x7F},{VIACR,CR71,0x08,0x44}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x83}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xBE},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x07},{VIASR,SR47,0xFF,0x21} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_8X6_14X10 ARRAY_SIZE(K400_LCD_RES_8X6_14X10) + +static struct io_reg K400_LCD_RES_10X7_14X10[] = { /* 1024x768 */ + {VIACR,CR50,0xFF,0x9D},{VIACR,CR55,0x0F,0x56}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x9D},{VIACR,CR54,0x38,0x75},{VIACR,CR5D,0x40,0x24}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0xA3},{VIACR,CR71,0x08,0x44}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0xA7}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xC3},{VIACR,CR67,0x03,0x04}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x05},{VIASR,SR47,0xFF,0x1E} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_10X7_14X10 ARRAY_SIZE(K400_LCD_RES_10X7_14X10) + +static struct io_reg K400_LCD_RES_12X10_14X10[] = { /* 1280x768, 1280x960, 1280x1024 */ + {VIACR,CR50,0xFF,0x97},{VIACR,CR55,0x0F,0x56}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x97},{VIACR,CR54,0x38,0x75},{VIACR,CR5D,0x40,0x24}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0xCE},{VIACR,CR71,0x08,0x44}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0xD2}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xC9},{VIACR,CR67,0x03,0x04}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x84},{VIASR,SR47,0xFF,0x79} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_12X10_14X10 ARRAY_SIZE(K400_LCD_RES_12X10_14X10) + + +/* ++++++ K400 ++++++ */ +/* Panel 1280x1024 */ +struct io_reg K400_LCD_RES_6X4_12X10[] = { + {VIACR,CR50,0xFF,0x9D},{VIACR,CR55,0x0F,0x46}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x9D},{VIACR,CR54,0x38,0x74},{VIACR,CR5D,0x40,0x1C}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x5F},{VIACR,CR71,0x08,0x34}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x63}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xAA},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x07},{VIASR,SR47,0xFF,0x19} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_6X4_12X10 ARRAY_SIZE(K400_LCD_RES_6X4_12X10) + +struct io_reg K400_LCD_RES_7X4_12X10[] = { + {VIACR,CR50,0xFF,0x9D},{VIACR,CR55,0x0F,0x46}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x9D},{VIACR,CR54,0x38,0x74},{VIACR,CR5D,0x40,0x1C}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x68},{VIACR,CR71,0x08,0x34}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x6C}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xA8},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x87},{VIASR,SR47,0xFF,0xED} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_7X4_12X10 ARRAY_SIZE(K400_LCD_RES_7X4_12X10) + +struct io_reg K400_LCD_RES_8X6_12X10[] = { + {VIACR,CR50,0xFF,0x9D},{VIACR,CR55,0x0F,0x46}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x9D},{VIACR,CR54,0x38,0x74},{VIACR,CR5D,0x40,0x1C}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x7F},{VIACR,CR71,0x08,0x34}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x83}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xBE},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x07},{VIASR,SR47,0xFF,0x21} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_8X6_12X10 ARRAY_SIZE(K400_LCD_RES_8X6_12X10) + +struct io_reg K400_LCD_RES_10X7_12X10[] = { + {VIACR,CR50,0xFF,0x9D},{VIACR,CR55,0x0F,0x46}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x9D},{VIACR,CR54,0x38,0x74},{VIACR,CR5D,0x40,0x1C}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0xA3},{VIACR,CR71,0x08,0x34}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0xA7}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0xBE},{VIACR,CR67,0x03,0x04}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x05},{VIASR,SR47,0xFF,0x1E} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_10X7_12X10 ARRAY_SIZE(K400_LCD_RES_10X7_12X10) + + +/* ++++++ K400 ++++++ */ +/* Panel 1024x768 */ +struct io_reg K400_LCD_RES_6X4_10X7[] = { + {VIACR,CR50,0xFF,0x47},{VIACR,CR55,0x0F,0x35}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x47},{VIACR,CR54,0x38,0x2B},{VIACR,CR5D,0x40,0x13}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x60},{VIACR,CR71,0x08,0x23}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x64}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0x8C},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x87},{VIASR,SR47,0xFF,0x4C} /* VCLK */ +}; + +#define NUM_TOTAL_K400_LCD_RES_6X4_10X7 ARRAY_SIZE(K400_LCD_RES_6X4_10X7) + +struct io_reg K400_LCD_RES_7X4_10X7[] = { + {VIACR,CR50,0xFF,0x3B},{VIACR,CR55,0x0F,0x35}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x3B},{VIACR,CR54,0x38,0x2B},{VIACR,CR5D,0x40,0x13}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x71},{VIACR,CR71,0x08,0x23}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x75}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0x96},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x05},{VIASR,SR47,0xFF,0x10} /* VCLK */ +}; + +#define NUM_TOTAL_K400_LCD_RES_7X4_10X7 ARRAY_SIZE(K400_LCD_RES_7X4_10X7) + +struct io_reg K400_LCD_RES_8X6_10X7[] = { + {VIACR,CR50,0xFF,0x37},{VIACR,CR55,0x0F,0x35}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x37},{VIACR,CR54,0x38,0x2B},{VIACR,CR5D,0x40,0x13}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x7E},{VIACR,CR71,0x08,0x23}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x82}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0x8C},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x84},{VIASR,SR47,0xFF,0xB9} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_8X6_10X7 ARRAY_SIZE(K400_LCD_RES_8X6_10X7) + +/* ++++++ K400 ++++++ */ +/* Panel 800x600 */ +struct io_reg K400_LCD_RES_6X4_8X6[] = { + {VIACR,CR50,0xFF,0x1A},{VIACR,CR55,0x0F,0x34}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x1A},{VIACR,CR54,0x38,0xE3},{VIACR,CR5D,0x40,0x12}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x5F},{VIACR,CR71,0x08,0x22}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x63}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0x6E},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0x86},{VIASR,SR47,0xFF,0xB3} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_6X4_8X6 ARRAY_SIZE(K400_LCD_RES_6X4_8X6) + +struct io_reg K400_LCD_RES_7X4_8X6[] = { + {VIACR,CR50,0xFF,0x1F},{VIACR,CR55,0x0F,0x34}, /* IGA2 Horizontal Total */ + {VIACR,CR53,0xFF,0x1F},{VIACR,CR54,0x38,0xE3},{VIACR,CR5D,0x40,0x12}, /* IGA2 Horizontal Blank End */ + {VIACR,CR6D,0xFF,0x7F},{VIACR,CR71,0x08,0x22}, /* IGA2 Horizontal Total Shadow */ + {VIACR,CR6E,0xFF,0x83}, /* IGA2 Horizontal Blank End Shadow */ + {VIACR,CR66,0xFF,0x78},{VIACR,CR67,0x03,0x00}, /* IGA2 Offset */ + {VIASR,SR46,0xFF,0xC4},{VIASR,SR47,0xFF,0x59} /* VCLK */ +}; +#define NUM_TOTAL_K400_LCD_RES_7X4_8X6 ARRAY_SIZE(K400_LCD_RES_7X4_8X6) + +#endif /* __LCDTBL_H__ */
diff -Nur linux-2.6.21-rc7/drivers/video/via/Makefile linux-2.6.21-rc7.viafb/drivers/video/via/Makefile
--- linux-2.6.21-rc7/drivers/video/via/Makefile 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.21-rc7.viafb/drivers/video/via/Makefile 2007-04-26 19:52:32.000000000 -0400@@ -0,0 +1,7 @@ +# +# Makefile for the VIA framebuffer driver (for Linux Kernel 2.6) +# + +obj-$(CONFIG_FB_VIA) += viafb.o + +viafb-objs := viafbdev.o hw.o iface.o tv.o via_i2c.o vt1622.o vt1622a.o dvi.o lcd.o vt1625.o ioctl.o accel.o via_utility.o IntegratedTV.o vt1636.o
diff -Nur linux-2.6.21-rc7/drivers/video/via/share.h linux-2.6.21-rc7.viafb/drivers/video/via/share.h
--- linux-2.6.21-rc7/drivers/video/via/share.h 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.21-rc7.viafb/drivers/video/via/share.h 2007-04-26 19:58:40.000000000 -0400@@ -0,0 +1,771 @@ +/* + * Copyright 1998-2007 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2007 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __SHARE_H__ +#define __SHARE_H__ + +#include <linux/version.h> + +/* Define Return Value */ +#define FAIL -1 +#define OK 1 + +/* Define Boolean Value */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +#ifndef bool +typedef int bool; +#endif +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/* Define Bit Field */ +#define BIT0 0x01 +#define BIT1 0x02 +#define BIT2 0x04 +#define BIT3 0x08 +#define BIT4 0x10 +#define BIT5 0x20 +#define BIT6 0x40 +#define BIT7 0x80 + +/* Video Memory Size */ +#define VIDEO_MEMORY_SIZE_16M 0x1000000 + +/* Definition Mode Index */ +#define VIA_RES_640X480 0 +#define VIA_RES_800X600 1 +#define VIA_RES_1024X768 2 +#define VIA_RES_1152X864 3 +#define VIA_RES_1280X1024 4 +#define VIA_RES_1600X1200 5 +#define VIA_RES_1440X1050 6 +#define VIA_RES_1280X768 7 +#define VIA_RES_1280X960 8 +#define VIA_RES_1920X1440 9 +#define VIA_RES_848X480 10 +#define VIA_RES_1400X1050 11 +#define VIA_RES_720X480 12 +#define VIA_RES_720X576 13 +#define VIA_RES_1024X512 14 +#define VIA_RES_856X480 15 +#define VIA_RES_1024X576 16 +#define VIA_RES_640X400 17 +#define VIA_RES_1280X720 18 +#define VIA_RES_1920X1080 19 +#define VIA_RES_800X480 20 +#define VIA_RES_1368X768 21 +#define VIA_RES_1024X600 22 +#define VIA_RES_1280X800 23 +#define VIA_RES_INVALID 255 + + +/* standard VGA IO port */ +#define VIARMisc 0x3CC +#define VIAWMisc 0x3C2 +#define VIAStatus 0x3DA +#define VIACR 0x3D4 +#define VIASR 0x3C4 +#define VIAGR 0x3CE +#define VIAAR 0x3C0 + +#define StdCR 0x19 +#define StdSR 0x04 +#define StdGR 0x09 +#define StdAR 0x14 + +#define PatchCR 11 + +/* Display path */ +#define IGA1 1 +#define IGA2 2 +#define IGA1_IGA2 3 + +/* Define Color Depth */ +#define MODE_8BPP 1 +#define MODE_16BPP 2 +#define MODE_32BPP 4 + +#define GR20 0x20 +#define GR21 0x21 +#define GR22 0x22 + + +/* Sequencer Registers */ +#define SR01 0x01 +#define SR10 0x10 +#define SR12 0x12 +#define SR15 0x15 +#define SR16 0x16 +#define SR17 0x17 +#define SR18 0x18 +#define SR1B 0x1B +#define SR1A 0x1A +#define SR1C 0x1C +#define SR1D 0x1D +#define SR1E 0x1E +#define SR1F 0x1F +#define SR20 0x20 +#define SR21 0x21 +#define SR22 0x22 +#define SR2A 0x2A +#define SR2D 0x2D +#define SR2E 0x2E + +#define SR30 0x30 +#define SR39 0x39 +#define SR3D 0x3D +#define SR3E 0x3E +#define SR3F 0x3F +#define SR40 0x40 +#define SR43 0x43 +#define SR44 0x44 +#define SR45 0x45 +#define SR46 0x46 +#define SR47 0x47 +#define SR48 0x48 +#define SR49 0x49 +#define SR4A 0x4A +#define SR4B 0x4B +#define SR4C 0x4C +#define SR52 0x52 +#define SR5E 0x5E +#define SR65 0x65 + + +/* CRT Controller Registers */ +#define CR00 0x00 +#define CR01 0x01 +#define CR02 0x02 +#define CR03 0x03 +#define CR04 0x04 +#define CR05 0x05 +#define CR06 0x06 +#define CR07 0x07 +#define CR08 0x08 +#define CR09 0x09 +#define CR0A 0x0A +#define CR0B 0x0B +#define CR0C 0x0C +#define CR0D 0x0D +#define CR0E 0x0E +#define CR0F 0x0F +#define CR10 0x10 +#define CR11 0x11 +#define CR12 0x12 +#define CR13 0x13 +#define CR14 0x14 +#define CR15 0x15 +#define CR16 0x16 +#define CR17 0x17 +#define CR18 0x18 + +/* Extend CRT Controller Registers */ +#define CR30 0x30 +#define CR31 0x31 +#define CR32 0x32 +#define CR33 0x33 +#define CR34 0x34 +#define CR35 0x35 +#define CR36 0x36 +#define CR37 0x37 +#define CR38 0x38 +#define CR39 0x39 +#define CR3A 0x3A +#define CR3B 0x3B +#define CR3C 0x3C +#define CR3D 0x3D +#define CR3E 0x3E +#define CR3F 0x3F +#define CR40 0x40 +#define CR41 0x41 +#define CR42 0x42 +#define CR43 0x43 +#define CR44 0x44 +#define CR45 0x45 +#define CR46 0x46 +#define CR47 0x47 +#define CR48 0x48 +#define CR49 0x49 +#define CR4A 0x4A +#define CR4B 0x4B +#define CR4C 0x4C +#define CR4D 0x4D +#define CR4E 0x4E +#define CR4F 0x4F +#define CR50 0x50 +#define CR51 0x51 +#define CR52 0x52 +#define CR53 0x53 +#define CR54 0x54 +#define CR55 0x55 +#define CR56 0x56 +#define CR57 0x57 +#define CR58 0x58 +#define CR59 0x59 +#define CR5A 0x5A +#define CR5B 0x5B +#define CR5C 0x5C +#define CR5D 0x5D +#define CR5E 0x5E +#define CR5F 0x5F +#define CR60 0x60 +#define CR61 0x61 +#define CR62 0x62 +#define CR63 0x63 +#define CR64 0x64 +#define CR65 0x65 +#define CR66 0x66 +#define CR67 0x67 +#define CR68 0x68 +#define CR69 0x69 +#define CR6A 0x6A +#define CR6B 0x6B +#define CR6C 0x6C +#define CR6D 0x6D +#define CR6E 0x6E +#define CR6F 0x6F +#define CR70 0x70 +#define CR71 0x71 +#define CR72 0x72 +#define CR73 0x73 +#define CR74 0x74 +#define CR75 0x75 +#define CR76 0x76 +#define CR77 0x77 +#define CR78 0x78 +#define CR79 0x79 +#define CR7A 0x7A +#define CR7B 0x7B +#define CR7C 0x7C +#define CR7D 0x7D +#define CR7E 0x7E +#define CR7F 0x7F +#define CR80 0x80 +#define CR81 0x81 +#define CR82 0x82 +#define CR83 0x83 +#define CR84 0x84 +#define CR85 0x85 +#define CR86 0x86 +#define CR87 0x87 +#define CR88 0x88 +#define CR89 0x89 +#define CR8A 0x8A +#define CR8B 0x8B +#define CR8C 0x8C +#define CR8D 0x8D +#define CR8E 0x8E +#define CR8F 0x8F +#define CR90 0x90 +#define CR91 0x91 +#define CR92 0x92 +#define CR93 0x93 +#define CR94 0x94 +#define CR95 0x95 +#define CR96 0x96 +#define CR97 0x97 +#define CR98 0x98 +#define CR99 0x99 +#define CR9A 0x9A +#define CR9B 0x9B +#define CR9C 0x9C +#define CR9D 0x9D +#define CR9E 0x9E +#define CR9F 0x9F +#define CRA0 0xA0 +#define CRA1 0xA1 +#define CRA2 0xA2 +#define CRA3 0xA3 +#define CRD2 0xD2 +#define CRD3 0xD3 +#define CRD4 0xD4 + +/* LUT Table*/ +#define LUT_DATA 0x3C9 /* DACDATA */ +#define LUT_INDEX_READ 0x3C7 /* DACRX */ +#define LUT_INDEX_WRITE 0x3C8 /* DACWX */ +#define DACMASK 0x3C6 + +/* Definition Device */ +#define DEVICE_CRT 0x01 +#define DEVICE_TV 0x02 +#define DEVICE_DVI 0x03 +#define DEVICE_LCD 0x04 + +/* Device output interface */ +#define INTERFACE_NONE 0x00 +#define INTERFACE_ANALOG_RGB 0x01 +#define INTERFACE_DVP0 0x02 +#define INTERFACE_DVP1 0x03 +#define INTERFACE_DFP_HIGH 0x04 +#define INTERFACE_DFP_LOW 0x05 +#define INTERFACE_DFP 0x06 +#define INTERFACE_LVDS0 0x07 +#define INTERFACE_LVDS1 0x08 +#define INTERFACE_LVDS0LVDS1 0x09 +#define INTERFACE_TMDS 0x0A + +/* Hardware layout for internal LVDS/TMDS. */ +#define HW_LAYOUT_LCD_ONLY 0x01 +#define HW_LAYOUT_DVI_ONLY 0x02 +#define HW_LAYOUT_LCD_DVI 0x03 +#define HW_LAYOUT_LCD1_LCD2 0x04 +#define HW_LAYOUT_LCD_EXTERNAL_LCD2 0x10 + +/* Definition Refresh Rate */ +#define REFRESH_60 60 +#define REFRESH_75 75 +#define REFRESH_85 85 +#define REFRESH_100 100 +#define REFRESH_120 120 + +/* Definition Sync Polarity */ +#define NEGATIVE 1 +#define POSITIVE 0 + +/* 640x480@60 Sync Polarity (VESA Mode) */ +#define M640X480_R60_HSP NEGATIVE +#define M640X480_R60_VSP NEGATIVE + +/* 640x480@75 Sync Polarity (VESA Mode) */ +#define M640X480_R75_HSP NEGATIVE +#define M640X480_R75_VSP NEGATIVE + +/* 640x480@85 Sync Polarity (VESA Mode) */ +#define M640X480_R85_HSP NEGATIVE +#define M640X480_R85_VSP NEGATIVE + +/* 640x480@100 Sync Polarity (GTF Mode) */ +#define M640X480_R100_HSP NEGATIVE +#define M640X480_R100_VSP POSITIVE + +/* 640x480@120 Sync Polarity (GTF Mode) */ +#define M640X480_R120_HSP NEGATIVE +#define M640X480_R120_VSP POSITIVE + +/* 720x480@60 Sync Polarity (GTF Mode) */ +#define M720X480_R60_HSP NEGATIVE +#define M720X480_R60_VSP POSITIVE + +/* 720x576@60 Sync Polarity (GTF Mode) */ +#define M720X576_R60_HSP NEGATIVE +#define M720X576_R60_VSP POSITIVE + +/* 800x600@60 Sync Polarity (VESA Mode) */ +#define M800X600_R60_HSP POSITIVE +#define M800X600_R60_VSP POSITIVE + +/* 800x600@75 Sync Polarity (VESA Mode) */ +#define M800X600_R75_HSP POSITIVE +#define M800X600_R75_VSP POSITIVE + +/* 800x600@85 Sync Polarity (VESA Mode) */ +#define M800X600_R85_HSP POSITIVE +#define M800X600_R85_VSP POSITIVE + +/* 800x600@100 Sync Polarity (GTF Mode) */ +#define M800X600_R100_HSP NEGATIVE +#define M800X600_R100_VSP POSITIVE + +/* 800x600@120 Sync Polarity (GTF Mode) */ +#define M800X600_R120_HSP NEGATIVE +#define M800X600_R120_VSP POSITIVE + +/* 800x480@60 Sync Polarity (GTF Mode) */ +#define M800X480_R60_HSP NEGATIVE +#define M800X480_R60_VSP POSITIVE + +/* 848x480@60 Sync Polarity (GTF Mode) */ +#define M848X480_R60_HSP NEGATIVE +#define M848X480_R60_VSP POSITIVE + +/* 852x480@60 Sync Polarity (GTF Mode) */ +#define M852X480_R60_HSP NEGATIVE +#define M852X480_R60_VSP POSITIVE + +/* 1024x512@60 Sync Polarity (GTF Mode) */ +#define M1024X512_R60_HSP NEGATIVE +#define M1024X512_R60_VSP POSITIVE + +/* 1024x600@60 Sync Polarity (GTF Mode) */ +#define M1024X600_R60_HSP NEGATIVE +#define M1024X600_R60_VSP POSITIVE + + +/* 1024x768@60 Sync Polarity (VESA Mode) */ +#define M1024X768_R60_HSP NEGATIVE +#define M1024X768_R60_VSP NEGATIVE + +/* 1024x768@75 Sync Polarity (VESA Mode) */ +#define M1024X768_R75_HSP POSITIVE +#define M1024X768_R75_VSP POSITIVE + +/* 1024x768@85 Sync Polarity (VESA Mode) */ +#define M1024X768_R85_HSP POSITIVE +#define M1024X768_R85_VSP POSITIVE + +/* 1024x768@100 Sync Polarity (GTF Mode) */ +#define M1024X768_R100_HSP NEGATIVE +#define M1024X768_R100_VSP POSITIVE + +/* 1152x864@75 Sync Polarity (VESA Mode) */ +#define M1152X864_R75_HSP POSITIVE +#define M1152X864_R75_VSP POSITIVE + +/* 1280x720@60 Sync Polarity (GTF Mode) */ +#define M1280X720_R60_HSP NEGATIVE +#define M1280X720_R60_VSP POSITIVE + +/* 1280x768@60 Sync Polarity (GTF Mode) */ +#define M1280X768_R60_HSP NEGATIVE +#define M1280X768_R60_VSP POSITIVE + +/* 1280x800@60 Sync Polarity (GTF Mode) */ +#define M1280X800_R60_HSP NEGATIVE +#define M1280X800_R60_VSP POSITIVE + +/* 1280x960@60 Sync Polarity (VESA Mode) */ +#define M1280X960_R60_HSP POSITIVE +#define M1280X960_R60_VSP POSITIVE + +/* 1280x1024@60 Sync Polarity (VESA Mode) */ +#define M1280X1024_R60_HSP POSITIVE +#define M1280X1024_R60_VSP POSITIVE + +/* 1368x768@60 Sync Polarity (VESA Mode) */ +#define M1368X768_R60_HSP NEGATIVE +#define M1368X768_R60_VSP POSITIVE + +/* 1280x1024@75 Sync Polarity (VESA Mode) */ +#define M1280X1024_R75_HSP POSITIVE +#define M1280X1024_R75_VSP POSITIVE + +/* 1280x1024@85 Sync Polarity (VESA Mode) */ +#define M1280X1024_R85_HSP POSITIVE +#define M1280X1024_R85_VSP POSITIVE + +/* 1440x1050@60 Sync Polarity (GTF Mode) */ +#define M1440X1050_R60_HSP NEGATIVE +#define M1440X1050_R60_VSP POSITIVE + +/* 1600x1200@60 Sync Polarity (VESA Mode) */ +#define M1600X1200_R60_HSP POSITIVE +#define M1600X1200_R60_VSP POSITIVE + +/* 1600x1200@75 Sync Polarity (VESA Mode) */ +#define M1600X1200_R75_HSP POSITIVE +#define M1600X1200_R75_VSP POSITIVE + +/* 1920x1080@60 Sync Polarity (GTF Mode) */ +#define M1920X1080_R60_HSP NEGATIVE +#define M1920X1080_R60_VSP POSITIVE + +/* 1920x1440@60 Sync Polarity (VESA Mode) */ +#define M1920X1440_R60_HSP NEGATIVE +#define M1920X1440_R60_VSP POSITIVE + +/* 1920x1440@75 Sync Polarity (VESA Mode) */ +#define M1920X1440_R75_HSP NEGATIVE +#define M1920X1440_R75_VSP POSITIVE + +#if 0 +/* 1400x1050@60 Sync Polarity (VESA Mode) */ +#define M1400X1050_R60_HSP NEGATIVE +#define M1400X1050_R60_VSP NEGATIVE +#endif + +/* 1400x1050@60 Sync Polarity (GTF Mode) */ +#define M1400X1050_R60_HSP NEGATIVE +#define M1400X1050_R60_VSP POSITIVE + + +/* define PLL index: */ +#define CLK_25_175M 25175000 +#define CLK_26_880M 26880000 +#define CLK_29_581M 29581000 +#define CLK_31_490M 31490000 +#define CLK_31_500M 31500000 +#define CLK_31_728M 31728000 +#define CLK_32_668M 32688000 +#define CLK_36_000M 36000000 +#define CLK_40_000M 40000000 +#define CLK_41_291M 41291000 +#define CLK_43_163M 43163000 +/* #define CLK_46_996M 46996000 */ +#define CLK_48_875M 48875000 +#define CLK_49_500M 49500000 +#define CLK_52_406M 52406000 +#define CLK_56_250M 56250000 +#define CLK_65_000M 65000000 +#define CLK_68_179M 68179000 +#define CLK_78_750M 78750000 +#define CLK_80_136M 80136000 +#define CLK_83_375M 83375000 +#define CLK_83_950M 83950000 +#define CLK_85_860M 85860000 +#define CLK_94_500M 94500000 +#define CLK_108_000M 108000000 +#define CLK_125_104M 125104000 +#define CLK_133_308M 133308000 +#define CLK_135_000M 135000000 +/* #define CLK_148_500M 148500000 */ +#define CLK_157_500M 157500000 +#define CLK_162_000M 162000000 +#define CLK_202_500M 202500000 +#define CLK_234_000M 234000000 +#define CLK_297_500M 297500000 +#define CLK_74_481M 74481000 +#define CLK_172_798M 172798000 +#define CLK_122_614M 122614000 + + +/* CLE266 PLL value */ +#define CLE266_PLL_25_175M 0x0000C763 +#define CLE266_PLL_26_880M 0x0000440F +#define CLE266_PLL_29_581M 0x00008421 +#define CLE266_PLL_31_490M 0x00004721 +#define CLE266_PLL_31_500M 0x0000C3B5 +#define CLE266_PLL_31_728M 0x0000471F +#define CLE266_PLL_32_668M 0x0000C449 +#define CLE266_PLL_36_000M 0x0000C5E5 +#define CLE266_PLL_40_000M 0x0000C459 +#define CLE266_PLL_41_291M 0x00004417 +#define CLE266_PLL_43_163M 0x0000C579 +/* #define CLE266_PLL_46_996M 0x0000C4E9 */ +#define CLE266_PLL_48_875M 0x00001D63 +#define CLE266_PLL_49_500M 0x00008653 +#define CLE266_PLL_52_406M 0x0000C475 +#define CLE266_PLL_56_250M 0x000047B7 +#define CLE266_PLL_65_000M 0x000086ED +#define CLE266_PLL_68_179M 0x00000413 +#define CLE266_PLL_78_750M 0x00004321 +#define CLE266_PLL_80_136M 0x0000051C +#define CLE266_PLL_83_375M 0x0000C25D +#define CLE266_PLL_83_950M 0x00000729 +#define CLE266_PLL_85_860M 0x00004754 +#define CLE266_PLL_94_500M 0x00000521 +#define CLE266_PLL_108_000M 0x00008479 +#define CLE266_PLL_125_104M 0x000006B5 +#define CLE266_PLL_133_308M 0x0000465F +#define CLE266_PLL_135_000M 0x0000455E +/* #define CLE266_PLL_148_500M 0x0000 */ +#define CLE266_PLL_157_500M 0x000005B7 +#define CLE266_PLL_162_000M 0x00004571 +#define CLE266_PLL_202_500M 0x00000763 +#define CLE266_PLL_234_000M 0x00000662 +#define CLE266_PLL_297_500M 0x000005E6 +#define CLE266_PLL_74_481M 0x0000051A +#define CLE266_PLL_172_798M 0x00004579 +#define CLE266_PLL_122_614M 0x0000073C + +/* K800 PLL value */ +#define K800_PLL_25_175M 0x00539001 +#define K800_PLL_26_880M 0x001C8C80 +#define K800_PLL_29_581M 0x00409080 +#define K800_PLL_31_490M 0x006F9001 +#define K800_PLL_31_500M 0x008B9002 +#define K800_PLL_31_728M 0x00AF9003 +#define K800_PLL_32_668M 0x00909002 +#define K800_PLL_36_000M 0x009F9002 +#define K800_PLL_40_000M 0x00578C02 +#define K800_PLL_41_291M 0x00438C01 +#define K800_PLL_43_163M 0x00778C03 +/* #define K800_PLL_46_996M 0x00000000 */ +#define K800_PLL_48_875M 0x00508C81 +#define K800_PLL_49_500M 0x00518C01 +#define K800_PLL_52_406M 0x00738C02 +#define K800_PLL_56_250M 0x007C8C02 +#define K800_PLL_65_000M 0x006B8C01 +#define K800_PLL_68_179M 0x00708C01 +#define K800_PLL_78_750M 0x00408801 +#define K800_PLL_80_136M 0x00428801 +#define K800_PLL_83_375M 0x005B0882 +#define K800_PLL_83_950M 0x00738803 +#define K800_PLL_85_860M 0x00768883 +#define K800_PLL_94_500M 0x00828803 +#define K800_PLL_108_000M 0x00778882 +#define K800_PLL_125_104M 0x00688801 +#define K800_PLL_133_308M 0x005D8801 +#define K800_PLL_135_000M 0x001A4081 +/* #define K800_PLL_148_500M 0x0000 */ +#define K800_PLL_157_500M 0x00142080 +#define K800_PLL_162_000M 0x006F8483 +#define K800_PLL_202_500M 0x00538481 +#define K800_PLL_234_000M 0x00608401 +#define K800_PLL_297_500M 0x00A48402 +#define K800_PLL_74_481M 0x007B8C81 +#define K800_PLL_172_798M 0x00778483 +#define K800_PLL_122_614M 0x00878882 + +/* PLL for VT3324 */ +#define CX700_25_175M 0x008B1003 +#define CX700_26_719M 0x00931003 +#define CX700_26_880M 0x00941003 +#define CX700_29_581M 0x00A49003 +#define CX700_31_490M 0x00AE1003 +#define CX700_31_500M 0x00AE1003 +#define CX700_31_728M 0x00AF1003 +#define CX700_32_668M 0x00B51003 +#define CX700_36_000M 0x00C81003 +#define CX700_40_000M 0x006E0C03 +#define CX700_41_291M 0x00710C03 +#define CX700_43_163M 0x00770C03 +#define CX700_48_875M 0x00508C81 +#define CX700_49_500M 0x00880C03 +#define CX700_52_406M 0x00730C02 +#define CX700_56_250M 0x009B0C03 +#define CX700_65_000M 0x006B0C01 +#define CX700_68_179M 0x00BC0C03 +#define CX700_74_481M 0x00CE0C03 +#define CX700_78_750M 0x006C0803 +#define CX700_80_136M 0x006E0803 +#define CX700_83_375M 0x005B0882 +#define CX700_83_950M 0x00730803 +#define CX700_85_860M 0x00760803 +#define CX700_94_500M 0x00820803 +#define CX700_108_000M 0x00950803 +#define CX700_125_104M 0x00AD0803 +#define CX700_133_308M 0x00930802 +#define CX700_135_000M 0x00950802 +#define CX700_157_500M 0x006C0403 +#define CX700_162_000M 0x006F0403 +#define CX700_172_798M 0x00770403 +#define CX700_202_500M 0x008C0403 +#define CX700_234_000M 0x00600401 +#define CX700_297_500M 0x00CE0403 +#define CX700_122_614M 0x00870802 + +/* Definition CRTC Timing Index */ +#define H_TOTAL_INDEX 0 +#define H_ADDR_INDEX 1 +#define H_BLANK_START_INDEX 2 +#define H_BLANK_END_INDEX 3 +#define H_SYNC_START_INDEX 4 +#define H_SYNC_END_INDEX 5 +#define V_TOTAL_INDEX 6 +#define V_ADDR_INDEX 7 +#define V_BLANK_START_INDEX 8 +#define V_BLANK_END_INDEX 9 +#define V_SYNC_START_INDEX 10 +#define V_SYNC_END_INDEX 11 +#define H_TOTAL_SHADOW_INDEX 12 +#define H_BLANK_END_SHADOW_INDEX 13 +#define V_TOTAL_SHADOW_INDEX 14 +#define V_ADDR_SHADOW_INDEX 15 +#define V_BLANK_SATRT_SHADOW_INDEX 16 +#define V_BLANK_END_SHADOW_INDEX 17 +#define V_SYNC_SATRT_SHADOW_INDEX 18 +#define V_SYNC_END_SHADOW_INDEX 19 + +/* Definition Video Mode Pixel Clock (picoseconds) */ +#define RES_640X480_60HZ_PIXCLOCK 39722 +#define RES_640X480_75HZ_PIXCLOCK 31747 +#define RES_640X480_85HZ_PIXCLOCK 27777 +#define RES_640X480_100HZ_PIXCLOCK 23168 +#define RES_640X480_120HZ_PIXCLOCK 19081 +#define RES_720X480_60HZ_PIXCLOCK 37020 +#define RES_720X576_60HZ_PIXCLOCK 30611 +#define RES_800X600_60HZ_PIXCLOCK 25000 +#define RES_800X600_75HZ_PIXCLOCK 20203 +#define RES_800X600_85HZ_PIXCLOCK 17777 +#define RES_800X600_100HZ_PIXCLOCK 14815 +#define RES_800X600_120HZ_PIXCLOCK 11912 +#define RES_800X480_60HZ_PIXCLOCK 33805 +#define RES_848X480_60HZ_PIXCLOCK 31756 +#define RES_856X480_60HZ_PIXCLOCK 31518 +#define RES_1024X512_60HZ_PIXCLOCK 24218 +#define RES_1024X600_60HZ_PIXCLOCK 20460 +#define RES_1024X768_60HZ_PIXCLOCK 15385 +#define RES_1024X768_75HZ_PIXCLOCK 12699 +#define RES_1024X768_85HZ_PIXCLOCK 10582 +#define RES_1024X768_100HZ_PIXCLOCK 9091 +#define RES_1152X864_70HZ_PIXCLOCK 10000 +#define RES_1152X864_75HZ_PIXCLOCK 9091 +#define RES_1280X768_60HZ_PIXCLOCK 12480 +#define RES_1280X800_60HZ_PIXCLOCK 11994 +#define RES_1280X960_60HZ_PIXCLOCK 9259 +#define RES_1280X1024_60HZ_PIXCLOCK 9260 +#define RES_1280X1024_75HZ_PIXCLOCK 7408 +#define RES_1280X768_85HZ_PIXCLOCK 6349 +#define RES_1440X1050_60HZ_PIXCLOCK 7993 +#define RES_1600X1200_60HZ_PIXCLOCK 6411 +#define RES_1600X1200_75HZ_PIXCLOCK 4938 +#define RES_1280X720_60HZ_PIXCLOCK 13426 +#define RES_1920X1080_60HZ_PIXCLOCK 5787 +#define RES_1400X1050_60HZ_PIXCLOCK 8156 +#define RES_1368X768_60HZ_PIXCLOCK 11647 + +/* LCD display method */ +#define LCD_EXPANDSION 0x00 +#define LCD_CENTERING 0x01 + +/* LCD mode */ +#define LCD_OPENLDI 0x00 +#define LCD_SPWG 0x01 + + +/* Define display timing */ +struct display_timing { + u16 hor_total; + u16 hor_addr; + u16 hor_blank_start; + u16 hor_blank_end; + u16 hor_sync_start; + u16 hor_sync_end; + u16 ver_total; + u16 ver_addr; + u16 ver_blank_start; + u16 ver_blank_end; + u16 ver_sync_start; + u16 ver_sync_end; +}; + +struct crt_mode_table { + int refresh_rate; + unsigned long clk; + int h_sync_polarity; + int v_sync_polarity; + struct display_timing crtc; +}; + +struct io_reg{ + int port; + u8 index; + u8 mask; + u8 value; +}; + +#endif /* __SHARE_H__ */ +