brintos

brintos / linux-shallow public Read only

0
0
Text · 57.9 KiB · 66afd7b Raw
2120 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.4 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.5 6 */7 8#include <linux/via-core.h>9#include "global.h"10#include "via_clock.h"11 12static struct pll_limit cle266_pll_limits[] = {13	{19, 19, 4, 0},14	{26, 102, 5, 0},15	{53, 112, 6, 0},16	{41, 100, 7, 0},17	{83, 108, 8, 0},18	{87, 118, 9, 0},19	{95, 115, 12, 0},20	{108, 108, 13, 0},21	{83, 83, 17, 0},22	{67, 98, 20, 0},23	{121, 121, 24, 0},24	{99, 99, 29, 0},25	{33, 33, 3, 1},26	{15, 23, 4, 1},27	{37, 121, 5, 1},28	{82, 82, 6, 1},29	{31, 84, 7, 1},30	{83, 83, 8, 1},31	{76, 127, 9, 1},32	{33, 121, 4, 2},33	{91, 118, 5, 2},34	{83, 109, 6, 2},35	{90, 90, 7, 2},36	{93, 93, 2, 3},37	{53, 53, 3, 3},38	{73, 117, 4, 3},39	{101, 127, 5, 3},40	{99, 99, 7, 3}41};42 43static struct pll_limit k800_pll_limits[] = {44	{22, 22, 2, 0},45	{28, 28, 3, 0},46	{81, 112, 3, 1},47	{86, 166, 4, 1},48	{109, 153, 5, 1},49	{66, 116, 3, 2},50	{93, 137, 4, 2},51	{117, 208, 5, 2},52	{30, 30, 2, 3},53	{69, 125, 3, 3},54	{89, 161, 4, 3},55	{121, 208, 5, 3},56	{66, 66, 2, 4},57	{85, 85, 3, 4},58	{141, 161, 4, 4},59	{177, 177, 5, 4}60};61 62static struct pll_limit cx700_pll_limits[] = {63	{98, 98, 3, 1},64	{86, 86, 4, 1},65	{109, 208, 5, 1},66	{68, 68, 2, 2},67	{95, 116, 3, 2},68	{93, 166, 4, 2},69	{110, 206, 5, 2},70	{174, 174, 7, 2},71	{82, 109, 3, 3},72	{117, 161, 4, 3},73	{112, 208, 5, 3},74	{141, 202, 5, 4}75};76 77static struct pll_limit vx855_pll_limits[] = {78	{86, 86, 4, 1},79	{108, 208, 5, 1},80	{110, 208, 5, 2},81	{83, 112, 3, 3},82	{103, 161, 4, 3},83	{112, 209, 5, 3},84	{142, 161, 4, 4},85	{141, 176, 5, 4}86};87 88/* according to VIA Technologies these values are based on experiment */89static struct io_reg scaling_parameters[] = {90	{VIACR, CR7A, 0xFF, 0x01},	/* LCD Scaling Parameter 1 */91	{VIACR, CR7B, 0xFF, 0x02},	/* LCD Scaling Parameter 2 */92	{VIACR, CR7C, 0xFF, 0x03},	/* LCD Scaling Parameter 3 */93	{VIACR, CR7D, 0xFF, 0x04},	/* LCD Scaling Parameter 4 */94	{VIACR, CR7E, 0xFF, 0x07},	/* LCD Scaling Parameter 5 */95	{VIACR, CR7F, 0xFF, 0x0A},	/* LCD Scaling Parameter 6 */96	{VIACR, CR80, 0xFF, 0x0D},	/* LCD Scaling Parameter 7 */97	{VIACR, CR81, 0xFF, 0x13},	/* LCD Scaling Parameter 8 */98	{VIACR, CR82, 0xFF, 0x16},	/* LCD Scaling Parameter 9 */99	{VIACR, CR83, 0xFF, 0x19},	/* LCD Scaling Parameter 10 */100	{VIACR, CR84, 0xFF, 0x1C},	/* LCD Scaling Parameter 11 */101	{VIACR, CR85, 0xFF, 0x1D},	/* LCD Scaling Parameter 12 */102	{VIACR, CR86, 0xFF, 0x1E},	/* LCD Scaling Parameter 13 */103	{VIACR, CR87, 0xFF, 0x1F},	/* LCD Scaling Parameter 14 */104};105 106static struct io_reg common_vga[] = {107	{VIACR, CR07, 0x10, 0x10}, /* [0] vertical total (bit 8)108					[1] vertical display end (bit 8)109					[2] vertical retrace start (bit 8)110					[3] start vertical blanking (bit 8)111					[4] line compare (bit 8)112					[5] vertical total (bit 9)113					[6] vertical display end (bit 9)114					[7] vertical retrace start (bit 9) */115	{VIACR, CR08, 0xFF, 0x00}, /* [0-4] preset row scan116					[5-6] byte panning */117	{VIACR, CR09, 0xDF, 0x40}, /* [0-4] max scan line118					[5] start vertical blanking (bit 9)119					[6] line compare (bit 9)120					[7] scan doubling */121	{VIACR, CR0A, 0xFF, 0x1E}, /* [0-4] cursor start122					[5] cursor disable */123	{VIACR, CR0B, 0xFF, 0x00}, /* [0-4] cursor end124					[5-6] cursor skew */125	{VIACR, CR0E, 0xFF, 0x00}, /* [0-7] cursor location (high) */126	{VIACR, CR0F, 0xFF, 0x00}, /* [0-7] cursor location (low) */127	{VIACR, CR11, 0xF0, 0x80}, /* [0-3] vertical retrace end128					[6] memory refresh bandwidth129					[7] CRTC register protect enable */130	{VIACR, CR14, 0xFF, 0x00}, /* [0-4] underline location131					[5] divide memory address clock by 4132					[6] double word addressing */133	{VIACR, CR17, 0xFF, 0x63}, /* [0-1] mapping of display address 13-14134					[2] divide scan line clock by 2135					[3] divide memory address clock by 2136					[5] address wrap137					[6] byte mode select138					[7] sync enable */139	{VIACR, CR18, 0xFF, 0xFF}, /* [0-7] line compare */140};141 142static struct fifo_depth_select display_fifo_depth_reg = {143	/* IGA1 FIFO Depth_Select */144	{IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } },145	/* IGA2 FIFO Depth_Select */146	{IGA2_FIFO_DEPTH_SELECT_REG_NUM,147	 {{CR68, 4, 7}, {CR94, 7, 7}, {CR95, 7, 7} } }148};149 150static struct fifo_threshold_select fifo_threshold_select_reg = {151	/* IGA1 FIFO Threshold Select */152	{IGA1_FIFO_THRESHOLD_REG_NUM, {{SR16, 0, 5}, {SR16, 7, 7} } },153	/* IGA2 FIFO Threshold Select */154	{IGA2_FIFO_THRESHOLD_REG_NUM, {{CR68, 0, 3}, {CR95, 4, 6} } }155};156 157static struct fifo_high_threshold_select fifo_high_threshold_select_reg = {158	/* IGA1 FIFO High Threshold Select */159	{IGA1_FIFO_HIGH_THRESHOLD_REG_NUM, {{SR18, 0, 5}, {SR18, 7, 7} } },160	/* IGA2 FIFO High Threshold Select */161	{IGA2_FIFO_HIGH_THRESHOLD_REG_NUM, {{CR92, 0, 3}, {CR95, 0, 2} } }162};163 164static struct display_queue_expire_num display_queue_expire_num_reg = {165	/* IGA1 Display Queue Expire Num */166	{IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{SR22, 0, 4} } },167	/* IGA2 Display Queue Expire Num */168	{IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{CR94, 0, 6} } }169};170 171/* Definition Fetch Count Registers*/172static struct fetch_count fetch_count_reg = {173	/* IGA1 Fetch Count Register */174	{IGA1_FETCH_COUNT_REG_NUM, {{SR1C, 0, 7}, {SR1D, 0, 1} } },175	/* IGA2 Fetch Count Register */176	{IGA2_FETCH_COUNT_REG_NUM, {{CR65, 0, 7}, {CR67, 2, 3} } }177};178 179static struct rgbLUT palLUT_table[] = {180	/* {R,G,B} */181	/* Index 0x00~0x03 */182	{0x00, 0x00, 0x00}, {0x00, 0x00, 0x2A}, {0x00, 0x2A, 0x00}, {0x00,183								     0x2A,184								     0x2A},185	/* Index 0x04~0x07 */186	{0x2A, 0x00, 0x00}, {0x2A, 0x00, 0x2A}, {0x2A, 0x15, 0x00}, {0x2A,187								     0x2A,188								     0x2A},189	/* Index 0x08~0x0B */190	{0x15, 0x15, 0x15}, {0x15, 0x15, 0x3F}, {0x15, 0x3F, 0x15}, {0x15,191								     0x3F,192								     0x3F},193	/* Index 0x0C~0x0F */194	{0x3F, 0x15, 0x15}, {0x3F, 0x15, 0x3F}, {0x3F, 0x3F, 0x15}, {0x3F,195								     0x3F,196								     0x3F},197	/* Index 0x10~0x13 */198	{0x00, 0x00, 0x00}, {0x05, 0x05, 0x05}, {0x08, 0x08, 0x08}, {0x0B,199								     0x0B,200								     0x0B},201	/* Index 0x14~0x17 */202	{0x0E, 0x0E, 0x0E}, {0x11, 0x11, 0x11}, {0x14, 0x14, 0x14}, {0x18,203								     0x18,204								     0x18},205	/* Index 0x18~0x1B */206	{0x1C, 0x1C, 0x1C}, {0x20, 0x20, 0x20}, {0x24, 0x24, 0x24}, {0x28,207								     0x28,208								     0x28},209	/* Index 0x1C~0x1F */210	{0x2D, 0x2D, 0x2D}, {0x32, 0x32, 0x32}, {0x38, 0x38, 0x38}, {0x3F,211								     0x3F,212								     0x3F},213	/* Index 0x20~0x23 */214	{0x00, 0x00, 0x3F}, {0x10, 0x00, 0x3F}, {0x1F, 0x00, 0x3F}, {0x2F,215								     0x00,216								     0x3F},217	/* Index 0x24~0x27 */218	{0x3F, 0x00, 0x3F}, {0x3F, 0x00, 0x2F}, {0x3F, 0x00, 0x1F}, {0x3F,219								     0x00,220								     0x10},221	/* Index 0x28~0x2B */222	{0x3F, 0x00, 0x00}, {0x3F, 0x10, 0x00}, {0x3F, 0x1F, 0x00}, {0x3F,223								     0x2F,224								     0x00},225	/* Index 0x2C~0x2F */226	{0x3F, 0x3F, 0x00}, {0x2F, 0x3F, 0x00}, {0x1F, 0x3F, 0x00}, {0x10,227								     0x3F,228								     0x00},229	/* Index 0x30~0x33 */230	{0x00, 0x3F, 0x00}, {0x00, 0x3F, 0x10}, {0x00, 0x3F, 0x1F}, {0x00,231								     0x3F,232								     0x2F},233	/* Index 0x34~0x37 */234	{0x00, 0x3F, 0x3F}, {0x00, 0x2F, 0x3F}, {0x00, 0x1F, 0x3F}, {0x00,235								     0x10,236								     0x3F},237	/* Index 0x38~0x3B */238	{0x1F, 0x1F, 0x3F}, {0x27, 0x1F, 0x3F}, {0x2F, 0x1F, 0x3F}, {0x37,239								     0x1F,240								     0x3F},241	/* Index 0x3C~0x3F */242	{0x3F, 0x1F, 0x3F}, {0x3F, 0x1F, 0x37}, {0x3F, 0x1F, 0x2F}, {0x3F,243								     0x1F,244								     0x27},245	/* Index 0x40~0x43 */246	{0x3F, 0x1F, 0x1F}, {0x3F, 0x27, 0x1F}, {0x3F, 0x2F, 0x1F}, {0x3F,247								     0x3F,248								     0x1F},249	/* Index 0x44~0x47 */250	{0x3F, 0x3F, 0x1F}, {0x37, 0x3F, 0x1F}, {0x2F, 0x3F, 0x1F}, {0x27,251								     0x3F,252								     0x1F},253	/* Index 0x48~0x4B */254	{0x1F, 0x3F, 0x1F}, {0x1F, 0x3F, 0x27}, {0x1F, 0x3F, 0x2F}, {0x1F,255								     0x3F,256								     0x37},257	/* Index 0x4C~0x4F */258	{0x1F, 0x3F, 0x3F}, {0x1F, 0x37, 0x3F}, {0x1F, 0x2F, 0x3F}, {0x1F,259								     0x27,260								     0x3F},261	/* Index 0x50~0x53 */262	{0x2D, 0x2D, 0x3F}, {0x31, 0x2D, 0x3F}, {0x36, 0x2D, 0x3F}, {0x3A,263								     0x2D,264								     0x3F},265	/* Index 0x54~0x57 */266	{0x3F, 0x2D, 0x3F}, {0x3F, 0x2D, 0x3A}, {0x3F, 0x2D, 0x36}, {0x3F,267								     0x2D,268								     0x31},269	/* Index 0x58~0x5B */270	{0x3F, 0x2D, 0x2D}, {0x3F, 0x31, 0x2D}, {0x3F, 0x36, 0x2D}, {0x3F,271								     0x3A,272								     0x2D},273	/* Index 0x5C~0x5F */274	{0x3F, 0x3F, 0x2D}, {0x3A, 0x3F, 0x2D}, {0x36, 0x3F, 0x2D}, {0x31,275								     0x3F,276								     0x2D},277	/* Index 0x60~0x63 */278	{0x2D, 0x3F, 0x2D}, {0x2D, 0x3F, 0x31}, {0x2D, 0x3F, 0x36}, {0x2D,279								     0x3F,280								     0x3A},281	/* Index 0x64~0x67 */282	{0x2D, 0x3F, 0x3F}, {0x2D, 0x3A, 0x3F}, {0x2D, 0x36, 0x3F}, {0x2D,283								     0x31,284								     0x3F},285	/* Index 0x68~0x6B */286	{0x00, 0x00, 0x1C}, {0x07, 0x00, 0x1C}, {0x0E, 0x00, 0x1C}, {0x15,287								     0x00,288								     0x1C},289	/* Index 0x6C~0x6F */290	{0x1C, 0x00, 0x1C}, {0x1C, 0x00, 0x15}, {0x1C, 0x00, 0x0E}, {0x1C,291								     0x00,292								     0x07},293	/* Index 0x70~0x73 */294	{0x1C, 0x00, 0x00}, {0x1C, 0x07, 0x00}, {0x1C, 0x0E, 0x00}, {0x1C,295								     0x15,296								     0x00},297	/* Index 0x74~0x77 */298	{0x1C, 0x1C, 0x00}, {0x15, 0x1C, 0x00}, {0x0E, 0x1C, 0x00}, {0x07,299								     0x1C,300								     0x00},301	/* Index 0x78~0x7B */302	{0x00, 0x1C, 0x00}, {0x00, 0x1C, 0x07}, {0x00, 0x1C, 0x0E}, {0x00,303								     0x1C,304								     0x15},305	/* Index 0x7C~0x7F */306	{0x00, 0x1C, 0x1C}, {0x00, 0x15, 0x1C}, {0x00, 0x0E, 0x1C}, {0x00,307								     0x07,308								     0x1C},309	/* Index 0x80~0x83 */310	{0x0E, 0x0E, 0x1C}, {0x11, 0x0E, 0x1C}, {0x15, 0x0E, 0x1C}, {0x18,311								     0x0E,312								     0x1C},313	/* Index 0x84~0x87 */314	{0x1C, 0x0E, 0x1C}, {0x1C, 0x0E, 0x18}, {0x1C, 0x0E, 0x15}, {0x1C,315								     0x0E,316								     0x11},317	/* Index 0x88~0x8B */318	{0x1C, 0x0E, 0x0E}, {0x1C, 0x11, 0x0E}, {0x1C, 0x15, 0x0E}, {0x1C,319								     0x18,320								     0x0E},321	/* Index 0x8C~0x8F */322	{0x1C, 0x1C, 0x0E}, {0x18, 0x1C, 0x0E}, {0x15, 0x1C, 0x0E}, {0x11,323								     0x1C,324								     0x0E},325	/* Index 0x90~0x93 */326	{0x0E, 0x1C, 0x0E}, {0x0E, 0x1C, 0x11}, {0x0E, 0x1C, 0x15}, {0x0E,327								     0x1C,328								     0x18},329	/* Index 0x94~0x97 */330	{0x0E, 0x1C, 0x1C}, {0x0E, 0x18, 0x1C}, {0x0E, 0x15, 0x1C}, {0x0E,331								     0x11,332								     0x1C},333	/* Index 0x98~0x9B */334	{0x14, 0x14, 0x1C}, {0x16, 0x14, 0x1C}, {0x18, 0x14, 0x1C}, {0x1A,335								     0x14,336								     0x1C},337	/* Index 0x9C~0x9F */338	{0x1C, 0x14, 0x1C}, {0x1C, 0x14, 0x1A}, {0x1C, 0x14, 0x18}, {0x1C,339								     0x14,340								     0x16},341	/* Index 0xA0~0xA3 */342	{0x1C, 0x14, 0x14}, {0x1C, 0x16, 0x14}, {0x1C, 0x18, 0x14}, {0x1C,343								     0x1A,344								     0x14},345	/* Index 0xA4~0xA7 */346	{0x1C, 0x1C, 0x14}, {0x1A, 0x1C, 0x14}, {0x18, 0x1C, 0x14}, {0x16,347								     0x1C,348								     0x14},349	/* Index 0xA8~0xAB */350	{0x14, 0x1C, 0x14}, {0x14, 0x1C, 0x16}, {0x14, 0x1C, 0x18}, {0x14,351								     0x1C,352								     0x1A},353	/* Index 0xAC~0xAF */354	{0x14, 0x1C, 0x1C}, {0x14, 0x1A, 0x1C}, {0x14, 0x18, 0x1C}, {0x14,355								     0x16,356								     0x1C},357	/* Index 0xB0~0xB3 */358	{0x00, 0x00, 0x10}, {0x04, 0x00, 0x10}, {0x08, 0x00, 0x10}, {0x0C,359								     0x00,360								     0x10},361	/* Index 0xB4~0xB7 */362	{0x10, 0x00, 0x10}, {0x10, 0x00, 0x0C}, {0x10, 0x00, 0x08}, {0x10,363								     0x00,364								     0x04},365	/* Index 0xB8~0xBB */366	{0x10, 0x00, 0x00}, {0x10, 0x04, 0x00}, {0x10, 0x08, 0x00}, {0x10,367								     0x0C,368								     0x00},369	/* Index 0xBC~0xBF */370	{0x10, 0x10, 0x00}, {0x0C, 0x10, 0x00}, {0x08, 0x10, 0x00}, {0x04,371								     0x10,372								     0x00},373	/* Index 0xC0~0xC3 */374	{0x00, 0x10, 0x00}, {0x00, 0x10, 0x04}, {0x00, 0x10, 0x08}, {0x00,375								     0x10,376								     0x0C},377	/* Index 0xC4~0xC7 */378	{0x00, 0x10, 0x10}, {0x00, 0x0C, 0x10}, {0x00, 0x08, 0x10}, {0x00,379								     0x04,380								     0x10},381	/* Index 0xC8~0xCB */382	{0x08, 0x08, 0x10}, {0x0A, 0x08, 0x10}, {0x0C, 0x08, 0x10}, {0x0E,383								     0x08,384								     0x10},385	/* Index 0xCC~0xCF */386	{0x10, 0x08, 0x10}, {0x10, 0x08, 0x0E}, {0x10, 0x08, 0x0C}, {0x10,387								     0x08,388								     0x0A},389	/* Index 0xD0~0xD3 */390	{0x10, 0x08, 0x08}, {0x10, 0x0A, 0x08}, {0x10, 0x0C, 0x08}, {0x10,391								     0x0E,392								     0x08},393	/* Index 0xD4~0xD7 */394	{0x10, 0x10, 0x08}, {0x0E, 0x10, 0x08}, {0x0C, 0x10, 0x08}, {0x0A,395								     0x10,396								     0x08},397	/* Index 0xD8~0xDB */398	{0x08, 0x10, 0x08}, {0x08, 0x10, 0x0A}, {0x08, 0x10, 0x0C}, {0x08,399								     0x10,400								     0x0E},401	/* Index 0xDC~0xDF */402	{0x08, 0x10, 0x10}, {0x08, 0x0E, 0x10}, {0x08, 0x0C, 0x10}, {0x08,403								     0x0A,404								     0x10},405	/* Index 0xE0~0xE3 */406	{0x0B, 0x0B, 0x10}, {0x0C, 0x0B, 0x10}, {0x0D, 0x0B, 0x10}, {0x0F,407								     0x0B,408								     0x10},409	/* Index 0xE4~0xE7 */410	{0x10, 0x0B, 0x10}, {0x10, 0x0B, 0x0F}, {0x10, 0x0B, 0x0D}, {0x10,411								     0x0B,412								     0x0C},413	/* Index 0xE8~0xEB */414	{0x10, 0x0B, 0x0B}, {0x10, 0x0C, 0x0B}, {0x10, 0x0D, 0x0B}, {0x10,415								     0x0F,416								     0x0B},417	/* Index 0xEC~0xEF */418	{0x10, 0x10, 0x0B}, {0x0F, 0x10, 0x0B}, {0x0D, 0x10, 0x0B}, {0x0C,419								     0x10,420								     0x0B},421	/* Index 0xF0~0xF3 */422	{0x0B, 0x10, 0x0B}, {0x0B, 0x10, 0x0C}, {0x0B, 0x10, 0x0D}, {0x0B,423								     0x10,424								     0x0F},425	/* Index 0xF4~0xF7 */426	{0x0B, 0x10, 0x10}, {0x0B, 0x0F, 0x10}, {0x0B, 0x0D, 0x10}, {0x0B,427								     0x0C,428								     0x10},429	/* Index 0xF8~0xFB */430	{0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,431								     0x00,432								     0x00},433	/* Index 0xFC~0xFF */434	{0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,435								     0x00,436								     0x00}437};438 439static struct via_device_mapping device_mapping[] = {440	{VIA_LDVP0, "LDVP0"},441	{VIA_LDVP1, "LDVP1"},442	{VIA_DVP0, "DVP0"},443	{VIA_CRT, "CRT"},444	{VIA_DVP1, "DVP1"},445	{VIA_LVDS1, "LVDS1"},446	{VIA_LVDS2, "LVDS2"}447};448 449/* structure with function pointers to support clock control */450static struct via_clock clock;451 452static void load_fix_bit_crtc_reg(void);453static void init_gfx_chip_info(int chip_type);454static void init_tmds_chip_info(void);455static void init_lvds_chip_info(void);456static void device_screen_off(void);457static void device_screen_on(void);458static void set_display_channel(void);459static void device_off(void);460static void device_on(void);461static void enable_second_display_channel(void);462static void disable_second_display_channel(void);463 464void viafb_lock_crt(void)465{466	viafb_write_reg_mask(CR11, VIACR, BIT7, BIT7);467}468 469void viafb_unlock_crt(void)470{471	viafb_write_reg_mask(CR11, VIACR, 0, BIT7);472	viafb_write_reg_mask(CR47, VIACR, 0, BIT0);473}474 475static void write_dac_reg(u8 index, u8 r, u8 g, u8 b)476{477	outb(index, LUT_INDEX_WRITE);478	outb(r, LUT_DATA);479	outb(g, LUT_DATA);480	outb(b, LUT_DATA);481}482 483static u32 get_dvi_devices(int output_interface)484{485	switch (output_interface) {486	case INTERFACE_DVP0:487		return VIA_DVP0 | VIA_LDVP0;488 489	case INTERFACE_DVP1:490		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)491			return VIA_LDVP1;492		else493			return VIA_DVP1;494 495	case INTERFACE_DFP_HIGH:496		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)497			return 0;498		else499			return VIA_LVDS2 | VIA_DVP0;500 501	case INTERFACE_DFP_LOW:502		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)503			return 0;504		else505			return VIA_DVP1 | VIA_LVDS1;506 507	case INTERFACE_TMDS:508		return VIA_LVDS1;509	}510 511	return 0;512}513 514static u32 get_lcd_devices(int output_interface)515{516	switch (output_interface) {517	case INTERFACE_DVP0:518		return VIA_DVP0;519 520	case INTERFACE_DVP1:521		return VIA_DVP1;522 523	case INTERFACE_DFP_HIGH:524		return VIA_LVDS2 | VIA_DVP0;525 526	case INTERFACE_DFP_LOW:527		return VIA_LVDS1 | VIA_DVP1;528 529	case INTERFACE_DFP:530		return VIA_LVDS1 | VIA_LVDS2;531 532	case INTERFACE_LVDS0:533	case INTERFACE_LVDS0LVDS1:534		return VIA_LVDS1;535 536	case INTERFACE_LVDS1:537		return VIA_LVDS2;538	}539 540	return 0;541}542 543/*Set IGA path for each device*/544void viafb_set_iga_path(void)545{546	int crt_iga_path = 0;547 548	if (viafb_SAMM_ON == 1) {549		if (viafb_CRT_ON) {550			if (viafb_primary_dev == CRT_Device)551				crt_iga_path = IGA1;552			else553				crt_iga_path = IGA2;554		}555 556		if (viafb_DVI_ON) {557			if (viafb_primary_dev == DVI_Device)558				viaparinfo->tmds_setting_info->iga_path = IGA1;559			else560				viaparinfo->tmds_setting_info->iga_path = IGA2;561		}562 563		if (viafb_LCD_ON) {564			if (viafb_primary_dev == LCD_Device) {565				if (viafb_dual_fb &&566					(viaparinfo->chip_info->gfx_chip_name ==567					UNICHROME_CLE266)) {568					viaparinfo->569					lvds_setting_info->iga_path = IGA2;570					crt_iga_path = IGA1;571					viaparinfo->572					tmds_setting_info->iga_path = IGA1;573				} else574					viaparinfo->575					lvds_setting_info->iga_path = IGA1;576			} else {577				viaparinfo->lvds_setting_info->iga_path = IGA2;578			}579		}580		if (viafb_LCD2_ON) {581			if (LCD2_Device == viafb_primary_dev)582				viaparinfo->lvds_setting_info2->iga_path = IGA1;583			else584				viaparinfo->lvds_setting_info2->iga_path = IGA2;585		}586	} else {587		viafb_SAMM_ON = 0;588 589		if (viafb_CRT_ON && viafb_LCD_ON) {590			crt_iga_path = IGA1;591			viaparinfo->lvds_setting_info->iga_path = IGA2;592		} else if (viafb_CRT_ON && viafb_DVI_ON) {593			crt_iga_path = IGA1;594			viaparinfo->tmds_setting_info->iga_path = IGA2;595		} else if (viafb_LCD_ON && viafb_DVI_ON) {596			viaparinfo->tmds_setting_info->iga_path = IGA1;597			viaparinfo->lvds_setting_info->iga_path = IGA2;598		} else if (viafb_LCD_ON && viafb_LCD2_ON) {599			viaparinfo->lvds_setting_info->iga_path = IGA2;600			viaparinfo->lvds_setting_info2->iga_path = IGA2;601		} else if (viafb_CRT_ON) {602			crt_iga_path = IGA1;603		} else if (viafb_LCD_ON) {604			viaparinfo->lvds_setting_info->iga_path = IGA2;605		} else if (viafb_DVI_ON) {606			viaparinfo->tmds_setting_info->iga_path = IGA1;607		}608	}609 610	viaparinfo->shared->iga1_devices = 0;611	viaparinfo->shared->iga2_devices = 0;612	if (viafb_CRT_ON) {613		if (crt_iga_path == IGA1)614			viaparinfo->shared->iga1_devices |= VIA_CRT;615		else616			viaparinfo->shared->iga2_devices |= VIA_CRT;617	}618 619	if (viafb_DVI_ON) {620		if (viaparinfo->tmds_setting_info->iga_path == IGA1)621			viaparinfo->shared->iga1_devices |= get_dvi_devices(622				viaparinfo->chip_info->623				tmds_chip_info.output_interface);624		else625			viaparinfo->shared->iga2_devices |= get_dvi_devices(626				viaparinfo->chip_info->627				tmds_chip_info.output_interface);628	}629 630	if (viafb_LCD_ON) {631		if (viaparinfo->lvds_setting_info->iga_path == IGA1)632			viaparinfo->shared->iga1_devices |= get_lcd_devices(633				viaparinfo->chip_info->634				lvds_chip_info.output_interface);635		else636			viaparinfo->shared->iga2_devices |= get_lcd_devices(637				viaparinfo->chip_info->638				lvds_chip_info.output_interface);639	}640 641	if (viafb_LCD2_ON) {642		if (viaparinfo->lvds_setting_info2->iga_path == IGA1)643			viaparinfo->shared->iga1_devices |= get_lcd_devices(644				viaparinfo->chip_info->645				lvds_chip_info2.output_interface);646		else647			viaparinfo->shared->iga2_devices |= get_lcd_devices(648				viaparinfo->chip_info->649				lvds_chip_info2.output_interface);650	}651 652	/* looks like the OLPC has its display wired to DVP1 and LVDS2 */653	if (machine_is_olpc())654		viaparinfo->shared->iga2_devices = VIA_DVP1 | VIA_LVDS2;655}656 657static void set_color_register(u8 index, u8 red, u8 green, u8 blue)658{659	outb(0xFF, 0x3C6); /* bit mask of palette */660	outb(index, 0x3C8);661	outb(red, 0x3C9);662	outb(green, 0x3C9);663	outb(blue, 0x3C9);664}665 666void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue)667{668	viafb_write_reg_mask(0x1A, VIASR, 0x00, 0x01);669	set_color_register(index, red, green, blue);670}671 672void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue)673{674	viafb_write_reg_mask(0x1A, VIASR, 0x01, 0x01);675	set_color_register(index, red, green, blue);676}677 678static void set_source_common(u8 index, u8 offset, u8 iga)679{680	u8 value, mask = 1 << offset;681 682	switch (iga) {683	case IGA1:684		value = 0x00;685		break;686	case IGA2:687		value = mask;688		break;689	default:690		printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);691		return;692	}693 694	via_write_reg_mask(VIACR, index, value, mask);695}696 697static void set_crt_source(u8 iga)698{699	u8 value;700 701	switch (iga) {702	case IGA1:703		value = 0x00;704		break;705	case IGA2:706		value = 0x40;707		break;708	default:709		printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);710		return;711	}712 713	via_write_reg_mask(VIASR, 0x16, value, 0x40);714}715 716static inline void set_ldvp0_source(u8 iga)717{718	set_source_common(0x6C, 7, iga);719}720 721static inline void set_ldvp1_source(u8 iga)722{723	set_source_common(0x93, 7, iga);724}725 726static inline void set_dvp0_source(u8 iga)727{728	set_source_common(0x96, 4, iga);729}730 731static inline void set_dvp1_source(u8 iga)732{733	set_source_common(0x9B, 4, iga);734}735 736static inline void set_lvds1_source(u8 iga)737{738	set_source_common(0x99, 4, iga);739}740 741static inline void set_lvds2_source(u8 iga)742{743	set_source_common(0x97, 4, iga);744}745 746void via_set_source(u32 devices, u8 iga)747{748	if (devices & VIA_LDVP0)749		set_ldvp0_source(iga);750	if (devices & VIA_LDVP1)751		set_ldvp1_source(iga);752	if (devices & VIA_DVP0)753		set_dvp0_source(iga);754	if (devices & VIA_CRT)755		set_crt_source(iga);756	if (devices & VIA_DVP1)757		set_dvp1_source(iga);758	if (devices & VIA_LVDS1)759		set_lvds1_source(iga);760	if (devices & VIA_LVDS2)761		set_lvds2_source(iga);762}763 764static void set_crt_state(u8 state)765{766	u8 value;767 768	switch (state) {769	case VIA_STATE_ON:770		value = 0x00;771		break;772	case VIA_STATE_STANDBY:773		value = 0x10;774		break;775	case VIA_STATE_SUSPEND:776		value = 0x20;777		break;778	case VIA_STATE_OFF:779		value = 0x30;780		break;781	default:782		return;783	}784 785	via_write_reg_mask(VIACR, 0x36, value, 0x30);786}787 788static void set_dvp0_state(u8 state)789{790	u8 value;791 792	switch (state) {793	case VIA_STATE_ON:794		value = 0xC0;795		break;796	case VIA_STATE_OFF:797		value = 0x00;798		break;799	default:800		return;801	}802 803	via_write_reg_mask(VIASR, 0x1E, value, 0xC0);804}805 806static void set_dvp1_state(u8 state)807{808	u8 value;809 810	switch (state) {811	case VIA_STATE_ON:812		value = 0x30;813		break;814	case VIA_STATE_OFF:815		value = 0x00;816		break;817	default:818		return;819	}820 821	via_write_reg_mask(VIASR, 0x1E, value, 0x30);822}823 824static void set_lvds1_state(u8 state)825{826	u8 value;827 828	switch (state) {829	case VIA_STATE_ON:830		value = 0x03;831		break;832	case VIA_STATE_OFF:833		value = 0x00;834		break;835	default:836		return;837	}838 839	via_write_reg_mask(VIASR, 0x2A, value, 0x03);840}841 842static void set_lvds2_state(u8 state)843{844	u8 value;845 846	switch (state) {847	case VIA_STATE_ON:848		value = 0x0C;849		break;850	case VIA_STATE_OFF:851		value = 0x00;852		break;853	default:854		return;855	}856 857	via_write_reg_mask(VIASR, 0x2A, value, 0x0C);858}859 860void via_set_state(u32 devices, u8 state)861{862	/*863	TODO: Can we enable/disable these devices? How?864	if (devices & VIA_LDVP0)865	if (devices & VIA_LDVP1)866	*/867	if (devices & VIA_DVP0)868		set_dvp0_state(state);869	if (devices & VIA_CRT)870		set_crt_state(state);871	if (devices & VIA_DVP1)872		set_dvp1_state(state);873	if (devices & VIA_LVDS1)874		set_lvds1_state(state);875	if (devices & VIA_LVDS2)876		set_lvds2_state(state);877}878 879void via_set_sync_polarity(u32 devices, u8 polarity)880{881	if (polarity & ~(VIA_HSYNC_NEGATIVE | VIA_VSYNC_NEGATIVE)) {882		printk(KERN_WARNING "viafb: Unsupported polarity: %d\n",883			polarity);884		return;885	}886 887	if (devices & VIA_CRT)888		via_write_misc_reg_mask(polarity << 6, 0xC0);889	if (devices & VIA_DVP1)890		via_write_reg_mask(VIACR, 0x9B, polarity << 5, 0x60);891	if (devices & VIA_LVDS1)892		via_write_reg_mask(VIACR, 0x99, polarity << 5, 0x60);893	if (devices & VIA_LVDS2)894		via_write_reg_mask(VIACR, 0x97, polarity << 5, 0x60);895}896 897u32 via_parse_odev(char *input, char **end)898{899	char *ptr = input;900	u32 odev = 0;901	bool next = true;902	int i, len;903 904	while (next) {905		next = false;906		for (i = 0; i < ARRAY_SIZE(device_mapping); i++) {907			len = strlen(device_mapping[i].name);908			if (!strncmp(ptr, device_mapping[i].name, len)) {909				odev |= device_mapping[i].device;910				ptr += len;911				if (*ptr == ',') {912					ptr++;913					next = true;914				}915			}916		}917	}918 919	*end = ptr;920	return odev;921}922 923void via_odev_to_seq(struct seq_file *m, u32 odev)924{925	int i, count = 0;926 927	for (i = 0; i < ARRAY_SIZE(device_mapping); i++) {928		if (odev & device_mapping[i].device) {929			if (count > 0)930				seq_putc(m, ',');931 932			seq_puts(m, device_mapping[i].name);933			count++;934		}935	}936 937	seq_putc(m, '\n');938}939 940static void load_fix_bit_crtc_reg(void)941{942	viafb_unlock_crt();943 944	/* always set to 1 */945	viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7);946	/* line compare should set all bits = 1 (extend modes) */947	viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4);948	/* line compare should set all bits = 1 (extend modes) */949	viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2);950	/*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */951 952	viafb_lock_crt();953 954	/* If K8M800, enable Prefetch Mode. */955	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)956		|| (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890))957		viafb_write_reg_mask(CR33, VIACR, 0x08, BIT3);958	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)959	    && (viaparinfo->chip_info->gfx_chip_revision == CLE266_REVISION_AX))960		viafb_write_reg_mask(SR1A, VIASR, 0x02, BIT1);961 962}963 964void viafb_load_reg(int timing_value, int viafb_load_reg_num,965	struct io_register *reg,966	      int io_type)967{968	int reg_mask;969	int bit_num = 0;970	int data;971	int i, j;972	int shift_next_reg;973	int start_index, end_index, cr_index;974	u16 get_bit;975 976	for (i = 0; i < viafb_load_reg_num; i++) {977		reg_mask = 0;978		data = 0;979		start_index = reg[i].start_bit;980		end_index = reg[i].end_bit;981		cr_index = reg[i].io_addr;982 983		shift_next_reg = bit_num;984		for (j = start_index; j <= end_index; j++) {985			/*if (bit_num==8) timing_value = timing_value >>8; */986			reg_mask = reg_mask | (BIT0 << j);987			get_bit = (timing_value & (BIT0 << bit_num));988			data =989			    data | ((get_bit >> shift_next_reg) << start_index);990			bit_num++;991		}992		if (io_type == VIACR)993			viafb_write_reg_mask(cr_index, VIACR, data, reg_mask);994		else995			viafb_write_reg_mask(cr_index, VIASR, data, reg_mask);996	}997 998}999 1000/* Write Registers */1001void viafb_write_regx(struct io_reg RegTable[], int ItemNum)1002{1003	int i;1004 1005	/*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */1006 1007	for (i = 0; i < ItemNum; i++)1008		via_write_reg_mask(RegTable[i].port, RegTable[i].index,1009			RegTable[i].value, RegTable[i].mask);1010}1011 1012void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga)1013{1014	int reg_value;1015	int viafb_load_reg_num;1016	struct io_register *reg = NULL;1017 1018	switch (set_iga) {1019	case IGA1:1020		reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte);1021		viafb_load_reg_num = fetch_count_reg.1022			iga1_fetch_count_reg.reg_num;1023		reg = fetch_count_reg.iga1_fetch_count_reg.reg;1024		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);1025		break;1026	case IGA2:1027		reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte);1028		viafb_load_reg_num = fetch_count_reg.1029			iga2_fetch_count_reg.reg_num;1030		reg = fetch_count_reg.iga2_fetch_count_reg.reg;1031		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);1032		break;1033	}1034 1035}1036 1037void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)1038{1039	int reg_value;1040	int viafb_load_reg_num;1041	struct io_register *reg = NULL;1042	int iga1_fifo_max_depth = 0, iga1_fifo_threshold =1043	    0, iga1_fifo_high_threshold = 0, iga1_display_queue_expire_num = 0;1044	int iga2_fifo_max_depth = 0, iga2_fifo_threshold =1045	    0, iga2_fifo_high_threshold = 0, iga2_display_queue_expire_num = 0;1046 1047	if (set_iga == IGA1) {1048		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {1049			iga1_fifo_max_depth = K800_IGA1_FIFO_MAX_DEPTH;1050			iga1_fifo_threshold = K800_IGA1_FIFO_THRESHOLD;1051			iga1_fifo_high_threshold =1052			    K800_IGA1_FIFO_HIGH_THRESHOLD;1053			/* If resolution > 1280x1024, expire length = 64, else1054			   expire length = 128 */1055			if ((hor_active > 1280) && (ver_active > 1024))1056				iga1_display_queue_expire_num = 16;1057			else1058				iga1_display_queue_expire_num =1059				    K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;1060 1061		}1062 1063		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {1064			iga1_fifo_max_depth = P880_IGA1_FIFO_MAX_DEPTH;1065			iga1_fifo_threshold = P880_IGA1_FIFO_THRESHOLD;1066			iga1_fifo_high_threshold =1067			    P880_IGA1_FIFO_HIGH_THRESHOLD;1068			iga1_display_queue_expire_num =1069			    P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;1070 1071			/* If resolution > 1280x1024, expire length = 64, else1072			   expire length = 128 */1073			if ((hor_active > 1280) && (ver_active > 1024))1074				iga1_display_queue_expire_num = 16;1075			else1076				iga1_display_queue_expire_num =1077				    P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;1078		}1079 1080		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {1081			iga1_fifo_max_depth = CN700_IGA1_FIFO_MAX_DEPTH;1082			iga1_fifo_threshold = CN700_IGA1_FIFO_THRESHOLD;1083			iga1_fifo_high_threshold =1084			    CN700_IGA1_FIFO_HIGH_THRESHOLD;1085 1086			/* If resolution > 1280x1024, expire length = 64,1087			   else expire length = 128 */1088			if ((hor_active > 1280) && (ver_active > 1024))1089				iga1_display_queue_expire_num = 16;1090			else1091				iga1_display_queue_expire_num =1092				    CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;1093		}1094 1095		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {1096			iga1_fifo_max_depth = CX700_IGA1_FIFO_MAX_DEPTH;1097			iga1_fifo_threshold = CX700_IGA1_FIFO_THRESHOLD;1098			iga1_fifo_high_threshold =1099			    CX700_IGA1_FIFO_HIGH_THRESHOLD;1100			iga1_display_queue_expire_num =1101			    CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;1102		}1103 1104		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {1105			iga1_fifo_max_depth = K8M890_IGA1_FIFO_MAX_DEPTH;1106			iga1_fifo_threshold = K8M890_IGA1_FIFO_THRESHOLD;1107			iga1_fifo_high_threshold =1108			    K8M890_IGA1_FIFO_HIGH_THRESHOLD;1109			iga1_display_queue_expire_num =1110			    K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;1111		}1112 1113		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {1114			iga1_fifo_max_depth = P4M890_IGA1_FIFO_MAX_DEPTH;1115			iga1_fifo_threshold = P4M890_IGA1_FIFO_THRESHOLD;1116			iga1_fifo_high_threshold =1117			    P4M890_IGA1_FIFO_HIGH_THRESHOLD;1118			iga1_display_queue_expire_num =1119			    P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;1120		}1121 1122		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {1123			iga1_fifo_max_depth = P4M900_IGA1_FIFO_MAX_DEPTH;1124			iga1_fifo_threshold = P4M900_IGA1_FIFO_THRESHOLD;1125			iga1_fifo_high_threshold =1126			    P4M900_IGA1_FIFO_HIGH_THRESHOLD;1127			iga1_display_queue_expire_num =1128			    P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;1129		}1130 1131		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {1132			iga1_fifo_max_depth = VX800_IGA1_FIFO_MAX_DEPTH;1133			iga1_fifo_threshold = VX800_IGA1_FIFO_THRESHOLD;1134			iga1_fifo_high_threshold =1135			    VX800_IGA1_FIFO_HIGH_THRESHOLD;1136			iga1_display_queue_expire_num =1137			    VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;1138		}1139 1140		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {1141			iga1_fifo_max_depth = VX855_IGA1_FIFO_MAX_DEPTH;1142			iga1_fifo_threshold = VX855_IGA1_FIFO_THRESHOLD;1143			iga1_fifo_high_threshold =1144			    VX855_IGA1_FIFO_HIGH_THRESHOLD;1145			iga1_display_queue_expire_num =1146			    VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;1147		}1148 1149		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) {1150			iga1_fifo_max_depth = VX900_IGA1_FIFO_MAX_DEPTH;1151			iga1_fifo_threshold = VX900_IGA1_FIFO_THRESHOLD;1152			iga1_fifo_high_threshold =1153			    VX900_IGA1_FIFO_HIGH_THRESHOLD;1154			iga1_display_queue_expire_num =1155			    VX900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;1156		}1157 1158		/* Set Display FIFO Depath Select */1159		reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth);1160		viafb_load_reg_num =1161		    display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg_num;1162		reg = display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg;1163		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);1164 1165		/* Set Display FIFO Threshold Select */1166		reg_value = IGA1_FIFO_THRESHOLD_FORMULA(iga1_fifo_threshold);1167		viafb_load_reg_num =1168		    fifo_threshold_select_reg.1169		    iga1_fifo_threshold_select_reg.reg_num;1170		reg =1171		    fifo_threshold_select_reg.1172		    iga1_fifo_threshold_select_reg.reg;1173		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);1174 1175		/* Set FIFO High Threshold Select */1176		reg_value =1177		    IGA1_FIFO_HIGH_THRESHOLD_FORMULA(iga1_fifo_high_threshold);1178		viafb_load_reg_num =1179		    fifo_high_threshold_select_reg.1180		    iga1_fifo_high_threshold_select_reg.reg_num;1181		reg =1182		    fifo_high_threshold_select_reg.1183		    iga1_fifo_high_threshold_select_reg.reg;1184		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);1185 1186		/* Set Display Queue Expire Num */1187		reg_value =1188		    IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA1189		    (iga1_display_queue_expire_num);1190		viafb_load_reg_num =1191		    display_queue_expire_num_reg.1192		    iga1_display_queue_expire_num_reg.reg_num;1193		reg =1194		    display_queue_expire_num_reg.1195		    iga1_display_queue_expire_num_reg.reg;1196		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);1197 1198	} else {1199		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {1200			iga2_fifo_max_depth = K800_IGA2_FIFO_MAX_DEPTH;1201			iga2_fifo_threshold = K800_IGA2_FIFO_THRESHOLD;1202			iga2_fifo_high_threshold =1203			    K800_IGA2_FIFO_HIGH_THRESHOLD;1204 1205			/* If resolution > 1280x1024, expire length = 64,1206			   else  expire length = 128 */1207			if ((hor_active > 1280) && (ver_active > 1024))1208				iga2_display_queue_expire_num = 16;1209			else1210				iga2_display_queue_expire_num =1211				    K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;1212		}1213 1214		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {1215			iga2_fifo_max_depth = P880_IGA2_FIFO_MAX_DEPTH;1216			iga2_fifo_threshold = P880_IGA2_FIFO_THRESHOLD;1217			iga2_fifo_high_threshold =1218			    P880_IGA2_FIFO_HIGH_THRESHOLD;1219 1220			/* If resolution > 1280x1024, expire length = 64,1221			   else  expire length = 128 */1222			if ((hor_active > 1280) && (ver_active > 1024))1223				iga2_display_queue_expire_num = 16;1224			else1225				iga2_display_queue_expire_num =1226				    P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;1227		}1228 1229		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {1230			iga2_fifo_max_depth = CN700_IGA2_FIFO_MAX_DEPTH;1231			iga2_fifo_threshold = CN700_IGA2_FIFO_THRESHOLD;1232			iga2_fifo_high_threshold =1233			    CN700_IGA2_FIFO_HIGH_THRESHOLD;1234 1235			/* If resolution > 1280x1024, expire length = 64,1236			   else expire length = 128 */1237			if ((hor_active > 1280) && (ver_active > 1024))1238				iga2_display_queue_expire_num = 16;1239			else1240				iga2_display_queue_expire_num =1241				    CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;1242		}1243 1244		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {1245			iga2_fifo_max_depth = CX700_IGA2_FIFO_MAX_DEPTH;1246			iga2_fifo_threshold = CX700_IGA2_FIFO_THRESHOLD;1247			iga2_fifo_high_threshold =1248			    CX700_IGA2_FIFO_HIGH_THRESHOLD;1249			iga2_display_queue_expire_num =1250			    CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;1251		}1252 1253		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {1254			iga2_fifo_max_depth = K8M890_IGA2_FIFO_MAX_DEPTH;1255			iga2_fifo_threshold = K8M890_IGA2_FIFO_THRESHOLD;1256			iga2_fifo_high_threshold =1257			    K8M890_IGA2_FIFO_HIGH_THRESHOLD;1258			iga2_display_queue_expire_num =1259			    K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;1260		}1261 1262		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {1263			iga2_fifo_max_depth = P4M890_IGA2_FIFO_MAX_DEPTH;1264			iga2_fifo_threshold = P4M890_IGA2_FIFO_THRESHOLD;1265			iga2_fifo_high_threshold =1266			    P4M890_IGA2_FIFO_HIGH_THRESHOLD;1267			iga2_display_queue_expire_num =1268			    P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;1269		}1270 1271		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {1272			iga2_fifo_max_depth = P4M900_IGA2_FIFO_MAX_DEPTH;1273			iga2_fifo_threshold = P4M900_IGA2_FIFO_THRESHOLD;1274			iga2_fifo_high_threshold =1275			    P4M900_IGA2_FIFO_HIGH_THRESHOLD;1276			iga2_display_queue_expire_num =1277			    P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;1278		}1279 1280		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {1281			iga2_fifo_max_depth = VX800_IGA2_FIFO_MAX_DEPTH;1282			iga2_fifo_threshold = VX800_IGA2_FIFO_THRESHOLD;1283			iga2_fifo_high_threshold =1284			    VX800_IGA2_FIFO_HIGH_THRESHOLD;1285			iga2_display_queue_expire_num =1286			    VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;1287		}1288 1289		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {1290			iga2_fifo_max_depth = VX855_IGA2_FIFO_MAX_DEPTH;1291			iga2_fifo_threshold = VX855_IGA2_FIFO_THRESHOLD;1292			iga2_fifo_high_threshold =1293			    VX855_IGA2_FIFO_HIGH_THRESHOLD;1294			iga2_display_queue_expire_num =1295			    VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;1296		}1297 1298		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) {1299			iga2_fifo_max_depth = VX900_IGA2_FIFO_MAX_DEPTH;1300			iga2_fifo_threshold = VX900_IGA2_FIFO_THRESHOLD;1301			iga2_fifo_high_threshold =1302			    VX900_IGA2_FIFO_HIGH_THRESHOLD;1303			iga2_display_queue_expire_num =1304			    VX900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;1305		}1306 1307		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {1308			/* Set Display FIFO Depath Select */1309			reg_value =1310			    IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth)1311			    - 1;1312			/* Patch LCD in IGA2 case */1313			viafb_load_reg_num =1314			    display_fifo_depth_reg.1315			    iga2_fifo_depth_select_reg.reg_num;1316			reg =1317			    display_fifo_depth_reg.1318			    iga2_fifo_depth_select_reg.reg;1319			viafb_load_reg(reg_value,1320				viafb_load_reg_num, reg, VIACR);1321		} else {1322 1323			/* Set Display FIFO Depath Select */1324			reg_value =1325			    IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth);1326			viafb_load_reg_num =1327			    display_fifo_depth_reg.1328			    iga2_fifo_depth_select_reg.reg_num;1329			reg =1330			    display_fifo_depth_reg.1331			    iga2_fifo_depth_select_reg.reg;1332			viafb_load_reg(reg_value,1333				viafb_load_reg_num, reg, VIACR);1334		}1335 1336		/* Set Display FIFO Threshold Select */1337		reg_value = IGA2_FIFO_THRESHOLD_FORMULA(iga2_fifo_threshold);1338		viafb_load_reg_num =1339		    fifo_threshold_select_reg.1340		    iga2_fifo_threshold_select_reg.reg_num;1341		reg =1342		    fifo_threshold_select_reg.1343		    iga2_fifo_threshold_select_reg.reg;1344		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);1345 1346		/* Set FIFO High Threshold Select */1347		reg_value =1348		    IGA2_FIFO_HIGH_THRESHOLD_FORMULA(iga2_fifo_high_threshold);1349		viafb_load_reg_num =1350		    fifo_high_threshold_select_reg.1351		    iga2_fifo_high_threshold_select_reg.reg_num;1352		reg =1353		    fifo_high_threshold_select_reg.1354		    iga2_fifo_high_threshold_select_reg.reg;1355		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);1356 1357		/* Set Display Queue Expire Num */1358		reg_value =1359		    IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA1360		    (iga2_display_queue_expire_num);1361		viafb_load_reg_num =1362		    display_queue_expire_num_reg.1363		    iga2_display_queue_expire_num_reg.reg_num;1364		reg =1365		    display_queue_expire_num_reg.1366		    iga2_display_queue_expire_num_reg.reg;1367		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);1368 1369	}1370 1371}1372 1373static struct via_pll_config get_pll_config(struct pll_limit *limits, int size,1374	int clk)1375{1376	struct via_pll_config cur, up, down, best = {0, 1, 0};1377	const u32 f0 = 14318180; /* X1 frequency */1378	int i, f;1379 1380	for (i = 0; i < size; i++) {1381		cur.rshift = limits[i].rshift;1382		cur.divisor = limits[i].divisor;1383		cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift);1384		f = abs(get_pll_output_frequency(f0, cur) - clk);1385		up = down = cur;1386		up.multiplier++;1387		down.multiplier--;1388		if (abs(get_pll_output_frequency(f0, up) - clk) < f)1389			cur = up;1390		else if (abs(get_pll_output_frequency(f0, down) - clk) < f)1391			cur = down;1392 1393		if (cur.multiplier < limits[i].multiplier_min)1394			cur.multiplier = limits[i].multiplier_min;1395		else if (cur.multiplier > limits[i].multiplier_max)1396			cur.multiplier = limits[i].multiplier_max;1397 1398		f = abs(get_pll_output_frequency(f0, cur) - clk);1399		if (f < abs(get_pll_output_frequency(f0, best) - clk))1400			best = cur;1401	}1402 1403	return best;1404}1405 1406static struct via_pll_config get_best_pll_config(int clk)1407{1408	struct via_pll_config config;1409 1410	switch (viaparinfo->chip_info->gfx_chip_name) {1411	case UNICHROME_CLE266:1412	case UNICHROME_K400:1413		config = get_pll_config(cle266_pll_limits,1414			ARRAY_SIZE(cle266_pll_limits), clk);1415		break;1416	case UNICHROME_K800:1417	case UNICHROME_PM800:1418	case UNICHROME_CN700:1419		config = get_pll_config(k800_pll_limits,1420			ARRAY_SIZE(k800_pll_limits), clk);1421		break;1422	case UNICHROME_CX700:1423	case UNICHROME_CN750:1424	case UNICHROME_K8M890:1425	case UNICHROME_P4M890:1426	case UNICHROME_P4M900:1427	case UNICHROME_VX800:1428		config = get_pll_config(cx700_pll_limits,1429			ARRAY_SIZE(cx700_pll_limits), clk);1430		break;1431	case UNICHROME_VX855:1432	case UNICHROME_VX900:1433		config = get_pll_config(vx855_pll_limits,1434			ARRAY_SIZE(vx855_pll_limits), clk);1435		break;1436	}1437 1438	return config;1439}1440 1441/* Set VCLK*/1442void viafb_set_vclock(u32 clk, int set_iga)1443{1444	struct via_pll_config config = get_best_pll_config(clk);1445 1446	if (set_iga == IGA1)1447		clock.set_primary_pll(config);1448	if (set_iga == IGA2)1449		clock.set_secondary_pll(config);1450 1451	/* Fire! */1452	via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */1453}1454 1455struct via_display_timing var_to_timing(const struct fb_var_screeninfo *var,1456	u16 cxres, u16 cyres)1457{1458	struct via_display_timing timing;1459	u16 dx = (var->xres - cxres) / 2, dy = (var->yres - cyres) / 2;1460 1461	timing.hor_addr = cxres;1462	timing.hor_sync_start = timing.hor_addr + var->right_margin + dx;1463	timing.hor_sync_end = timing.hor_sync_start + var->hsync_len;1464	timing.hor_total = timing.hor_sync_end + var->left_margin + dx;1465	timing.hor_blank_start = timing.hor_addr + dx;1466	timing.hor_blank_end = timing.hor_total - dx;1467	timing.ver_addr = cyres;1468	timing.ver_sync_start = timing.ver_addr + var->lower_margin + dy;1469	timing.ver_sync_end = timing.ver_sync_start + var->vsync_len;1470	timing.ver_total = timing.ver_sync_end + var->upper_margin + dy;1471	timing.ver_blank_start = timing.ver_addr + dy;1472	timing.ver_blank_end = timing.ver_total - dy;1473	return timing;1474}1475 1476void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,1477	u16 cxres, u16 cyres, int iga)1478{1479	struct via_display_timing crt_reg = var_to_timing(var,1480		cxres ? cxres : var->xres, cyres ? cyres : var->yres);1481 1482	if (iga == IGA1)1483		via_set_primary_timing(&crt_reg);1484	else if (iga == IGA2)1485		via_set_secondary_timing(&crt_reg);1486 1487	viafb_load_fetch_count_reg(var->xres, var->bits_per_pixel / 8, iga);1488	if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE2661489		&& viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)1490		viafb_load_FIFO_reg(iga, var->xres, var->yres);1491 1492	viafb_set_vclock(PICOS2KHZ(var->pixclock) * 1000, iga);1493}1494 1495void viafb_init_chip_info(int chip_type)1496{1497	via_clock_init(&clock, chip_type);1498	init_gfx_chip_info(chip_type);1499	init_tmds_chip_info();1500	init_lvds_chip_info();1501 1502	/*Set IGA path for each device */1503	viafb_set_iga_path();1504 1505	viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method;1506	viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode;1507	viaparinfo->lvds_setting_info2->display_method =1508		viaparinfo->lvds_setting_info->display_method;1509	viaparinfo->lvds_setting_info2->lcd_mode =1510		viaparinfo->lvds_setting_info->lcd_mode;1511}1512 1513void viafb_update_device_setting(int hres, int vres, int bpp, int flag)1514{1515	if (flag == 0) {1516		viaparinfo->tmds_setting_info->h_active = hres;1517		viaparinfo->tmds_setting_info->v_active = vres;1518	} else {1519 1520		if (viaparinfo->tmds_setting_info->iga_path == IGA2) {1521			viaparinfo->tmds_setting_info->h_active = hres;1522			viaparinfo->tmds_setting_info->v_active = vres;1523		}1524 1525	}1526}1527 1528static void init_gfx_chip_info(int chip_type)1529{1530	u8 tmp;1531 1532	viaparinfo->chip_info->gfx_chip_name = chip_type;1533 1534	/* Check revision of CLE266 Chip */1535	if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {1536		/* CR4F only define in CLE266.CX chip */1537		tmp = viafb_read_reg(VIACR, CR4F);1538		viafb_write_reg(CR4F, VIACR, 0x55);1539		if (viafb_read_reg(VIACR, CR4F) != 0x55)1540			viaparinfo->chip_info->gfx_chip_revision =1541			CLE266_REVISION_AX;1542		else1543			viaparinfo->chip_info->gfx_chip_revision =1544			CLE266_REVISION_CX;1545		/* restore orignal CR4F value */1546		viafb_write_reg(CR4F, VIACR, tmp);1547	}1548 1549	if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {1550		tmp = viafb_read_reg(VIASR, SR43);1551		DEBUG_MSG(KERN_INFO "SR43:%X\n", tmp);1552		if (tmp & 0x02) {1553			viaparinfo->chip_info->gfx_chip_revision =1554				CX700_REVISION_700M2;1555		} else if (tmp & 0x40) {1556			viaparinfo->chip_info->gfx_chip_revision =1557				CX700_REVISION_700M;1558		} else {1559			viaparinfo->chip_info->gfx_chip_revision =1560				CX700_REVISION_700;1561		}1562	}1563 1564	/* Determine which 2D engine we have */1565	switch (viaparinfo->chip_info->gfx_chip_name) {1566	case UNICHROME_VX800:1567	case UNICHROME_VX855:1568	case UNICHROME_VX900:1569		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_M1;1570		break;1571	case UNICHROME_K8M890:1572	case UNICHROME_P4M900:1573		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H5;1574		break;1575	default:1576		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H2;1577		break;1578	}1579}1580 1581static void init_tmds_chip_info(void)1582{1583	viafb_tmds_trasmitter_identify();1584 1585	if (INTERFACE_NONE == viaparinfo->chip_info->tmds_chip_info.1586		output_interface) {1587		switch (viaparinfo->chip_info->gfx_chip_name) {1588		case UNICHROME_CX700:1589			{1590				/* we should check support by hardware layout.*/1591				if ((viafb_display_hardware_layout ==1592				     HW_LAYOUT_DVI_ONLY)1593				    || (viafb_display_hardware_layout ==1594					HW_LAYOUT_LCD_DVI)) {1595					viaparinfo->chip_info->tmds_chip_info.1596					    output_interface = INTERFACE_TMDS;1597				} else {1598					viaparinfo->chip_info->tmds_chip_info.1599						output_interface =1600						INTERFACE_NONE;1601				}1602				break;1603			}1604		case UNICHROME_K8M890:1605		case UNICHROME_P4M900:1606		case UNICHROME_P4M890:1607			/* TMDS on PCIE, we set DFPLOW as default. */1608			viaparinfo->chip_info->tmds_chip_info.output_interface =1609			    INTERFACE_DFP_LOW;1610			break;1611		default:1612			{1613				/* set DVP1 default for DVI */1614				viaparinfo->chip_info->tmds_chip_info1615				.output_interface = INTERFACE_DVP1;1616			}1617		}1618	}1619 1620	DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n",1621		  viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);1622	viafb_init_dvi_size(&viaparinfo->shared->chip_info.tmds_chip_info,1623		&viaparinfo->shared->tmds_setting_info);1624}1625 1626static void init_lvds_chip_info(void)1627{1628	viafb_lvds_trasmitter_identify();1629	viafb_init_lcd_size();1630	viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info,1631				   viaparinfo->lvds_setting_info);1632	if (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {1633		viafb_init_lvds_output_interface(&viaparinfo->chip_info->1634			lvds_chip_info2, viaparinfo->lvds_setting_info2);1635	}1636	/*If CX700,two singel LCD, we need to reassign1637	   LCD interface to different LVDS port */1638	if ((UNICHROME_CX700 == viaparinfo->chip_info->gfx_chip_name)1639	    && (HW_LAYOUT_LCD1_LCD2 == viafb_display_hardware_layout)) {1640		if ((INTEGRATED_LVDS == viaparinfo->chip_info->lvds_chip_info.1641			lvds_chip_name) && (INTEGRATED_LVDS ==1642			viaparinfo->chip_info->1643			lvds_chip_info2.lvds_chip_name)) {1644			viaparinfo->chip_info->lvds_chip_info.output_interface =1645				INTERFACE_LVDS0;1646			viaparinfo->chip_info->lvds_chip_info2.1647				output_interface =1648			    INTERFACE_LVDS1;1649		}1650	}1651 1652	DEBUG_MSG(KERN_INFO "LVDS Chip = %d\n",1653		  viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);1654	DEBUG_MSG(KERN_INFO "LVDS1 output_interface = %d\n",1655		  viaparinfo->chip_info->lvds_chip_info.output_interface);1656	DEBUG_MSG(KERN_INFO "LVDS2 output_interface = %d\n",1657		  viaparinfo->chip_info->lvds_chip_info.output_interface);1658}1659 1660void viafb_init_dac(int set_iga)1661{1662	int i;1663	u8 tmp;1664 1665	if (set_iga == IGA1) {1666		/* access Primary Display's LUT */1667		viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);1668		/* turn off LCK */1669		viafb_write_reg_mask(SR1B, VIASR, 0x00, BIT7 + BIT6);1670		for (i = 0; i < 256; i++) {1671			write_dac_reg(i, palLUT_table[i].red,1672				      palLUT_table[i].green,1673				      palLUT_table[i].blue);1674		}1675		/* turn on LCK */1676		viafb_write_reg_mask(SR1B, VIASR, 0xC0, BIT7 + BIT6);1677	} else {1678		tmp = viafb_read_reg(VIACR, CR6A);1679		/* access Secondary Display's LUT */1680		viafb_write_reg_mask(CR6A, VIACR, 0x40, BIT6);1681		viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);1682		for (i = 0; i < 256; i++) {1683			write_dac_reg(i, palLUT_table[i].red,1684				      palLUT_table[i].green,1685				      palLUT_table[i].blue);1686		}1687		/* set IGA1 DAC for default */1688		viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);1689		viafb_write_reg(CR6A, VIACR, tmp);1690	}1691}1692 1693static void device_screen_off(void)1694{1695	/* turn off CRT screen (IGA1) */1696	viafb_write_reg_mask(SR01, VIASR, 0x20, BIT5);1697}1698 1699static void device_screen_on(void)1700{1701	/* turn on CRT screen (IGA1) */1702	viafb_write_reg_mask(SR01, VIASR, 0x00, BIT5);1703}1704 1705static void set_display_channel(void)1706{1707	/*If viafb_LCD2_ON, on cx700, internal lvds's information1708	is keeped on lvds_setting_info2 */1709	if (viafb_LCD2_ON &&1710		viaparinfo->lvds_setting_info2->device_lcd_dualedge) {1711		/* For dual channel LCD: */1712		/* Set to Dual LVDS channel. */1713		viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);1714	} else if (viafb_LCD_ON && viafb_DVI_ON) {1715		/* For LCD+DFP: */1716		/* Set to LVDS1 + TMDS channel. */1717		viafb_write_reg_mask(CRD2, VIACR, 0x10, BIT4 + BIT5);1718	} else if (viafb_DVI_ON) {1719		/* Set to single TMDS channel. */1720		viafb_write_reg_mask(CRD2, VIACR, 0x30, BIT4 + BIT5);1721	} else if (viafb_LCD_ON) {1722		if (viaparinfo->lvds_setting_info->device_lcd_dualedge) {1723			/* For dual channel LCD: */1724			/* Set to Dual LVDS channel. */1725			viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);1726		} else {1727			/* Set to LVDS0 + LVDS1 channel. */1728			viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT4 + BIT5);1729		}1730	}1731}1732 1733static u8 get_sync(struct fb_var_screeninfo *var)1734{1735	u8 polarity = 0;1736 1737	if (!(var->sync & FB_SYNC_HOR_HIGH_ACT))1738		polarity |= VIA_HSYNC_NEGATIVE;1739	if (!(var->sync & FB_SYNC_VERT_HIGH_ACT))1740		polarity |= VIA_VSYNC_NEGATIVE;1741	return polarity;1742}1743 1744static void hw_init(void)1745{1746	int i;1747 1748	inb(VIAStatus);1749	outb(0x00, VIAAR);1750 1751	/* Write Common Setting for Video Mode */1752	viafb_write_regx(common_vga, ARRAY_SIZE(common_vga));1753	switch (viaparinfo->chip_info->gfx_chip_name) {1754	case UNICHROME_CLE266:1755		viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs);1756		break;1757 1758	case UNICHROME_K400:1759		viafb_write_regx(KM400_ModeXregs, NUM_TOTAL_KM400_ModeXregs);1760		break;1761 1762	case UNICHROME_K800:1763	case UNICHROME_PM800:1764		viafb_write_regx(CN400_ModeXregs, NUM_TOTAL_CN400_ModeXregs);1765		break;1766 1767	case UNICHROME_CN700:1768	case UNICHROME_K8M890:1769	case UNICHROME_P4M890:1770	case UNICHROME_P4M900:1771		viafb_write_regx(CN700_ModeXregs, NUM_TOTAL_CN700_ModeXregs);1772		break;1773 1774	case UNICHROME_CX700:1775	case UNICHROME_VX800:1776		viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs);1777		break;1778 1779	case UNICHROME_VX855:1780	case UNICHROME_VX900:1781		viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs);1782		break;1783	}1784 1785	/* magic required on VX900 for correct modesetting on IGA1 */1786	via_write_reg_mask(VIACR, 0x45, 0x00, 0x01);1787 1788	/* probably this should go to the scaling code one day */1789	via_write_reg_mask(VIACR, 0xFD, 0, 0x80); /* VX900 hw scale on IGA2 */1790	viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters));1791 1792	/* Fill VPIT Parameters */1793	/* Write Misc Register */1794	outb(VPIT.Misc, VIA_MISC_REG_WRITE);1795 1796	/* Write Sequencer */1797	for (i = 1; i <= StdSR; i++)1798		via_write_reg(VIASR, i, VPIT.SR[i - 1]);1799 1800	viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2);1801 1802	/* Write Graphic Controller */1803	for (i = 0; i < StdGR; i++)1804		via_write_reg(VIAGR, i, VPIT.GR[i]);1805 1806	/* Write Attribute Controller */1807	for (i = 0; i < StdAR; i++) {1808		inb(VIAStatus);1809		outb(i, VIAAR);1810		outb(VPIT.AR[i], VIAAR);1811	}1812 1813	inb(VIAStatus);1814	outb(0x20, VIAAR);1815 1816	load_fix_bit_crtc_reg();1817}1818 1819int viafb_setmode(void)1820{1821	int j, cxres = 0, cyres = 0;1822	int port;1823	u32 devices = viaparinfo->shared->iga1_devices1824		| viaparinfo->shared->iga2_devices;1825	u8 value, index, mask;1826	struct fb_var_screeninfo var2;1827 1828	device_screen_off();1829	device_off();1830	via_set_state(devices, VIA_STATE_OFF);1831 1832	hw_init();1833 1834	/* Update Patch Register */1835 1836	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE2661837		|| viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)1838		&& viafbinfo->var.xres == 1024 && viafbinfo->var.yres == 768) {1839		for (j = 0; j < res_patch_table[0].table_length; j++) {1840			index = res_patch_table[0].io_reg_table[j].index;1841			port = res_patch_table[0].io_reg_table[j].port;1842			value = res_patch_table[0].io_reg_table[j].value;1843			mask = res_patch_table[0].io_reg_table[j].mask;1844			viafb_write_reg_mask(index, port, value, mask);1845		}1846	}1847 1848	via_set_primary_pitch(viafbinfo->fix.line_length);1849	via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length1850		: viafbinfo->fix.line_length);1851	via_set_primary_color_depth(viaparinfo->depth);1852	via_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth1853		: viaparinfo->depth);1854	via_set_source(viaparinfo->shared->iga1_devices, IGA1);1855	via_set_source(viaparinfo->shared->iga2_devices, IGA2);1856	if (viaparinfo->shared->iga2_devices)1857		enable_second_display_channel();1858	else1859		disable_second_display_channel();1860 1861	/* Update Refresh Rate Setting */1862 1863	/* Clear On Screen */1864 1865	if (viafb_dual_fb) {1866		var2 = viafbinfo1->var;1867	} else if (viafb_SAMM_ON) {1868		viafb_fill_var_timing_info(&var2, viafb_get_best_mode(1869			viafb_second_xres, viafb_second_yres, viafb_refresh1));1870		cxres = viafbinfo->var.xres;1871		cyres = viafbinfo->var.yres;1872		var2.bits_per_pixel = viafbinfo->var.bits_per_pixel;1873	}1874 1875	/* CRT set mode */1876	if (viafb_CRT_ON) {1877		if (viaparinfo->shared->iga2_devices & VIA_CRT1878			&& viafb_SAMM_ON)1879			viafb_fill_crtc_timing(&var2, cxres, cyres, IGA2);1880		else1881			viafb_fill_crtc_timing(&viafbinfo->var, 0, 0,1882				(viaparinfo->shared->iga1_devices & VIA_CRT)1883				? IGA1 : IGA2);1884 1885		/* Patch if set_hres is not 8 alignment (1366) to viafb_setmode1886		to 8 alignment (1368),there is several pixels (2 pixels)1887		on right side of screen. */1888		if (viafbinfo->var.xres % 8) {1889			viafb_unlock_crt();1890			viafb_write_reg(CR02, VIACR,1891				viafb_read_reg(VIACR, CR02) - 1);1892			viafb_lock_crt();1893		}1894	}1895 1896	if (viafb_DVI_ON) {1897		if (viaparinfo->shared->tmds_setting_info.iga_path == IGA21898			&& viafb_SAMM_ON)1899			viafb_dvi_set_mode(&var2, cxres, cyres, IGA2);1900		else1901			viafb_dvi_set_mode(&viafbinfo->var, 0, 0,1902				viaparinfo->tmds_setting_info->iga_path);1903	}1904 1905	if (viafb_LCD_ON) {1906		if (viafb_SAMM_ON &&1907			(viaparinfo->lvds_setting_info->iga_path == IGA2)) {1908			viafb_lcd_set_mode(&var2, cxres, cyres,1909				viaparinfo->lvds_setting_info,1910				&viaparinfo->chip_info->lvds_chip_info);1911		} else {1912			/* IGA1 doesn't have LCD scaling, so set it center. */1913			if (viaparinfo->lvds_setting_info->iga_path == IGA1) {1914				viaparinfo->lvds_setting_info->display_method =1915				    LCD_CENTERING;1916			}1917			viafb_lcd_set_mode(&viafbinfo->var, 0, 0,1918				viaparinfo->lvds_setting_info,1919				&viaparinfo->chip_info->lvds_chip_info);1920		}1921	}1922	if (viafb_LCD2_ON) {1923		if (viafb_SAMM_ON &&1924			(viaparinfo->lvds_setting_info2->iga_path == IGA2)) {1925			viafb_lcd_set_mode(&var2, cxres, cyres,1926				viaparinfo->lvds_setting_info2,1927				&viaparinfo->chip_info->lvds_chip_info2);1928		} else {1929			/* IGA1 doesn't have LCD scaling, so set it center. */1930			if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {1931				viaparinfo->lvds_setting_info2->display_method =1932				    LCD_CENTERING;1933			}1934			viafb_lcd_set_mode(&viafbinfo->var, 0, 0,1935				viaparinfo->lvds_setting_info2,1936				&viaparinfo->chip_info->lvds_chip_info2);1937		}1938	}1939 1940	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)1941	    && (viafb_LCD_ON || viafb_DVI_ON))1942		set_display_channel();1943 1944	/* If set mode normally, save resolution information for hot-plug . */1945	if (!viafb_hotplug) {1946		viafb_hotplug_Xres = viafbinfo->var.xres;1947		viafb_hotplug_Yres = viafbinfo->var.yres;1948		viafb_hotplug_bpp = viafbinfo->var.bits_per_pixel;1949		viafb_hotplug_refresh = viafb_refresh;1950 1951		if (viafb_DVI_ON)1952			viafb_DeviceStatus = DVI_Device;1953		else1954			viafb_DeviceStatus = CRT_Device;1955	}1956	device_on();1957	if (!viafb_SAMM_ON)1958		via_set_sync_polarity(devices, get_sync(&viafbinfo->var));1959	else {1960		via_set_sync_polarity(viaparinfo->shared->iga1_devices,1961			get_sync(&viafbinfo->var));1962		via_set_sync_polarity(viaparinfo->shared->iga2_devices,1963			get_sync(&var2));1964	}1965 1966	clock.set_engine_pll_state(VIA_STATE_ON);1967	clock.set_primary_clock_source(VIA_CLKSRC_X1, true);1968	clock.set_secondary_clock_source(VIA_CLKSRC_X1, true);1969 1970#ifdef CONFIG_FB_VIA_X_COMPATIBILITY1971	clock.set_primary_pll_state(VIA_STATE_ON);1972	clock.set_primary_clock_state(VIA_STATE_ON);1973	clock.set_secondary_pll_state(VIA_STATE_ON);1974	clock.set_secondary_clock_state(VIA_STATE_ON);1975#else1976	if (viaparinfo->shared->iga1_devices) {1977		clock.set_primary_pll_state(VIA_STATE_ON);1978		clock.set_primary_clock_state(VIA_STATE_ON);1979	} else {1980		clock.set_primary_pll_state(VIA_STATE_OFF);1981		clock.set_primary_clock_state(VIA_STATE_OFF);1982	}1983 1984	if (viaparinfo->shared->iga2_devices) {1985		clock.set_secondary_pll_state(VIA_STATE_ON);1986		clock.set_secondary_clock_state(VIA_STATE_ON);1987	} else {1988		clock.set_secondary_pll_state(VIA_STATE_OFF);1989		clock.set_secondary_clock_state(VIA_STATE_OFF);1990	}1991#endif /*CONFIG_FB_VIA_X_COMPATIBILITY*/1992 1993	via_set_state(devices, VIA_STATE_ON);1994	device_screen_on();1995	return 1;1996}1997 1998int viafb_get_refresh(int hres, int vres, u32 long_refresh)1999{2000	const struct fb_videomode *best;2001 2002	best = viafb_get_best_mode(hres, vres, long_refresh);2003	if (!best)2004		return 60;2005 2006	if (abs(best->refresh - long_refresh) > 3) {2007		if (hres == 1200 && vres == 900)2008			return 49; /* OLPC DCON only supports 50 Hz */2009		else2010			return 60;2011	}2012 2013	return best->refresh;2014}2015 2016static void device_off(void)2017{2018	viafb_dvi_disable();2019	viafb_lcd_disable();2020}2021 2022static void device_on(void)2023{2024	if (viafb_DVI_ON == 1)2025		viafb_dvi_enable();2026	if (viafb_LCD_ON == 1)2027		viafb_lcd_enable();2028}2029 2030static void enable_second_display_channel(void)2031{2032	/* to enable second display channel. */2033	viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);2034	viafb_write_reg_mask(CR6A, VIACR, BIT7, BIT7);2035	viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);2036}2037 2038static void disable_second_display_channel(void)2039{2040	/* to disable second display channel. */2041	viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);2042	viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT7);2043	viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);2044}2045 2046void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\2047					*p_gfx_dpa_setting)2048{2049	switch (output_interface) {2050	case INTERFACE_DVP0:2051		{2052			/* DVP0 Clock Polarity and Adjust: */2053			viafb_write_reg_mask(CR96, VIACR,2054				       p_gfx_dpa_setting->DVP0, 0x0F);2055 2056			/* DVP0 Clock and Data Pads Driving: */2057			viafb_write_reg_mask(SR1E, VIASR,2058				       p_gfx_dpa_setting->DVP0ClockDri_S, BIT2);2059			viafb_write_reg_mask(SR2A, VIASR,2060				       p_gfx_dpa_setting->DVP0ClockDri_S1,2061				       BIT4);2062			viafb_write_reg_mask(SR1B, VIASR,2063				       p_gfx_dpa_setting->DVP0DataDri_S, BIT1);2064			viafb_write_reg_mask(SR2A, VIASR,2065				       p_gfx_dpa_setting->DVP0DataDri_S1, BIT5);2066			break;2067		}2068 2069	case INTERFACE_DVP1:2070		{2071			/* DVP1 Clock Polarity and Adjust: */2072			viafb_write_reg_mask(CR9B, VIACR,2073				       p_gfx_dpa_setting->DVP1, 0x0F);2074 2075			/* DVP1 Clock and Data Pads Driving: */2076			viafb_write_reg_mask(SR65, VIASR,2077				       p_gfx_dpa_setting->DVP1Driving, 0x0F);2078			break;2079		}2080 2081	case INTERFACE_DFP_HIGH:2082		{2083			viafb_write_reg_mask(CR97, VIACR,2084				       p_gfx_dpa_setting->DFPHigh, 0x0F);2085			break;2086		}2087 2088	case INTERFACE_DFP_LOW:2089		{2090			viafb_write_reg_mask(CR99, VIACR,2091				       p_gfx_dpa_setting->DFPLow, 0x0F);2092			break;2093		}2094 2095	case INTERFACE_DFP:2096		{2097			viafb_write_reg_mask(CR97, VIACR,2098				       p_gfx_dpa_setting->DFPHigh, 0x0F);2099			viafb_write_reg_mask(CR99, VIACR,2100				       p_gfx_dpa_setting->DFPLow, 0x0F);2101			break;2102		}2103	}2104}2105 2106void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,2107	const struct fb_videomode *mode)2108{2109	var->pixclock = mode->pixclock;2110	var->xres = mode->xres;2111	var->yres = mode->yres;2112	var->left_margin = mode->left_margin;2113	var->right_margin = mode->right_margin;2114	var->hsync_len = mode->hsync_len;2115	var->upper_margin = mode->upper_margin;2116	var->lower_margin = mode->lower_margin;2117	var->vsync_len = mode->vsync_len;2118	var->sync = mode->sync;2119}2120