162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
462306a36Sopenharmony_ci * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/via-core.h>
962306a36Sopenharmony_ci#include "global.h"
1062306a36Sopenharmony_ci#include "via_clock.h"
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_cistatic struct pll_limit cle266_pll_limits[] = {
1362306a36Sopenharmony_ci	{19, 19, 4, 0},
1462306a36Sopenharmony_ci	{26, 102, 5, 0},
1562306a36Sopenharmony_ci	{53, 112, 6, 0},
1662306a36Sopenharmony_ci	{41, 100, 7, 0},
1762306a36Sopenharmony_ci	{83, 108, 8, 0},
1862306a36Sopenharmony_ci	{87, 118, 9, 0},
1962306a36Sopenharmony_ci	{95, 115, 12, 0},
2062306a36Sopenharmony_ci	{108, 108, 13, 0},
2162306a36Sopenharmony_ci	{83, 83, 17, 0},
2262306a36Sopenharmony_ci	{67, 98, 20, 0},
2362306a36Sopenharmony_ci	{121, 121, 24, 0},
2462306a36Sopenharmony_ci	{99, 99, 29, 0},
2562306a36Sopenharmony_ci	{33, 33, 3, 1},
2662306a36Sopenharmony_ci	{15, 23, 4, 1},
2762306a36Sopenharmony_ci	{37, 121, 5, 1},
2862306a36Sopenharmony_ci	{82, 82, 6, 1},
2962306a36Sopenharmony_ci	{31, 84, 7, 1},
3062306a36Sopenharmony_ci	{83, 83, 8, 1},
3162306a36Sopenharmony_ci	{76, 127, 9, 1},
3262306a36Sopenharmony_ci	{33, 121, 4, 2},
3362306a36Sopenharmony_ci	{91, 118, 5, 2},
3462306a36Sopenharmony_ci	{83, 109, 6, 2},
3562306a36Sopenharmony_ci	{90, 90, 7, 2},
3662306a36Sopenharmony_ci	{93, 93, 2, 3},
3762306a36Sopenharmony_ci	{53, 53, 3, 3},
3862306a36Sopenharmony_ci	{73, 117, 4, 3},
3962306a36Sopenharmony_ci	{101, 127, 5, 3},
4062306a36Sopenharmony_ci	{99, 99, 7, 3}
4162306a36Sopenharmony_ci};
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistatic struct pll_limit k800_pll_limits[] = {
4462306a36Sopenharmony_ci	{22, 22, 2, 0},
4562306a36Sopenharmony_ci	{28, 28, 3, 0},
4662306a36Sopenharmony_ci	{81, 112, 3, 1},
4762306a36Sopenharmony_ci	{86, 166, 4, 1},
4862306a36Sopenharmony_ci	{109, 153, 5, 1},
4962306a36Sopenharmony_ci	{66, 116, 3, 2},
5062306a36Sopenharmony_ci	{93, 137, 4, 2},
5162306a36Sopenharmony_ci	{117, 208, 5, 2},
5262306a36Sopenharmony_ci	{30, 30, 2, 3},
5362306a36Sopenharmony_ci	{69, 125, 3, 3},
5462306a36Sopenharmony_ci	{89, 161, 4, 3},
5562306a36Sopenharmony_ci	{121, 208, 5, 3},
5662306a36Sopenharmony_ci	{66, 66, 2, 4},
5762306a36Sopenharmony_ci	{85, 85, 3, 4},
5862306a36Sopenharmony_ci	{141, 161, 4, 4},
5962306a36Sopenharmony_ci	{177, 177, 5, 4}
6062306a36Sopenharmony_ci};
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_cistatic struct pll_limit cx700_pll_limits[] = {
6362306a36Sopenharmony_ci	{98, 98, 3, 1},
6462306a36Sopenharmony_ci	{86, 86, 4, 1},
6562306a36Sopenharmony_ci	{109, 208, 5, 1},
6662306a36Sopenharmony_ci	{68, 68, 2, 2},
6762306a36Sopenharmony_ci	{95, 116, 3, 2},
6862306a36Sopenharmony_ci	{93, 166, 4, 2},
6962306a36Sopenharmony_ci	{110, 206, 5, 2},
7062306a36Sopenharmony_ci	{174, 174, 7, 2},
7162306a36Sopenharmony_ci	{82, 109, 3, 3},
7262306a36Sopenharmony_ci	{117, 161, 4, 3},
7362306a36Sopenharmony_ci	{112, 208, 5, 3},
7462306a36Sopenharmony_ci	{141, 202, 5, 4}
7562306a36Sopenharmony_ci};
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_cistatic struct pll_limit vx855_pll_limits[] = {
7862306a36Sopenharmony_ci	{86, 86, 4, 1},
7962306a36Sopenharmony_ci	{108, 208, 5, 1},
8062306a36Sopenharmony_ci	{110, 208, 5, 2},
8162306a36Sopenharmony_ci	{83, 112, 3, 3},
8262306a36Sopenharmony_ci	{103, 161, 4, 3},
8362306a36Sopenharmony_ci	{112, 209, 5, 3},
8462306a36Sopenharmony_ci	{142, 161, 4, 4},
8562306a36Sopenharmony_ci	{141, 176, 5, 4}
8662306a36Sopenharmony_ci};
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci/* according to VIA Technologies these values are based on experiment */
8962306a36Sopenharmony_cistatic struct io_reg scaling_parameters[] = {
9062306a36Sopenharmony_ci	{VIACR, CR7A, 0xFF, 0x01},	/* LCD Scaling Parameter 1 */
9162306a36Sopenharmony_ci	{VIACR, CR7B, 0xFF, 0x02},	/* LCD Scaling Parameter 2 */
9262306a36Sopenharmony_ci	{VIACR, CR7C, 0xFF, 0x03},	/* LCD Scaling Parameter 3 */
9362306a36Sopenharmony_ci	{VIACR, CR7D, 0xFF, 0x04},	/* LCD Scaling Parameter 4 */
9462306a36Sopenharmony_ci	{VIACR, CR7E, 0xFF, 0x07},	/* LCD Scaling Parameter 5 */
9562306a36Sopenharmony_ci	{VIACR, CR7F, 0xFF, 0x0A},	/* LCD Scaling Parameter 6 */
9662306a36Sopenharmony_ci	{VIACR, CR80, 0xFF, 0x0D},	/* LCD Scaling Parameter 7 */
9762306a36Sopenharmony_ci	{VIACR, CR81, 0xFF, 0x13},	/* LCD Scaling Parameter 8 */
9862306a36Sopenharmony_ci	{VIACR, CR82, 0xFF, 0x16},	/* LCD Scaling Parameter 9 */
9962306a36Sopenharmony_ci	{VIACR, CR83, 0xFF, 0x19},	/* LCD Scaling Parameter 10 */
10062306a36Sopenharmony_ci	{VIACR, CR84, 0xFF, 0x1C},	/* LCD Scaling Parameter 11 */
10162306a36Sopenharmony_ci	{VIACR, CR85, 0xFF, 0x1D},	/* LCD Scaling Parameter 12 */
10262306a36Sopenharmony_ci	{VIACR, CR86, 0xFF, 0x1E},	/* LCD Scaling Parameter 13 */
10362306a36Sopenharmony_ci	{VIACR, CR87, 0xFF, 0x1F},	/* LCD Scaling Parameter 14 */
10462306a36Sopenharmony_ci};
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_cistatic struct io_reg common_vga[] = {
10762306a36Sopenharmony_ci	{VIACR, CR07, 0x10, 0x10}, /* [0] vertical total (bit 8)
10862306a36Sopenharmony_ci					[1] vertical display end (bit 8)
10962306a36Sopenharmony_ci					[2] vertical retrace start (bit 8)
11062306a36Sopenharmony_ci					[3] start vertical blanking (bit 8)
11162306a36Sopenharmony_ci					[4] line compare (bit 8)
11262306a36Sopenharmony_ci					[5] vertical total (bit 9)
11362306a36Sopenharmony_ci					[6] vertical display end (bit 9)
11462306a36Sopenharmony_ci					[7] vertical retrace start (bit 9) */
11562306a36Sopenharmony_ci	{VIACR, CR08, 0xFF, 0x00}, /* [0-4] preset row scan
11662306a36Sopenharmony_ci					[5-6] byte panning */
11762306a36Sopenharmony_ci	{VIACR, CR09, 0xDF, 0x40}, /* [0-4] max scan line
11862306a36Sopenharmony_ci					[5] start vertical blanking (bit 9)
11962306a36Sopenharmony_ci					[6] line compare (bit 9)
12062306a36Sopenharmony_ci					[7] scan doubling */
12162306a36Sopenharmony_ci	{VIACR, CR0A, 0xFF, 0x1E}, /* [0-4] cursor start
12262306a36Sopenharmony_ci					[5] cursor disable */
12362306a36Sopenharmony_ci	{VIACR, CR0B, 0xFF, 0x00}, /* [0-4] cursor end
12462306a36Sopenharmony_ci					[5-6] cursor skew */
12562306a36Sopenharmony_ci	{VIACR, CR0E, 0xFF, 0x00}, /* [0-7] cursor location (high) */
12662306a36Sopenharmony_ci	{VIACR, CR0F, 0xFF, 0x00}, /* [0-7] cursor location (low) */
12762306a36Sopenharmony_ci	{VIACR, CR11, 0xF0, 0x80}, /* [0-3] vertical retrace end
12862306a36Sopenharmony_ci					[6] memory refresh bandwidth
12962306a36Sopenharmony_ci					[7] CRTC register protect enable */
13062306a36Sopenharmony_ci	{VIACR, CR14, 0xFF, 0x00}, /* [0-4] underline location
13162306a36Sopenharmony_ci					[5] divide memory address clock by 4
13262306a36Sopenharmony_ci					[6] double word addressing */
13362306a36Sopenharmony_ci	{VIACR, CR17, 0xFF, 0x63}, /* [0-1] mapping of display address 13-14
13462306a36Sopenharmony_ci					[2] divide scan line clock by 2
13562306a36Sopenharmony_ci					[3] divide memory address clock by 2
13662306a36Sopenharmony_ci					[5] address wrap
13762306a36Sopenharmony_ci					[6] byte mode select
13862306a36Sopenharmony_ci					[7] sync enable */
13962306a36Sopenharmony_ci	{VIACR, CR18, 0xFF, 0xFF}, /* [0-7] line compare */
14062306a36Sopenharmony_ci};
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_cistatic struct fifo_depth_select display_fifo_depth_reg = {
14362306a36Sopenharmony_ci	/* IGA1 FIFO Depth_Select */
14462306a36Sopenharmony_ci	{IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } },
14562306a36Sopenharmony_ci	/* IGA2 FIFO Depth_Select */
14662306a36Sopenharmony_ci	{IGA2_FIFO_DEPTH_SELECT_REG_NUM,
14762306a36Sopenharmony_ci	 {{CR68, 4, 7}, {CR94, 7, 7}, {CR95, 7, 7} } }
14862306a36Sopenharmony_ci};
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_cistatic struct fifo_threshold_select fifo_threshold_select_reg = {
15162306a36Sopenharmony_ci	/* IGA1 FIFO Threshold Select */
15262306a36Sopenharmony_ci	{IGA1_FIFO_THRESHOLD_REG_NUM, {{SR16, 0, 5}, {SR16, 7, 7} } },
15362306a36Sopenharmony_ci	/* IGA2 FIFO Threshold Select */
15462306a36Sopenharmony_ci	{IGA2_FIFO_THRESHOLD_REG_NUM, {{CR68, 0, 3}, {CR95, 4, 6} } }
15562306a36Sopenharmony_ci};
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_cistatic struct fifo_high_threshold_select fifo_high_threshold_select_reg = {
15862306a36Sopenharmony_ci	/* IGA1 FIFO High Threshold Select */
15962306a36Sopenharmony_ci	{IGA1_FIFO_HIGH_THRESHOLD_REG_NUM, {{SR18, 0, 5}, {SR18, 7, 7} } },
16062306a36Sopenharmony_ci	/* IGA2 FIFO High Threshold Select */
16162306a36Sopenharmony_ci	{IGA2_FIFO_HIGH_THRESHOLD_REG_NUM, {{CR92, 0, 3}, {CR95, 0, 2} } }
16262306a36Sopenharmony_ci};
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_cistatic struct display_queue_expire_num display_queue_expire_num_reg = {
16562306a36Sopenharmony_ci	/* IGA1 Display Queue Expire Num */
16662306a36Sopenharmony_ci	{IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{SR22, 0, 4} } },
16762306a36Sopenharmony_ci	/* IGA2 Display Queue Expire Num */
16862306a36Sopenharmony_ci	{IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{CR94, 0, 6} } }
16962306a36Sopenharmony_ci};
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci/* Definition Fetch Count Registers*/
17262306a36Sopenharmony_cistatic struct fetch_count fetch_count_reg = {
17362306a36Sopenharmony_ci	/* IGA1 Fetch Count Register */
17462306a36Sopenharmony_ci	{IGA1_FETCH_COUNT_REG_NUM, {{SR1C, 0, 7}, {SR1D, 0, 1} } },
17562306a36Sopenharmony_ci	/* IGA2 Fetch Count Register */
17662306a36Sopenharmony_ci	{IGA2_FETCH_COUNT_REG_NUM, {{CR65, 0, 7}, {CR67, 2, 3} } }
17762306a36Sopenharmony_ci};
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_cistatic struct rgbLUT palLUT_table[] = {
18062306a36Sopenharmony_ci	/* {R,G,B} */
18162306a36Sopenharmony_ci	/* Index 0x00~0x03 */
18262306a36Sopenharmony_ci	{0x00, 0x00, 0x00}, {0x00, 0x00, 0x2A}, {0x00, 0x2A, 0x00}, {0x00,
18362306a36Sopenharmony_ci								     0x2A,
18462306a36Sopenharmony_ci								     0x2A},
18562306a36Sopenharmony_ci	/* Index 0x04~0x07 */
18662306a36Sopenharmony_ci	{0x2A, 0x00, 0x00}, {0x2A, 0x00, 0x2A}, {0x2A, 0x15, 0x00}, {0x2A,
18762306a36Sopenharmony_ci								     0x2A,
18862306a36Sopenharmony_ci								     0x2A},
18962306a36Sopenharmony_ci	/* Index 0x08~0x0B */
19062306a36Sopenharmony_ci	{0x15, 0x15, 0x15}, {0x15, 0x15, 0x3F}, {0x15, 0x3F, 0x15}, {0x15,
19162306a36Sopenharmony_ci								     0x3F,
19262306a36Sopenharmony_ci								     0x3F},
19362306a36Sopenharmony_ci	/* Index 0x0C~0x0F */
19462306a36Sopenharmony_ci	{0x3F, 0x15, 0x15}, {0x3F, 0x15, 0x3F}, {0x3F, 0x3F, 0x15}, {0x3F,
19562306a36Sopenharmony_ci								     0x3F,
19662306a36Sopenharmony_ci								     0x3F},
19762306a36Sopenharmony_ci	/* Index 0x10~0x13 */
19862306a36Sopenharmony_ci	{0x00, 0x00, 0x00}, {0x05, 0x05, 0x05}, {0x08, 0x08, 0x08}, {0x0B,
19962306a36Sopenharmony_ci								     0x0B,
20062306a36Sopenharmony_ci								     0x0B},
20162306a36Sopenharmony_ci	/* Index 0x14~0x17 */
20262306a36Sopenharmony_ci	{0x0E, 0x0E, 0x0E}, {0x11, 0x11, 0x11}, {0x14, 0x14, 0x14}, {0x18,
20362306a36Sopenharmony_ci								     0x18,
20462306a36Sopenharmony_ci								     0x18},
20562306a36Sopenharmony_ci	/* Index 0x18~0x1B */
20662306a36Sopenharmony_ci	{0x1C, 0x1C, 0x1C}, {0x20, 0x20, 0x20}, {0x24, 0x24, 0x24}, {0x28,
20762306a36Sopenharmony_ci								     0x28,
20862306a36Sopenharmony_ci								     0x28},
20962306a36Sopenharmony_ci	/* Index 0x1C~0x1F */
21062306a36Sopenharmony_ci	{0x2D, 0x2D, 0x2D}, {0x32, 0x32, 0x32}, {0x38, 0x38, 0x38}, {0x3F,
21162306a36Sopenharmony_ci								     0x3F,
21262306a36Sopenharmony_ci								     0x3F},
21362306a36Sopenharmony_ci	/* Index 0x20~0x23 */
21462306a36Sopenharmony_ci	{0x00, 0x00, 0x3F}, {0x10, 0x00, 0x3F}, {0x1F, 0x00, 0x3F}, {0x2F,
21562306a36Sopenharmony_ci								     0x00,
21662306a36Sopenharmony_ci								     0x3F},
21762306a36Sopenharmony_ci	/* Index 0x24~0x27 */
21862306a36Sopenharmony_ci	{0x3F, 0x00, 0x3F}, {0x3F, 0x00, 0x2F}, {0x3F, 0x00, 0x1F}, {0x3F,
21962306a36Sopenharmony_ci								     0x00,
22062306a36Sopenharmony_ci								     0x10},
22162306a36Sopenharmony_ci	/* Index 0x28~0x2B */
22262306a36Sopenharmony_ci	{0x3F, 0x00, 0x00}, {0x3F, 0x10, 0x00}, {0x3F, 0x1F, 0x00}, {0x3F,
22362306a36Sopenharmony_ci								     0x2F,
22462306a36Sopenharmony_ci								     0x00},
22562306a36Sopenharmony_ci	/* Index 0x2C~0x2F */
22662306a36Sopenharmony_ci	{0x3F, 0x3F, 0x00}, {0x2F, 0x3F, 0x00}, {0x1F, 0x3F, 0x00}, {0x10,
22762306a36Sopenharmony_ci								     0x3F,
22862306a36Sopenharmony_ci								     0x00},
22962306a36Sopenharmony_ci	/* Index 0x30~0x33 */
23062306a36Sopenharmony_ci	{0x00, 0x3F, 0x00}, {0x00, 0x3F, 0x10}, {0x00, 0x3F, 0x1F}, {0x00,
23162306a36Sopenharmony_ci								     0x3F,
23262306a36Sopenharmony_ci								     0x2F},
23362306a36Sopenharmony_ci	/* Index 0x34~0x37 */
23462306a36Sopenharmony_ci	{0x00, 0x3F, 0x3F}, {0x00, 0x2F, 0x3F}, {0x00, 0x1F, 0x3F}, {0x00,
23562306a36Sopenharmony_ci								     0x10,
23662306a36Sopenharmony_ci								     0x3F},
23762306a36Sopenharmony_ci	/* Index 0x38~0x3B */
23862306a36Sopenharmony_ci	{0x1F, 0x1F, 0x3F}, {0x27, 0x1F, 0x3F}, {0x2F, 0x1F, 0x3F}, {0x37,
23962306a36Sopenharmony_ci								     0x1F,
24062306a36Sopenharmony_ci								     0x3F},
24162306a36Sopenharmony_ci	/* Index 0x3C~0x3F */
24262306a36Sopenharmony_ci	{0x3F, 0x1F, 0x3F}, {0x3F, 0x1F, 0x37}, {0x3F, 0x1F, 0x2F}, {0x3F,
24362306a36Sopenharmony_ci								     0x1F,
24462306a36Sopenharmony_ci								     0x27},
24562306a36Sopenharmony_ci	/* Index 0x40~0x43 */
24662306a36Sopenharmony_ci	{0x3F, 0x1F, 0x1F}, {0x3F, 0x27, 0x1F}, {0x3F, 0x2F, 0x1F}, {0x3F,
24762306a36Sopenharmony_ci								     0x3F,
24862306a36Sopenharmony_ci								     0x1F},
24962306a36Sopenharmony_ci	/* Index 0x44~0x47 */
25062306a36Sopenharmony_ci	{0x3F, 0x3F, 0x1F}, {0x37, 0x3F, 0x1F}, {0x2F, 0x3F, 0x1F}, {0x27,
25162306a36Sopenharmony_ci								     0x3F,
25262306a36Sopenharmony_ci								     0x1F},
25362306a36Sopenharmony_ci	/* Index 0x48~0x4B */
25462306a36Sopenharmony_ci	{0x1F, 0x3F, 0x1F}, {0x1F, 0x3F, 0x27}, {0x1F, 0x3F, 0x2F}, {0x1F,
25562306a36Sopenharmony_ci								     0x3F,
25662306a36Sopenharmony_ci								     0x37},
25762306a36Sopenharmony_ci	/* Index 0x4C~0x4F */
25862306a36Sopenharmony_ci	{0x1F, 0x3F, 0x3F}, {0x1F, 0x37, 0x3F}, {0x1F, 0x2F, 0x3F}, {0x1F,
25962306a36Sopenharmony_ci								     0x27,
26062306a36Sopenharmony_ci								     0x3F},
26162306a36Sopenharmony_ci	/* Index 0x50~0x53 */
26262306a36Sopenharmony_ci	{0x2D, 0x2D, 0x3F}, {0x31, 0x2D, 0x3F}, {0x36, 0x2D, 0x3F}, {0x3A,
26362306a36Sopenharmony_ci								     0x2D,
26462306a36Sopenharmony_ci								     0x3F},
26562306a36Sopenharmony_ci	/* Index 0x54~0x57 */
26662306a36Sopenharmony_ci	{0x3F, 0x2D, 0x3F}, {0x3F, 0x2D, 0x3A}, {0x3F, 0x2D, 0x36}, {0x3F,
26762306a36Sopenharmony_ci								     0x2D,
26862306a36Sopenharmony_ci								     0x31},
26962306a36Sopenharmony_ci	/* Index 0x58~0x5B */
27062306a36Sopenharmony_ci	{0x3F, 0x2D, 0x2D}, {0x3F, 0x31, 0x2D}, {0x3F, 0x36, 0x2D}, {0x3F,
27162306a36Sopenharmony_ci								     0x3A,
27262306a36Sopenharmony_ci								     0x2D},
27362306a36Sopenharmony_ci	/* Index 0x5C~0x5F */
27462306a36Sopenharmony_ci	{0x3F, 0x3F, 0x2D}, {0x3A, 0x3F, 0x2D}, {0x36, 0x3F, 0x2D}, {0x31,
27562306a36Sopenharmony_ci								     0x3F,
27662306a36Sopenharmony_ci								     0x2D},
27762306a36Sopenharmony_ci	/* Index 0x60~0x63 */
27862306a36Sopenharmony_ci	{0x2D, 0x3F, 0x2D}, {0x2D, 0x3F, 0x31}, {0x2D, 0x3F, 0x36}, {0x2D,
27962306a36Sopenharmony_ci								     0x3F,
28062306a36Sopenharmony_ci								     0x3A},
28162306a36Sopenharmony_ci	/* Index 0x64~0x67 */
28262306a36Sopenharmony_ci	{0x2D, 0x3F, 0x3F}, {0x2D, 0x3A, 0x3F}, {0x2D, 0x36, 0x3F}, {0x2D,
28362306a36Sopenharmony_ci								     0x31,
28462306a36Sopenharmony_ci								     0x3F},
28562306a36Sopenharmony_ci	/* Index 0x68~0x6B */
28662306a36Sopenharmony_ci	{0x00, 0x00, 0x1C}, {0x07, 0x00, 0x1C}, {0x0E, 0x00, 0x1C}, {0x15,
28762306a36Sopenharmony_ci								     0x00,
28862306a36Sopenharmony_ci								     0x1C},
28962306a36Sopenharmony_ci	/* Index 0x6C~0x6F */
29062306a36Sopenharmony_ci	{0x1C, 0x00, 0x1C}, {0x1C, 0x00, 0x15}, {0x1C, 0x00, 0x0E}, {0x1C,
29162306a36Sopenharmony_ci								     0x00,
29262306a36Sopenharmony_ci								     0x07},
29362306a36Sopenharmony_ci	/* Index 0x70~0x73 */
29462306a36Sopenharmony_ci	{0x1C, 0x00, 0x00}, {0x1C, 0x07, 0x00}, {0x1C, 0x0E, 0x00}, {0x1C,
29562306a36Sopenharmony_ci								     0x15,
29662306a36Sopenharmony_ci								     0x00},
29762306a36Sopenharmony_ci	/* Index 0x74~0x77 */
29862306a36Sopenharmony_ci	{0x1C, 0x1C, 0x00}, {0x15, 0x1C, 0x00}, {0x0E, 0x1C, 0x00}, {0x07,
29962306a36Sopenharmony_ci								     0x1C,
30062306a36Sopenharmony_ci								     0x00},
30162306a36Sopenharmony_ci	/* Index 0x78~0x7B */
30262306a36Sopenharmony_ci	{0x00, 0x1C, 0x00}, {0x00, 0x1C, 0x07}, {0x00, 0x1C, 0x0E}, {0x00,
30362306a36Sopenharmony_ci								     0x1C,
30462306a36Sopenharmony_ci								     0x15},
30562306a36Sopenharmony_ci	/* Index 0x7C~0x7F */
30662306a36Sopenharmony_ci	{0x00, 0x1C, 0x1C}, {0x00, 0x15, 0x1C}, {0x00, 0x0E, 0x1C}, {0x00,
30762306a36Sopenharmony_ci								     0x07,
30862306a36Sopenharmony_ci								     0x1C},
30962306a36Sopenharmony_ci	/* Index 0x80~0x83 */
31062306a36Sopenharmony_ci	{0x0E, 0x0E, 0x1C}, {0x11, 0x0E, 0x1C}, {0x15, 0x0E, 0x1C}, {0x18,
31162306a36Sopenharmony_ci								     0x0E,
31262306a36Sopenharmony_ci								     0x1C},
31362306a36Sopenharmony_ci	/* Index 0x84~0x87 */
31462306a36Sopenharmony_ci	{0x1C, 0x0E, 0x1C}, {0x1C, 0x0E, 0x18}, {0x1C, 0x0E, 0x15}, {0x1C,
31562306a36Sopenharmony_ci								     0x0E,
31662306a36Sopenharmony_ci								     0x11},
31762306a36Sopenharmony_ci	/* Index 0x88~0x8B */
31862306a36Sopenharmony_ci	{0x1C, 0x0E, 0x0E}, {0x1C, 0x11, 0x0E}, {0x1C, 0x15, 0x0E}, {0x1C,
31962306a36Sopenharmony_ci								     0x18,
32062306a36Sopenharmony_ci								     0x0E},
32162306a36Sopenharmony_ci	/* Index 0x8C~0x8F */
32262306a36Sopenharmony_ci	{0x1C, 0x1C, 0x0E}, {0x18, 0x1C, 0x0E}, {0x15, 0x1C, 0x0E}, {0x11,
32362306a36Sopenharmony_ci								     0x1C,
32462306a36Sopenharmony_ci								     0x0E},
32562306a36Sopenharmony_ci	/* Index 0x90~0x93 */
32662306a36Sopenharmony_ci	{0x0E, 0x1C, 0x0E}, {0x0E, 0x1C, 0x11}, {0x0E, 0x1C, 0x15}, {0x0E,
32762306a36Sopenharmony_ci								     0x1C,
32862306a36Sopenharmony_ci								     0x18},
32962306a36Sopenharmony_ci	/* Index 0x94~0x97 */
33062306a36Sopenharmony_ci	{0x0E, 0x1C, 0x1C}, {0x0E, 0x18, 0x1C}, {0x0E, 0x15, 0x1C}, {0x0E,
33162306a36Sopenharmony_ci								     0x11,
33262306a36Sopenharmony_ci								     0x1C},
33362306a36Sopenharmony_ci	/* Index 0x98~0x9B */
33462306a36Sopenharmony_ci	{0x14, 0x14, 0x1C}, {0x16, 0x14, 0x1C}, {0x18, 0x14, 0x1C}, {0x1A,
33562306a36Sopenharmony_ci								     0x14,
33662306a36Sopenharmony_ci								     0x1C},
33762306a36Sopenharmony_ci	/* Index 0x9C~0x9F */
33862306a36Sopenharmony_ci	{0x1C, 0x14, 0x1C}, {0x1C, 0x14, 0x1A}, {0x1C, 0x14, 0x18}, {0x1C,
33962306a36Sopenharmony_ci								     0x14,
34062306a36Sopenharmony_ci								     0x16},
34162306a36Sopenharmony_ci	/* Index 0xA0~0xA3 */
34262306a36Sopenharmony_ci	{0x1C, 0x14, 0x14}, {0x1C, 0x16, 0x14}, {0x1C, 0x18, 0x14}, {0x1C,
34362306a36Sopenharmony_ci								     0x1A,
34462306a36Sopenharmony_ci								     0x14},
34562306a36Sopenharmony_ci	/* Index 0xA4~0xA7 */
34662306a36Sopenharmony_ci	{0x1C, 0x1C, 0x14}, {0x1A, 0x1C, 0x14}, {0x18, 0x1C, 0x14}, {0x16,
34762306a36Sopenharmony_ci								     0x1C,
34862306a36Sopenharmony_ci								     0x14},
34962306a36Sopenharmony_ci	/* Index 0xA8~0xAB */
35062306a36Sopenharmony_ci	{0x14, 0x1C, 0x14}, {0x14, 0x1C, 0x16}, {0x14, 0x1C, 0x18}, {0x14,
35162306a36Sopenharmony_ci								     0x1C,
35262306a36Sopenharmony_ci								     0x1A},
35362306a36Sopenharmony_ci	/* Index 0xAC~0xAF */
35462306a36Sopenharmony_ci	{0x14, 0x1C, 0x1C}, {0x14, 0x1A, 0x1C}, {0x14, 0x18, 0x1C}, {0x14,
35562306a36Sopenharmony_ci								     0x16,
35662306a36Sopenharmony_ci								     0x1C},
35762306a36Sopenharmony_ci	/* Index 0xB0~0xB3 */
35862306a36Sopenharmony_ci	{0x00, 0x00, 0x10}, {0x04, 0x00, 0x10}, {0x08, 0x00, 0x10}, {0x0C,
35962306a36Sopenharmony_ci								     0x00,
36062306a36Sopenharmony_ci								     0x10},
36162306a36Sopenharmony_ci	/* Index 0xB4~0xB7 */
36262306a36Sopenharmony_ci	{0x10, 0x00, 0x10}, {0x10, 0x00, 0x0C}, {0x10, 0x00, 0x08}, {0x10,
36362306a36Sopenharmony_ci								     0x00,
36462306a36Sopenharmony_ci								     0x04},
36562306a36Sopenharmony_ci	/* Index 0xB8~0xBB */
36662306a36Sopenharmony_ci	{0x10, 0x00, 0x00}, {0x10, 0x04, 0x00}, {0x10, 0x08, 0x00}, {0x10,
36762306a36Sopenharmony_ci								     0x0C,
36862306a36Sopenharmony_ci								     0x00},
36962306a36Sopenharmony_ci	/* Index 0xBC~0xBF */
37062306a36Sopenharmony_ci	{0x10, 0x10, 0x00}, {0x0C, 0x10, 0x00}, {0x08, 0x10, 0x00}, {0x04,
37162306a36Sopenharmony_ci								     0x10,
37262306a36Sopenharmony_ci								     0x00},
37362306a36Sopenharmony_ci	/* Index 0xC0~0xC3 */
37462306a36Sopenharmony_ci	{0x00, 0x10, 0x00}, {0x00, 0x10, 0x04}, {0x00, 0x10, 0x08}, {0x00,
37562306a36Sopenharmony_ci								     0x10,
37662306a36Sopenharmony_ci								     0x0C},
37762306a36Sopenharmony_ci	/* Index 0xC4~0xC7 */
37862306a36Sopenharmony_ci	{0x00, 0x10, 0x10}, {0x00, 0x0C, 0x10}, {0x00, 0x08, 0x10}, {0x00,
37962306a36Sopenharmony_ci								     0x04,
38062306a36Sopenharmony_ci								     0x10},
38162306a36Sopenharmony_ci	/* Index 0xC8~0xCB */
38262306a36Sopenharmony_ci	{0x08, 0x08, 0x10}, {0x0A, 0x08, 0x10}, {0x0C, 0x08, 0x10}, {0x0E,
38362306a36Sopenharmony_ci								     0x08,
38462306a36Sopenharmony_ci								     0x10},
38562306a36Sopenharmony_ci	/* Index 0xCC~0xCF */
38662306a36Sopenharmony_ci	{0x10, 0x08, 0x10}, {0x10, 0x08, 0x0E}, {0x10, 0x08, 0x0C}, {0x10,
38762306a36Sopenharmony_ci								     0x08,
38862306a36Sopenharmony_ci								     0x0A},
38962306a36Sopenharmony_ci	/* Index 0xD0~0xD3 */
39062306a36Sopenharmony_ci	{0x10, 0x08, 0x08}, {0x10, 0x0A, 0x08}, {0x10, 0x0C, 0x08}, {0x10,
39162306a36Sopenharmony_ci								     0x0E,
39262306a36Sopenharmony_ci								     0x08},
39362306a36Sopenharmony_ci	/* Index 0xD4~0xD7 */
39462306a36Sopenharmony_ci	{0x10, 0x10, 0x08}, {0x0E, 0x10, 0x08}, {0x0C, 0x10, 0x08}, {0x0A,
39562306a36Sopenharmony_ci								     0x10,
39662306a36Sopenharmony_ci								     0x08},
39762306a36Sopenharmony_ci	/* Index 0xD8~0xDB */
39862306a36Sopenharmony_ci	{0x08, 0x10, 0x08}, {0x08, 0x10, 0x0A}, {0x08, 0x10, 0x0C}, {0x08,
39962306a36Sopenharmony_ci								     0x10,
40062306a36Sopenharmony_ci								     0x0E},
40162306a36Sopenharmony_ci	/* Index 0xDC~0xDF */
40262306a36Sopenharmony_ci	{0x08, 0x10, 0x10}, {0x08, 0x0E, 0x10}, {0x08, 0x0C, 0x10}, {0x08,
40362306a36Sopenharmony_ci								     0x0A,
40462306a36Sopenharmony_ci								     0x10},
40562306a36Sopenharmony_ci	/* Index 0xE0~0xE3 */
40662306a36Sopenharmony_ci	{0x0B, 0x0B, 0x10}, {0x0C, 0x0B, 0x10}, {0x0D, 0x0B, 0x10}, {0x0F,
40762306a36Sopenharmony_ci								     0x0B,
40862306a36Sopenharmony_ci								     0x10},
40962306a36Sopenharmony_ci	/* Index 0xE4~0xE7 */
41062306a36Sopenharmony_ci	{0x10, 0x0B, 0x10}, {0x10, 0x0B, 0x0F}, {0x10, 0x0B, 0x0D}, {0x10,
41162306a36Sopenharmony_ci								     0x0B,
41262306a36Sopenharmony_ci								     0x0C},
41362306a36Sopenharmony_ci	/* Index 0xE8~0xEB */
41462306a36Sopenharmony_ci	{0x10, 0x0B, 0x0B}, {0x10, 0x0C, 0x0B}, {0x10, 0x0D, 0x0B}, {0x10,
41562306a36Sopenharmony_ci								     0x0F,
41662306a36Sopenharmony_ci								     0x0B},
41762306a36Sopenharmony_ci	/* Index 0xEC~0xEF */
41862306a36Sopenharmony_ci	{0x10, 0x10, 0x0B}, {0x0F, 0x10, 0x0B}, {0x0D, 0x10, 0x0B}, {0x0C,
41962306a36Sopenharmony_ci								     0x10,
42062306a36Sopenharmony_ci								     0x0B},
42162306a36Sopenharmony_ci	/* Index 0xF0~0xF3 */
42262306a36Sopenharmony_ci	{0x0B, 0x10, 0x0B}, {0x0B, 0x10, 0x0C}, {0x0B, 0x10, 0x0D}, {0x0B,
42362306a36Sopenharmony_ci								     0x10,
42462306a36Sopenharmony_ci								     0x0F},
42562306a36Sopenharmony_ci	/* Index 0xF4~0xF7 */
42662306a36Sopenharmony_ci	{0x0B, 0x10, 0x10}, {0x0B, 0x0F, 0x10}, {0x0B, 0x0D, 0x10}, {0x0B,
42762306a36Sopenharmony_ci								     0x0C,
42862306a36Sopenharmony_ci								     0x10},
42962306a36Sopenharmony_ci	/* Index 0xF8~0xFB */
43062306a36Sopenharmony_ci	{0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
43162306a36Sopenharmony_ci								     0x00,
43262306a36Sopenharmony_ci								     0x00},
43362306a36Sopenharmony_ci	/* Index 0xFC~0xFF */
43462306a36Sopenharmony_ci	{0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
43562306a36Sopenharmony_ci								     0x00,
43662306a36Sopenharmony_ci								     0x00}
43762306a36Sopenharmony_ci};
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_cistatic struct via_device_mapping device_mapping[] = {
44062306a36Sopenharmony_ci	{VIA_LDVP0, "LDVP0"},
44162306a36Sopenharmony_ci	{VIA_LDVP1, "LDVP1"},
44262306a36Sopenharmony_ci	{VIA_DVP0, "DVP0"},
44362306a36Sopenharmony_ci	{VIA_CRT, "CRT"},
44462306a36Sopenharmony_ci	{VIA_DVP1, "DVP1"},
44562306a36Sopenharmony_ci	{VIA_LVDS1, "LVDS1"},
44662306a36Sopenharmony_ci	{VIA_LVDS2, "LVDS2"}
44762306a36Sopenharmony_ci};
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci/* structure with function pointers to support clock control */
45062306a36Sopenharmony_cistatic struct via_clock clock;
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_cistatic void load_fix_bit_crtc_reg(void);
45362306a36Sopenharmony_cistatic void init_gfx_chip_info(int chip_type);
45462306a36Sopenharmony_cistatic void init_tmds_chip_info(void);
45562306a36Sopenharmony_cistatic void init_lvds_chip_info(void);
45662306a36Sopenharmony_cistatic void device_screen_off(void);
45762306a36Sopenharmony_cistatic void device_screen_on(void);
45862306a36Sopenharmony_cistatic void set_display_channel(void);
45962306a36Sopenharmony_cistatic void device_off(void);
46062306a36Sopenharmony_cistatic void device_on(void);
46162306a36Sopenharmony_cistatic void enable_second_display_channel(void);
46262306a36Sopenharmony_cistatic void disable_second_display_channel(void);
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_civoid viafb_lock_crt(void)
46562306a36Sopenharmony_ci{
46662306a36Sopenharmony_ci	viafb_write_reg_mask(CR11, VIACR, BIT7, BIT7);
46762306a36Sopenharmony_ci}
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_civoid viafb_unlock_crt(void)
47062306a36Sopenharmony_ci{
47162306a36Sopenharmony_ci	viafb_write_reg_mask(CR11, VIACR, 0, BIT7);
47262306a36Sopenharmony_ci	viafb_write_reg_mask(CR47, VIACR, 0, BIT0);
47362306a36Sopenharmony_ci}
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_cistatic void write_dac_reg(u8 index, u8 r, u8 g, u8 b)
47662306a36Sopenharmony_ci{
47762306a36Sopenharmony_ci	outb(index, LUT_INDEX_WRITE);
47862306a36Sopenharmony_ci	outb(r, LUT_DATA);
47962306a36Sopenharmony_ci	outb(g, LUT_DATA);
48062306a36Sopenharmony_ci	outb(b, LUT_DATA);
48162306a36Sopenharmony_ci}
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_cistatic u32 get_dvi_devices(int output_interface)
48462306a36Sopenharmony_ci{
48562306a36Sopenharmony_ci	switch (output_interface) {
48662306a36Sopenharmony_ci	case INTERFACE_DVP0:
48762306a36Sopenharmony_ci		return VIA_DVP0 | VIA_LDVP0;
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci	case INTERFACE_DVP1:
49062306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
49162306a36Sopenharmony_ci			return VIA_LDVP1;
49262306a36Sopenharmony_ci		else
49362306a36Sopenharmony_ci			return VIA_DVP1;
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	case INTERFACE_DFP_HIGH:
49662306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
49762306a36Sopenharmony_ci			return 0;
49862306a36Sopenharmony_ci		else
49962306a36Sopenharmony_ci			return VIA_LVDS2 | VIA_DVP0;
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_ci	case INTERFACE_DFP_LOW:
50262306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
50362306a36Sopenharmony_ci			return 0;
50462306a36Sopenharmony_ci		else
50562306a36Sopenharmony_ci			return VIA_DVP1 | VIA_LVDS1;
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci	case INTERFACE_TMDS:
50862306a36Sopenharmony_ci		return VIA_LVDS1;
50962306a36Sopenharmony_ci	}
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci	return 0;
51262306a36Sopenharmony_ci}
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_cistatic u32 get_lcd_devices(int output_interface)
51562306a36Sopenharmony_ci{
51662306a36Sopenharmony_ci	switch (output_interface) {
51762306a36Sopenharmony_ci	case INTERFACE_DVP0:
51862306a36Sopenharmony_ci		return VIA_DVP0;
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci	case INTERFACE_DVP1:
52162306a36Sopenharmony_ci		return VIA_DVP1;
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_ci	case INTERFACE_DFP_HIGH:
52462306a36Sopenharmony_ci		return VIA_LVDS2 | VIA_DVP0;
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci	case INTERFACE_DFP_LOW:
52762306a36Sopenharmony_ci		return VIA_LVDS1 | VIA_DVP1;
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_ci	case INTERFACE_DFP:
53062306a36Sopenharmony_ci		return VIA_LVDS1 | VIA_LVDS2;
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci	case INTERFACE_LVDS0:
53362306a36Sopenharmony_ci	case INTERFACE_LVDS0LVDS1:
53462306a36Sopenharmony_ci		return VIA_LVDS1;
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci	case INTERFACE_LVDS1:
53762306a36Sopenharmony_ci		return VIA_LVDS2;
53862306a36Sopenharmony_ci	}
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	return 0;
54162306a36Sopenharmony_ci}
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_ci/*Set IGA path for each device*/
54462306a36Sopenharmony_civoid viafb_set_iga_path(void)
54562306a36Sopenharmony_ci{
54662306a36Sopenharmony_ci	int crt_iga_path = 0;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	if (viafb_SAMM_ON == 1) {
54962306a36Sopenharmony_ci		if (viafb_CRT_ON) {
55062306a36Sopenharmony_ci			if (viafb_primary_dev == CRT_Device)
55162306a36Sopenharmony_ci				crt_iga_path = IGA1;
55262306a36Sopenharmony_ci			else
55362306a36Sopenharmony_ci				crt_iga_path = IGA2;
55462306a36Sopenharmony_ci		}
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci		if (viafb_DVI_ON) {
55762306a36Sopenharmony_ci			if (viafb_primary_dev == DVI_Device)
55862306a36Sopenharmony_ci				viaparinfo->tmds_setting_info->iga_path = IGA1;
55962306a36Sopenharmony_ci			else
56062306a36Sopenharmony_ci				viaparinfo->tmds_setting_info->iga_path = IGA2;
56162306a36Sopenharmony_ci		}
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_ci		if (viafb_LCD_ON) {
56462306a36Sopenharmony_ci			if (viafb_primary_dev == LCD_Device) {
56562306a36Sopenharmony_ci				if (viafb_dual_fb &&
56662306a36Sopenharmony_ci					(viaparinfo->chip_info->gfx_chip_name ==
56762306a36Sopenharmony_ci					UNICHROME_CLE266)) {
56862306a36Sopenharmony_ci					viaparinfo->
56962306a36Sopenharmony_ci					lvds_setting_info->iga_path = IGA2;
57062306a36Sopenharmony_ci					crt_iga_path = IGA1;
57162306a36Sopenharmony_ci					viaparinfo->
57262306a36Sopenharmony_ci					tmds_setting_info->iga_path = IGA1;
57362306a36Sopenharmony_ci				} else
57462306a36Sopenharmony_ci					viaparinfo->
57562306a36Sopenharmony_ci					lvds_setting_info->iga_path = IGA1;
57662306a36Sopenharmony_ci			} else {
57762306a36Sopenharmony_ci				viaparinfo->lvds_setting_info->iga_path = IGA2;
57862306a36Sopenharmony_ci			}
57962306a36Sopenharmony_ci		}
58062306a36Sopenharmony_ci		if (viafb_LCD2_ON) {
58162306a36Sopenharmony_ci			if (LCD2_Device == viafb_primary_dev)
58262306a36Sopenharmony_ci				viaparinfo->lvds_setting_info2->iga_path = IGA1;
58362306a36Sopenharmony_ci			else
58462306a36Sopenharmony_ci				viaparinfo->lvds_setting_info2->iga_path = IGA2;
58562306a36Sopenharmony_ci		}
58662306a36Sopenharmony_ci	} else {
58762306a36Sopenharmony_ci		viafb_SAMM_ON = 0;
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci		if (viafb_CRT_ON && viafb_LCD_ON) {
59062306a36Sopenharmony_ci			crt_iga_path = IGA1;
59162306a36Sopenharmony_ci			viaparinfo->lvds_setting_info->iga_path = IGA2;
59262306a36Sopenharmony_ci		} else if (viafb_CRT_ON && viafb_DVI_ON) {
59362306a36Sopenharmony_ci			crt_iga_path = IGA1;
59462306a36Sopenharmony_ci			viaparinfo->tmds_setting_info->iga_path = IGA2;
59562306a36Sopenharmony_ci		} else if (viafb_LCD_ON && viafb_DVI_ON) {
59662306a36Sopenharmony_ci			viaparinfo->tmds_setting_info->iga_path = IGA1;
59762306a36Sopenharmony_ci			viaparinfo->lvds_setting_info->iga_path = IGA2;
59862306a36Sopenharmony_ci		} else if (viafb_LCD_ON && viafb_LCD2_ON) {
59962306a36Sopenharmony_ci			viaparinfo->lvds_setting_info->iga_path = IGA2;
60062306a36Sopenharmony_ci			viaparinfo->lvds_setting_info2->iga_path = IGA2;
60162306a36Sopenharmony_ci		} else if (viafb_CRT_ON) {
60262306a36Sopenharmony_ci			crt_iga_path = IGA1;
60362306a36Sopenharmony_ci		} else if (viafb_LCD_ON) {
60462306a36Sopenharmony_ci			viaparinfo->lvds_setting_info->iga_path = IGA2;
60562306a36Sopenharmony_ci		} else if (viafb_DVI_ON) {
60662306a36Sopenharmony_ci			viaparinfo->tmds_setting_info->iga_path = IGA1;
60762306a36Sopenharmony_ci		}
60862306a36Sopenharmony_ci	}
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	viaparinfo->shared->iga1_devices = 0;
61162306a36Sopenharmony_ci	viaparinfo->shared->iga2_devices = 0;
61262306a36Sopenharmony_ci	if (viafb_CRT_ON) {
61362306a36Sopenharmony_ci		if (crt_iga_path == IGA1)
61462306a36Sopenharmony_ci			viaparinfo->shared->iga1_devices |= VIA_CRT;
61562306a36Sopenharmony_ci		else
61662306a36Sopenharmony_ci			viaparinfo->shared->iga2_devices |= VIA_CRT;
61762306a36Sopenharmony_ci	}
61862306a36Sopenharmony_ci
61962306a36Sopenharmony_ci	if (viafb_DVI_ON) {
62062306a36Sopenharmony_ci		if (viaparinfo->tmds_setting_info->iga_path == IGA1)
62162306a36Sopenharmony_ci			viaparinfo->shared->iga1_devices |= get_dvi_devices(
62262306a36Sopenharmony_ci				viaparinfo->chip_info->
62362306a36Sopenharmony_ci				tmds_chip_info.output_interface);
62462306a36Sopenharmony_ci		else
62562306a36Sopenharmony_ci			viaparinfo->shared->iga2_devices |= get_dvi_devices(
62662306a36Sopenharmony_ci				viaparinfo->chip_info->
62762306a36Sopenharmony_ci				tmds_chip_info.output_interface);
62862306a36Sopenharmony_ci	}
62962306a36Sopenharmony_ci
63062306a36Sopenharmony_ci	if (viafb_LCD_ON) {
63162306a36Sopenharmony_ci		if (viaparinfo->lvds_setting_info->iga_path == IGA1)
63262306a36Sopenharmony_ci			viaparinfo->shared->iga1_devices |= get_lcd_devices(
63362306a36Sopenharmony_ci				viaparinfo->chip_info->
63462306a36Sopenharmony_ci				lvds_chip_info.output_interface);
63562306a36Sopenharmony_ci		else
63662306a36Sopenharmony_ci			viaparinfo->shared->iga2_devices |= get_lcd_devices(
63762306a36Sopenharmony_ci				viaparinfo->chip_info->
63862306a36Sopenharmony_ci				lvds_chip_info.output_interface);
63962306a36Sopenharmony_ci	}
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci	if (viafb_LCD2_ON) {
64262306a36Sopenharmony_ci		if (viaparinfo->lvds_setting_info2->iga_path == IGA1)
64362306a36Sopenharmony_ci			viaparinfo->shared->iga1_devices |= get_lcd_devices(
64462306a36Sopenharmony_ci				viaparinfo->chip_info->
64562306a36Sopenharmony_ci				lvds_chip_info2.output_interface);
64662306a36Sopenharmony_ci		else
64762306a36Sopenharmony_ci			viaparinfo->shared->iga2_devices |= get_lcd_devices(
64862306a36Sopenharmony_ci				viaparinfo->chip_info->
64962306a36Sopenharmony_ci				lvds_chip_info2.output_interface);
65062306a36Sopenharmony_ci	}
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_ci	/* looks like the OLPC has its display wired to DVP1 and LVDS2 */
65362306a36Sopenharmony_ci	if (machine_is_olpc())
65462306a36Sopenharmony_ci		viaparinfo->shared->iga2_devices = VIA_DVP1 | VIA_LVDS2;
65562306a36Sopenharmony_ci}
65662306a36Sopenharmony_ci
65762306a36Sopenharmony_cistatic void set_color_register(u8 index, u8 red, u8 green, u8 blue)
65862306a36Sopenharmony_ci{
65962306a36Sopenharmony_ci	outb(0xFF, 0x3C6); /* bit mask of palette */
66062306a36Sopenharmony_ci	outb(index, 0x3C8);
66162306a36Sopenharmony_ci	outb(red, 0x3C9);
66262306a36Sopenharmony_ci	outb(green, 0x3C9);
66362306a36Sopenharmony_ci	outb(blue, 0x3C9);
66462306a36Sopenharmony_ci}
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_civoid viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue)
66762306a36Sopenharmony_ci{
66862306a36Sopenharmony_ci	viafb_write_reg_mask(0x1A, VIASR, 0x00, 0x01);
66962306a36Sopenharmony_ci	set_color_register(index, red, green, blue);
67062306a36Sopenharmony_ci}
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_civoid viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue)
67362306a36Sopenharmony_ci{
67462306a36Sopenharmony_ci	viafb_write_reg_mask(0x1A, VIASR, 0x01, 0x01);
67562306a36Sopenharmony_ci	set_color_register(index, red, green, blue);
67662306a36Sopenharmony_ci}
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_cistatic void set_source_common(u8 index, u8 offset, u8 iga)
67962306a36Sopenharmony_ci{
68062306a36Sopenharmony_ci	u8 value, mask = 1 << offset;
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci	switch (iga) {
68362306a36Sopenharmony_ci	case IGA1:
68462306a36Sopenharmony_ci		value = 0x00;
68562306a36Sopenharmony_ci		break;
68662306a36Sopenharmony_ci	case IGA2:
68762306a36Sopenharmony_ci		value = mask;
68862306a36Sopenharmony_ci		break;
68962306a36Sopenharmony_ci	default:
69062306a36Sopenharmony_ci		printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);
69162306a36Sopenharmony_ci		return;
69262306a36Sopenharmony_ci	}
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci	via_write_reg_mask(VIACR, index, value, mask);
69562306a36Sopenharmony_ci}
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_cistatic void set_crt_source(u8 iga)
69862306a36Sopenharmony_ci{
69962306a36Sopenharmony_ci	u8 value;
70062306a36Sopenharmony_ci
70162306a36Sopenharmony_ci	switch (iga) {
70262306a36Sopenharmony_ci	case IGA1:
70362306a36Sopenharmony_ci		value = 0x00;
70462306a36Sopenharmony_ci		break;
70562306a36Sopenharmony_ci	case IGA2:
70662306a36Sopenharmony_ci		value = 0x40;
70762306a36Sopenharmony_ci		break;
70862306a36Sopenharmony_ci	default:
70962306a36Sopenharmony_ci		printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);
71062306a36Sopenharmony_ci		return;
71162306a36Sopenharmony_ci	}
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci	via_write_reg_mask(VIASR, 0x16, value, 0x40);
71462306a36Sopenharmony_ci}
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_cistatic inline void set_ldvp0_source(u8 iga)
71762306a36Sopenharmony_ci{
71862306a36Sopenharmony_ci	set_source_common(0x6C, 7, iga);
71962306a36Sopenharmony_ci}
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_cistatic inline void set_ldvp1_source(u8 iga)
72262306a36Sopenharmony_ci{
72362306a36Sopenharmony_ci	set_source_common(0x93, 7, iga);
72462306a36Sopenharmony_ci}
72562306a36Sopenharmony_ci
72662306a36Sopenharmony_cistatic inline void set_dvp0_source(u8 iga)
72762306a36Sopenharmony_ci{
72862306a36Sopenharmony_ci	set_source_common(0x96, 4, iga);
72962306a36Sopenharmony_ci}
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_cistatic inline void set_dvp1_source(u8 iga)
73262306a36Sopenharmony_ci{
73362306a36Sopenharmony_ci	set_source_common(0x9B, 4, iga);
73462306a36Sopenharmony_ci}
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_cistatic inline void set_lvds1_source(u8 iga)
73762306a36Sopenharmony_ci{
73862306a36Sopenharmony_ci	set_source_common(0x99, 4, iga);
73962306a36Sopenharmony_ci}
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_cistatic inline void set_lvds2_source(u8 iga)
74262306a36Sopenharmony_ci{
74362306a36Sopenharmony_ci	set_source_common(0x97, 4, iga);
74462306a36Sopenharmony_ci}
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_civoid via_set_source(u32 devices, u8 iga)
74762306a36Sopenharmony_ci{
74862306a36Sopenharmony_ci	if (devices & VIA_LDVP0)
74962306a36Sopenharmony_ci		set_ldvp0_source(iga);
75062306a36Sopenharmony_ci	if (devices & VIA_LDVP1)
75162306a36Sopenharmony_ci		set_ldvp1_source(iga);
75262306a36Sopenharmony_ci	if (devices & VIA_DVP0)
75362306a36Sopenharmony_ci		set_dvp0_source(iga);
75462306a36Sopenharmony_ci	if (devices & VIA_CRT)
75562306a36Sopenharmony_ci		set_crt_source(iga);
75662306a36Sopenharmony_ci	if (devices & VIA_DVP1)
75762306a36Sopenharmony_ci		set_dvp1_source(iga);
75862306a36Sopenharmony_ci	if (devices & VIA_LVDS1)
75962306a36Sopenharmony_ci		set_lvds1_source(iga);
76062306a36Sopenharmony_ci	if (devices & VIA_LVDS2)
76162306a36Sopenharmony_ci		set_lvds2_source(iga);
76262306a36Sopenharmony_ci}
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_cistatic void set_crt_state(u8 state)
76562306a36Sopenharmony_ci{
76662306a36Sopenharmony_ci	u8 value;
76762306a36Sopenharmony_ci
76862306a36Sopenharmony_ci	switch (state) {
76962306a36Sopenharmony_ci	case VIA_STATE_ON:
77062306a36Sopenharmony_ci		value = 0x00;
77162306a36Sopenharmony_ci		break;
77262306a36Sopenharmony_ci	case VIA_STATE_STANDBY:
77362306a36Sopenharmony_ci		value = 0x10;
77462306a36Sopenharmony_ci		break;
77562306a36Sopenharmony_ci	case VIA_STATE_SUSPEND:
77662306a36Sopenharmony_ci		value = 0x20;
77762306a36Sopenharmony_ci		break;
77862306a36Sopenharmony_ci	case VIA_STATE_OFF:
77962306a36Sopenharmony_ci		value = 0x30;
78062306a36Sopenharmony_ci		break;
78162306a36Sopenharmony_ci	default:
78262306a36Sopenharmony_ci		return;
78362306a36Sopenharmony_ci	}
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ci	via_write_reg_mask(VIACR, 0x36, value, 0x30);
78662306a36Sopenharmony_ci}
78762306a36Sopenharmony_ci
78862306a36Sopenharmony_cistatic void set_dvp0_state(u8 state)
78962306a36Sopenharmony_ci{
79062306a36Sopenharmony_ci	u8 value;
79162306a36Sopenharmony_ci
79262306a36Sopenharmony_ci	switch (state) {
79362306a36Sopenharmony_ci	case VIA_STATE_ON:
79462306a36Sopenharmony_ci		value = 0xC0;
79562306a36Sopenharmony_ci		break;
79662306a36Sopenharmony_ci	case VIA_STATE_OFF:
79762306a36Sopenharmony_ci		value = 0x00;
79862306a36Sopenharmony_ci		break;
79962306a36Sopenharmony_ci	default:
80062306a36Sopenharmony_ci		return;
80162306a36Sopenharmony_ci	}
80262306a36Sopenharmony_ci
80362306a36Sopenharmony_ci	via_write_reg_mask(VIASR, 0x1E, value, 0xC0);
80462306a36Sopenharmony_ci}
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_cistatic void set_dvp1_state(u8 state)
80762306a36Sopenharmony_ci{
80862306a36Sopenharmony_ci	u8 value;
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_ci	switch (state) {
81162306a36Sopenharmony_ci	case VIA_STATE_ON:
81262306a36Sopenharmony_ci		value = 0x30;
81362306a36Sopenharmony_ci		break;
81462306a36Sopenharmony_ci	case VIA_STATE_OFF:
81562306a36Sopenharmony_ci		value = 0x00;
81662306a36Sopenharmony_ci		break;
81762306a36Sopenharmony_ci	default:
81862306a36Sopenharmony_ci		return;
81962306a36Sopenharmony_ci	}
82062306a36Sopenharmony_ci
82162306a36Sopenharmony_ci	via_write_reg_mask(VIASR, 0x1E, value, 0x30);
82262306a36Sopenharmony_ci}
82362306a36Sopenharmony_ci
82462306a36Sopenharmony_cistatic void set_lvds1_state(u8 state)
82562306a36Sopenharmony_ci{
82662306a36Sopenharmony_ci	u8 value;
82762306a36Sopenharmony_ci
82862306a36Sopenharmony_ci	switch (state) {
82962306a36Sopenharmony_ci	case VIA_STATE_ON:
83062306a36Sopenharmony_ci		value = 0x03;
83162306a36Sopenharmony_ci		break;
83262306a36Sopenharmony_ci	case VIA_STATE_OFF:
83362306a36Sopenharmony_ci		value = 0x00;
83462306a36Sopenharmony_ci		break;
83562306a36Sopenharmony_ci	default:
83662306a36Sopenharmony_ci		return;
83762306a36Sopenharmony_ci	}
83862306a36Sopenharmony_ci
83962306a36Sopenharmony_ci	via_write_reg_mask(VIASR, 0x2A, value, 0x03);
84062306a36Sopenharmony_ci}
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_cistatic void set_lvds2_state(u8 state)
84362306a36Sopenharmony_ci{
84462306a36Sopenharmony_ci	u8 value;
84562306a36Sopenharmony_ci
84662306a36Sopenharmony_ci	switch (state) {
84762306a36Sopenharmony_ci	case VIA_STATE_ON:
84862306a36Sopenharmony_ci		value = 0x0C;
84962306a36Sopenharmony_ci		break;
85062306a36Sopenharmony_ci	case VIA_STATE_OFF:
85162306a36Sopenharmony_ci		value = 0x00;
85262306a36Sopenharmony_ci		break;
85362306a36Sopenharmony_ci	default:
85462306a36Sopenharmony_ci		return;
85562306a36Sopenharmony_ci	}
85662306a36Sopenharmony_ci
85762306a36Sopenharmony_ci	via_write_reg_mask(VIASR, 0x2A, value, 0x0C);
85862306a36Sopenharmony_ci}
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_civoid via_set_state(u32 devices, u8 state)
86162306a36Sopenharmony_ci{
86262306a36Sopenharmony_ci	/*
86362306a36Sopenharmony_ci	TODO: Can we enable/disable these devices? How?
86462306a36Sopenharmony_ci	if (devices & VIA_LDVP0)
86562306a36Sopenharmony_ci	if (devices & VIA_LDVP1)
86662306a36Sopenharmony_ci	*/
86762306a36Sopenharmony_ci	if (devices & VIA_DVP0)
86862306a36Sopenharmony_ci		set_dvp0_state(state);
86962306a36Sopenharmony_ci	if (devices & VIA_CRT)
87062306a36Sopenharmony_ci		set_crt_state(state);
87162306a36Sopenharmony_ci	if (devices & VIA_DVP1)
87262306a36Sopenharmony_ci		set_dvp1_state(state);
87362306a36Sopenharmony_ci	if (devices & VIA_LVDS1)
87462306a36Sopenharmony_ci		set_lvds1_state(state);
87562306a36Sopenharmony_ci	if (devices & VIA_LVDS2)
87662306a36Sopenharmony_ci		set_lvds2_state(state);
87762306a36Sopenharmony_ci}
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_civoid via_set_sync_polarity(u32 devices, u8 polarity)
88062306a36Sopenharmony_ci{
88162306a36Sopenharmony_ci	if (polarity & ~(VIA_HSYNC_NEGATIVE | VIA_VSYNC_NEGATIVE)) {
88262306a36Sopenharmony_ci		printk(KERN_WARNING "viafb: Unsupported polarity: %d\n",
88362306a36Sopenharmony_ci			polarity);
88462306a36Sopenharmony_ci		return;
88562306a36Sopenharmony_ci	}
88662306a36Sopenharmony_ci
88762306a36Sopenharmony_ci	if (devices & VIA_CRT)
88862306a36Sopenharmony_ci		via_write_misc_reg_mask(polarity << 6, 0xC0);
88962306a36Sopenharmony_ci	if (devices & VIA_DVP1)
89062306a36Sopenharmony_ci		via_write_reg_mask(VIACR, 0x9B, polarity << 5, 0x60);
89162306a36Sopenharmony_ci	if (devices & VIA_LVDS1)
89262306a36Sopenharmony_ci		via_write_reg_mask(VIACR, 0x99, polarity << 5, 0x60);
89362306a36Sopenharmony_ci	if (devices & VIA_LVDS2)
89462306a36Sopenharmony_ci		via_write_reg_mask(VIACR, 0x97, polarity << 5, 0x60);
89562306a36Sopenharmony_ci}
89662306a36Sopenharmony_ci
89762306a36Sopenharmony_ciu32 via_parse_odev(char *input, char **end)
89862306a36Sopenharmony_ci{
89962306a36Sopenharmony_ci	char *ptr = input;
90062306a36Sopenharmony_ci	u32 odev = 0;
90162306a36Sopenharmony_ci	bool next = true;
90262306a36Sopenharmony_ci	int i, len;
90362306a36Sopenharmony_ci
90462306a36Sopenharmony_ci	while (next) {
90562306a36Sopenharmony_ci		next = false;
90662306a36Sopenharmony_ci		for (i = 0; i < ARRAY_SIZE(device_mapping); i++) {
90762306a36Sopenharmony_ci			len = strlen(device_mapping[i].name);
90862306a36Sopenharmony_ci			if (!strncmp(ptr, device_mapping[i].name, len)) {
90962306a36Sopenharmony_ci				odev |= device_mapping[i].device;
91062306a36Sopenharmony_ci				ptr += len;
91162306a36Sopenharmony_ci				if (*ptr == ',') {
91262306a36Sopenharmony_ci					ptr++;
91362306a36Sopenharmony_ci					next = true;
91462306a36Sopenharmony_ci				}
91562306a36Sopenharmony_ci			}
91662306a36Sopenharmony_ci		}
91762306a36Sopenharmony_ci	}
91862306a36Sopenharmony_ci
91962306a36Sopenharmony_ci	*end = ptr;
92062306a36Sopenharmony_ci	return odev;
92162306a36Sopenharmony_ci}
92262306a36Sopenharmony_ci
92362306a36Sopenharmony_civoid via_odev_to_seq(struct seq_file *m, u32 odev)
92462306a36Sopenharmony_ci{
92562306a36Sopenharmony_ci	int i, count = 0;
92662306a36Sopenharmony_ci
92762306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(device_mapping); i++) {
92862306a36Sopenharmony_ci		if (odev & device_mapping[i].device) {
92962306a36Sopenharmony_ci			if (count > 0)
93062306a36Sopenharmony_ci				seq_putc(m, ',');
93162306a36Sopenharmony_ci
93262306a36Sopenharmony_ci			seq_puts(m, device_mapping[i].name);
93362306a36Sopenharmony_ci			count++;
93462306a36Sopenharmony_ci		}
93562306a36Sopenharmony_ci	}
93662306a36Sopenharmony_ci
93762306a36Sopenharmony_ci	seq_putc(m, '\n');
93862306a36Sopenharmony_ci}
93962306a36Sopenharmony_ci
94062306a36Sopenharmony_cistatic void load_fix_bit_crtc_reg(void)
94162306a36Sopenharmony_ci{
94262306a36Sopenharmony_ci	viafb_unlock_crt();
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_ci	/* always set to 1 */
94562306a36Sopenharmony_ci	viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7);
94662306a36Sopenharmony_ci	/* line compare should set all bits = 1 (extend modes) */
94762306a36Sopenharmony_ci	viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4);
94862306a36Sopenharmony_ci	/* line compare should set all bits = 1 (extend modes) */
94962306a36Sopenharmony_ci	viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2);
95062306a36Sopenharmony_ci	/*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */
95162306a36Sopenharmony_ci
95262306a36Sopenharmony_ci	viafb_lock_crt();
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_ci	/* If K8M800, enable Prefetch Mode. */
95562306a36Sopenharmony_ci	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
95662306a36Sopenharmony_ci		|| (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890))
95762306a36Sopenharmony_ci		viafb_write_reg_mask(CR33, VIACR, 0x08, BIT3);
95862306a36Sopenharmony_ci	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
95962306a36Sopenharmony_ci	    && (viaparinfo->chip_info->gfx_chip_revision == CLE266_REVISION_AX))
96062306a36Sopenharmony_ci		viafb_write_reg_mask(SR1A, VIASR, 0x02, BIT1);
96162306a36Sopenharmony_ci
96262306a36Sopenharmony_ci}
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_civoid viafb_load_reg(int timing_value, int viafb_load_reg_num,
96562306a36Sopenharmony_ci	struct io_register *reg,
96662306a36Sopenharmony_ci	      int io_type)
96762306a36Sopenharmony_ci{
96862306a36Sopenharmony_ci	int reg_mask;
96962306a36Sopenharmony_ci	int bit_num = 0;
97062306a36Sopenharmony_ci	int data;
97162306a36Sopenharmony_ci	int i, j;
97262306a36Sopenharmony_ci	int shift_next_reg;
97362306a36Sopenharmony_ci	int start_index, end_index, cr_index;
97462306a36Sopenharmony_ci	u16 get_bit;
97562306a36Sopenharmony_ci
97662306a36Sopenharmony_ci	for (i = 0; i < viafb_load_reg_num; i++) {
97762306a36Sopenharmony_ci		reg_mask = 0;
97862306a36Sopenharmony_ci		data = 0;
97962306a36Sopenharmony_ci		start_index = reg[i].start_bit;
98062306a36Sopenharmony_ci		end_index = reg[i].end_bit;
98162306a36Sopenharmony_ci		cr_index = reg[i].io_addr;
98262306a36Sopenharmony_ci
98362306a36Sopenharmony_ci		shift_next_reg = bit_num;
98462306a36Sopenharmony_ci		for (j = start_index; j <= end_index; j++) {
98562306a36Sopenharmony_ci			/*if (bit_num==8) timing_value = timing_value >>8; */
98662306a36Sopenharmony_ci			reg_mask = reg_mask | (BIT0 << j);
98762306a36Sopenharmony_ci			get_bit = (timing_value & (BIT0 << bit_num));
98862306a36Sopenharmony_ci			data =
98962306a36Sopenharmony_ci			    data | ((get_bit >> shift_next_reg) << start_index);
99062306a36Sopenharmony_ci			bit_num++;
99162306a36Sopenharmony_ci		}
99262306a36Sopenharmony_ci		if (io_type == VIACR)
99362306a36Sopenharmony_ci			viafb_write_reg_mask(cr_index, VIACR, data, reg_mask);
99462306a36Sopenharmony_ci		else
99562306a36Sopenharmony_ci			viafb_write_reg_mask(cr_index, VIASR, data, reg_mask);
99662306a36Sopenharmony_ci	}
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_ci}
99962306a36Sopenharmony_ci
100062306a36Sopenharmony_ci/* Write Registers */
100162306a36Sopenharmony_civoid viafb_write_regx(struct io_reg RegTable[], int ItemNum)
100262306a36Sopenharmony_ci{
100362306a36Sopenharmony_ci	int i;
100462306a36Sopenharmony_ci
100562306a36Sopenharmony_ci	/*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */
100662306a36Sopenharmony_ci
100762306a36Sopenharmony_ci	for (i = 0; i < ItemNum; i++)
100862306a36Sopenharmony_ci		via_write_reg_mask(RegTable[i].port, RegTable[i].index,
100962306a36Sopenharmony_ci			RegTable[i].value, RegTable[i].mask);
101062306a36Sopenharmony_ci}
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_civoid viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga)
101362306a36Sopenharmony_ci{
101462306a36Sopenharmony_ci	int reg_value;
101562306a36Sopenharmony_ci	int viafb_load_reg_num;
101662306a36Sopenharmony_ci	struct io_register *reg = NULL;
101762306a36Sopenharmony_ci
101862306a36Sopenharmony_ci	switch (set_iga) {
101962306a36Sopenharmony_ci	case IGA1:
102062306a36Sopenharmony_ci		reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
102162306a36Sopenharmony_ci		viafb_load_reg_num = fetch_count_reg.
102262306a36Sopenharmony_ci			iga1_fetch_count_reg.reg_num;
102362306a36Sopenharmony_ci		reg = fetch_count_reg.iga1_fetch_count_reg.reg;
102462306a36Sopenharmony_ci		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
102562306a36Sopenharmony_ci		break;
102662306a36Sopenharmony_ci	case IGA2:
102762306a36Sopenharmony_ci		reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
102862306a36Sopenharmony_ci		viafb_load_reg_num = fetch_count_reg.
102962306a36Sopenharmony_ci			iga2_fetch_count_reg.reg_num;
103062306a36Sopenharmony_ci		reg = fetch_count_reg.iga2_fetch_count_reg.reg;
103162306a36Sopenharmony_ci		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
103262306a36Sopenharmony_ci		break;
103362306a36Sopenharmony_ci	}
103462306a36Sopenharmony_ci
103562306a36Sopenharmony_ci}
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_civoid viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
103862306a36Sopenharmony_ci{
103962306a36Sopenharmony_ci	int reg_value;
104062306a36Sopenharmony_ci	int viafb_load_reg_num;
104162306a36Sopenharmony_ci	struct io_register *reg = NULL;
104262306a36Sopenharmony_ci	int iga1_fifo_max_depth = 0, iga1_fifo_threshold =
104362306a36Sopenharmony_ci	    0, iga1_fifo_high_threshold = 0, iga1_display_queue_expire_num = 0;
104462306a36Sopenharmony_ci	int iga2_fifo_max_depth = 0, iga2_fifo_threshold =
104562306a36Sopenharmony_ci	    0, iga2_fifo_high_threshold = 0, iga2_display_queue_expire_num = 0;
104662306a36Sopenharmony_ci
104762306a36Sopenharmony_ci	if (set_iga == IGA1) {
104862306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
104962306a36Sopenharmony_ci			iga1_fifo_max_depth = K800_IGA1_FIFO_MAX_DEPTH;
105062306a36Sopenharmony_ci			iga1_fifo_threshold = K800_IGA1_FIFO_THRESHOLD;
105162306a36Sopenharmony_ci			iga1_fifo_high_threshold =
105262306a36Sopenharmony_ci			    K800_IGA1_FIFO_HIGH_THRESHOLD;
105362306a36Sopenharmony_ci			/* If resolution > 1280x1024, expire length = 64, else
105462306a36Sopenharmony_ci			   expire length = 128 */
105562306a36Sopenharmony_ci			if ((hor_active > 1280) && (ver_active > 1024))
105662306a36Sopenharmony_ci				iga1_display_queue_expire_num = 16;
105762306a36Sopenharmony_ci			else
105862306a36Sopenharmony_ci				iga1_display_queue_expire_num =
105962306a36Sopenharmony_ci				    K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
106062306a36Sopenharmony_ci
106162306a36Sopenharmony_ci		}
106262306a36Sopenharmony_ci
106362306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
106462306a36Sopenharmony_ci			iga1_fifo_max_depth = P880_IGA1_FIFO_MAX_DEPTH;
106562306a36Sopenharmony_ci			iga1_fifo_threshold = P880_IGA1_FIFO_THRESHOLD;
106662306a36Sopenharmony_ci			iga1_fifo_high_threshold =
106762306a36Sopenharmony_ci			    P880_IGA1_FIFO_HIGH_THRESHOLD;
106862306a36Sopenharmony_ci			iga1_display_queue_expire_num =
106962306a36Sopenharmony_ci			    P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
107062306a36Sopenharmony_ci
107162306a36Sopenharmony_ci			/* If resolution > 1280x1024, expire length = 64, else
107262306a36Sopenharmony_ci			   expire length = 128 */
107362306a36Sopenharmony_ci			if ((hor_active > 1280) && (ver_active > 1024))
107462306a36Sopenharmony_ci				iga1_display_queue_expire_num = 16;
107562306a36Sopenharmony_ci			else
107662306a36Sopenharmony_ci				iga1_display_queue_expire_num =
107762306a36Sopenharmony_ci				    P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
107862306a36Sopenharmony_ci		}
107962306a36Sopenharmony_ci
108062306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
108162306a36Sopenharmony_ci			iga1_fifo_max_depth = CN700_IGA1_FIFO_MAX_DEPTH;
108262306a36Sopenharmony_ci			iga1_fifo_threshold = CN700_IGA1_FIFO_THRESHOLD;
108362306a36Sopenharmony_ci			iga1_fifo_high_threshold =
108462306a36Sopenharmony_ci			    CN700_IGA1_FIFO_HIGH_THRESHOLD;
108562306a36Sopenharmony_ci
108662306a36Sopenharmony_ci			/* If resolution > 1280x1024, expire length = 64,
108762306a36Sopenharmony_ci			   else expire length = 128 */
108862306a36Sopenharmony_ci			if ((hor_active > 1280) && (ver_active > 1024))
108962306a36Sopenharmony_ci				iga1_display_queue_expire_num = 16;
109062306a36Sopenharmony_ci			else
109162306a36Sopenharmony_ci				iga1_display_queue_expire_num =
109262306a36Sopenharmony_ci				    CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
109362306a36Sopenharmony_ci		}
109462306a36Sopenharmony_ci
109562306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
109662306a36Sopenharmony_ci			iga1_fifo_max_depth = CX700_IGA1_FIFO_MAX_DEPTH;
109762306a36Sopenharmony_ci			iga1_fifo_threshold = CX700_IGA1_FIFO_THRESHOLD;
109862306a36Sopenharmony_ci			iga1_fifo_high_threshold =
109962306a36Sopenharmony_ci			    CX700_IGA1_FIFO_HIGH_THRESHOLD;
110062306a36Sopenharmony_ci			iga1_display_queue_expire_num =
110162306a36Sopenharmony_ci			    CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
110262306a36Sopenharmony_ci		}
110362306a36Sopenharmony_ci
110462306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
110562306a36Sopenharmony_ci			iga1_fifo_max_depth = K8M890_IGA1_FIFO_MAX_DEPTH;
110662306a36Sopenharmony_ci			iga1_fifo_threshold = K8M890_IGA1_FIFO_THRESHOLD;
110762306a36Sopenharmony_ci			iga1_fifo_high_threshold =
110862306a36Sopenharmony_ci			    K8M890_IGA1_FIFO_HIGH_THRESHOLD;
110962306a36Sopenharmony_ci			iga1_display_queue_expire_num =
111062306a36Sopenharmony_ci			    K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
111162306a36Sopenharmony_ci		}
111262306a36Sopenharmony_ci
111362306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
111462306a36Sopenharmony_ci			iga1_fifo_max_depth = P4M890_IGA1_FIFO_MAX_DEPTH;
111562306a36Sopenharmony_ci			iga1_fifo_threshold = P4M890_IGA1_FIFO_THRESHOLD;
111662306a36Sopenharmony_ci			iga1_fifo_high_threshold =
111762306a36Sopenharmony_ci			    P4M890_IGA1_FIFO_HIGH_THRESHOLD;
111862306a36Sopenharmony_ci			iga1_display_queue_expire_num =
111962306a36Sopenharmony_ci			    P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
112062306a36Sopenharmony_ci		}
112162306a36Sopenharmony_ci
112262306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
112362306a36Sopenharmony_ci			iga1_fifo_max_depth = P4M900_IGA1_FIFO_MAX_DEPTH;
112462306a36Sopenharmony_ci			iga1_fifo_threshold = P4M900_IGA1_FIFO_THRESHOLD;
112562306a36Sopenharmony_ci			iga1_fifo_high_threshold =
112662306a36Sopenharmony_ci			    P4M900_IGA1_FIFO_HIGH_THRESHOLD;
112762306a36Sopenharmony_ci			iga1_display_queue_expire_num =
112862306a36Sopenharmony_ci			    P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
112962306a36Sopenharmony_ci		}
113062306a36Sopenharmony_ci
113162306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
113262306a36Sopenharmony_ci			iga1_fifo_max_depth = VX800_IGA1_FIFO_MAX_DEPTH;
113362306a36Sopenharmony_ci			iga1_fifo_threshold = VX800_IGA1_FIFO_THRESHOLD;
113462306a36Sopenharmony_ci			iga1_fifo_high_threshold =
113562306a36Sopenharmony_ci			    VX800_IGA1_FIFO_HIGH_THRESHOLD;
113662306a36Sopenharmony_ci			iga1_display_queue_expire_num =
113762306a36Sopenharmony_ci			    VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
113862306a36Sopenharmony_ci		}
113962306a36Sopenharmony_ci
114062306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {
114162306a36Sopenharmony_ci			iga1_fifo_max_depth = VX855_IGA1_FIFO_MAX_DEPTH;
114262306a36Sopenharmony_ci			iga1_fifo_threshold = VX855_IGA1_FIFO_THRESHOLD;
114362306a36Sopenharmony_ci			iga1_fifo_high_threshold =
114462306a36Sopenharmony_ci			    VX855_IGA1_FIFO_HIGH_THRESHOLD;
114562306a36Sopenharmony_ci			iga1_display_queue_expire_num =
114662306a36Sopenharmony_ci			    VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
114762306a36Sopenharmony_ci		}
114862306a36Sopenharmony_ci
114962306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) {
115062306a36Sopenharmony_ci			iga1_fifo_max_depth = VX900_IGA1_FIFO_MAX_DEPTH;
115162306a36Sopenharmony_ci			iga1_fifo_threshold = VX900_IGA1_FIFO_THRESHOLD;
115262306a36Sopenharmony_ci			iga1_fifo_high_threshold =
115362306a36Sopenharmony_ci			    VX900_IGA1_FIFO_HIGH_THRESHOLD;
115462306a36Sopenharmony_ci			iga1_display_queue_expire_num =
115562306a36Sopenharmony_ci			    VX900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
115662306a36Sopenharmony_ci		}
115762306a36Sopenharmony_ci
115862306a36Sopenharmony_ci		/* Set Display FIFO Depath Select */
115962306a36Sopenharmony_ci		reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth);
116062306a36Sopenharmony_ci		viafb_load_reg_num =
116162306a36Sopenharmony_ci		    display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg_num;
116262306a36Sopenharmony_ci		reg = display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg;
116362306a36Sopenharmony_ci		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
116462306a36Sopenharmony_ci
116562306a36Sopenharmony_ci		/* Set Display FIFO Threshold Select */
116662306a36Sopenharmony_ci		reg_value = IGA1_FIFO_THRESHOLD_FORMULA(iga1_fifo_threshold);
116762306a36Sopenharmony_ci		viafb_load_reg_num =
116862306a36Sopenharmony_ci		    fifo_threshold_select_reg.
116962306a36Sopenharmony_ci		    iga1_fifo_threshold_select_reg.reg_num;
117062306a36Sopenharmony_ci		reg =
117162306a36Sopenharmony_ci		    fifo_threshold_select_reg.
117262306a36Sopenharmony_ci		    iga1_fifo_threshold_select_reg.reg;
117362306a36Sopenharmony_ci		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
117462306a36Sopenharmony_ci
117562306a36Sopenharmony_ci		/* Set FIFO High Threshold Select */
117662306a36Sopenharmony_ci		reg_value =
117762306a36Sopenharmony_ci		    IGA1_FIFO_HIGH_THRESHOLD_FORMULA(iga1_fifo_high_threshold);
117862306a36Sopenharmony_ci		viafb_load_reg_num =
117962306a36Sopenharmony_ci		    fifo_high_threshold_select_reg.
118062306a36Sopenharmony_ci		    iga1_fifo_high_threshold_select_reg.reg_num;
118162306a36Sopenharmony_ci		reg =
118262306a36Sopenharmony_ci		    fifo_high_threshold_select_reg.
118362306a36Sopenharmony_ci		    iga1_fifo_high_threshold_select_reg.reg;
118462306a36Sopenharmony_ci		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
118562306a36Sopenharmony_ci
118662306a36Sopenharmony_ci		/* Set Display Queue Expire Num */
118762306a36Sopenharmony_ci		reg_value =
118862306a36Sopenharmony_ci		    IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
118962306a36Sopenharmony_ci		    (iga1_display_queue_expire_num);
119062306a36Sopenharmony_ci		viafb_load_reg_num =
119162306a36Sopenharmony_ci		    display_queue_expire_num_reg.
119262306a36Sopenharmony_ci		    iga1_display_queue_expire_num_reg.reg_num;
119362306a36Sopenharmony_ci		reg =
119462306a36Sopenharmony_ci		    display_queue_expire_num_reg.
119562306a36Sopenharmony_ci		    iga1_display_queue_expire_num_reg.reg;
119662306a36Sopenharmony_ci		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
119762306a36Sopenharmony_ci
119862306a36Sopenharmony_ci	} else {
119962306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
120062306a36Sopenharmony_ci			iga2_fifo_max_depth = K800_IGA2_FIFO_MAX_DEPTH;
120162306a36Sopenharmony_ci			iga2_fifo_threshold = K800_IGA2_FIFO_THRESHOLD;
120262306a36Sopenharmony_ci			iga2_fifo_high_threshold =
120362306a36Sopenharmony_ci			    K800_IGA2_FIFO_HIGH_THRESHOLD;
120462306a36Sopenharmony_ci
120562306a36Sopenharmony_ci			/* If resolution > 1280x1024, expire length = 64,
120662306a36Sopenharmony_ci			   else  expire length = 128 */
120762306a36Sopenharmony_ci			if ((hor_active > 1280) && (ver_active > 1024))
120862306a36Sopenharmony_ci				iga2_display_queue_expire_num = 16;
120962306a36Sopenharmony_ci			else
121062306a36Sopenharmony_ci				iga2_display_queue_expire_num =
121162306a36Sopenharmony_ci				    K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
121262306a36Sopenharmony_ci		}
121362306a36Sopenharmony_ci
121462306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
121562306a36Sopenharmony_ci			iga2_fifo_max_depth = P880_IGA2_FIFO_MAX_DEPTH;
121662306a36Sopenharmony_ci			iga2_fifo_threshold = P880_IGA2_FIFO_THRESHOLD;
121762306a36Sopenharmony_ci			iga2_fifo_high_threshold =
121862306a36Sopenharmony_ci			    P880_IGA2_FIFO_HIGH_THRESHOLD;
121962306a36Sopenharmony_ci
122062306a36Sopenharmony_ci			/* If resolution > 1280x1024, expire length = 64,
122162306a36Sopenharmony_ci			   else  expire length = 128 */
122262306a36Sopenharmony_ci			if ((hor_active > 1280) && (ver_active > 1024))
122362306a36Sopenharmony_ci				iga2_display_queue_expire_num = 16;
122462306a36Sopenharmony_ci			else
122562306a36Sopenharmony_ci				iga2_display_queue_expire_num =
122662306a36Sopenharmony_ci				    P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
122762306a36Sopenharmony_ci		}
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
123062306a36Sopenharmony_ci			iga2_fifo_max_depth = CN700_IGA2_FIFO_MAX_DEPTH;
123162306a36Sopenharmony_ci			iga2_fifo_threshold = CN700_IGA2_FIFO_THRESHOLD;
123262306a36Sopenharmony_ci			iga2_fifo_high_threshold =
123362306a36Sopenharmony_ci			    CN700_IGA2_FIFO_HIGH_THRESHOLD;
123462306a36Sopenharmony_ci
123562306a36Sopenharmony_ci			/* If resolution > 1280x1024, expire length = 64,
123662306a36Sopenharmony_ci			   else expire length = 128 */
123762306a36Sopenharmony_ci			if ((hor_active > 1280) && (ver_active > 1024))
123862306a36Sopenharmony_ci				iga2_display_queue_expire_num = 16;
123962306a36Sopenharmony_ci			else
124062306a36Sopenharmony_ci				iga2_display_queue_expire_num =
124162306a36Sopenharmony_ci				    CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
124262306a36Sopenharmony_ci		}
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
124562306a36Sopenharmony_ci			iga2_fifo_max_depth = CX700_IGA2_FIFO_MAX_DEPTH;
124662306a36Sopenharmony_ci			iga2_fifo_threshold = CX700_IGA2_FIFO_THRESHOLD;
124762306a36Sopenharmony_ci			iga2_fifo_high_threshold =
124862306a36Sopenharmony_ci			    CX700_IGA2_FIFO_HIGH_THRESHOLD;
124962306a36Sopenharmony_ci			iga2_display_queue_expire_num =
125062306a36Sopenharmony_ci			    CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
125162306a36Sopenharmony_ci		}
125262306a36Sopenharmony_ci
125362306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
125462306a36Sopenharmony_ci			iga2_fifo_max_depth = K8M890_IGA2_FIFO_MAX_DEPTH;
125562306a36Sopenharmony_ci			iga2_fifo_threshold = K8M890_IGA2_FIFO_THRESHOLD;
125662306a36Sopenharmony_ci			iga2_fifo_high_threshold =
125762306a36Sopenharmony_ci			    K8M890_IGA2_FIFO_HIGH_THRESHOLD;
125862306a36Sopenharmony_ci			iga2_display_queue_expire_num =
125962306a36Sopenharmony_ci			    K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
126062306a36Sopenharmony_ci		}
126162306a36Sopenharmony_ci
126262306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
126362306a36Sopenharmony_ci			iga2_fifo_max_depth = P4M890_IGA2_FIFO_MAX_DEPTH;
126462306a36Sopenharmony_ci			iga2_fifo_threshold = P4M890_IGA2_FIFO_THRESHOLD;
126562306a36Sopenharmony_ci			iga2_fifo_high_threshold =
126662306a36Sopenharmony_ci			    P4M890_IGA2_FIFO_HIGH_THRESHOLD;
126762306a36Sopenharmony_ci			iga2_display_queue_expire_num =
126862306a36Sopenharmony_ci			    P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
126962306a36Sopenharmony_ci		}
127062306a36Sopenharmony_ci
127162306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
127262306a36Sopenharmony_ci			iga2_fifo_max_depth = P4M900_IGA2_FIFO_MAX_DEPTH;
127362306a36Sopenharmony_ci			iga2_fifo_threshold = P4M900_IGA2_FIFO_THRESHOLD;
127462306a36Sopenharmony_ci			iga2_fifo_high_threshold =
127562306a36Sopenharmony_ci			    P4M900_IGA2_FIFO_HIGH_THRESHOLD;
127662306a36Sopenharmony_ci			iga2_display_queue_expire_num =
127762306a36Sopenharmony_ci			    P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
127862306a36Sopenharmony_ci		}
127962306a36Sopenharmony_ci
128062306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
128162306a36Sopenharmony_ci			iga2_fifo_max_depth = VX800_IGA2_FIFO_MAX_DEPTH;
128262306a36Sopenharmony_ci			iga2_fifo_threshold = VX800_IGA2_FIFO_THRESHOLD;
128362306a36Sopenharmony_ci			iga2_fifo_high_threshold =
128462306a36Sopenharmony_ci			    VX800_IGA2_FIFO_HIGH_THRESHOLD;
128562306a36Sopenharmony_ci			iga2_display_queue_expire_num =
128662306a36Sopenharmony_ci			    VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
128762306a36Sopenharmony_ci		}
128862306a36Sopenharmony_ci
128962306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {
129062306a36Sopenharmony_ci			iga2_fifo_max_depth = VX855_IGA2_FIFO_MAX_DEPTH;
129162306a36Sopenharmony_ci			iga2_fifo_threshold = VX855_IGA2_FIFO_THRESHOLD;
129262306a36Sopenharmony_ci			iga2_fifo_high_threshold =
129362306a36Sopenharmony_ci			    VX855_IGA2_FIFO_HIGH_THRESHOLD;
129462306a36Sopenharmony_ci			iga2_display_queue_expire_num =
129562306a36Sopenharmony_ci			    VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
129662306a36Sopenharmony_ci		}
129762306a36Sopenharmony_ci
129862306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) {
129962306a36Sopenharmony_ci			iga2_fifo_max_depth = VX900_IGA2_FIFO_MAX_DEPTH;
130062306a36Sopenharmony_ci			iga2_fifo_threshold = VX900_IGA2_FIFO_THRESHOLD;
130162306a36Sopenharmony_ci			iga2_fifo_high_threshold =
130262306a36Sopenharmony_ci			    VX900_IGA2_FIFO_HIGH_THRESHOLD;
130362306a36Sopenharmony_ci			iga2_display_queue_expire_num =
130462306a36Sopenharmony_ci			    VX900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
130562306a36Sopenharmony_ci		}
130662306a36Sopenharmony_ci
130762306a36Sopenharmony_ci		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
130862306a36Sopenharmony_ci			/* Set Display FIFO Depath Select */
130962306a36Sopenharmony_ci			reg_value =
131062306a36Sopenharmony_ci			    IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth)
131162306a36Sopenharmony_ci			    - 1;
131262306a36Sopenharmony_ci			/* Patch LCD in IGA2 case */
131362306a36Sopenharmony_ci			viafb_load_reg_num =
131462306a36Sopenharmony_ci			    display_fifo_depth_reg.
131562306a36Sopenharmony_ci			    iga2_fifo_depth_select_reg.reg_num;
131662306a36Sopenharmony_ci			reg =
131762306a36Sopenharmony_ci			    display_fifo_depth_reg.
131862306a36Sopenharmony_ci			    iga2_fifo_depth_select_reg.reg;
131962306a36Sopenharmony_ci			viafb_load_reg(reg_value,
132062306a36Sopenharmony_ci				viafb_load_reg_num, reg, VIACR);
132162306a36Sopenharmony_ci		} else {
132262306a36Sopenharmony_ci
132362306a36Sopenharmony_ci			/* Set Display FIFO Depath Select */
132462306a36Sopenharmony_ci			reg_value =
132562306a36Sopenharmony_ci			    IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth);
132662306a36Sopenharmony_ci			viafb_load_reg_num =
132762306a36Sopenharmony_ci			    display_fifo_depth_reg.
132862306a36Sopenharmony_ci			    iga2_fifo_depth_select_reg.reg_num;
132962306a36Sopenharmony_ci			reg =
133062306a36Sopenharmony_ci			    display_fifo_depth_reg.
133162306a36Sopenharmony_ci			    iga2_fifo_depth_select_reg.reg;
133262306a36Sopenharmony_ci			viafb_load_reg(reg_value,
133362306a36Sopenharmony_ci				viafb_load_reg_num, reg, VIACR);
133462306a36Sopenharmony_ci		}
133562306a36Sopenharmony_ci
133662306a36Sopenharmony_ci		/* Set Display FIFO Threshold Select */
133762306a36Sopenharmony_ci		reg_value = IGA2_FIFO_THRESHOLD_FORMULA(iga2_fifo_threshold);
133862306a36Sopenharmony_ci		viafb_load_reg_num =
133962306a36Sopenharmony_ci		    fifo_threshold_select_reg.
134062306a36Sopenharmony_ci		    iga2_fifo_threshold_select_reg.reg_num;
134162306a36Sopenharmony_ci		reg =
134262306a36Sopenharmony_ci		    fifo_threshold_select_reg.
134362306a36Sopenharmony_ci		    iga2_fifo_threshold_select_reg.reg;
134462306a36Sopenharmony_ci		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
134562306a36Sopenharmony_ci
134662306a36Sopenharmony_ci		/* Set FIFO High Threshold Select */
134762306a36Sopenharmony_ci		reg_value =
134862306a36Sopenharmony_ci		    IGA2_FIFO_HIGH_THRESHOLD_FORMULA(iga2_fifo_high_threshold);
134962306a36Sopenharmony_ci		viafb_load_reg_num =
135062306a36Sopenharmony_ci		    fifo_high_threshold_select_reg.
135162306a36Sopenharmony_ci		    iga2_fifo_high_threshold_select_reg.reg_num;
135262306a36Sopenharmony_ci		reg =
135362306a36Sopenharmony_ci		    fifo_high_threshold_select_reg.
135462306a36Sopenharmony_ci		    iga2_fifo_high_threshold_select_reg.reg;
135562306a36Sopenharmony_ci		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
135662306a36Sopenharmony_ci
135762306a36Sopenharmony_ci		/* Set Display Queue Expire Num */
135862306a36Sopenharmony_ci		reg_value =
135962306a36Sopenharmony_ci		    IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
136062306a36Sopenharmony_ci		    (iga2_display_queue_expire_num);
136162306a36Sopenharmony_ci		viafb_load_reg_num =
136262306a36Sopenharmony_ci		    display_queue_expire_num_reg.
136362306a36Sopenharmony_ci		    iga2_display_queue_expire_num_reg.reg_num;
136462306a36Sopenharmony_ci		reg =
136562306a36Sopenharmony_ci		    display_queue_expire_num_reg.
136662306a36Sopenharmony_ci		    iga2_display_queue_expire_num_reg.reg;
136762306a36Sopenharmony_ci		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
136862306a36Sopenharmony_ci
136962306a36Sopenharmony_ci	}
137062306a36Sopenharmony_ci
137162306a36Sopenharmony_ci}
137262306a36Sopenharmony_ci
137362306a36Sopenharmony_cistatic struct via_pll_config get_pll_config(struct pll_limit *limits, int size,
137462306a36Sopenharmony_ci	int clk)
137562306a36Sopenharmony_ci{
137662306a36Sopenharmony_ci	struct via_pll_config cur, up, down, best = {0, 1, 0};
137762306a36Sopenharmony_ci	const u32 f0 = 14318180; /* X1 frequency */
137862306a36Sopenharmony_ci	int i, f;
137962306a36Sopenharmony_ci
138062306a36Sopenharmony_ci	for (i = 0; i < size; i++) {
138162306a36Sopenharmony_ci		cur.rshift = limits[i].rshift;
138262306a36Sopenharmony_ci		cur.divisor = limits[i].divisor;
138362306a36Sopenharmony_ci		cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift);
138462306a36Sopenharmony_ci		f = abs(get_pll_output_frequency(f0, cur) - clk);
138562306a36Sopenharmony_ci		up = down = cur;
138662306a36Sopenharmony_ci		up.multiplier++;
138762306a36Sopenharmony_ci		down.multiplier--;
138862306a36Sopenharmony_ci		if (abs(get_pll_output_frequency(f0, up) - clk) < f)
138962306a36Sopenharmony_ci			cur = up;
139062306a36Sopenharmony_ci		else if (abs(get_pll_output_frequency(f0, down) - clk) < f)
139162306a36Sopenharmony_ci			cur = down;
139262306a36Sopenharmony_ci
139362306a36Sopenharmony_ci		if (cur.multiplier < limits[i].multiplier_min)
139462306a36Sopenharmony_ci			cur.multiplier = limits[i].multiplier_min;
139562306a36Sopenharmony_ci		else if (cur.multiplier > limits[i].multiplier_max)
139662306a36Sopenharmony_ci			cur.multiplier = limits[i].multiplier_max;
139762306a36Sopenharmony_ci
139862306a36Sopenharmony_ci		f = abs(get_pll_output_frequency(f0, cur) - clk);
139962306a36Sopenharmony_ci		if (f < abs(get_pll_output_frequency(f0, best) - clk))
140062306a36Sopenharmony_ci			best = cur;
140162306a36Sopenharmony_ci	}
140262306a36Sopenharmony_ci
140362306a36Sopenharmony_ci	return best;
140462306a36Sopenharmony_ci}
140562306a36Sopenharmony_ci
140662306a36Sopenharmony_cistatic struct via_pll_config get_best_pll_config(int clk)
140762306a36Sopenharmony_ci{
140862306a36Sopenharmony_ci	struct via_pll_config config;
140962306a36Sopenharmony_ci
141062306a36Sopenharmony_ci	switch (viaparinfo->chip_info->gfx_chip_name) {
141162306a36Sopenharmony_ci	case UNICHROME_CLE266:
141262306a36Sopenharmony_ci	case UNICHROME_K400:
141362306a36Sopenharmony_ci		config = get_pll_config(cle266_pll_limits,
141462306a36Sopenharmony_ci			ARRAY_SIZE(cle266_pll_limits), clk);
141562306a36Sopenharmony_ci		break;
141662306a36Sopenharmony_ci	case UNICHROME_K800:
141762306a36Sopenharmony_ci	case UNICHROME_PM800:
141862306a36Sopenharmony_ci	case UNICHROME_CN700:
141962306a36Sopenharmony_ci		config = get_pll_config(k800_pll_limits,
142062306a36Sopenharmony_ci			ARRAY_SIZE(k800_pll_limits), clk);
142162306a36Sopenharmony_ci		break;
142262306a36Sopenharmony_ci	case UNICHROME_CX700:
142362306a36Sopenharmony_ci	case UNICHROME_CN750:
142462306a36Sopenharmony_ci	case UNICHROME_K8M890:
142562306a36Sopenharmony_ci	case UNICHROME_P4M890:
142662306a36Sopenharmony_ci	case UNICHROME_P4M900:
142762306a36Sopenharmony_ci	case UNICHROME_VX800:
142862306a36Sopenharmony_ci		config = get_pll_config(cx700_pll_limits,
142962306a36Sopenharmony_ci			ARRAY_SIZE(cx700_pll_limits), clk);
143062306a36Sopenharmony_ci		break;
143162306a36Sopenharmony_ci	case UNICHROME_VX855:
143262306a36Sopenharmony_ci	case UNICHROME_VX900:
143362306a36Sopenharmony_ci		config = get_pll_config(vx855_pll_limits,
143462306a36Sopenharmony_ci			ARRAY_SIZE(vx855_pll_limits), clk);
143562306a36Sopenharmony_ci		break;
143662306a36Sopenharmony_ci	}
143762306a36Sopenharmony_ci
143862306a36Sopenharmony_ci	return config;
143962306a36Sopenharmony_ci}
144062306a36Sopenharmony_ci
144162306a36Sopenharmony_ci/* Set VCLK*/
144262306a36Sopenharmony_civoid viafb_set_vclock(u32 clk, int set_iga)
144362306a36Sopenharmony_ci{
144462306a36Sopenharmony_ci	struct via_pll_config config = get_best_pll_config(clk);
144562306a36Sopenharmony_ci
144662306a36Sopenharmony_ci	if (set_iga == IGA1)
144762306a36Sopenharmony_ci		clock.set_primary_pll(config);
144862306a36Sopenharmony_ci	if (set_iga == IGA2)
144962306a36Sopenharmony_ci		clock.set_secondary_pll(config);
145062306a36Sopenharmony_ci
145162306a36Sopenharmony_ci	/* Fire! */
145262306a36Sopenharmony_ci	via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
145362306a36Sopenharmony_ci}
145462306a36Sopenharmony_ci
145562306a36Sopenharmony_cistruct via_display_timing var_to_timing(const struct fb_var_screeninfo *var,
145662306a36Sopenharmony_ci	u16 cxres, u16 cyres)
145762306a36Sopenharmony_ci{
145862306a36Sopenharmony_ci	struct via_display_timing timing;
145962306a36Sopenharmony_ci	u16 dx = (var->xres - cxres) / 2, dy = (var->yres - cyres) / 2;
146062306a36Sopenharmony_ci
146162306a36Sopenharmony_ci	timing.hor_addr = cxres;
146262306a36Sopenharmony_ci	timing.hor_sync_start = timing.hor_addr + var->right_margin + dx;
146362306a36Sopenharmony_ci	timing.hor_sync_end = timing.hor_sync_start + var->hsync_len;
146462306a36Sopenharmony_ci	timing.hor_total = timing.hor_sync_end + var->left_margin + dx;
146562306a36Sopenharmony_ci	timing.hor_blank_start = timing.hor_addr + dx;
146662306a36Sopenharmony_ci	timing.hor_blank_end = timing.hor_total - dx;
146762306a36Sopenharmony_ci	timing.ver_addr = cyres;
146862306a36Sopenharmony_ci	timing.ver_sync_start = timing.ver_addr + var->lower_margin + dy;
146962306a36Sopenharmony_ci	timing.ver_sync_end = timing.ver_sync_start + var->vsync_len;
147062306a36Sopenharmony_ci	timing.ver_total = timing.ver_sync_end + var->upper_margin + dy;
147162306a36Sopenharmony_ci	timing.ver_blank_start = timing.ver_addr + dy;
147262306a36Sopenharmony_ci	timing.ver_blank_end = timing.ver_total - dy;
147362306a36Sopenharmony_ci	return timing;
147462306a36Sopenharmony_ci}
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_civoid viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
147762306a36Sopenharmony_ci	u16 cxres, u16 cyres, int iga)
147862306a36Sopenharmony_ci{
147962306a36Sopenharmony_ci	struct via_display_timing crt_reg = var_to_timing(var,
148062306a36Sopenharmony_ci		cxres ? cxres : var->xres, cyres ? cyres : var->yres);
148162306a36Sopenharmony_ci
148262306a36Sopenharmony_ci	if (iga == IGA1)
148362306a36Sopenharmony_ci		via_set_primary_timing(&crt_reg);
148462306a36Sopenharmony_ci	else if (iga == IGA2)
148562306a36Sopenharmony_ci		via_set_secondary_timing(&crt_reg);
148662306a36Sopenharmony_ci
148762306a36Sopenharmony_ci	viafb_load_fetch_count_reg(var->xres, var->bits_per_pixel / 8, iga);
148862306a36Sopenharmony_ci	if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266
148962306a36Sopenharmony_ci		&& viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)
149062306a36Sopenharmony_ci		viafb_load_FIFO_reg(iga, var->xres, var->yres);
149162306a36Sopenharmony_ci
149262306a36Sopenharmony_ci	viafb_set_vclock(PICOS2KHZ(var->pixclock) * 1000, iga);
149362306a36Sopenharmony_ci}
149462306a36Sopenharmony_ci
149562306a36Sopenharmony_civoid viafb_init_chip_info(int chip_type)
149662306a36Sopenharmony_ci{
149762306a36Sopenharmony_ci	via_clock_init(&clock, chip_type);
149862306a36Sopenharmony_ci	init_gfx_chip_info(chip_type);
149962306a36Sopenharmony_ci	init_tmds_chip_info();
150062306a36Sopenharmony_ci	init_lvds_chip_info();
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci	/*Set IGA path for each device */
150362306a36Sopenharmony_ci	viafb_set_iga_path();
150462306a36Sopenharmony_ci
150562306a36Sopenharmony_ci	viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method;
150662306a36Sopenharmony_ci	viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode;
150762306a36Sopenharmony_ci	viaparinfo->lvds_setting_info2->display_method =
150862306a36Sopenharmony_ci		viaparinfo->lvds_setting_info->display_method;
150962306a36Sopenharmony_ci	viaparinfo->lvds_setting_info2->lcd_mode =
151062306a36Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_mode;
151162306a36Sopenharmony_ci}
151262306a36Sopenharmony_ci
151362306a36Sopenharmony_civoid viafb_update_device_setting(int hres, int vres, int bpp, int flag)
151462306a36Sopenharmony_ci{
151562306a36Sopenharmony_ci	if (flag == 0) {
151662306a36Sopenharmony_ci		viaparinfo->tmds_setting_info->h_active = hres;
151762306a36Sopenharmony_ci		viaparinfo->tmds_setting_info->v_active = vres;
151862306a36Sopenharmony_ci	} else {
151962306a36Sopenharmony_ci
152062306a36Sopenharmony_ci		if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
152162306a36Sopenharmony_ci			viaparinfo->tmds_setting_info->h_active = hres;
152262306a36Sopenharmony_ci			viaparinfo->tmds_setting_info->v_active = vres;
152362306a36Sopenharmony_ci		}
152462306a36Sopenharmony_ci
152562306a36Sopenharmony_ci	}
152662306a36Sopenharmony_ci}
152762306a36Sopenharmony_ci
152862306a36Sopenharmony_cistatic void init_gfx_chip_info(int chip_type)
152962306a36Sopenharmony_ci{
153062306a36Sopenharmony_ci	u8 tmp;
153162306a36Sopenharmony_ci
153262306a36Sopenharmony_ci	viaparinfo->chip_info->gfx_chip_name = chip_type;
153362306a36Sopenharmony_ci
153462306a36Sopenharmony_ci	/* Check revision of CLE266 Chip */
153562306a36Sopenharmony_ci	if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
153662306a36Sopenharmony_ci		/* CR4F only define in CLE266.CX chip */
153762306a36Sopenharmony_ci		tmp = viafb_read_reg(VIACR, CR4F);
153862306a36Sopenharmony_ci		viafb_write_reg(CR4F, VIACR, 0x55);
153962306a36Sopenharmony_ci		if (viafb_read_reg(VIACR, CR4F) != 0x55)
154062306a36Sopenharmony_ci			viaparinfo->chip_info->gfx_chip_revision =
154162306a36Sopenharmony_ci			CLE266_REVISION_AX;
154262306a36Sopenharmony_ci		else
154362306a36Sopenharmony_ci			viaparinfo->chip_info->gfx_chip_revision =
154462306a36Sopenharmony_ci			CLE266_REVISION_CX;
154562306a36Sopenharmony_ci		/* restore orignal CR4F value */
154662306a36Sopenharmony_ci		viafb_write_reg(CR4F, VIACR, tmp);
154762306a36Sopenharmony_ci	}
154862306a36Sopenharmony_ci
154962306a36Sopenharmony_ci	if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
155062306a36Sopenharmony_ci		tmp = viafb_read_reg(VIASR, SR43);
155162306a36Sopenharmony_ci		DEBUG_MSG(KERN_INFO "SR43:%X\n", tmp);
155262306a36Sopenharmony_ci		if (tmp & 0x02) {
155362306a36Sopenharmony_ci			viaparinfo->chip_info->gfx_chip_revision =
155462306a36Sopenharmony_ci				CX700_REVISION_700M2;
155562306a36Sopenharmony_ci		} else if (tmp & 0x40) {
155662306a36Sopenharmony_ci			viaparinfo->chip_info->gfx_chip_revision =
155762306a36Sopenharmony_ci				CX700_REVISION_700M;
155862306a36Sopenharmony_ci		} else {
155962306a36Sopenharmony_ci			viaparinfo->chip_info->gfx_chip_revision =
156062306a36Sopenharmony_ci				CX700_REVISION_700;
156162306a36Sopenharmony_ci		}
156262306a36Sopenharmony_ci	}
156362306a36Sopenharmony_ci
156462306a36Sopenharmony_ci	/* Determine which 2D engine we have */
156562306a36Sopenharmony_ci	switch (viaparinfo->chip_info->gfx_chip_name) {
156662306a36Sopenharmony_ci	case UNICHROME_VX800:
156762306a36Sopenharmony_ci	case UNICHROME_VX855:
156862306a36Sopenharmony_ci	case UNICHROME_VX900:
156962306a36Sopenharmony_ci		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_M1;
157062306a36Sopenharmony_ci		break;
157162306a36Sopenharmony_ci	case UNICHROME_K8M890:
157262306a36Sopenharmony_ci	case UNICHROME_P4M900:
157362306a36Sopenharmony_ci		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H5;
157462306a36Sopenharmony_ci		break;
157562306a36Sopenharmony_ci	default:
157662306a36Sopenharmony_ci		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H2;
157762306a36Sopenharmony_ci		break;
157862306a36Sopenharmony_ci	}
157962306a36Sopenharmony_ci}
158062306a36Sopenharmony_ci
158162306a36Sopenharmony_cistatic void init_tmds_chip_info(void)
158262306a36Sopenharmony_ci{
158362306a36Sopenharmony_ci	viafb_tmds_trasmitter_identify();
158462306a36Sopenharmony_ci
158562306a36Sopenharmony_ci	if (INTERFACE_NONE == viaparinfo->chip_info->tmds_chip_info.
158662306a36Sopenharmony_ci		output_interface) {
158762306a36Sopenharmony_ci		switch (viaparinfo->chip_info->gfx_chip_name) {
158862306a36Sopenharmony_ci		case UNICHROME_CX700:
158962306a36Sopenharmony_ci			{
159062306a36Sopenharmony_ci				/* we should check support by hardware layout.*/
159162306a36Sopenharmony_ci				if ((viafb_display_hardware_layout ==
159262306a36Sopenharmony_ci				     HW_LAYOUT_DVI_ONLY)
159362306a36Sopenharmony_ci				    || (viafb_display_hardware_layout ==
159462306a36Sopenharmony_ci					HW_LAYOUT_LCD_DVI)) {
159562306a36Sopenharmony_ci					viaparinfo->chip_info->tmds_chip_info.
159662306a36Sopenharmony_ci					    output_interface = INTERFACE_TMDS;
159762306a36Sopenharmony_ci				} else {
159862306a36Sopenharmony_ci					viaparinfo->chip_info->tmds_chip_info.
159962306a36Sopenharmony_ci						output_interface =
160062306a36Sopenharmony_ci						INTERFACE_NONE;
160162306a36Sopenharmony_ci				}
160262306a36Sopenharmony_ci				break;
160362306a36Sopenharmony_ci			}
160462306a36Sopenharmony_ci		case UNICHROME_K8M890:
160562306a36Sopenharmony_ci		case UNICHROME_P4M900:
160662306a36Sopenharmony_ci		case UNICHROME_P4M890:
160762306a36Sopenharmony_ci			/* TMDS on PCIE, we set DFPLOW as default. */
160862306a36Sopenharmony_ci			viaparinfo->chip_info->tmds_chip_info.output_interface =
160962306a36Sopenharmony_ci			    INTERFACE_DFP_LOW;
161062306a36Sopenharmony_ci			break;
161162306a36Sopenharmony_ci		default:
161262306a36Sopenharmony_ci			{
161362306a36Sopenharmony_ci				/* set DVP1 default for DVI */
161462306a36Sopenharmony_ci				viaparinfo->chip_info->tmds_chip_info
161562306a36Sopenharmony_ci				.output_interface = INTERFACE_DVP1;
161662306a36Sopenharmony_ci			}
161762306a36Sopenharmony_ci		}
161862306a36Sopenharmony_ci	}
161962306a36Sopenharmony_ci
162062306a36Sopenharmony_ci	DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n",
162162306a36Sopenharmony_ci		  viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
162262306a36Sopenharmony_ci	viafb_init_dvi_size(&viaparinfo->shared->chip_info.tmds_chip_info,
162362306a36Sopenharmony_ci		&viaparinfo->shared->tmds_setting_info);
162462306a36Sopenharmony_ci}
162562306a36Sopenharmony_ci
162662306a36Sopenharmony_cistatic void init_lvds_chip_info(void)
162762306a36Sopenharmony_ci{
162862306a36Sopenharmony_ci	viafb_lvds_trasmitter_identify();
162962306a36Sopenharmony_ci	viafb_init_lcd_size();
163062306a36Sopenharmony_ci	viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info,
163162306a36Sopenharmony_ci				   viaparinfo->lvds_setting_info);
163262306a36Sopenharmony_ci	if (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
163362306a36Sopenharmony_ci		viafb_init_lvds_output_interface(&viaparinfo->chip_info->
163462306a36Sopenharmony_ci			lvds_chip_info2, viaparinfo->lvds_setting_info2);
163562306a36Sopenharmony_ci	}
163662306a36Sopenharmony_ci	/*If CX700,two singel LCD, we need to reassign
163762306a36Sopenharmony_ci	   LCD interface to different LVDS port */
163862306a36Sopenharmony_ci	if ((UNICHROME_CX700 == viaparinfo->chip_info->gfx_chip_name)
163962306a36Sopenharmony_ci	    && (HW_LAYOUT_LCD1_LCD2 == viafb_display_hardware_layout)) {
164062306a36Sopenharmony_ci		if ((INTEGRATED_LVDS == viaparinfo->chip_info->lvds_chip_info.
164162306a36Sopenharmony_ci			lvds_chip_name) && (INTEGRATED_LVDS ==
164262306a36Sopenharmony_ci			viaparinfo->chip_info->
164362306a36Sopenharmony_ci			lvds_chip_info2.lvds_chip_name)) {
164462306a36Sopenharmony_ci			viaparinfo->chip_info->lvds_chip_info.output_interface =
164562306a36Sopenharmony_ci				INTERFACE_LVDS0;
164662306a36Sopenharmony_ci			viaparinfo->chip_info->lvds_chip_info2.
164762306a36Sopenharmony_ci				output_interface =
164862306a36Sopenharmony_ci			    INTERFACE_LVDS1;
164962306a36Sopenharmony_ci		}
165062306a36Sopenharmony_ci	}
165162306a36Sopenharmony_ci
165262306a36Sopenharmony_ci	DEBUG_MSG(KERN_INFO "LVDS Chip = %d\n",
165362306a36Sopenharmony_ci		  viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
165462306a36Sopenharmony_ci	DEBUG_MSG(KERN_INFO "LVDS1 output_interface = %d\n",
165562306a36Sopenharmony_ci		  viaparinfo->chip_info->lvds_chip_info.output_interface);
165662306a36Sopenharmony_ci	DEBUG_MSG(KERN_INFO "LVDS2 output_interface = %d\n",
165762306a36Sopenharmony_ci		  viaparinfo->chip_info->lvds_chip_info.output_interface);
165862306a36Sopenharmony_ci}
165962306a36Sopenharmony_ci
166062306a36Sopenharmony_civoid viafb_init_dac(int set_iga)
166162306a36Sopenharmony_ci{
166262306a36Sopenharmony_ci	int i;
166362306a36Sopenharmony_ci	u8 tmp;
166462306a36Sopenharmony_ci
166562306a36Sopenharmony_ci	if (set_iga == IGA1) {
166662306a36Sopenharmony_ci		/* access Primary Display's LUT */
166762306a36Sopenharmony_ci		viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
166862306a36Sopenharmony_ci		/* turn off LCK */
166962306a36Sopenharmony_ci		viafb_write_reg_mask(SR1B, VIASR, 0x00, BIT7 + BIT6);
167062306a36Sopenharmony_ci		for (i = 0; i < 256; i++) {
167162306a36Sopenharmony_ci			write_dac_reg(i, palLUT_table[i].red,
167262306a36Sopenharmony_ci				      palLUT_table[i].green,
167362306a36Sopenharmony_ci				      palLUT_table[i].blue);
167462306a36Sopenharmony_ci		}
167562306a36Sopenharmony_ci		/* turn on LCK */
167662306a36Sopenharmony_ci		viafb_write_reg_mask(SR1B, VIASR, 0xC0, BIT7 + BIT6);
167762306a36Sopenharmony_ci	} else {
167862306a36Sopenharmony_ci		tmp = viafb_read_reg(VIACR, CR6A);
167962306a36Sopenharmony_ci		/* access Secondary Display's LUT */
168062306a36Sopenharmony_ci		viafb_write_reg_mask(CR6A, VIACR, 0x40, BIT6);
168162306a36Sopenharmony_ci		viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
168262306a36Sopenharmony_ci		for (i = 0; i < 256; i++) {
168362306a36Sopenharmony_ci			write_dac_reg(i, palLUT_table[i].red,
168462306a36Sopenharmony_ci				      palLUT_table[i].green,
168562306a36Sopenharmony_ci				      palLUT_table[i].blue);
168662306a36Sopenharmony_ci		}
168762306a36Sopenharmony_ci		/* set IGA1 DAC for default */
168862306a36Sopenharmony_ci		viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
168962306a36Sopenharmony_ci		viafb_write_reg(CR6A, VIACR, tmp);
169062306a36Sopenharmony_ci	}
169162306a36Sopenharmony_ci}
169262306a36Sopenharmony_ci
169362306a36Sopenharmony_cistatic void device_screen_off(void)
169462306a36Sopenharmony_ci{
169562306a36Sopenharmony_ci	/* turn off CRT screen (IGA1) */
169662306a36Sopenharmony_ci	viafb_write_reg_mask(SR01, VIASR, 0x20, BIT5);
169762306a36Sopenharmony_ci}
169862306a36Sopenharmony_ci
169962306a36Sopenharmony_cistatic void device_screen_on(void)
170062306a36Sopenharmony_ci{
170162306a36Sopenharmony_ci	/* turn on CRT screen (IGA1) */
170262306a36Sopenharmony_ci	viafb_write_reg_mask(SR01, VIASR, 0x00, BIT5);
170362306a36Sopenharmony_ci}
170462306a36Sopenharmony_ci
170562306a36Sopenharmony_cistatic void set_display_channel(void)
170662306a36Sopenharmony_ci{
170762306a36Sopenharmony_ci	/*If viafb_LCD2_ON, on cx700, internal lvds's information
170862306a36Sopenharmony_ci	is keeped on lvds_setting_info2 */
170962306a36Sopenharmony_ci	if (viafb_LCD2_ON &&
171062306a36Sopenharmony_ci		viaparinfo->lvds_setting_info2->device_lcd_dualedge) {
171162306a36Sopenharmony_ci		/* For dual channel LCD: */
171262306a36Sopenharmony_ci		/* Set to Dual LVDS channel. */
171362306a36Sopenharmony_ci		viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
171462306a36Sopenharmony_ci	} else if (viafb_LCD_ON && viafb_DVI_ON) {
171562306a36Sopenharmony_ci		/* For LCD+DFP: */
171662306a36Sopenharmony_ci		/* Set to LVDS1 + TMDS channel. */
171762306a36Sopenharmony_ci		viafb_write_reg_mask(CRD2, VIACR, 0x10, BIT4 + BIT5);
171862306a36Sopenharmony_ci	} else if (viafb_DVI_ON) {
171962306a36Sopenharmony_ci		/* Set to single TMDS channel. */
172062306a36Sopenharmony_ci		viafb_write_reg_mask(CRD2, VIACR, 0x30, BIT4 + BIT5);
172162306a36Sopenharmony_ci	} else if (viafb_LCD_ON) {
172262306a36Sopenharmony_ci		if (viaparinfo->lvds_setting_info->device_lcd_dualedge) {
172362306a36Sopenharmony_ci			/* For dual channel LCD: */
172462306a36Sopenharmony_ci			/* Set to Dual LVDS channel. */
172562306a36Sopenharmony_ci			viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
172662306a36Sopenharmony_ci		} else {
172762306a36Sopenharmony_ci			/* Set to LVDS0 + LVDS1 channel. */
172862306a36Sopenharmony_ci			viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT4 + BIT5);
172962306a36Sopenharmony_ci		}
173062306a36Sopenharmony_ci	}
173162306a36Sopenharmony_ci}
173262306a36Sopenharmony_ci
173362306a36Sopenharmony_cistatic u8 get_sync(struct fb_var_screeninfo *var)
173462306a36Sopenharmony_ci{
173562306a36Sopenharmony_ci	u8 polarity = 0;
173662306a36Sopenharmony_ci
173762306a36Sopenharmony_ci	if (!(var->sync & FB_SYNC_HOR_HIGH_ACT))
173862306a36Sopenharmony_ci		polarity |= VIA_HSYNC_NEGATIVE;
173962306a36Sopenharmony_ci	if (!(var->sync & FB_SYNC_VERT_HIGH_ACT))
174062306a36Sopenharmony_ci		polarity |= VIA_VSYNC_NEGATIVE;
174162306a36Sopenharmony_ci	return polarity;
174262306a36Sopenharmony_ci}
174362306a36Sopenharmony_ci
174462306a36Sopenharmony_cistatic void hw_init(void)
174562306a36Sopenharmony_ci{
174662306a36Sopenharmony_ci	int i;
174762306a36Sopenharmony_ci
174862306a36Sopenharmony_ci	inb(VIAStatus);
174962306a36Sopenharmony_ci	outb(0x00, VIAAR);
175062306a36Sopenharmony_ci
175162306a36Sopenharmony_ci	/* Write Common Setting for Video Mode */
175262306a36Sopenharmony_ci	viafb_write_regx(common_vga, ARRAY_SIZE(common_vga));
175362306a36Sopenharmony_ci	switch (viaparinfo->chip_info->gfx_chip_name) {
175462306a36Sopenharmony_ci	case UNICHROME_CLE266:
175562306a36Sopenharmony_ci		viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs);
175662306a36Sopenharmony_ci		break;
175762306a36Sopenharmony_ci
175862306a36Sopenharmony_ci	case UNICHROME_K400:
175962306a36Sopenharmony_ci		viafb_write_regx(KM400_ModeXregs, NUM_TOTAL_KM400_ModeXregs);
176062306a36Sopenharmony_ci		break;
176162306a36Sopenharmony_ci
176262306a36Sopenharmony_ci	case UNICHROME_K800:
176362306a36Sopenharmony_ci	case UNICHROME_PM800:
176462306a36Sopenharmony_ci		viafb_write_regx(CN400_ModeXregs, NUM_TOTAL_CN400_ModeXregs);
176562306a36Sopenharmony_ci		break;
176662306a36Sopenharmony_ci
176762306a36Sopenharmony_ci	case UNICHROME_CN700:
176862306a36Sopenharmony_ci	case UNICHROME_K8M890:
176962306a36Sopenharmony_ci	case UNICHROME_P4M890:
177062306a36Sopenharmony_ci	case UNICHROME_P4M900:
177162306a36Sopenharmony_ci		viafb_write_regx(CN700_ModeXregs, NUM_TOTAL_CN700_ModeXregs);
177262306a36Sopenharmony_ci		break;
177362306a36Sopenharmony_ci
177462306a36Sopenharmony_ci	case UNICHROME_CX700:
177562306a36Sopenharmony_ci	case UNICHROME_VX800:
177662306a36Sopenharmony_ci		viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs);
177762306a36Sopenharmony_ci		break;
177862306a36Sopenharmony_ci
177962306a36Sopenharmony_ci	case UNICHROME_VX855:
178062306a36Sopenharmony_ci	case UNICHROME_VX900:
178162306a36Sopenharmony_ci		viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs);
178262306a36Sopenharmony_ci		break;
178362306a36Sopenharmony_ci	}
178462306a36Sopenharmony_ci
178562306a36Sopenharmony_ci	/* magic required on VX900 for correct modesetting on IGA1 */
178662306a36Sopenharmony_ci	via_write_reg_mask(VIACR, 0x45, 0x00, 0x01);
178762306a36Sopenharmony_ci
178862306a36Sopenharmony_ci	/* probably this should go to the scaling code one day */
178962306a36Sopenharmony_ci	via_write_reg_mask(VIACR, 0xFD, 0, 0x80); /* VX900 hw scale on IGA2 */
179062306a36Sopenharmony_ci	viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters));
179162306a36Sopenharmony_ci
179262306a36Sopenharmony_ci	/* Fill VPIT Parameters */
179362306a36Sopenharmony_ci	/* Write Misc Register */
179462306a36Sopenharmony_ci	outb(VPIT.Misc, VIA_MISC_REG_WRITE);
179562306a36Sopenharmony_ci
179662306a36Sopenharmony_ci	/* Write Sequencer */
179762306a36Sopenharmony_ci	for (i = 1; i <= StdSR; i++)
179862306a36Sopenharmony_ci		via_write_reg(VIASR, i, VPIT.SR[i - 1]);
179962306a36Sopenharmony_ci
180062306a36Sopenharmony_ci	viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2);
180162306a36Sopenharmony_ci
180262306a36Sopenharmony_ci	/* Write Graphic Controller */
180362306a36Sopenharmony_ci	for (i = 0; i < StdGR; i++)
180462306a36Sopenharmony_ci		via_write_reg(VIAGR, i, VPIT.GR[i]);
180562306a36Sopenharmony_ci
180662306a36Sopenharmony_ci	/* Write Attribute Controller */
180762306a36Sopenharmony_ci	for (i = 0; i < StdAR; i++) {
180862306a36Sopenharmony_ci		inb(VIAStatus);
180962306a36Sopenharmony_ci		outb(i, VIAAR);
181062306a36Sopenharmony_ci		outb(VPIT.AR[i], VIAAR);
181162306a36Sopenharmony_ci	}
181262306a36Sopenharmony_ci
181362306a36Sopenharmony_ci	inb(VIAStatus);
181462306a36Sopenharmony_ci	outb(0x20, VIAAR);
181562306a36Sopenharmony_ci
181662306a36Sopenharmony_ci	load_fix_bit_crtc_reg();
181762306a36Sopenharmony_ci}
181862306a36Sopenharmony_ci
181962306a36Sopenharmony_ciint viafb_setmode(void)
182062306a36Sopenharmony_ci{
182162306a36Sopenharmony_ci	int j, cxres = 0, cyres = 0;
182262306a36Sopenharmony_ci	int port;
182362306a36Sopenharmony_ci	u32 devices = viaparinfo->shared->iga1_devices
182462306a36Sopenharmony_ci		| viaparinfo->shared->iga2_devices;
182562306a36Sopenharmony_ci	u8 value, index, mask;
182662306a36Sopenharmony_ci	struct fb_var_screeninfo var2;
182762306a36Sopenharmony_ci
182862306a36Sopenharmony_ci	device_screen_off();
182962306a36Sopenharmony_ci	device_off();
183062306a36Sopenharmony_ci	via_set_state(devices, VIA_STATE_OFF);
183162306a36Sopenharmony_ci
183262306a36Sopenharmony_ci	hw_init();
183362306a36Sopenharmony_ci
183462306a36Sopenharmony_ci	/* Update Patch Register */
183562306a36Sopenharmony_ci
183662306a36Sopenharmony_ci	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266
183762306a36Sopenharmony_ci		|| viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)
183862306a36Sopenharmony_ci		&& viafbinfo->var.xres == 1024 && viafbinfo->var.yres == 768) {
183962306a36Sopenharmony_ci		for (j = 0; j < res_patch_table[0].table_length; j++) {
184062306a36Sopenharmony_ci			index = res_patch_table[0].io_reg_table[j].index;
184162306a36Sopenharmony_ci			port = res_patch_table[0].io_reg_table[j].port;
184262306a36Sopenharmony_ci			value = res_patch_table[0].io_reg_table[j].value;
184362306a36Sopenharmony_ci			mask = res_patch_table[0].io_reg_table[j].mask;
184462306a36Sopenharmony_ci			viafb_write_reg_mask(index, port, value, mask);
184562306a36Sopenharmony_ci		}
184662306a36Sopenharmony_ci	}
184762306a36Sopenharmony_ci
184862306a36Sopenharmony_ci	via_set_primary_pitch(viafbinfo->fix.line_length);
184962306a36Sopenharmony_ci	via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length
185062306a36Sopenharmony_ci		: viafbinfo->fix.line_length);
185162306a36Sopenharmony_ci	via_set_primary_color_depth(viaparinfo->depth);
185262306a36Sopenharmony_ci	via_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth
185362306a36Sopenharmony_ci		: viaparinfo->depth);
185462306a36Sopenharmony_ci	via_set_source(viaparinfo->shared->iga1_devices, IGA1);
185562306a36Sopenharmony_ci	via_set_source(viaparinfo->shared->iga2_devices, IGA2);
185662306a36Sopenharmony_ci	if (viaparinfo->shared->iga2_devices)
185762306a36Sopenharmony_ci		enable_second_display_channel();
185862306a36Sopenharmony_ci	else
185962306a36Sopenharmony_ci		disable_second_display_channel();
186062306a36Sopenharmony_ci
186162306a36Sopenharmony_ci	/* Update Refresh Rate Setting */
186262306a36Sopenharmony_ci
186362306a36Sopenharmony_ci	/* Clear On Screen */
186462306a36Sopenharmony_ci
186562306a36Sopenharmony_ci	if (viafb_dual_fb) {
186662306a36Sopenharmony_ci		var2 = viafbinfo1->var;
186762306a36Sopenharmony_ci	} else if (viafb_SAMM_ON) {
186862306a36Sopenharmony_ci		viafb_fill_var_timing_info(&var2, viafb_get_best_mode(
186962306a36Sopenharmony_ci			viafb_second_xres, viafb_second_yres, viafb_refresh1));
187062306a36Sopenharmony_ci		cxres = viafbinfo->var.xres;
187162306a36Sopenharmony_ci		cyres = viafbinfo->var.yres;
187262306a36Sopenharmony_ci		var2.bits_per_pixel = viafbinfo->var.bits_per_pixel;
187362306a36Sopenharmony_ci	}
187462306a36Sopenharmony_ci
187562306a36Sopenharmony_ci	/* CRT set mode */
187662306a36Sopenharmony_ci	if (viafb_CRT_ON) {
187762306a36Sopenharmony_ci		if (viaparinfo->shared->iga2_devices & VIA_CRT
187862306a36Sopenharmony_ci			&& viafb_SAMM_ON)
187962306a36Sopenharmony_ci			viafb_fill_crtc_timing(&var2, cxres, cyres, IGA2);
188062306a36Sopenharmony_ci		else
188162306a36Sopenharmony_ci			viafb_fill_crtc_timing(&viafbinfo->var, 0, 0,
188262306a36Sopenharmony_ci				(viaparinfo->shared->iga1_devices & VIA_CRT)
188362306a36Sopenharmony_ci				? IGA1 : IGA2);
188462306a36Sopenharmony_ci
188562306a36Sopenharmony_ci		/* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
188662306a36Sopenharmony_ci		to 8 alignment (1368),there is several pixels (2 pixels)
188762306a36Sopenharmony_ci		on right side of screen. */
188862306a36Sopenharmony_ci		if (viafbinfo->var.xres % 8) {
188962306a36Sopenharmony_ci			viafb_unlock_crt();
189062306a36Sopenharmony_ci			viafb_write_reg(CR02, VIACR,
189162306a36Sopenharmony_ci				viafb_read_reg(VIACR, CR02) - 1);
189262306a36Sopenharmony_ci			viafb_lock_crt();
189362306a36Sopenharmony_ci		}
189462306a36Sopenharmony_ci	}
189562306a36Sopenharmony_ci
189662306a36Sopenharmony_ci	if (viafb_DVI_ON) {
189762306a36Sopenharmony_ci		if (viaparinfo->shared->tmds_setting_info.iga_path == IGA2
189862306a36Sopenharmony_ci			&& viafb_SAMM_ON)
189962306a36Sopenharmony_ci			viafb_dvi_set_mode(&var2, cxres, cyres, IGA2);
190062306a36Sopenharmony_ci		else
190162306a36Sopenharmony_ci			viafb_dvi_set_mode(&viafbinfo->var, 0, 0,
190262306a36Sopenharmony_ci				viaparinfo->tmds_setting_info->iga_path);
190362306a36Sopenharmony_ci	}
190462306a36Sopenharmony_ci
190562306a36Sopenharmony_ci	if (viafb_LCD_ON) {
190662306a36Sopenharmony_ci		if (viafb_SAMM_ON &&
190762306a36Sopenharmony_ci			(viaparinfo->lvds_setting_info->iga_path == IGA2)) {
190862306a36Sopenharmony_ci			viafb_lcd_set_mode(&var2, cxres, cyres,
190962306a36Sopenharmony_ci				viaparinfo->lvds_setting_info,
191062306a36Sopenharmony_ci				&viaparinfo->chip_info->lvds_chip_info);
191162306a36Sopenharmony_ci		} else {
191262306a36Sopenharmony_ci			/* IGA1 doesn't have LCD scaling, so set it center. */
191362306a36Sopenharmony_ci			if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
191462306a36Sopenharmony_ci				viaparinfo->lvds_setting_info->display_method =
191562306a36Sopenharmony_ci				    LCD_CENTERING;
191662306a36Sopenharmony_ci			}
191762306a36Sopenharmony_ci			viafb_lcd_set_mode(&viafbinfo->var, 0, 0,
191862306a36Sopenharmony_ci				viaparinfo->lvds_setting_info,
191962306a36Sopenharmony_ci				&viaparinfo->chip_info->lvds_chip_info);
192062306a36Sopenharmony_ci		}
192162306a36Sopenharmony_ci	}
192262306a36Sopenharmony_ci	if (viafb_LCD2_ON) {
192362306a36Sopenharmony_ci		if (viafb_SAMM_ON &&
192462306a36Sopenharmony_ci			(viaparinfo->lvds_setting_info2->iga_path == IGA2)) {
192562306a36Sopenharmony_ci			viafb_lcd_set_mode(&var2, cxres, cyres,
192662306a36Sopenharmony_ci				viaparinfo->lvds_setting_info2,
192762306a36Sopenharmony_ci				&viaparinfo->chip_info->lvds_chip_info2);
192862306a36Sopenharmony_ci		} else {
192962306a36Sopenharmony_ci			/* IGA1 doesn't have LCD scaling, so set it center. */
193062306a36Sopenharmony_ci			if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {
193162306a36Sopenharmony_ci				viaparinfo->lvds_setting_info2->display_method =
193262306a36Sopenharmony_ci				    LCD_CENTERING;
193362306a36Sopenharmony_ci			}
193462306a36Sopenharmony_ci			viafb_lcd_set_mode(&viafbinfo->var, 0, 0,
193562306a36Sopenharmony_ci				viaparinfo->lvds_setting_info2,
193662306a36Sopenharmony_ci				&viaparinfo->chip_info->lvds_chip_info2);
193762306a36Sopenharmony_ci		}
193862306a36Sopenharmony_ci	}
193962306a36Sopenharmony_ci
194062306a36Sopenharmony_ci	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
194162306a36Sopenharmony_ci	    && (viafb_LCD_ON || viafb_DVI_ON))
194262306a36Sopenharmony_ci		set_display_channel();
194362306a36Sopenharmony_ci
194462306a36Sopenharmony_ci	/* If set mode normally, save resolution information for hot-plug . */
194562306a36Sopenharmony_ci	if (!viafb_hotplug) {
194662306a36Sopenharmony_ci		viafb_hotplug_Xres = viafbinfo->var.xres;
194762306a36Sopenharmony_ci		viafb_hotplug_Yres = viafbinfo->var.yres;
194862306a36Sopenharmony_ci		viafb_hotplug_bpp = viafbinfo->var.bits_per_pixel;
194962306a36Sopenharmony_ci		viafb_hotplug_refresh = viafb_refresh;
195062306a36Sopenharmony_ci
195162306a36Sopenharmony_ci		if (viafb_DVI_ON)
195262306a36Sopenharmony_ci			viafb_DeviceStatus = DVI_Device;
195362306a36Sopenharmony_ci		else
195462306a36Sopenharmony_ci			viafb_DeviceStatus = CRT_Device;
195562306a36Sopenharmony_ci	}
195662306a36Sopenharmony_ci	device_on();
195762306a36Sopenharmony_ci	if (!viafb_SAMM_ON)
195862306a36Sopenharmony_ci		via_set_sync_polarity(devices, get_sync(&viafbinfo->var));
195962306a36Sopenharmony_ci	else {
196062306a36Sopenharmony_ci		via_set_sync_polarity(viaparinfo->shared->iga1_devices,
196162306a36Sopenharmony_ci			get_sync(&viafbinfo->var));
196262306a36Sopenharmony_ci		via_set_sync_polarity(viaparinfo->shared->iga2_devices,
196362306a36Sopenharmony_ci			get_sync(&var2));
196462306a36Sopenharmony_ci	}
196562306a36Sopenharmony_ci
196662306a36Sopenharmony_ci	clock.set_engine_pll_state(VIA_STATE_ON);
196762306a36Sopenharmony_ci	clock.set_primary_clock_source(VIA_CLKSRC_X1, true);
196862306a36Sopenharmony_ci	clock.set_secondary_clock_source(VIA_CLKSRC_X1, true);
196962306a36Sopenharmony_ci
197062306a36Sopenharmony_ci#ifdef CONFIG_FB_VIA_X_COMPATIBILITY
197162306a36Sopenharmony_ci	clock.set_primary_pll_state(VIA_STATE_ON);
197262306a36Sopenharmony_ci	clock.set_primary_clock_state(VIA_STATE_ON);
197362306a36Sopenharmony_ci	clock.set_secondary_pll_state(VIA_STATE_ON);
197462306a36Sopenharmony_ci	clock.set_secondary_clock_state(VIA_STATE_ON);
197562306a36Sopenharmony_ci#else
197662306a36Sopenharmony_ci	if (viaparinfo->shared->iga1_devices) {
197762306a36Sopenharmony_ci		clock.set_primary_pll_state(VIA_STATE_ON);
197862306a36Sopenharmony_ci		clock.set_primary_clock_state(VIA_STATE_ON);
197962306a36Sopenharmony_ci	} else {
198062306a36Sopenharmony_ci		clock.set_primary_pll_state(VIA_STATE_OFF);
198162306a36Sopenharmony_ci		clock.set_primary_clock_state(VIA_STATE_OFF);
198262306a36Sopenharmony_ci	}
198362306a36Sopenharmony_ci
198462306a36Sopenharmony_ci	if (viaparinfo->shared->iga2_devices) {
198562306a36Sopenharmony_ci		clock.set_secondary_pll_state(VIA_STATE_ON);
198662306a36Sopenharmony_ci		clock.set_secondary_clock_state(VIA_STATE_ON);
198762306a36Sopenharmony_ci	} else {
198862306a36Sopenharmony_ci		clock.set_secondary_pll_state(VIA_STATE_OFF);
198962306a36Sopenharmony_ci		clock.set_secondary_clock_state(VIA_STATE_OFF);
199062306a36Sopenharmony_ci	}
199162306a36Sopenharmony_ci#endif /*CONFIG_FB_VIA_X_COMPATIBILITY*/
199262306a36Sopenharmony_ci
199362306a36Sopenharmony_ci	via_set_state(devices, VIA_STATE_ON);
199462306a36Sopenharmony_ci	device_screen_on();
199562306a36Sopenharmony_ci	return 1;
199662306a36Sopenharmony_ci}
199762306a36Sopenharmony_ci
199862306a36Sopenharmony_ciint viafb_get_refresh(int hres, int vres, u32 long_refresh)
199962306a36Sopenharmony_ci{
200062306a36Sopenharmony_ci	const struct fb_videomode *best;
200162306a36Sopenharmony_ci
200262306a36Sopenharmony_ci	best = viafb_get_best_mode(hres, vres, long_refresh);
200362306a36Sopenharmony_ci	if (!best)
200462306a36Sopenharmony_ci		return 60;
200562306a36Sopenharmony_ci
200662306a36Sopenharmony_ci	if (abs(best->refresh - long_refresh) > 3) {
200762306a36Sopenharmony_ci		if (hres == 1200 && vres == 900)
200862306a36Sopenharmony_ci			return 49; /* OLPC DCON only supports 50 Hz */
200962306a36Sopenharmony_ci		else
201062306a36Sopenharmony_ci			return 60;
201162306a36Sopenharmony_ci	}
201262306a36Sopenharmony_ci
201362306a36Sopenharmony_ci	return best->refresh;
201462306a36Sopenharmony_ci}
201562306a36Sopenharmony_ci
201662306a36Sopenharmony_cistatic void device_off(void)
201762306a36Sopenharmony_ci{
201862306a36Sopenharmony_ci	viafb_dvi_disable();
201962306a36Sopenharmony_ci	viafb_lcd_disable();
202062306a36Sopenharmony_ci}
202162306a36Sopenharmony_ci
202262306a36Sopenharmony_cistatic void device_on(void)
202362306a36Sopenharmony_ci{
202462306a36Sopenharmony_ci	if (viafb_DVI_ON == 1)
202562306a36Sopenharmony_ci		viafb_dvi_enable();
202662306a36Sopenharmony_ci	if (viafb_LCD_ON == 1)
202762306a36Sopenharmony_ci		viafb_lcd_enable();
202862306a36Sopenharmony_ci}
202962306a36Sopenharmony_ci
203062306a36Sopenharmony_cistatic void enable_second_display_channel(void)
203162306a36Sopenharmony_ci{
203262306a36Sopenharmony_ci	/* to enable second display channel. */
203362306a36Sopenharmony_ci	viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
203462306a36Sopenharmony_ci	viafb_write_reg_mask(CR6A, VIACR, BIT7, BIT7);
203562306a36Sopenharmony_ci	viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
203662306a36Sopenharmony_ci}
203762306a36Sopenharmony_ci
203862306a36Sopenharmony_cistatic void disable_second_display_channel(void)
203962306a36Sopenharmony_ci{
204062306a36Sopenharmony_ci	/* to disable second display channel. */
204162306a36Sopenharmony_ci	viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
204262306a36Sopenharmony_ci	viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT7);
204362306a36Sopenharmony_ci	viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
204462306a36Sopenharmony_ci}
204562306a36Sopenharmony_ci
204662306a36Sopenharmony_civoid viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
204762306a36Sopenharmony_ci					*p_gfx_dpa_setting)
204862306a36Sopenharmony_ci{
204962306a36Sopenharmony_ci	switch (output_interface) {
205062306a36Sopenharmony_ci	case INTERFACE_DVP0:
205162306a36Sopenharmony_ci		{
205262306a36Sopenharmony_ci			/* DVP0 Clock Polarity and Adjust: */
205362306a36Sopenharmony_ci			viafb_write_reg_mask(CR96, VIACR,
205462306a36Sopenharmony_ci				       p_gfx_dpa_setting->DVP0, 0x0F);
205562306a36Sopenharmony_ci
205662306a36Sopenharmony_ci			/* DVP0 Clock and Data Pads Driving: */
205762306a36Sopenharmony_ci			viafb_write_reg_mask(SR1E, VIASR,
205862306a36Sopenharmony_ci				       p_gfx_dpa_setting->DVP0ClockDri_S, BIT2);
205962306a36Sopenharmony_ci			viafb_write_reg_mask(SR2A, VIASR,
206062306a36Sopenharmony_ci				       p_gfx_dpa_setting->DVP0ClockDri_S1,
206162306a36Sopenharmony_ci				       BIT4);
206262306a36Sopenharmony_ci			viafb_write_reg_mask(SR1B, VIASR,
206362306a36Sopenharmony_ci				       p_gfx_dpa_setting->DVP0DataDri_S, BIT1);
206462306a36Sopenharmony_ci			viafb_write_reg_mask(SR2A, VIASR,
206562306a36Sopenharmony_ci				       p_gfx_dpa_setting->DVP0DataDri_S1, BIT5);
206662306a36Sopenharmony_ci			break;
206762306a36Sopenharmony_ci		}
206862306a36Sopenharmony_ci
206962306a36Sopenharmony_ci	case INTERFACE_DVP1:
207062306a36Sopenharmony_ci		{
207162306a36Sopenharmony_ci			/* DVP1 Clock Polarity and Adjust: */
207262306a36Sopenharmony_ci			viafb_write_reg_mask(CR9B, VIACR,
207362306a36Sopenharmony_ci				       p_gfx_dpa_setting->DVP1, 0x0F);
207462306a36Sopenharmony_ci
207562306a36Sopenharmony_ci			/* DVP1 Clock and Data Pads Driving: */
207662306a36Sopenharmony_ci			viafb_write_reg_mask(SR65, VIASR,
207762306a36Sopenharmony_ci				       p_gfx_dpa_setting->DVP1Driving, 0x0F);
207862306a36Sopenharmony_ci			break;
207962306a36Sopenharmony_ci		}
208062306a36Sopenharmony_ci
208162306a36Sopenharmony_ci	case INTERFACE_DFP_HIGH:
208262306a36Sopenharmony_ci		{
208362306a36Sopenharmony_ci			viafb_write_reg_mask(CR97, VIACR,
208462306a36Sopenharmony_ci				       p_gfx_dpa_setting->DFPHigh, 0x0F);
208562306a36Sopenharmony_ci			break;
208662306a36Sopenharmony_ci		}
208762306a36Sopenharmony_ci
208862306a36Sopenharmony_ci	case INTERFACE_DFP_LOW:
208962306a36Sopenharmony_ci		{
209062306a36Sopenharmony_ci			viafb_write_reg_mask(CR99, VIACR,
209162306a36Sopenharmony_ci				       p_gfx_dpa_setting->DFPLow, 0x0F);
209262306a36Sopenharmony_ci			break;
209362306a36Sopenharmony_ci		}
209462306a36Sopenharmony_ci
209562306a36Sopenharmony_ci	case INTERFACE_DFP:
209662306a36Sopenharmony_ci		{
209762306a36Sopenharmony_ci			viafb_write_reg_mask(CR97, VIACR,
209862306a36Sopenharmony_ci				       p_gfx_dpa_setting->DFPHigh, 0x0F);
209962306a36Sopenharmony_ci			viafb_write_reg_mask(CR99, VIACR,
210062306a36Sopenharmony_ci				       p_gfx_dpa_setting->DFPLow, 0x0F);
210162306a36Sopenharmony_ci			break;
210262306a36Sopenharmony_ci		}
210362306a36Sopenharmony_ci	}
210462306a36Sopenharmony_ci}
210562306a36Sopenharmony_ci
210662306a36Sopenharmony_civoid viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
210762306a36Sopenharmony_ci	const struct fb_videomode *mode)
210862306a36Sopenharmony_ci{
210962306a36Sopenharmony_ci	var->pixclock = mode->pixclock;
211062306a36Sopenharmony_ci	var->xres = mode->xres;
211162306a36Sopenharmony_ci	var->yres = mode->yres;
211262306a36Sopenharmony_ci	var->left_margin = mode->left_margin;
211362306a36Sopenharmony_ci	var->right_margin = mode->right_margin;
211462306a36Sopenharmony_ci	var->hsync_len = mode->hsync_len;
211562306a36Sopenharmony_ci	var->upper_margin = mode->upper_margin;
211662306a36Sopenharmony_ci	var->lower_margin = mode->lower_margin;
211762306a36Sopenharmony_ci	var->vsync_len = mode->vsync_len;
211862306a36Sopenharmony_ci	var->sync = mode->sync;
211962306a36Sopenharmony_ci}
2120