2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 static struct pll_map pll_value
[] = {
25 {CLK_25_175M
, CLE266_PLL_25_175M
, K800_PLL_25_175M
,
26 CX700_25_175M
, VX855_25_175M
},
27 {CLK_29_581M
, CLE266_PLL_29_581M
, K800_PLL_29_581M
,
28 CX700_29_581M
, VX855_29_581M
},
29 {CLK_26_880M
, CLE266_PLL_26_880M
, K800_PLL_26_880M
,
30 CX700_26_880M
, VX855_26_880M
},
31 {CLK_31_490M
, CLE266_PLL_31_490M
, K800_PLL_31_490M
,
32 CX700_31_490M
, VX855_31_490M
},
33 {CLK_31_500M
, CLE266_PLL_31_500M
, K800_PLL_31_500M
,
34 CX700_31_500M
, VX855_31_500M
},
35 {CLK_31_728M
, CLE266_PLL_31_728M
, K800_PLL_31_728M
,
36 CX700_31_728M
, VX855_31_728M
},
37 {CLK_32_668M
, CLE266_PLL_32_668M
, K800_PLL_32_668M
,
38 CX700_32_668M
, VX855_32_668M
},
39 {CLK_36_000M
, CLE266_PLL_36_000M
, K800_PLL_36_000M
,
40 CX700_36_000M
, VX855_36_000M
},
41 {CLK_40_000M
, CLE266_PLL_40_000M
, K800_PLL_40_000M
,
42 CX700_40_000M
, VX855_40_000M
},
43 {CLK_41_291M
, CLE266_PLL_41_291M
, K800_PLL_41_291M
,
44 CX700_41_291M
, VX855_41_291M
},
45 {CLK_43_163M
, CLE266_PLL_43_163M
, K800_PLL_43_163M
,
46 CX700_43_163M
, VX855_43_163M
},
47 {CLK_45_250M
, CLE266_PLL_45_250M
, K800_PLL_45_250M
,
48 CX700_45_250M
, VX855_45_250M
},
49 {CLK_46_000M
, CLE266_PLL_46_000M
, K800_PLL_46_000M
,
50 CX700_46_000M
, VX855_46_000M
},
51 {CLK_46_996M
, CLE266_PLL_46_996M
, K800_PLL_46_996M
,
52 CX700_46_996M
, VX855_46_996M
},
53 {CLK_48_000M
, CLE266_PLL_48_000M
, K800_PLL_48_000M
,
54 CX700_48_000M
, VX855_48_000M
},
55 {CLK_48_875M
, CLE266_PLL_48_875M
, K800_PLL_48_875M
,
56 CX700_48_875M
, VX855_48_875M
},
57 {CLK_49_500M
, CLE266_PLL_49_500M
, K800_PLL_49_500M
,
58 CX700_49_500M
, VX855_49_500M
},
59 {CLK_52_406M
, CLE266_PLL_52_406M
, K800_PLL_52_406M
,
60 CX700_52_406M
, VX855_52_406M
},
61 {CLK_52_977M
, CLE266_PLL_52_977M
, K800_PLL_52_977M
,
62 CX700_52_977M
, VX855_52_977M
},
63 {CLK_56_250M
, CLE266_PLL_56_250M
, K800_PLL_56_250M
,
64 CX700_56_250M
, VX855_56_250M
},
65 {CLK_60_466M
, CLE266_PLL_60_466M
, K800_PLL_60_466M
,
66 CX700_60_466M
, VX855_60_466M
},
67 {CLK_61_500M
, CLE266_PLL_61_500M
, K800_PLL_61_500M
,
68 CX700_61_500M
, VX855_61_500M
},
69 {CLK_65_000M
, CLE266_PLL_65_000M
, K800_PLL_65_000M
,
70 CX700_65_000M
, VX855_65_000M
},
71 {CLK_65_178M
, CLE266_PLL_65_178M
, K800_PLL_65_178M
,
72 CX700_65_178M
, VX855_65_178M
},
73 {CLK_66_750M
, CLE266_PLL_66_750M
, K800_PLL_66_750M
,
74 CX700_66_750M
, VX855_66_750M
},
75 {CLK_68_179M
, CLE266_PLL_68_179M
, K800_PLL_68_179M
,
76 CX700_68_179M
, VX855_68_179M
},
77 {CLK_69_924M
, CLE266_PLL_69_924M
, K800_PLL_69_924M
,
78 CX700_69_924M
, VX855_69_924M
},
79 {CLK_70_159M
, CLE266_PLL_70_159M
, K800_PLL_70_159M
,
80 CX700_70_159M
, VX855_70_159M
},
81 {CLK_72_000M
, CLE266_PLL_72_000M
, K800_PLL_72_000M
,
82 CX700_72_000M
, VX855_72_000M
},
83 {CLK_78_750M
, CLE266_PLL_78_750M
, K800_PLL_78_750M
,
84 CX700_78_750M
, VX855_78_750M
},
85 {CLK_80_136M
, CLE266_PLL_80_136M
, K800_PLL_80_136M
,
86 CX700_80_136M
, VX855_80_136M
},
87 {CLK_83_375M
, CLE266_PLL_83_375M
, K800_PLL_83_375M
,
88 CX700_83_375M
, VX855_83_375M
},
89 {CLK_83_950M
, CLE266_PLL_83_950M
, K800_PLL_83_950M
,
90 CX700_83_950M
, VX855_83_950M
},
91 {CLK_84_750M
, CLE266_PLL_84_750M
, K800_PLL_84_750M
,
92 CX700_84_750M
, VX855_84_750M
},
93 {CLK_85_860M
, CLE266_PLL_85_860M
, K800_PLL_85_860M
,
94 CX700_85_860M
, VX855_85_860M
},
95 {CLK_88_750M
, CLE266_PLL_88_750M
, K800_PLL_88_750M
,
96 CX700_88_750M
, VX855_88_750M
},
97 {CLK_94_500M
, CLE266_PLL_94_500M
, K800_PLL_94_500M
,
98 CX700_94_500M
, VX855_94_500M
},
99 {CLK_97_750M
, CLE266_PLL_97_750M
, K800_PLL_97_750M
,
100 CX700_97_750M
, VX855_97_750M
},
101 {CLK_101_000M
, CLE266_PLL_101_000M
, K800_PLL_101_000M
,
102 CX700_101_000M
, VX855_101_000M
},
103 {CLK_106_500M
, CLE266_PLL_106_500M
, K800_PLL_106_500M
,
104 CX700_106_500M
, VX855_106_500M
},
105 {CLK_108_000M
, CLE266_PLL_108_000M
, K800_PLL_108_000M
,
106 CX700_108_000M
, VX855_108_000M
},
107 {CLK_113_309M
, CLE266_PLL_113_309M
, K800_PLL_113_309M
,
108 CX700_113_309M
, VX855_113_309M
},
109 {CLK_118_840M
, CLE266_PLL_118_840M
, K800_PLL_118_840M
,
110 CX700_118_840M
, VX855_118_840M
},
111 {CLK_119_000M
, CLE266_PLL_119_000M
, K800_PLL_119_000M
,
112 CX700_119_000M
, VX855_119_000M
},
113 {CLK_121_750M
, CLE266_PLL_121_750M
, K800_PLL_121_750M
,
115 {CLK_125_104M
, CLE266_PLL_125_104M
, K800_PLL_125_104M
,
117 {CLK_133_308M
, CLE266_PLL_133_308M
, K800_PLL_133_308M
,
119 {CLK_135_000M
, CLE266_PLL_135_000M
, K800_PLL_135_000M
,
120 CX700_135_000M
, VX855_135_000M
},
121 {CLK_136_700M
, CLE266_PLL_136_700M
, K800_PLL_136_700M
,
122 CX700_136_700M
, VX855_136_700M
},
123 {CLK_138_400M
, CLE266_PLL_138_400M
, K800_PLL_138_400M
,
124 CX700_138_400M
, VX855_138_400M
},
125 {CLK_146_760M
, CLE266_PLL_146_760M
, K800_PLL_146_760M
,
126 CX700_146_760M
, VX855_146_760M
},
127 {CLK_153_920M
, CLE266_PLL_153_920M
, K800_PLL_153_920M
,
128 CX700_153_920M
, VX855_153_920M
},
129 {CLK_156_000M
, CLE266_PLL_156_000M
, K800_PLL_156_000M
,
130 CX700_156_000M
, VX855_156_000M
},
131 {CLK_157_500M
, CLE266_PLL_157_500M
, K800_PLL_157_500M
,
132 CX700_157_500M
, VX855_157_500M
},
133 {CLK_162_000M
, CLE266_PLL_162_000M
, K800_PLL_162_000M
,
134 CX700_162_000M
, VX855_162_000M
},
135 {CLK_187_000M
, CLE266_PLL_187_000M
, K800_PLL_187_000M
,
136 CX700_187_000M
, VX855_187_000M
},
137 {CLK_193_295M
, CLE266_PLL_193_295M
, K800_PLL_193_295M
,
138 CX700_193_295M
, VX855_193_295M
},
139 {CLK_202_500M
, CLE266_PLL_202_500M
, K800_PLL_202_500M
,
140 CX700_202_500M
, VX855_202_500M
},
141 {CLK_204_000M
, CLE266_PLL_204_000M
, K800_PLL_204_000M
,
142 CX700_204_000M
, VX855_204_000M
},
143 {CLK_218_500M
, CLE266_PLL_218_500M
, K800_PLL_218_500M
,
144 CX700_218_500M
, VX855_218_500M
},
145 {CLK_234_000M
, CLE266_PLL_234_000M
, K800_PLL_234_000M
,
146 CX700_234_000M
, VX855_234_000M
},
147 {CLK_267_250M
, CLE266_PLL_267_250M
, K800_PLL_267_250M
,
148 CX700_267_250M
, VX855_267_250M
},
149 {CLK_297_500M
, CLE266_PLL_297_500M
, K800_PLL_297_500M
,
150 CX700_297_500M
, VX855_297_500M
},
151 {CLK_74_481M
, CLE266_PLL_74_481M
, K800_PLL_74_481M
,
152 CX700_74_481M
, VX855_74_481M
},
153 {CLK_172_798M
, CLE266_PLL_172_798M
, K800_PLL_172_798M
,
154 CX700_172_798M
, VX855_172_798M
},
155 {CLK_122_614M
, CLE266_PLL_122_614M
, K800_PLL_122_614M
,
156 CX700_122_614M
, VX855_122_614M
},
157 {CLK_74_270M
, CLE266_PLL_74_270M
, K800_PLL_74_270M
,
159 {CLK_148_500M
, CLE266_PLL_148_500M
, K800_PLL_148_500M
,
160 CX700_148_500M
, VX855_148_500M
}
163 static struct fifo_depth_select display_fifo_depth_reg
= {
164 /* IGA1 FIFO Depth_Select */
165 {IGA1_FIFO_DEPTH_SELECT_REG_NUM
, {{SR17
, 0, 7} } },
166 /* IGA2 FIFO Depth_Select */
167 {IGA2_FIFO_DEPTH_SELECT_REG_NUM
,
168 {{CR68
, 4, 7}, {CR94
, 7, 7}, {CR95
, 7, 7} } }
171 static struct fifo_threshold_select fifo_threshold_select_reg
= {
172 /* IGA1 FIFO Threshold Select */
173 {IGA1_FIFO_THRESHOLD_REG_NUM
, {{SR16
, 0, 5}, {SR16
, 7, 7} } },
174 /* IGA2 FIFO Threshold Select */
175 {IGA2_FIFO_THRESHOLD_REG_NUM
, {{CR68
, 0, 3}, {CR95
, 4, 6} } }
178 static struct fifo_high_threshold_select fifo_high_threshold_select_reg
= {
179 /* IGA1 FIFO High Threshold Select */
180 {IGA1_FIFO_HIGH_THRESHOLD_REG_NUM
, {{SR18
, 0, 5}, {SR18
, 7, 7} } },
181 /* IGA2 FIFO High Threshold Select */
182 {IGA2_FIFO_HIGH_THRESHOLD_REG_NUM
, {{CR92
, 0, 3}, {CR95
, 0, 2} } }
185 static struct display_queue_expire_num display_queue_expire_num_reg
= {
186 /* IGA1 Display Queue Expire Num */
187 {IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM
, {{SR22
, 0, 4} } },
188 /* IGA2 Display Queue Expire Num */
189 {IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM
, {{CR94
, 0, 6} } }
192 /* Definition Fetch Count Registers*/
193 static struct fetch_count fetch_count_reg
= {
194 /* IGA1 Fetch Count Register */
195 {IGA1_FETCH_COUNT_REG_NUM
, {{SR1C
, 0, 7}, {SR1D
, 0, 1} } },
196 /* IGA2 Fetch Count Register */
197 {IGA2_FETCH_COUNT_REG_NUM
, {{CR65
, 0, 7}, {CR67
, 2, 3} } }
200 static struct iga1_crtc_timing iga1_crtc_reg
= {
201 /* IGA1 Horizontal Total */
202 {IGA1_HOR_TOTAL_REG_NUM
, {{CR00
, 0, 7}, {CR36
, 3, 3} } },
203 /* IGA1 Horizontal Addressable Video */
204 {IGA1_HOR_ADDR_REG_NUM
, {{CR01
, 0, 7} } },
205 /* IGA1 Horizontal Blank Start */
206 {IGA1_HOR_BLANK_START_REG_NUM
, {{CR02
, 0, 7} } },
207 /* IGA1 Horizontal Blank End */
208 {IGA1_HOR_BLANK_END_REG_NUM
,
209 {{CR03
, 0, 4}, {CR05
, 7, 7}, {CR33
, 5, 5} } },
210 /* IGA1 Horizontal Sync Start */
211 {IGA1_HOR_SYNC_START_REG_NUM
, {{CR04
, 0, 7}, {CR33
, 4, 4} } },
212 /* IGA1 Horizontal Sync End */
213 {IGA1_HOR_SYNC_END_REG_NUM
, {{CR05
, 0, 4} } },
214 /* IGA1 Vertical Total */
215 {IGA1_VER_TOTAL_REG_NUM
,
216 {{CR06
, 0, 7}, {CR07
, 0, 0}, {CR07
, 5, 5}, {CR35
, 0, 0} } },
217 /* IGA1 Vertical Addressable Video */
218 {IGA1_VER_ADDR_REG_NUM
,
219 {{CR12
, 0, 7}, {CR07
, 1, 1}, {CR07
, 6, 6}, {CR35
, 2, 2} } },
220 /* IGA1 Vertical Blank Start */
221 {IGA1_VER_BLANK_START_REG_NUM
,
222 {{CR15
, 0, 7}, {CR07
, 3, 3}, {CR09
, 5, 5}, {CR35
, 3, 3} } },
223 /* IGA1 Vertical Blank End */
224 {IGA1_VER_BLANK_END_REG_NUM
, {{CR16
, 0, 7} } },
225 /* IGA1 Vertical Sync Start */
226 {IGA1_VER_SYNC_START_REG_NUM
,
227 {{CR10
, 0, 7}, {CR07
, 2, 2}, {CR07
, 7, 7}, {CR35
, 1, 1} } },
228 /* IGA1 Vertical Sync End */
229 {IGA1_VER_SYNC_END_REG_NUM
, {{CR11
, 0, 3} } }
232 static struct iga2_crtc_timing iga2_crtc_reg
= {
233 /* IGA2 Horizontal Total */
234 {IGA2_HOR_TOTAL_REG_NUM
, {{CR50
, 0, 7}, {CR55
, 0, 3} } },
235 /* IGA2 Horizontal Addressable Video */
236 {IGA2_HOR_ADDR_REG_NUM
, {{CR51
, 0, 7}, {CR55
, 4, 6} } },
237 /* IGA2 Horizontal Blank Start */
238 {IGA2_HOR_BLANK_START_REG_NUM
, {{CR52
, 0, 7}, {CR54
, 0, 2} } },
239 /* IGA2 Horizontal Blank End */
240 {IGA2_HOR_BLANK_END_REG_NUM
,
241 {{CR53
, 0, 7}, {CR54
, 3, 5}, {CR5D
, 6, 6} } },
242 /* IGA2 Horizontal Sync Start */
243 {IGA2_HOR_SYNC_START_REG_NUM
,
244 {{CR56
, 0, 7}, {CR54
, 6, 7}, {CR5C
, 7, 7}, {CR5D
, 7, 7} } },
245 /* IGA2 Horizontal Sync End */
246 {IGA2_HOR_SYNC_END_REG_NUM
, {{CR57
, 0, 7}, {CR5C
, 6, 6} } },
247 /* IGA2 Vertical Total */
248 {IGA2_VER_TOTAL_REG_NUM
, {{CR58
, 0, 7}, {CR5D
, 0, 2} } },
249 /* IGA2 Vertical Addressable Video */
250 {IGA2_VER_ADDR_REG_NUM
, {{CR59
, 0, 7}, {CR5D
, 3, 5} } },
251 /* IGA2 Vertical Blank Start */
252 {IGA2_VER_BLANK_START_REG_NUM
, {{CR5A
, 0, 7}, {CR5C
, 0, 2} } },
253 /* IGA2 Vertical Blank End */
254 {IGA2_VER_BLANK_END_REG_NUM
, {{CR5B
, 0, 7}, {CR5C
, 3, 5} } },
255 /* IGA2 Vertical Sync Start */
256 {IGA2_VER_SYNC_START_REG_NUM
, {{CR5E
, 0, 7}, {CR5F
, 5, 7} } },
257 /* IGA2 Vertical Sync End */
258 {IGA2_VER_SYNC_END_REG_NUM
, {{CR5F
, 0, 4} } }
261 static struct rgbLUT palLUT_table
[] = {
263 /* Index 0x00~0x03 */
264 {0x00, 0x00, 0x00}, {0x00, 0x00, 0x2A}, {0x00, 0x2A, 0x00}, {0x00,
267 /* Index 0x04~0x07 */
268 {0x2A, 0x00, 0x00}, {0x2A, 0x00, 0x2A}, {0x2A, 0x15, 0x00}, {0x2A,
271 /* Index 0x08~0x0B */
272 {0x15, 0x15, 0x15}, {0x15, 0x15, 0x3F}, {0x15, 0x3F, 0x15}, {0x15,
275 /* Index 0x0C~0x0F */
276 {0x3F, 0x15, 0x15}, {0x3F, 0x15, 0x3F}, {0x3F, 0x3F, 0x15}, {0x3F,
279 /* Index 0x10~0x13 */
280 {0x00, 0x00, 0x00}, {0x05, 0x05, 0x05}, {0x08, 0x08, 0x08}, {0x0B,
283 /* Index 0x14~0x17 */
284 {0x0E, 0x0E, 0x0E}, {0x11, 0x11, 0x11}, {0x14, 0x14, 0x14}, {0x18,
287 /* Index 0x18~0x1B */
288 {0x1C, 0x1C, 0x1C}, {0x20, 0x20, 0x20}, {0x24, 0x24, 0x24}, {0x28,
291 /* Index 0x1C~0x1F */
292 {0x2D, 0x2D, 0x2D}, {0x32, 0x32, 0x32}, {0x38, 0x38, 0x38}, {0x3F,
295 /* Index 0x20~0x23 */
296 {0x00, 0x00, 0x3F}, {0x10, 0x00, 0x3F}, {0x1F, 0x00, 0x3F}, {0x2F,
299 /* Index 0x24~0x27 */
300 {0x3F, 0x00, 0x3F}, {0x3F, 0x00, 0x2F}, {0x3F, 0x00, 0x1F}, {0x3F,
303 /* Index 0x28~0x2B */
304 {0x3F, 0x00, 0x00}, {0x3F, 0x10, 0x00}, {0x3F, 0x1F, 0x00}, {0x3F,
307 /* Index 0x2C~0x2F */
308 {0x3F, 0x3F, 0x00}, {0x2F, 0x3F, 0x00}, {0x1F, 0x3F, 0x00}, {0x10,
311 /* Index 0x30~0x33 */
312 {0x00, 0x3F, 0x00}, {0x00, 0x3F, 0x10}, {0x00, 0x3F, 0x1F}, {0x00,
315 /* Index 0x34~0x37 */
316 {0x00, 0x3F, 0x3F}, {0x00, 0x2F, 0x3F}, {0x00, 0x1F, 0x3F}, {0x00,
319 /* Index 0x38~0x3B */
320 {0x1F, 0x1F, 0x3F}, {0x27, 0x1F, 0x3F}, {0x2F, 0x1F, 0x3F}, {0x37,
323 /* Index 0x3C~0x3F */
324 {0x3F, 0x1F, 0x3F}, {0x3F, 0x1F, 0x37}, {0x3F, 0x1F, 0x2F}, {0x3F,
327 /* Index 0x40~0x43 */
328 {0x3F, 0x1F, 0x1F}, {0x3F, 0x27, 0x1F}, {0x3F, 0x2F, 0x1F}, {0x3F,
331 /* Index 0x44~0x47 */
332 {0x3F, 0x3F, 0x1F}, {0x37, 0x3F, 0x1F}, {0x2F, 0x3F, 0x1F}, {0x27,
335 /* Index 0x48~0x4B */
336 {0x1F, 0x3F, 0x1F}, {0x1F, 0x3F, 0x27}, {0x1F, 0x3F, 0x2F}, {0x1F,
339 /* Index 0x4C~0x4F */
340 {0x1F, 0x3F, 0x3F}, {0x1F, 0x37, 0x3F}, {0x1F, 0x2F, 0x3F}, {0x1F,
343 /* Index 0x50~0x53 */
344 {0x2D, 0x2D, 0x3F}, {0x31, 0x2D, 0x3F}, {0x36, 0x2D, 0x3F}, {0x3A,
347 /* Index 0x54~0x57 */
348 {0x3F, 0x2D, 0x3F}, {0x3F, 0x2D, 0x3A}, {0x3F, 0x2D, 0x36}, {0x3F,
351 /* Index 0x58~0x5B */
352 {0x3F, 0x2D, 0x2D}, {0x3F, 0x31, 0x2D}, {0x3F, 0x36, 0x2D}, {0x3F,
355 /* Index 0x5C~0x5F */
356 {0x3F, 0x3F, 0x2D}, {0x3A, 0x3F, 0x2D}, {0x36, 0x3F, 0x2D}, {0x31,
359 /* Index 0x60~0x63 */
360 {0x2D, 0x3F, 0x2D}, {0x2D, 0x3F, 0x31}, {0x2D, 0x3F, 0x36}, {0x2D,
363 /* Index 0x64~0x67 */
364 {0x2D, 0x3F, 0x3F}, {0x2D, 0x3A, 0x3F}, {0x2D, 0x36, 0x3F}, {0x2D,
367 /* Index 0x68~0x6B */
368 {0x00, 0x00, 0x1C}, {0x07, 0x00, 0x1C}, {0x0E, 0x00, 0x1C}, {0x15,
371 /* Index 0x6C~0x6F */
372 {0x1C, 0x00, 0x1C}, {0x1C, 0x00, 0x15}, {0x1C, 0x00, 0x0E}, {0x1C,
375 /* Index 0x70~0x73 */
376 {0x1C, 0x00, 0x00}, {0x1C, 0x07, 0x00}, {0x1C, 0x0E, 0x00}, {0x1C,
379 /* Index 0x74~0x77 */
380 {0x1C, 0x1C, 0x00}, {0x15, 0x1C, 0x00}, {0x0E, 0x1C, 0x00}, {0x07,
383 /* Index 0x78~0x7B */
384 {0x00, 0x1C, 0x00}, {0x00, 0x1C, 0x07}, {0x00, 0x1C, 0x0E}, {0x00,
387 /* Index 0x7C~0x7F */
388 {0x00, 0x1C, 0x1C}, {0x00, 0x15, 0x1C}, {0x00, 0x0E, 0x1C}, {0x00,
391 /* Index 0x80~0x83 */
392 {0x0E, 0x0E, 0x1C}, {0x11, 0x0E, 0x1C}, {0x15, 0x0E, 0x1C}, {0x18,
395 /* Index 0x84~0x87 */
396 {0x1C, 0x0E, 0x1C}, {0x1C, 0x0E, 0x18}, {0x1C, 0x0E, 0x15}, {0x1C,
399 /* Index 0x88~0x8B */
400 {0x1C, 0x0E, 0x0E}, {0x1C, 0x11, 0x0E}, {0x1C, 0x15, 0x0E}, {0x1C,
403 /* Index 0x8C~0x8F */
404 {0x1C, 0x1C, 0x0E}, {0x18, 0x1C, 0x0E}, {0x15, 0x1C, 0x0E}, {0x11,
407 /* Index 0x90~0x93 */
408 {0x0E, 0x1C, 0x0E}, {0x0E, 0x1C, 0x11}, {0x0E, 0x1C, 0x15}, {0x0E,
411 /* Index 0x94~0x97 */
412 {0x0E, 0x1C, 0x1C}, {0x0E, 0x18, 0x1C}, {0x0E, 0x15, 0x1C}, {0x0E,
415 /* Index 0x98~0x9B */
416 {0x14, 0x14, 0x1C}, {0x16, 0x14, 0x1C}, {0x18, 0x14, 0x1C}, {0x1A,
419 /* Index 0x9C~0x9F */
420 {0x1C, 0x14, 0x1C}, {0x1C, 0x14, 0x1A}, {0x1C, 0x14, 0x18}, {0x1C,
423 /* Index 0xA0~0xA3 */
424 {0x1C, 0x14, 0x14}, {0x1C, 0x16, 0x14}, {0x1C, 0x18, 0x14}, {0x1C,
427 /* Index 0xA4~0xA7 */
428 {0x1C, 0x1C, 0x14}, {0x1A, 0x1C, 0x14}, {0x18, 0x1C, 0x14}, {0x16,
431 /* Index 0xA8~0xAB */
432 {0x14, 0x1C, 0x14}, {0x14, 0x1C, 0x16}, {0x14, 0x1C, 0x18}, {0x14,
435 /* Index 0xAC~0xAF */
436 {0x14, 0x1C, 0x1C}, {0x14, 0x1A, 0x1C}, {0x14, 0x18, 0x1C}, {0x14,
439 /* Index 0xB0~0xB3 */
440 {0x00, 0x00, 0x10}, {0x04, 0x00, 0x10}, {0x08, 0x00, 0x10}, {0x0C,
443 /* Index 0xB4~0xB7 */
444 {0x10, 0x00, 0x10}, {0x10, 0x00, 0x0C}, {0x10, 0x00, 0x08}, {0x10,
447 /* Index 0xB8~0xBB */
448 {0x10, 0x00, 0x00}, {0x10, 0x04, 0x00}, {0x10, 0x08, 0x00}, {0x10,
451 /* Index 0xBC~0xBF */
452 {0x10, 0x10, 0x00}, {0x0C, 0x10, 0x00}, {0x08, 0x10, 0x00}, {0x04,
455 /* Index 0xC0~0xC3 */
456 {0x00, 0x10, 0x00}, {0x00, 0x10, 0x04}, {0x00, 0x10, 0x08}, {0x00,
459 /* Index 0xC4~0xC7 */
460 {0x00, 0x10, 0x10}, {0x00, 0x0C, 0x10}, {0x00, 0x08, 0x10}, {0x00,
463 /* Index 0xC8~0xCB */
464 {0x08, 0x08, 0x10}, {0x0A, 0x08, 0x10}, {0x0C, 0x08, 0x10}, {0x0E,
467 /* Index 0xCC~0xCF */
468 {0x10, 0x08, 0x10}, {0x10, 0x08, 0x0E}, {0x10, 0x08, 0x0C}, {0x10,
471 /* Index 0xD0~0xD3 */
472 {0x10, 0x08, 0x08}, {0x10, 0x0A, 0x08}, {0x10, 0x0C, 0x08}, {0x10,
475 /* Index 0xD4~0xD7 */
476 {0x10, 0x10, 0x08}, {0x0E, 0x10, 0x08}, {0x0C, 0x10, 0x08}, {0x0A,
479 /* Index 0xD8~0xDB */
480 {0x08, 0x10, 0x08}, {0x08, 0x10, 0x0A}, {0x08, 0x10, 0x0C}, {0x08,
483 /* Index 0xDC~0xDF */
484 {0x08, 0x10, 0x10}, {0x08, 0x0E, 0x10}, {0x08, 0x0C, 0x10}, {0x08,
487 /* Index 0xE0~0xE3 */
488 {0x0B, 0x0B, 0x10}, {0x0C, 0x0B, 0x10}, {0x0D, 0x0B, 0x10}, {0x0F,
491 /* Index 0xE4~0xE7 */
492 {0x10, 0x0B, 0x10}, {0x10, 0x0B, 0x0F}, {0x10, 0x0B, 0x0D}, {0x10,
495 /* Index 0xE8~0xEB */
496 {0x10, 0x0B, 0x0B}, {0x10, 0x0C, 0x0B}, {0x10, 0x0D, 0x0B}, {0x10,
499 /* Index 0xEC~0xEF */
500 {0x10, 0x10, 0x0B}, {0x0F, 0x10, 0x0B}, {0x0D, 0x10, 0x0B}, {0x0C,
503 /* Index 0xF0~0xF3 */
504 {0x0B, 0x10, 0x0B}, {0x0B, 0x10, 0x0C}, {0x0B, 0x10, 0x0D}, {0x0B,
507 /* Index 0xF4~0xF7 */
508 {0x0B, 0x10, 0x10}, {0x0B, 0x0F, 0x10}, {0x0B, 0x0D, 0x10}, {0x0B,
511 /* Index 0xF8~0xFB */
512 {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
515 /* Index 0xFC~0xFF */
516 {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
521 static void set_crt_output_path(int set_iga
);
522 static void dvi_patch_skew_dvp0(void);
523 static void dvi_patch_skew_dvp1(void);
524 static void dvi_patch_skew_dvp_low(void);
525 static void set_dvi_output_path(int set_iga
, int output_interface
);
526 static void set_lcd_output_path(int set_iga
, int output_interface
);
527 static int search_mode_setting(int ModeInfoIndex
);
528 static void load_fix_bit_crtc_reg(void);
529 static void init_gfx_chip_info(struct pci_dev
*pdev
,
530 const struct pci_device_id
*pdi
);
531 static void init_tmds_chip_info(void);
532 static void init_lvds_chip_info(void);
533 static void device_screen_off(void);
534 static void device_screen_on(void);
535 static void set_display_channel(void);
536 static void device_off(void);
537 static void device_on(void);
538 static void enable_second_display_channel(void);
539 static void disable_second_display_channel(void);
541 void viafb_write_reg(u8 index
, u16 io_port
, u8 data
)
543 outb(index
, io_port
);
544 outb(data
, io_port
+ 1);
545 /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, data); */
547 u8
viafb_read_reg(int io_port
, u8 index
)
549 outb(index
, io_port
);
550 return inb(io_port
+ 1);
553 void viafb_lock_crt(void)
555 viafb_write_reg_mask(CR11
, VIACR
, BIT7
, BIT7
);
558 void viafb_unlock_crt(void)
560 viafb_write_reg_mask(CR11
, VIACR
, 0, BIT7
);
561 viafb_write_reg_mask(CR47
, VIACR
, 0, BIT0
);
564 void viafb_write_reg_mask(u8 index
, int io_port
, u8 data
, u8 mask
)
568 outb(index
, io_port
);
569 tmp
= inb(io_port
+ 1);
570 outb((data
& mask
) | (tmp
& (~mask
)), io_port
+ 1);
571 /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, tmp); */
574 void write_dac_reg(u8 index
, u8 r
, u8 g
, u8 b
)
576 outb(index
, LUT_INDEX_WRITE
);
582 /*Set IGA path for each device*/
583 void viafb_set_iga_path(void)
586 if (viafb_SAMM_ON
== 1) {
588 if (viafb_primary_dev
== CRT_Device
)
589 viaparinfo
->crt_setting_info
->iga_path
= IGA1
;
591 viaparinfo
->crt_setting_info
->iga_path
= IGA2
;
595 if (viafb_primary_dev
== DVI_Device
)
596 viaparinfo
->tmds_setting_info
->iga_path
= IGA1
;
598 viaparinfo
->tmds_setting_info
->iga_path
= IGA2
;
602 if (viafb_primary_dev
== LCD_Device
) {
604 (viaparinfo
->chip_info
->gfx_chip_name
==
607 lvds_setting_info
->iga_path
= IGA2
;
609 crt_setting_info
->iga_path
= IGA1
;
611 tmds_setting_info
->iga_path
= IGA1
;
614 lvds_setting_info
->iga_path
= IGA1
;
616 viaparinfo
->lvds_setting_info
->iga_path
= IGA2
;
620 if (LCD2_Device
== viafb_primary_dev
)
621 viaparinfo
->lvds_setting_info2
->iga_path
= IGA1
;
623 viaparinfo
->lvds_setting_info2
->iga_path
= IGA2
;
628 if (viafb_CRT_ON
&& viafb_LCD_ON
) {
629 viaparinfo
->crt_setting_info
->iga_path
= IGA1
;
630 viaparinfo
->lvds_setting_info
->iga_path
= IGA2
;
631 } else if (viafb_CRT_ON
&& viafb_DVI_ON
) {
632 viaparinfo
->crt_setting_info
->iga_path
= IGA1
;
633 viaparinfo
->tmds_setting_info
->iga_path
= IGA2
;
634 } else if (viafb_LCD_ON
&& viafb_DVI_ON
) {
635 viaparinfo
->tmds_setting_info
->iga_path
= IGA1
;
636 viaparinfo
->lvds_setting_info
->iga_path
= IGA2
;
637 } else if (viafb_LCD_ON
&& viafb_LCD2_ON
) {
638 viaparinfo
->lvds_setting_info
->iga_path
= IGA2
;
639 viaparinfo
->lvds_setting_info2
->iga_path
= IGA2
;
640 } else if (viafb_CRT_ON
) {
641 viaparinfo
->crt_setting_info
->iga_path
= IGA1
;
642 } else if (viafb_LCD_ON
) {
643 viaparinfo
->lvds_setting_info
->iga_path
= IGA2
;
644 } else if (viafb_DVI_ON
) {
645 viaparinfo
->tmds_setting_info
->iga_path
= IGA1
;
650 void viafb_set_primary_address(u32 addr
)
652 DEBUG_MSG(KERN_DEBUG
"viafb_set_primary_address(0x%08X)\n", addr
);
653 viafb_write_reg(CR0D
, VIACR
, addr
& 0xFF);
654 viafb_write_reg(CR0C
, VIACR
, (addr
>> 8) & 0xFF);
655 viafb_write_reg(CR34
, VIACR
, (addr
>> 16) & 0xFF);
656 viafb_write_reg_mask(CR48
, VIACR
, (addr
>> 24) & 0x1F, 0x1F);
659 void viafb_set_secondary_address(u32 addr
)
661 DEBUG_MSG(KERN_DEBUG
"viafb_set_secondary_address(0x%08X)\n", addr
);
662 /* secondary display supports only quadword aligned memory */
663 viafb_write_reg_mask(CR62
, VIACR
, (addr
>> 2) & 0xFE, 0xFE);
664 viafb_write_reg(CR63
, VIACR
, (addr
>> 10) & 0xFF);
665 viafb_write_reg(CR64
, VIACR
, (addr
>> 18) & 0xFF);
666 viafb_write_reg_mask(CRA3
, VIACR
, (addr
>> 26) & 0x07, 0x07);
669 void viafb_set_primary_pitch(u32 pitch
)
671 DEBUG_MSG(KERN_DEBUG
"viafb_set_primary_pitch(0x%08X)\n", pitch
);
672 /* spec does not say that first adapter skips 3 bits but old
673 * code did it and seems to be reasonable in analogy to 2nd adapter
676 viafb_write_reg(0x13, VIACR
, pitch
& 0xFF);
677 viafb_write_reg_mask(0x35, VIACR
, (pitch
>> (8 - 5)) & 0xE0, 0xE0);
680 void viafb_set_secondary_pitch(u32 pitch
)
682 DEBUG_MSG(KERN_DEBUG
"viafb_set_secondary_pitch(0x%08X)\n", pitch
);
684 viafb_write_reg(0x66, VIACR
, pitch
& 0xFF);
685 viafb_write_reg_mask(0x67, VIACR
, (pitch
>> 8) & 0x03, 0x03);
686 viafb_write_reg_mask(0x71, VIACR
, (pitch
>> (10 - 7)) & 0x80, 0x80);
689 void viafb_set_output_path(int device
, int set_iga
, int output_interface
)
693 set_crt_output_path(set_iga
);
696 set_dvi_output_path(set_iga
, output_interface
);
699 set_lcd_output_path(set_iga
, output_interface
);
704 static void set_crt_output_path(int set_iga
)
706 viafb_write_reg_mask(CR36
, VIACR
, 0x00, BIT4
+ BIT5
);
710 viafb_write_reg_mask(SR16
, VIASR
, 0x00, BIT6
);
714 viafb_write_reg_mask(CR6A
, VIACR
, 0xC0, BIT6
+ BIT7
);
715 viafb_write_reg_mask(SR16
, VIASR
, 0x40, BIT6
);
716 if (set_iga
== IGA1_IGA2
)
717 viafb_write_reg_mask(CR6B
, VIACR
, 0x08, BIT3
);
722 static void dvi_patch_skew_dvp0(void)
724 /* Reset data driving first: */
725 viafb_write_reg_mask(SR1B
, VIASR
, 0, BIT1
);
726 viafb_write_reg_mask(SR2A
, VIASR
, 0, BIT4
);
728 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
729 case UNICHROME_P4M890
:
731 if ((viaparinfo
->tmds_setting_info
->h_active
== 1600) &&
732 (viaparinfo
->tmds_setting_info
->v_active
==
734 viafb_write_reg_mask(CR96
, VIACR
, 0x03,
737 viafb_write_reg_mask(CR96
, VIACR
, 0x07,
742 case UNICHROME_P4M900
:
744 viafb_write_reg_mask(CR96
, VIACR
, 0x07,
745 BIT0
+ BIT1
+ BIT2
+ BIT3
);
746 viafb_write_reg_mask(SR1B
, VIASR
, 0x02, BIT1
);
747 viafb_write_reg_mask(SR2A
, VIASR
, 0x10, BIT4
);
758 static void dvi_patch_skew_dvp1(void)
760 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
761 case UNICHROME_CX700
:
773 static void dvi_patch_skew_dvp_low(void)
775 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
776 case UNICHROME_K8M890
:
778 viafb_write_reg_mask(CR99
, VIACR
, 0x03, BIT0
+ BIT1
);
782 case UNICHROME_P4M900
:
784 viafb_write_reg_mask(CR99
, VIACR
, 0x08,
785 BIT0
+ BIT1
+ BIT2
+ BIT3
);
789 case UNICHROME_P4M890
:
791 viafb_write_reg_mask(CR99
, VIACR
, 0x0F,
792 BIT0
+ BIT1
+ BIT2
+ BIT3
);
803 static void set_dvi_output_path(int set_iga
, int output_interface
)
805 switch (output_interface
) {
807 viafb_write_reg_mask(CR6B
, VIACR
, 0x01, BIT0
);
809 if (set_iga
== IGA1
) {
810 viafb_write_reg_mask(CR96
, VIACR
, 0x00, BIT4
);
811 viafb_write_reg_mask(CR6C
, VIACR
, 0x21, BIT0
+
814 viafb_write_reg_mask(CR96
, VIACR
, 0x10, BIT4
);
815 viafb_write_reg_mask(CR6C
, VIACR
, 0xA1, BIT0
+
819 viafb_write_reg_mask(SR1E
, VIASR
, 0xC0, BIT7
+ BIT6
);
821 dvi_patch_skew_dvp0();
825 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
) {
827 viafb_write_reg_mask(CR93
, VIACR
, 0x21,
830 viafb_write_reg_mask(CR93
, VIACR
, 0xA1,
834 viafb_write_reg_mask(CR9B
, VIACR
, 0x00, BIT4
);
836 viafb_write_reg_mask(CR9B
, VIACR
, 0x10, BIT4
);
839 viafb_write_reg_mask(SR1E
, VIASR
, 0x30, BIT4
+ BIT5
);
840 dvi_patch_skew_dvp1();
842 case INTERFACE_DFP_HIGH
:
843 if (viaparinfo
->chip_info
->gfx_chip_name
!= UNICHROME_CLE266
) {
844 if (set_iga
== IGA1
) {
845 viafb_write_reg_mask(CR96
, VIACR
, 0x00, BIT4
);
846 viafb_write_reg_mask(CR97
, VIACR
, 0x03,
849 viafb_write_reg_mask(CR96
, VIACR
, 0x10, BIT4
);
850 viafb_write_reg_mask(CR97
, VIACR
, 0x13,
854 viafb_write_reg_mask(SR2A
, VIASR
, 0x0C, BIT2
+ BIT3
);
857 case INTERFACE_DFP_LOW
:
858 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
)
861 if (set_iga
== IGA1
) {
862 viafb_write_reg_mask(CR99
, VIACR
, 0x00, BIT4
);
863 viafb_write_reg_mask(CR9B
, VIACR
, 0x00, BIT4
);
865 viafb_write_reg_mask(CR99
, VIACR
, 0x10, BIT4
);
866 viafb_write_reg_mask(CR9B
, VIACR
, 0x10, BIT4
);
869 viafb_write_reg_mask(SR2A
, VIASR
, 0x03, BIT0
+ BIT1
);
870 dvi_patch_skew_dvp_low();
875 viafb_write_reg_mask(CR99
, VIACR
, 0x00, BIT4
);
877 viafb_write_reg_mask(CR99
, VIACR
, 0x10, BIT4
);
881 if (set_iga
== IGA2
) {
882 enable_second_display_channel();
883 /* Disable LCD Scaling */
884 viafb_write_reg_mask(CR79
, VIACR
, 0x00, BIT0
);
888 static void set_lcd_output_path(int set_iga
, int output_interface
)
891 "set_lcd_output_path, iga:%d,out_interface:%d\n",
892 set_iga
, output_interface
);
895 viafb_write_reg_mask(CR6B
, VIACR
, 0x00, BIT3
);
896 viafb_write_reg_mask(CR6A
, VIACR
, 0x08, BIT3
);
898 disable_second_display_channel();
902 viafb_write_reg_mask(CR6B
, VIACR
, 0x00, BIT3
);
903 viafb_write_reg_mask(CR6A
, VIACR
, 0x08, BIT3
);
905 enable_second_display_channel();
909 viafb_write_reg_mask(CR6B
, VIACR
, 0x08, BIT3
);
910 viafb_write_reg_mask(CR6A
, VIACR
, 0x08, BIT3
);
912 disable_second_display_channel();
916 switch (output_interface
) {
918 if (set_iga
== IGA1
) {
919 viafb_write_reg_mask(CR96
, VIACR
, 0x00, BIT4
);
921 viafb_write_reg(CR91
, VIACR
, 0x00);
922 viafb_write_reg_mask(CR96
, VIACR
, 0x10, BIT4
);
928 viafb_write_reg_mask(CR9B
, VIACR
, 0x00, BIT4
);
930 viafb_write_reg(CR91
, VIACR
, 0x00);
931 viafb_write_reg_mask(CR9B
, VIACR
, 0x10, BIT4
);
935 case INTERFACE_DFP_HIGH
:
937 viafb_write_reg_mask(CR97
, VIACR
, 0x00, BIT4
);
939 viafb_write_reg(CR91
, VIACR
, 0x00);
940 viafb_write_reg_mask(CR97
, VIACR
, 0x10, BIT4
);
941 viafb_write_reg_mask(CR96
, VIACR
, 0x10, BIT4
);
945 case INTERFACE_DFP_LOW
:
947 viafb_write_reg_mask(CR99
, VIACR
, 0x00, BIT4
);
949 viafb_write_reg(CR91
, VIACR
, 0x00);
950 viafb_write_reg_mask(CR99
, VIACR
, 0x10, BIT4
);
951 viafb_write_reg_mask(CR9B
, VIACR
, 0x10, BIT4
);
957 if ((UNICHROME_K8M890
== viaparinfo
->chip_info
->gfx_chip_name
)
958 || (UNICHROME_P4M890
==
959 viaparinfo
->chip_info
->gfx_chip_name
))
960 viafb_write_reg_mask(CR97
, VIACR
, 0x84,
961 BIT7
+ BIT2
+ BIT1
+ BIT0
);
962 if (set_iga
== IGA1
) {
963 viafb_write_reg_mask(CR97
, VIACR
, 0x00, BIT4
);
964 viafb_write_reg_mask(CR99
, VIACR
, 0x00, BIT4
);
966 viafb_write_reg(CR91
, VIACR
, 0x00);
967 viafb_write_reg_mask(CR97
, VIACR
, 0x10, BIT4
);
968 viafb_write_reg_mask(CR99
, VIACR
, 0x10, BIT4
);
972 case INTERFACE_LVDS0
:
973 case INTERFACE_LVDS0LVDS1
:
975 viafb_write_reg_mask(CR99
, VIACR
, 0x00, BIT4
);
977 viafb_write_reg_mask(CR99
, VIACR
, 0x10, BIT4
);
981 case INTERFACE_LVDS1
:
983 viafb_write_reg_mask(CR97
, VIACR
, 0x00, BIT4
);
985 viafb_write_reg_mask(CR97
, VIACR
, 0x10, BIT4
);
990 /* Search Mode Index */
991 static int search_mode_setting(int ModeInfoIndex
)
995 while ((i
< NUM_TOTAL_MODETABLE
) &&
996 (ModeInfoIndex
!= CLE266Modes
[i
].ModeIndex
))
998 if (i
>= NUM_TOTAL_MODETABLE
)
1004 struct VideoModeTable
*viafb_get_modetbl_pointer(int Index
)
1006 struct VideoModeTable
*TmpTbl
= NULL
;
1007 TmpTbl
= &CLE266Modes
[search_mode_setting(Index
)];
1011 struct VideoModeTable
*viafb_get_cea_mode_tbl_pointer(int Index
)
1013 struct VideoModeTable
*TmpTbl
= NULL
;
1015 while ((i
< NUM_TOTAL_CEA_MODES
) &&
1016 (Index
!= CEA_HDMI_Modes
[i
].ModeIndex
))
1018 if ((i
< NUM_TOTAL_CEA_MODES
))
1019 TmpTbl
= &CEA_HDMI_Modes
[i
];
1021 /*Still use general timing if don't find CEA timing */
1023 while ((i
< NUM_TOTAL_MODETABLE
) &&
1024 (Index
!= CLE266Modes
[i
].ModeIndex
))
1026 if (i
>= NUM_TOTAL_MODETABLE
)
1028 TmpTbl
= &CLE266Modes
[i
];
1033 static void load_fix_bit_crtc_reg(void)
1035 /* always set to 1 */
1036 viafb_write_reg_mask(CR03
, VIACR
, 0x80, BIT7
);
1037 /* line compare should set all bits = 1 (extend modes) */
1038 viafb_write_reg(CR18
, VIACR
, 0xff);
1039 /* line compare should set all bits = 1 (extend modes) */
1040 viafb_write_reg_mask(CR07
, VIACR
, 0x10, BIT4
);
1041 /* line compare should set all bits = 1 (extend modes) */
1042 viafb_write_reg_mask(CR09
, VIACR
, 0x40, BIT6
);
1043 /* line compare should set all bits = 1 (extend modes) */
1044 viafb_write_reg_mask(CR35
, VIACR
, 0x10, BIT4
);
1045 /* line compare should set all bits = 1 (extend modes) */
1046 viafb_write_reg_mask(CR33
, VIACR
, 0x06, BIT0
+ BIT1
+ BIT2
);
1047 /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */
1048 /* extend mode always set to e3h */
1049 viafb_write_reg(CR17
, VIACR
, 0xe3);
1050 /* extend mode always set to 0h */
1051 viafb_write_reg(CR08
, VIACR
, 0x00);
1052 /* extend mode always set to 0h */
1053 viafb_write_reg(CR14
, VIACR
, 0x00);
1055 /* If K8M800, enable Prefetch Mode. */
1056 if ((viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K800
)
1057 || (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K8M890
))
1058 viafb_write_reg_mask(CR33
, VIACR
, 0x08, BIT3
);
1059 if ((viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
)
1060 && (viaparinfo
->chip_info
->gfx_chip_revision
== CLE266_REVISION_AX
))
1061 viafb_write_reg_mask(SR1A
, VIASR
, 0x02, BIT1
);
1065 void viafb_load_reg(int timing_value
, int viafb_load_reg_num
,
1066 struct io_register
*reg
,
1074 int start_index
, end_index
, cr_index
;
1077 for (i
= 0; i
< viafb_load_reg_num
; i
++) {
1080 start_index
= reg
[i
].start_bit
;
1081 end_index
= reg
[i
].end_bit
;
1082 cr_index
= reg
[i
].io_addr
;
1084 shift_next_reg
= bit_num
;
1085 for (j
= start_index
; j
<= end_index
; j
++) {
1086 /*if (bit_num==8) timing_value = timing_value >>8; */
1087 reg_mask
= reg_mask
| (BIT0
<< j
);
1088 get_bit
= (timing_value
& (BIT0
<< bit_num
));
1090 data
| ((get_bit
>> shift_next_reg
) << start_index
);
1093 if (io_type
== VIACR
)
1094 viafb_write_reg_mask(cr_index
, VIACR
, data
, reg_mask
);
1096 viafb_write_reg_mask(cr_index
, VIASR
, data
, reg_mask
);
1101 /* Write Registers */
1102 void viafb_write_regx(struct io_reg RegTable
[], int ItemNum
)
1105 unsigned char RegTemp
;
1107 /*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */
1109 for (i
= 0; i
< ItemNum
; i
++) {
1110 outb(RegTable
[i
].index
, RegTable
[i
].port
);
1111 RegTemp
= inb(RegTable
[i
].port
+ 1);
1112 RegTemp
= (RegTemp
& (~RegTable
[i
].mask
)) | RegTable
[i
].value
;
1113 outb(RegTemp
, RegTable
[i
].port
+ 1);
1117 void viafb_load_fetch_count_reg(int h_addr
, int bpp_byte
, int set_iga
)
1120 int viafb_load_reg_num
;
1121 struct io_register
*reg
= NULL
;
1126 reg_value
= IGA1_FETCH_COUNT_FORMULA(h_addr
, bpp_byte
);
1127 viafb_load_reg_num
= fetch_count_reg
.
1128 iga1_fetch_count_reg
.reg_num
;
1129 reg
= fetch_count_reg
.iga1_fetch_count_reg
.reg
;
1130 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIASR
);
1131 if (set_iga
== IGA1
)
1134 reg_value
= IGA2_FETCH_COUNT_FORMULA(h_addr
, bpp_byte
);
1135 viafb_load_reg_num
= fetch_count_reg
.
1136 iga2_fetch_count_reg
.reg_num
;
1137 reg
= fetch_count_reg
.iga2_fetch_count_reg
.reg
;
1138 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIACR
);
1144 void viafb_load_FIFO_reg(int set_iga
, int hor_active
, int ver_active
)
1147 int viafb_load_reg_num
;
1148 struct io_register
*reg
= NULL
;
1149 int iga1_fifo_max_depth
= 0, iga1_fifo_threshold
=
1150 0, iga1_fifo_high_threshold
= 0, iga1_display_queue_expire_num
= 0;
1151 int iga2_fifo_max_depth
= 0, iga2_fifo_threshold
=
1152 0, iga2_fifo_high_threshold
= 0, iga2_display_queue_expire_num
= 0;
1154 if (set_iga
== IGA1
) {
1155 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K800
) {
1156 iga1_fifo_max_depth
= K800_IGA1_FIFO_MAX_DEPTH
;
1157 iga1_fifo_threshold
= K800_IGA1_FIFO_THRESHOLD
;
1158 iga1_fifo_high_threshold
=
1159 K800_IGA1_FIFO_HIGH_THRESHOLD
;
1160 /* If resolution > 1280x1024, expire length = 64, else
1161 expire length = 128 */
1162 if ((hor_active
> 1280) && (ver_active
> 1024))
1163 iga1_display_queue_expire_num
= 16;
1165 iga1_display_queue_expire_num
=
1166 K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1170 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_PM800
) {
1171 iga1_fifo_max_depth
= P880_IGA1_FIFO_MAX_DEPTH
;
1172 iga1_fifo_threshold
= P880_IGA1_FIFO_THRESHOLD
;
1173 iga1_fifo_high_threshold
=
1174 P880_IGA1_FIFO_HIGH_THRESHOLD
;
1175 iga1_display_queue_expire_num
=
1176 P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1178 /* If resolution > 1280x1024, expire length = 64, else
1179 expire length = 128 */
1180 if ((hor_active
> 1280) && (ver_active
> 1024))
1181 iga1_display_queue_expire_num
= 16;
1183 iga1_display_queue_expire_num
=
1184 P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1187 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CN700
) {
1188 iga1_fifo_max_depth
= CN700_IGA1_FIFO_MAX_DEPTH
;
1189 iga1_fifo_threshold
= CN700_IGA1_FIFO_THRESHOLD
;
1190 iga1_fifo_high_threshold
=
1191 CN700_IGA1_FIFO_HIGH_THRESHOLD
;
1193 /* If resolution > 1280x1024, expire length = 64,
1194 else expire length = 128 */
1195 if ((hor_active
> 1280) && (ver_active
> 1024))
1196 iga1_display_queue_expire_num
= 16;
1198 iga1_display_queue_expire_num
=
1199 CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1202 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
) {
1203 iga1_fifo_max_depth
= CX700_IGA1_FIFO_MAX_DEPTH
;
1204 iga1_fifo_threshold
= CX700_IGA1_FIFO_THRESHOLD
;
1205 iga1_fifo_high_threshold
=
1206 CX700_IGA1_FIFO_HIGH_THRESHOLD
;
1207 iga1_display_queue_expire_num
=
1208 CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1211 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K8M890
) {
1212 iga1_fifo_max_depth
= K8M890_IGA1_FIFO_MAX_DEPTH
;
1213 iga1_fifo_threshold
= K8M890_IGA1_FIFO_THRESHOLD
;
1214 iga1_fifo_high_threshold
=
1215 K8M890_IGA1_FIFO_HIGH_THRESHOLD
;
1216 iga1_display_queue_expire_num
=
1217 K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1220 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_P4M890
) {
1221 iga1_fifo_max_depth
= P4M890_IGA1_FIFO_MAX_DEPTH
;
1222 iga1_fifo_threshold
= P4M890_IGA1_FIFO_THRESHOLD
;
1223 iga1_fifo_high_threshold
=
1224 P4M890_IGA1_FIFO_HIGH_THRESHOLD
;
1225 iga1_display_queue_expire_num
=
1226 P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1229 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_P4M900
) {
1230 iga1_fifo_max_depth
= P4M900_IGA1_FIFO_MAX_DEPTH
;
1231 iga1_fifo_threshold
= P4M900_IGA1_FIFO_THRESHOLD
;
1232 iga1_fifo_high_threshold
=
1233 P4M900_IGA1_FIFO_HIGH_THRESHOLD
;
1234 iga1_display_queue_expire_num
=
1235 P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1238 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_VX800
) {
1239 iga1_fifo_max_depth
= VX800_IGA1_FIFO_MAX_DEPTH
;
1240 iga1_fifo_threshold
= VX800_IGA1_FIFO_THRESHOLD
;
1241 iga1_fifo_high_threshold
=
1242 VX800_IGA1_FIFO_HIGH_THRESHOLD
;
1243 iga1_display_queue_expire_num
=
1244 VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1247 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_VX855
) {
1248 iga1_fifo_max_depth
= VX855_IGA1_FIFO_MAX_DEPTH
;
1249 iga1_fifo_threshold
= VX855_IGA1_FIFO_THRESHOLD
;
1250 iga1_fifo_high_threshold
=
1251 VX855_IGA1_FIFO_HIGH_THRESHOLD
;
1252 iga1_display_queue_expire_num
=
1253 VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1256 /* Set Display FIFO Depath Select */
1257 reg_value
= IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth
);
1258 viafb_load_reg_num
=
1259 display_fifo_depth_reg
.iga1_fifo_depth_select_reg
.reg_num
;
1260 reg
= display_fifo_depth_reg
.iga1_fifo_depth_select_reg
.reg
;
1261 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIASR
);
1263 /* Set Display FIFO Threshold Select */
1264 reg_value
= IGA1_FIFO_THRESHOLD_FORMULA(iga1_fifo_threshold
);
1265 viafb_load_reg_num
=
1266 fifo_threshold_select_reg
.
1267 iga1_fifo_threshold_select_reg
.reg_num
;
1269 fifo_threshold_select_reg
.
1270 iga1_fifo_threshold_select_reg
.reg
;
1271 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIASR
);
1273 /* Set FIFO High Threshold Select */
1275 IGA1_FIFO_HIGH_THRESHOLD_FORMULA(iga1_fifo_high_threshold
);
1276 viafb_load_reg_num
=
1277 fifo_high_threshold_select_reg
.
1278 iga1_fifo_high_threshold_select_reg
.reg_num
;
1280 fifo_high_threshold_select_reg
.
1281 iga1_fifo_high_threshold_select_reg
.reg
;
1282 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIASR
);
1284 /* Set Display Queue Expire Num */
1286 IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
1287 (iga1_display_queue_expire_num
);
1288 viafb_load_reg_num
=
1289 display_queue_expire_num_reg
.
1290 iga1_display_queue_expire_num_reg
.reg_num
;
1292 display_queue_expire_num_reg
.
1293 iga1_display_queue_expire_num_reg
.reg
;
1294 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIASR
);
1297 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K800
) {
1298 iga2_fifo_max_depth
= K800_IGA2_FIFO_MAX_DEPTH
;
1299 iga2_fifo_threshold
= K800_IGA2_FIFO_THRESHOLD
;
1300 iga2_fifo_high_threshold
=
1301 K800_IGA2_FIFO_HIGH_THRESHOLD
;
1303 /* If resolution > 1280x1024, expire length = 64,
1304 else expire length = 128 */
1305 if ((hor_active
> 1280) && (ver_active
> 1024))
1306 iga2_display_queue_expire_num
= 16;
1308 iga2_display_queue_expire_num
=
1309 K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1312 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_PM800
) {
1313 iga2_fifo_max_depth
= P880_IGA2_FIFO_MAX_DEPTH
;
1314 iga2_fifo_threshold
= P880_IGA2_FIFO_THRESHOLD
;
1315 iga2_fifo_high_threshold
=
1316 P880_IGA2_FIFO_HIGH_THRESHOLD
;
1318 /* If resolution > 1280x1024, expire length = 64,
1319 else expire length = 128 */
1320 if ((hor_active
> 1280) && (ver_active
> 1024))
1321 iga2_display_queue_expire_num
= 16;
1323 iga2_display_queue_expire_num
=
1324 P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1327 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CN700
) {
1328 iga2_fifo_max_depth
= CN700_IGA2_FIFO_MAX_DEPTH
;
1329 iga2_fifo_threshold
= CN700_IGA2_FIFO_THRESHOLD
;
1330 iga2_fifo_high_threshold
=
1331 CN700_IGA2_FIFO_HIGH_THRESHOLD
;
1333 /* If resolution > 1280x1024, expire length = 64,
1334 else expire length = 128 */
1335 if ((hor_active
> 1280) && (ver_active
> 1024))
1336 iga2_display_queue_expire_num
= 16;
1338 iga2_display_queue_expire_num
=
1339 CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1342 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
) {
1343 iga2_fifo_max_depth
= CX700_IGA2_FIFO_MAX_DEPTH
;
1344 iga2_fifo_threshold
= CX700_IGA2_FIFO_THRESHOLD
;
1345 iga2_fifo_high_threshold
=
1346 CX700_IGA2_FIFO_HIGH_THRESHOLD
;
1347 iga2_display_queue_expire_num
=
1348 CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1351 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K8M890
) {
1352 iga2_fifo_max_depth
= K8M890_IGA2_FIFO_MAX_DEPTH
;
1353 iga2_fifo_threshold
= K8M890_IGA2_FIFO_THRESHOLD
;
1354 iga2_fifo_high_threshold
=
1355 K8M890_IGA2_FIFO_HIGH_THRESHOLD
;
1356 iga2_display_queue_expire_num
=
1357 K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1360 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_P4M890
) {
1361 iga2_fifo_max_depth
= P4M890_IGA2_FIFO_MAX_DEPTH
;
1362 iga2_fifo_threshold
= P4M890_IGA2_FIFO_THRESHOLD
;
1363 iga2_fifo_high_threshold
=
1364 P4M890_IGA2_FIFO_HIGH_THRESHOLD
;
1365 iga2_display_queue_expire_num
=
1366 P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1369 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_P4M900
) {
1370 iga2_fifo_max_depth
= P4M900_IGA2_FIFO_MAX_DEPTH
;
1371 iga2_fifo_threshold
= P4M900_IGA2_FIFO_THRESHOLD
;
1372 iga2_fifo_high_threshold
=
1373 P4M900_IGA2_FIFO_HIGH_THRESHOLD
;
1374 iga2_display_queue_expire_num
=
1375 P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1378 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_VX800
) {
1379 iga2_fifo_max_depth
= VX800_IGA2_FIFO_MAX_DEPTH
;
1380 iga2_fifo_threshold
= VX800_IGA2_FIFO_THRESHOLD
;
1381 iga2_fifo_high_threshold
=
1382 VX800_IGA2_FIFO_HIGH_THRESHOLD
;
1383 iga2_display_queue_expire_num
=
1384 VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1387 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_VX855
) {
1388 iga2_fifo_max_depth
= VX855_IGA2_FIFO_MAX_DEPTH
;
1389 iga2_fifo_threshold
= VX855_IGA2_FIFO_THRESHOLD
;
1390 iga2_fifo_high_threshold
=
1391 VX855_IGA2_FIFO_HIGH_THRESHOLD
;
1392 iga2_display_queue_expire_num
=
1393 VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1396 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K800
) {
1397 /* Set Display FIFO Depath Select */
1399 IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth
)
1401 /* Patch LCD in IGA2 case */
1402 viafb_load_reg_num
=
1403 display_fifo_depth_reg
.
1404 iga2_fifo_depth_select_reg
.reg_num
;
1406 display_fifo_depth_reg
.
1407 iga2_fifo_depth_select_reg
.reg
;
1408 viafb_load_reg(reg_value
,
1409 viafb_load_reg_num
, reg
, VIACR
);
1412 /* Set Display FIFO Depath Select */
1414 IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth
);
1415 viafb_load_reg_num
=
1416 display_fifo_depth_reg
.
1417 iga2_fifo_depth_select_reg
.reg_num
;
1419 display_fifo_depth_reg
.
1420 iga2_fifo_depth_select_reg
.reg
;
1421 viafb_load_reg(reg_value
,
1422 viafb_load_reg_num
, reg
, VIACR
);
1425 /* Set Display FIFO Threshold Select */
1426 reg_value
= IGA2_FIFO_THRESHOLD_FORMULA(iga2_fifo_threshold
);
1427 viafb_load_reg_num
=
1428 fifo_threshold_select_reg
.
1429 iga2_fifo_threshold_select_reg
.reg_num
;
1431 fifo_threshold_select_reg
.
1432 iga2_fifo_threshold_select_reg
.reg
;
1433 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIACR
);
1435 /* Set FIFO High Threshold Select */
1437 IGA2_FIFO_HIGH_THRESHOLD_FORMULA(iga2_fifo_high_threshold
);
1438 viafb_load_reg_num
=
1439 fifo_high_threshold_select_reg
.
1440 iga2_fifo_high_threshold_select_reg
.reg_num
;
1442 fifo_high_threshold_select_reg
.
1443 iga2_fifo_high_threshold_select_reg
.reg
;
1444 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIACR
);
1446 /* Set Display Queue Expire Num */
1448 IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
1449 (iga2_display_queue_expire_num
);
1450 viafb_load_reg_num
=
1451 display_queue_expire_num_reg
.
1452 iga2_display_queue_expire_num_reg
.reg_num
;
1454 display_queue_expire_num_reg
.
1455 iga2_display_queue_expire_num_reg
.reg
;
1456 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIACR
);
1462 u32
viafb_get_clk_value(int clk
)
1466 for (i
= 0; i
< NUM_TOTAL_PLL_TABLE
; i
++) {
1467 if (clk
== pll_value
[i
].clk
) {
1468 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
1469 case UNICHROME_CLE266
:
1470 case UNICHROME_K400
:
1471 return pll_value
[i
].cle266_pll
;
1473 case UNICHROME_K800
:
1474 case UNICHROME_PM800
:
1475 case UNICHROME_CN700
:
1476 return pll_value
[i
].k800_pll
;
1478 case UNICHROME_CX700
:
1479 case UNICHROME_K8M890
:
1480 case UNICHROME_P4M890
:
1481 case UNICHROME_P4M900
:
1482 case UNICHROME_VX800
:
1483 return pll_value
[i
].cx700_pll
;
1484 case UNICHROME_VX855
:
1485 return pll_value
[i
].vx855_pll
;
1490 DEBUG_MSG(KERN_INFO
"Can't find match PLL value\n\n");
1495 void viafb_set_vclock(u32 CLK
, int set_iga
)
1497 unsigned char RegTemp
;
1499 /* H.W. Reset : ON */
1500 viafb_write_reg_mask(CR17
, VIACR
, 0x00, BIT7
);
1502 if ((set_iga
== IGA1
) || (set_iga
== IGA1_IGA2
)) {
1503 /* Change D,N FOR VCLK */
1504 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
1505 case UNICHROME_CLE266
:
1506 case UNICHROME_K400
:
1507 viafb_write_reg(SR46
, VIASR
, CLK
/ 0x100);
1508 viafb_write_reg(SR47
, VIASR
, CLK
% 0x100);
1511 case UNICHROME_K800
:
1512 case UNICHROME_PM800
:
1513 case UNICHROME_CN700
:
1514 case UNICHROME_CX700
:
1515 case UNICHROME_K8M890
:
1516 case UNICHROME_P4M890
:
1517 case UNICHROME_P4M900
:
1518 case UNICHROME_VX800
:
1519 case UNICHROME_VX855
:
1520 viafb_write_reg(SR44
, VIASR
, CLK
/ 0x10000);
1521 DEBUG_MSG(KERN_INFO
"\nSR44=%x", CLK
/ 0x10000);
1522 viafb_write_reg(SR45
, VIASR
, (CLK
& 0xFFFF) / 0x100);
1523 DEBUG_MSG(KERN_INFO
"\nSR45=%x",
1524 (CLK
& 0xFFFF) / 0x100);
1525 viafb_write_reg(SR46
, VIASR
, CLK
% 0x100);
1526 DEBUG_MSG(KERN_INFO
"\nSR46=%x", CLK
% 0x100);
1531 if ((set_iga
== IGA2
) || (set_iga
== IGA1_IGA2
)) {
1532 /* Change D,N FOR LCK */
1533 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
1534 case UNICHROME_CLE266
:
1535 case UNICHROME_K400
:
1536 viafb_write_reg(SR44
, VIASR
, CLK
/ 0x100);
1537 viafb_write_reg(SR45
, VIASR
, CLK
% 0x100);
1540 case UNICHROME_K800
:
1541 case UNICHROME_PM800
:
1542 case UNICHROME_CN700
:
1543 case UNICHROME_CX700
:
1544 case UNICHROME_K8M890
:
1545 case UNICHROME_P4M890
:
1546 case UNICHROME_P4M900
:
1547 case UNICHROME_VX800
:
1548 case UNICHROME_VX855
:
1549 viafb_write_reg(SR4A
, VIASR
, CLK
/ 0x10000);
1550 viafb_write_reg(SR4B
, VIASR
, (CLK
& 0xFFFF) / 0x100);
1551 viafb_write_reg(SR4C
, VIASR
, CLK
% 0x100);
1556 /* H.W. Reset : OFF */
1557 viafb_write_reg_mask(CR17
, VIACR
, 0x80, BIT7
);
1560 if ((set_iga
== IGA1
) || (set_iga
== IGA1_IGA2
)) {
1561 viafb_write_reg_mask(SR40
, VIASR
, 0x02, BIT1
);
1562 viafb_write_reg_mask(SR40
, VIASR
, 0x00, BIT1
);
1565 if ((set_iga
== IGA2
) || (set_iga
== IGA1_IGA2
)) {
1566 viafb_write_reg_mask(SR40
, VIASR
, 0x01, BIT0
);
1567 viafb_write_reg_mask(SR40
, VIASR
, 0x00, BIT0
);
1571 RegTemp
= inb(VIARMisc
);
1572 outb(RegTemp
| (BIT2
+ BIT3
), VIAWMisc
);
1575 void viafb_load_crtc_timing(struct display_timing device_timing
,
1579 int viafb_load_reg_num
= 0;
1581 struct io_register
*reg
= NULL
;
1585 for (i
= 0; i
< 12; i
++) {
1586 if (set_iga
== IGA1
) {
1590 IGA1_HOR_TOTAL_FORMULA(device_timing
.
1592 viafb_load_reg_num
=
1593 iga1_crtc_reg
.hor_total
.reg_num
;
1594 reg
= iga1_crtc_reg
.hor_total
.reg
;
1598 IGA1_HOR_ADDR_FORMULA(device_timing
.
1600 viafb_load_reg_num
=
1601 iga1_crtc_reg
.hor_addr
.reg_num
;
1602 reg
= iga1_crtc_reg
.hor_addr
.reg
;
1604 case H_BLANK_START_INDEX
:
1606 IGA1_HOR_BLANK_START_FORMULA
1607 (device_timing
.hor_blank_start
);
1608 viafb_load_reg_num
=
1609 iga1_crtc_reg
.hor_blank_start
.reg_num
;
1610 reg
= iga1_crtc_reg
.hor_blank_start
.reg
;
1612 case H_BLANK_END_INDEX
:
1614 IGA1_HOR_BLANK_END_FORMULA
1615 (device_timing
.hor_blank_start
,
1616 device_timing
.hor_blank_end
);
1617 viafb_load_reg_num
=
1618 iga1_crtc_reg
.hor_blank_end
.reg_num
;
1619 reg
= iga1_crtc_reg
.hor_blank_end
.reg
;
1621 case H_SYNC_START_INDEX
:
1623 IGA1_HOR_SYNC_START_FORMULA
1624 (device_timing
.hor_sync_start
);
1625 viafb_load_reg_num
=
1626 iga1_crtc_reg
.hor_sync_start
.reg_num
;
1627 reg
= iga1_crtc_reg
.hor_sync_start
.reg
;
1629 case H_SYNC_END_INDEX
:
1631 IGA1_HOR_SYNC_END_FORMULA
1632 (device_timing
.hor_sync_start
,
1633 device_timing
.hor_sync_end
);
1634 viafb_load_reg_num
=
1635 iga1_crtc_reg
.hor_sync_end
.reg_num
;
1636 reg
= iga1_crtc_reg
.hor_sync_end
.reg
;
1640 IGA1_VER_TOTAL_FORMULA(device_timing
.
1642 viafb_load_reg_num
=
1643 iga1_crtc_reg
.ver_total
.reg_num
;
1644 reg
= iga1_crtc_reg
.ver_total
.reg
;
1648 IGA1_VER_ADDR_FORMULA(device_timing
.
1650 viafb_load_reg_num
=
1651 iga1_crtc_reg
.ver_addr
.reg_num
;
1652 reg
= iga1_crtc_reg
.ver_addr
.reg
;
1654 case V_BLANK_START_INDEX
:
1656 IGA1_VER_BLANK_START_FORMULA
1657 (device_timing
.ver_blank_start
);
1658 viafb_load_reg_num
=
1659 iga1_crtc_reg
.ver_blank_start
.reg_num
;
1660 reg
= iga1_crtc_reg
.ver_blank_start
.reg
;
1662 case V_BLANK_END_INDEX
:
1664 IGA1_VER_BLANK_END_FORMULA
1665 (device_timing
.ver_blank_start
,
1666 device_timing
.ver_blank_end
);
1667 viafb_load_reg_num
=
1668 iga1_crtc_reg
.ver_blank_end
.reg_num
;
1669 reg
= iga1_crtc_reg
.ver_blank_end
.reg
;
1671 case V_SYNC_START_INDEX
:
1673 IGA1_VER_SYNC_START_FORMULA
1674 (device_timing
.ver_sync_start
);
1675 viafb_load_reg_num
=
1676 iga1_crtc_reg
.ver_sync_start
.reg_num
;
1677 reg
= iga1_crtc_reg
.ver_sync_start
.reg
;
1679 case V_SYNC_END_INDEX
:
1681 IGA1_VER_SYNC_END_FORMULA
1682 (device_timing
.ver_sync_start
,
1683 device_timing
.ver_sync_end
);
1684 viafb_load_reg_num
=
1685 iga1_crtc_reg
.ver_sync_end
.reg_num
;
1686 reg
= iga1_crtc_reg
.ver_sync_end
.reg
;
1692 if (set_iga
== IGA2
) {
1696 IGA2_HOR_TOTAL_FORMULA(device_timing
.
1698 viafb_load_reg_num
=
1699 iga2_crtc_reg
.hor_total
.reg_num
;
1700 reg
= iga2_crtc_reg
.hor_total
.reg
;
1704 IGA2_HOR_ADDR_FORMULA(device_timing
.
1706 viafb_load_reg_num
=
1707 iga2_crtc_reg
.hor_addr
.reg_num
;
1708 reg
= iga2_crtc_reg
.hor_addr
.reg
;
1710 case H_BLANK_START_INDEX
:
1712 IGA2_HOR_BLANK_START_FORMULA
1713 (device_timing
.hor_blank_start
);
1714 viafb_load_reg_num
=
1715 iga2_crtc_reg
.hor_blank_start
.reg_num
;
1716 reg
= iga2_crtc_reg
.hor_blank_start
.reg
;
1718 case H_BLANK_END_INDEX
:
1720 IGA2_HOR_BLANK_END_FORMULA
1721 (device_timing
.hor_blank_start
,
1722 device_timing
.hor_blank_end
);
1723 viafb_load_reg_num
=
1724 iga2_crtc_reg
.hor_blank_end
.reg_num
;
1725 reg
= iga2_crtc_reg
.hor_blank_end
.reg
;
1727 case H_SYNC_START_INDEX
:
1729 IGA2_HOR_SYNC_START_FORMULA
1730 (device_timing
.hor_sync_start
);
1731 if (UNICHROME_CN700
<=
1732 viaparinfo
->chip_info
->gfx_chip_name
)
1733 viafb_load_reg_num
=
1734 iga2_crtc_reg
.hor_sync_start
.
1737 viafb_load_reg_num
= 3;
1738 reg
= iga2_crtc_reg
.hor_sync_start
.reg
;
1740 case H_SYNC_END_INDEX
:
1742 IGA2_HOR_SYNC_END_FORMULA
1743 (device_timing
.hor_sync_start
,
1744 device_timing
.hor_sync_end
);
1745 viafb_load_reg_num
=
1746 iga2_crtc_reg
.hor_sync_end
.reg_num
;
1747 reg
= iga2_crtc_reg
.hor_sync_end
.reg
;
1751 IGA2_VER_TOTAL_FORMULA(device_timing
.
1753 viafb_load_reg_num
=
1754 iga2_crtc_reg
.ver_total
.reg_num
;
1755 reg
= iga2_crtc_reg
.ver_total
.reg
;
1759 IGA2_VER_ADDR_FORMULA(device_timing
.
1761 viafb_load_reg_num
=
1762 iga2_crtc_reg
.ver_addr
.reg_num
;
1763 reg
= iga2_crtc_reg
.ver_addr
.reg
;
1765 case V_BLANK_START_INDEX
:
1767 IGA2_VER_BLANK_START_FORMULA
1768 (device_timing
.ver_blank_start
);
1769 viafb_load_reg_num
=
1770 iga2_crtc_reg
.ver_blank_start
.reg_num
;
1771 reg
= iga2_crtc_reg
.ver_blank_start
.reg
;
1773 case V_BLANK_END_INDEX
:
1775 IGA2_VER_BLANK_END_FORMULA
1776 (device_timing
.ver_blank_start
,
1777 device_timing
.ver_blank_end
);
1778 viafb_load_reg_num
=
1779 iga2_crtc_reg
.ver_blank_end
.reg_num
;
1780 reg
= iga2_crtc_reg
.ver_blank_end
.reg
;
1782 case V_SYNC_START_INDEX
:
1784 IGA2_VER_SYNC_START_FORMULA
1785 (device_timing
.ver_sync_start
);
1786 viafb_load_reg_num
=
1787 iga2_crtc_reg
.ver_sync_start
.reg_num
;
1788 reg
= iga2_crtc_reg
.ver_sync_start
.reg
;
1790 case V_SYNC_END_INDEX
:
1792 IGA2_VER_SYNC_END_FORMULA
1793 (device_timing
.ver_sync_start
,
1794 device_timing
.ver_sync_end
);
1795 viafb_load_reg_num
=
1796 iga2_crtc_reg
.ver_sync_end
.reg_num
;
1797 reg
= iga2_crtc_reg
.ver_sync_end
.reg
;
1802 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIACR
);
1808 void viafb_set_color_depth(int bpp_byte
, int set_iga
)
1810 if (set_iga
== IGA1
) {
1813 viafb_write_reg_mask(SR15
, VIASR
, 0x22, 0x7E);
1816 viafb_write_reg_mask(SR15
, VIASR
, 0xB6, 0xFE);
1819 viafb_write_reg_mask(SR15
, VIASR
, 0xAE, 0xFE);
1825 viafb_write_reg_mask(CR67
, VIACR
, 0x00, BIT6
+ BIT7
);
1828 viafb_write_reg_mask(CR67
, VIACR
, 0x40, BIT6
+ BIT7
);
1831 viafb_write_reg_mask(CR67
, VIACR
, 0xC0, BIT6
+ BIT7
);
1837 void viafb_fill_crtc_timing(struct crt_mode_table
*crt_table
,
1838 int mode_index
, int bpp_byte
, int set_iga
)
1840 struct VideoModeTable
*video_mode
;
1841 struct display_timing crt_reg
;
1847 video_mode
= &CLE266Modes
[search_mode_setting(mode_index
)];
1849 for (i
= 0; i
< video_mode
->mode_array
; i
++) {
1852 if (crt_table
[i
].refresh_rate
== viaparinfo
->
1853 crt_setting_info
->refresh_rate
)
1857 crt_reg
= crt_table
[index
].crtc
;
1859 /* Mode 640x480 has border, but LCD/DFP didn't have border. */
1860 /* So we would delete border. */
1861 if ((viafb_LCD_ON
| viafb_DVI_ON
) && (mode_index
== VIA_RES_640X480
)
1862 && (viaparinfo
->crt_setting_info
->refresh_rate
== 60)) {
1863 /* The border is 8 pixels. */
1864 crt_reg
.hor_blank_start
= crt_reg
.hor_blank_start
- 8;
1866 /* Blanking time should add left and right borders. */
1867 crt_reg
.hor_blank_end
= crt_reg
.hor_blank_end
+ 16;
1870 h_addr
= crt_reg
.hor_addr
;
1871 v_addr
= crt_reg
.ver_addr
;
1873 /* update polarity for CRT timing */
1874 if (crt_table
[index
].h_sync_polarity
== NEGATIVE
) {
1875 if (crt_table
[index
].v_sync_polarity
== NEGATIVE
)
1876 outb((inb(VIARMisc
) & (~(BIT6
+ BIT7
))) |
1877 (BIT6
+ BIT7
), VIAWMisc
);
1879 outb((inb(VIARMisc
) & (~(BIT6
+ BIT7
))) | (BIT6
),
1882 if (crt_table
[index
].v_sync_polarity
== NEGATIVE
)
1883 outb((inb(VIARMisc
) & (~(BIT6
+ BIT7
))) | (BIT7
),
1886 outb((inb(VIARMisc
) & (~(BIT6
+ BIT7
))), VIAWMisc
);
1889 if (set_iga
== IGA1
) {
1891 viafb_write_reg(CR09
, VIACR
, 0x00); /*initial CR09=0 */
1892 viafb_write_reg_mask(CR11
, VIACR
, 0x00, BIT4
+ BIT5
+ BIT6
);
1893 viafb_write_reg_mask(CR17
, VIACR
, 0x00, BIT7
);
1898 viafb_load_crtc_timing(crt_reg
, IGA1
);
1901 viafb_load_crtc_timing(crt_reg
, IGA2
);
1905 load_fix_bit_crtc_reg();
1907 viafb_write_reg_mask(CR17
, VIACR
, 0x80, BIT7
);
1908 viafb_load_fetch_count_reg(h_addr
, bpp_byte
, set_iga
);
1911 if ((viaparinfo
->chip_info
->gfx_chip_name
!= UNICHROME_CLE266
)
1912 && (viaparinfo
->chip_info
->gfx_chip_name
!= UNICHROME_K400
))
1913 viafb_load_FIFO_reg(set_iga
, h_addr
, v_addr
);
1915 /* load SR Register About Memory and Color part */
1916 viafb_set_color_depth(bpp_byte
, set_iga
);
1918 pll_D_N
= viafb_get_clk_value(crt_table
[index
].clk
);
1919 DEBUG_MSG(KERN_INFO
"PLL=%x", pll_D_N
);
1920 viafb_set_vclock(pll_D_N
, set_iga
);
1924 void viafb_init_chip_info(struct pci_dev
*pdev
,
1925 const struct pci_device_id
*pdi
)
1927 init_gfx_chip_info(pdev
, pdi
);
1928 init_tmds_chip_info();
1929 init_lvds_chip_info();
1931 viaparinfo
->crt_setting_info
->iga_path
= IGA1
;
1932 viaparinfo
->crt_setting_info
->refresh_rate
= viafb_refresh
;
1934 /*Set IGA path for each device */
1935 viafb_set_iga_path();
1937 viaparinfo
->lvds_setting_info
->display_method
= viafb_lcd_dsp_method
;
1938 viaparinfo
->lvds_setting_info
->get_lcd_size_method
=
1939 GET_LCD_SIZE_BY_USER_SETTING
;
1940 viaparinfo
->lvds_setting_info
->lcd_mode
= viafb_lcd_mode
;
1941 viaparinfo
->lvds_setting_info2
->display_method
=
1942 viaparinfo
->lvds_setting_info
->display_method
;
1943 viaparinfo
->lvds_setting_info2
->lcd_mode
=
1944 viaparinfo
->lvds_setting_info
->lcd_mode
;
1947 void viafb_update_device_setting(int hres
, int vres
,
1948 int bpp
, int vmode_refresh
, int flag
)
1951 viaparinfo
->crt_setting_info
->h_active
= hres
;
1952 viaparinfo
->crt_setting_info
->v_active
= vres
;
1953 viaparinfo
->crt_setting_info
->bpp
= bpp
;
1954 viaparinfo
->crt_setting_info
->refresh_rate
=
1957 viaparinfo
->tmds_setting_info
->h_active
= hres
;
1958 viaparinfo
->tmds_setting_info
->v_active
= vres
;
1959 viaparinfo
->tmds_setting_info
->bpp
= bpp
;
1960 viaparinfo
->tmds_setting_info
->refresh_rate
=
1963 viaparinfo
->lvds_setting_info
->h_active
= hres
;
1964 viaparinfo
->lvds_setting_info
->v_active
= vres
;
1965 viaparinfo
->lvds_setting_info
->bpp
= bpp
;
1966 viaparinfo
->lvds_setting_info
->refresh_rate
=
1968 viaparinfo
->lvds_setting_info2
->h_active
= hres
;
1969 viaparinfo
->lvds_setting_info2
->v_active
= vres
;
1970 viaparinfo
->lvds_setting_info2
->bpp
= bpp
;
1971 viaparinfo
->lvds_setting_info2
->refresh_rate
=
1975 if (viaparinfo
->tmds_setting_info
->iga_path
== IGA2
) {
1976 viaparinfo
->tmds_setting_info
->h_active
= hres
;
1977 viaparinfo
->tmds_setting_info
->v_active
= vres
;
1978 viaparinfo
->tmds_setting_info
->bpp
= bpp
;
1979 viaparinfo
->tmds_setting_info
->refresh_rate
=
1983 if (viaparinfo
->lvds_setting_info
->iga_path
== IGA2
) {
1984 viaparinfo
->lvds_setting_info
->h_active
= hres
;
1985 viaparinfo
->lvds_setting_info
->v_active
= vres
;
1986 viaparinfo
->lvds_setting_info
->bpp
= bpp
;
1987 viaparinfo
->lvds_setting_info
->refresh_rate
=
1990 if (IGA2
== viaparinfo
->lvds_setting_info2
->iga_path
) {
1991 viaparinfo
->lvds_setting_info2
->h_active
= hres
;
1992 viaparinfo
->lvds_setting_info2
->v_active
= vres
;
1993 viaparinfo
->lvds_setting_info2
->bpp
= bpp
;
1994 viaparinfo
->lvds_setting_info2
->refresh_rate
=
2000 static void init_gfx_chip_info(struct pci_dev
*pdev
,
2001 const struct pci_device_id
*pdi
)
2005 viaparinfo
->chip_info
->gfx_chip_name
= pdi
->driver_data
;
2007 /* Check revision of CLE266 Chip */
2008 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
) {
2009 /* CR4F only define in CLE266.CX chip */
2010 tmp
= viafb_read_reg(VIACR
, CR4F
);
2011 viafb_write_reg(CR4F
, VIACR
, 0x55);
2012 if (viafb_read_reg(VIACR
, CR4F
) != 0x55)
2013 viaparinfo
->chip_info
->gfx_chip_revision
=
2016 viaparinfo
->chip_info
->gfx_chip_revision
=
2018 /* restore orignal CR4F value */
2019 viafb_write_reg(CR4F
, VIACR
, tmp
);
2022 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
) {
2023 tmp
= viafb_read_reg(VIASR
, SR43
);
2024 DEBUG_MSG(KERN_INFO
"SR43:%X\n", tmp
);
2026 viaparinfo
->chip_info
->gfx_chip_revision
=
2027 CX700_REVISION_700M2
;
2028 } else if (tmp
& 0x40) {
2029 viaparinfo
->chip_info
->gfx_chip_revision
=
2030 CX700_REVISION_700M
;
2032 viaparinfo
->chip_info
->gfx_chip_revision
=
2038 static void init_tmds_chip_info(void)
2040 viafb_tmds_trasmitter_identify();
2042 if (INTERFACE_NONE
== viaparinfo
->chip_info
->tmds_chip_info
.
2044 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
2045 case UNICHROME_CX700
:
2047 /* we should check support by hardware layout.*/
2048 if ((viafb_display_hardware_layout
==
2050 || (viafb_display_hardware_layout
==
2051 HW_LAYOUT_LCD_DVI
)) {
2052 viaparinfo
->chip_info
->tmds_chip_info
.
2053 output_interface
= INTERFACE_TMDS
;
2055 viaparinfo
->chip_info
->tmds_chip_info
.
2061 case UNICHROME_K8M890
:
2062 case UNICHROME_P4M900
:
2063 case UNICHROME_P4M890
:
2064 /* TMDS on PCIE, we set DFPLOW as default. */
2065 viaparinfo
->chip_info
->tmds_chip_info
.output_interface
=
2070 /* set DVP1 default for DVI */
2071 viaparinfo
->chip_info
->tmds_chip_info
2072 .output_interface
= INTERFACE_DVP1
;
2077 DEBUG_MSG(KERN_INFO
"TMDS Chip = %d\n",
2078 viaparinfo
->chip_info
->tmds_chip_info
.tmds_chip_name
);
2079 viaparinfo
->tmds_setting_info
->get_dvi_size_method
=
2080 GET_DVI_SIZE_BY_VGA_BIOS
;
2081 viafb_init_dvi_size();
2084 static void init_lvds_chip_info(void)
2086 if (viafb_lcd_panel_id
> LCD_PANEL_ID_MAXIMUM
)
2087 viaparinfo
->lvds_setting_info
->get_lcd_size_method
=
2088 GET_LCD_SIZE_BY_VGA_BIOS
;
2090 viaparinfo
->lvds_setting_info
->get_lcd_size_method
=
2091 GET_LCD_SIZE_BY_USER_SETTING
;
2093 viafb_lvds_trasmitter_identify();
2094 viafb_init_lcd_size();
2095 viafb_init_lvds_output_interface(&viaparinfo
->chip_info
->lvds_chip_info
,
2096 viaparinfo
->lvds_setting_info
);
2097 if (viaparinfo
->chip_info
->lvds_chip_info2
.lvds_chip_name
) {
2098 viafb_init_lvds_output_interface(&viaparinfo
->chip_info
->
2099 lvds_chip_info2
, viaparinfo
->lvds_setting_info2
);
2101 /*If CX700,two singel LCD, we need to reassign
2102 LCD interface to different LVDS port */
2103 if ((UNICHROME_CX700
== viaparinfo
->chip_info
->gfx_chip_name
)
2104 && (HW_LAYOUT_LCD1_LCD2
== viafb_display_hardware_layout
)) {
2105 if ((INTEGRATED_LVDS
== viaparinfo
->chip_info
->lvds_chip_info
.
2106 lvds_chip_name
) && (INTEGRATED_LVDS
==
2107 viaparinfo
->chip_info
->
2108 lvds_chip_info2
.lvds_chip_name
)) {
2109 viaparinfo
->chip_info
->lvds_chip_info
.output_interface
=
2111 viaparinfo
->chip_info
->lvds_chip_info2
.
2117 DEBUG_MSG(KERN_INFO
"LVDS Chip = %d\n",
2118 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
);
2119 DEBUG_MSG(KERN_INFO
"LVDS1 output_interface = %d\n",
2120 viaparinfo
->chip_info
->lvds_chip_info
.output_interface
);
2121 DEBUG_MSG(KERN_INFO
"LVDS2 output_interface = %d\n",
2122 viaparinfo
->chip_info
->lvds_chip_info
.output_interface
);
2125 void viafb_init_dac(int set_iga
)
2130 if (set_iga
== IGA1
) {
2131 /* access Primary Display's LUT */
2132 viafb_write_reg_mask(SR1A
, VIASR
, 0x00, BIT0
);
2134 viafb_write_reg_mask(SR1B
, VIASR
, 0x00, BIT7
+ BIT6
);
2135 for (i
= 0; i
< 256; i
++) {
2136 write_dac_reg(i
, palLUT_table
[i
].red
,
2137 palLUT_table
[i
].green
,
2138 palLUT_table
[i
].blue
);
2141 viafb_write_reg_mask(SR1B
, VIASR
, 0xC0, BIT7
+ BIT6
);
2143 tmp
= viafb_read_reg(VIACR
, CR6A
);
2144 /* access Secondary Display's LUT */
2145 viafb_write_reg_mask(CR6A
, VIACR
, 0x40, BIT6
);
2146 viafb_write_reg_mask(SR1A
, VIASR
, 0x01, BIT0
);
2147 for (i
= 0; i
< 256; i
++) {
2148 write_dac_reg(i
, palLUT_table
[i
].red
,
2149 palLUT_table
[i
].green
,
2150 palLUT_table
[i
].blue
);
2152 /* set IGA1 DAC for default */
2153 viafb_write_reg_mask(SR1A
, VIASR
, 0x00, BIT0
);
2154 viafb_write_reg(CR6A
, VIACR
, tmp
);
2158 static void device_screen_off(void)
2160 /* turn off CRT screen (IGA1) */
2161 viafb_write_reg_mask(SR01
, VIASR
, 0x20, BIT5
);
2164 static void device_screen_on(void)
2166 /* turn on CRT screen (IGA1) */
2167 viafb_write_reg_mask(SR01
, VIASR
, 0x00, BIT5
);
2170 static void set_display_channel(void)
2172 /*If viafb_LCD2_ON, on cx700, internal lvds's information
2173 is keeped on lvds_setting_info2 */
2174 if (viafb_LCD2_ON
&&
2175 viaparinfo
->lvds_setting_info2
->device_lcd_dualedge
) {
2176 /* For dual channel LCD: */
2177 /* Set to Dual LVDS channel. */
2178 viafb_write_reg_mask(CRD2
, VIACR
, 0x20, BIT4
+ BIT5
);
2179 } else if (viafb_LCD_ON
&& viafb_DVI_ON
) {
2181 /* Set to LVDS1 + TMDS channel. */
2182 viafb_write_reg_mask(CRD2
, VIACR
, 0x10, BIT4
+ BIT5
);
2183 } else if (viafb_DVI_ON
) {
2184 /* Set to single TMDS channel. */
2185 viafb_write_reg_mask(CRD2
, VIACR
, 0x30, BIT4
+ BIT5
);
2186 } else if (viafb_LCD_ON
) {
2187 if (viaparinfo
->lvds_setting_info
->device_lcd_dualedge
) {
2188 /* For dual channel LCD: */
2189 /* Set to Dual LVDS channel. */
2190 viafb_write_reg_mask(CRD2
, VIACR
, 0x20, BIT4
+ BIT5
);
2192 /* Set to LVDS0 + LVDS1 channel. */
2193 viafb_write_reg_mask(CRD2
, VIACR
, 0x00, BIT4
+ BIT5
);
2198 int viafb_setmode(int vmode_index
, int hor_res
, int ver_res
, int video_bpp
,
2199 int vmode_index1
, int hor_res1
, int ver_res1
, int video_bpp1
)
2203 u8 value
, index
, mask
;
2204 struct VideoModeTable
*vmode_tbl
;
2205 struct crt_mode_table
*crt_timing
;
2206 struct VideoModeTable
*vmode_tbl1
= NULL
;
2207 struct crt_mode_table
*crt_timing1
= NULL
;
2209 DEBUG_MSG(KERN_INFO
"Set Mode!!\n");
2211 "vmode_index=%d hor_res=%d ver_res=%d video_bpp=%d\n",
2212 vmode_index
, hor_res
, ver_res
, video_bpp
);
2214 device_screen_off();
2215 vmode_tbl
= &CLE266Modes
[search_mode_setting(vmode_index
)];
2216 crt_timing
= vmode_tbl
->crtc
;
2218 if (viafb_SAMM_ON
== 1) {
2219 vmode_tbl1
= &CLE266Modes
[search_mode_setting(vmode_index1
)];
2220 crt_timing1
= vmode_tbl1
->crtc
;
2226 /* Write Common Setting for Video Mode */
2227 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
2228 case UNICHROME_CLE266
:
2229 viafb_write_regx(CLE266_ModeXregs
, NUM_TOTAL_CLE266_ModeXregs
);
2232 case UNICHROME_K400
:
2233 viafb_write_regx(KM400_ModeXregs
, NUM_TOTAL_KM400_ModeXregs
);
2236 case UNICHROME_K800
:
2237 case UNICHROME_PM800
:
2238 viafb_write_regx(CN400_ModeXregs
, NUM_TOTAL_CN400_ModeXregs
);
2241 case UNICHROME_CN700
:
2242 case UNICHROME_K8M890
:
2243 case UNICHROME_P4M890
:
2244 case UNICHROME_P4M900
:
2245 viafb_write_regx(CN700_ModeXregs
, NUM_TOTAL_CN700_ModeXregs
);
2248 case UNICHROME_CX700
:
2249 case UNICHROME_VX800
:
2250 viafb_write_regx(CX700_ModeXregs
, NUM_TOTAL_CX700_ModeXregs
);
2253 case UNICHROME_VX855
:
2254 viafb_write_regx(VX855_ModeXregs
, NUM_TOTAL_VX855_ModeXregs
);
2260 /* Fill VPIT Parameters */
2261 /* Write Misc Register */
2262 outb(VPIT
.Misc
, VIAWMisc
);
2264 /* Write Sequencer */
2265 for (i
= 1; i
<= StdSR
; i
++) {
2267 outb(VPIT
.SR
[i
- 1], VIASR
+ 1);
2270 viafb_set_primary_address(0);
2271 viafb_set_secondary_address(viafb_SAMM_ON
? viafb_second_offset
: 0);
2272 viafb_set_iga_path();
2275 viafb_fill_crtc_timing(crt_timing
, vmode_index
, video_bpp
/ 8, IGA1
);
2277 /* Write Graphic Controller */
2278 for (i
= 0; i
< StdGR
; i
++) {
2280 outb(VPIT
.GR
[i
], VIAGR
+ 1);
2283 /* Write Attribute Controller */
2284 for (i
= 0; i
< StdAR
; i
++) {
2287 outb(VPIT
.AR
[i
], VIAAR
);
2293 /* Update Patch Register */
2295 if ((viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
)
2296 || (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K400
)) {
2297 for (i
= 0; i
< NUM_TOTAL_PATCH_MODE
; i
++) {
2298 if (res_patch_table
[i
].mode_index
== vmode_index
) {
2300 j
< res_patch_table
[i
].table_length
; j
++) {
2303 io_reg_table
[j
].index
;
2306 io_reg_table
[j
].port
;
2309 io_reg_table
[j
].value
;
2312 io_reg_table
[j
].mask
;
2313 viafb_write_reg_mask(index
, port
, value
,
2320 if (viafb_SAMM_ON
== 1) {
2321 if ((viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
)
2322 || (viaparinfo
->chip_info
->gfx_chip_name
==
2324 for (i
= 0; i
< NUM_TOTAL_PATCH_MODE
; i
++) {
2325 if (res_patch_table
[i
].mode_index
==
2330 table_length
; j
++) {
2333 io_reg_table
[j
].index
;
2336 io_reg_table
[j
].port
;
2339 io_reg_table
[j
].value
;
2342 io_reg_table
[j
].mask
;
2343 viafb_write_reg_mask(index
,
2351 viafb_set_primary_pitch(viafbinfo
->fix
.line_length
);
2352 viafb_set_secondary_pitch(viafb_dual_fb
? viafbinfo1
->fix
.line_length
2353 : viafbinfo
->fix
.line_length
);
2354 /* Update Refresh Rate Setting */
2356 /* Clear On Screen */
2360 if (viafb_SAMM_ON
&& (viaparinfo
->crt_setting_info
->iga_path
==
2362 viafb_fill_crtc_timing(crt_timing1
, vmode_index1
,
2364 viaparinfo
->crt_setting_info
->iga_path
);
2366 viafb_fill_crtc_timing(crt_timing
, vmode_index
,
2368 viaparinfo
->crt_setting_info
->iga_path
);
2371 set_crt_output_path(viaparinfo
->crt_setting_info
->iga_path
);
2373 /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
2374 to 8 alignment (1368),there is several pixels (2 pixels)
2375 on right side of screen. */
2378 viafb_write_reg(CR02
, VIACR
,
2379 viafb_read_reg(VIACR
, CR02
) - 1);
2385 if (viafb_SAMM_ON
&&
2386 (viaparinfo
->tmds_setting_info
->iga_path
== IGA2
)) {
2387 viafb_dvi_set_mode(viafb_get_mode_index
2388 (viaparinfo
->tmds_setting_info
->h_active
,
2389 viaparinfo
->tmds_setting_info
->
2391 video_bpp1
, viaparinfo
->
2392 tmds_setting_info
->iga_path
);
2394 viafb_dvi_set_mode(viafb_get_mode_index
2395 (viaparinfo
->tmds_setting_info
->h_active
,
2397 tmds_setting_info
->v_active
),
2398 video_bpp
, viaparinfo
->
2399 tmds_setting_info
->iga_path
);
2404 if (viafb_SAMM_ON
&&
2405 (viaparinfo
->lvds_setting_info
->iga_path
== IGA2
)) {
2406 viaparinfo
->lvds_setting_info
->bpp
= video_bpp1
;
2407 viafb_lcd_set_mode(crt_timing1
, viaparinfo
->
2409 &viaparinfo
->chip_info
->lvds_chip_info
);
2411 /* IGA1 doesn't have LCD scaling, so set it center. */
2412 if (viaparinfo
->lvds_setting_info
->iga_path
== IGA1
) {
2413 viaparinfo
->lvds_setting_info
->display_method
=
2416 viaparinfo
->lvds_setting_info
->bpp
= video_bpp
;
2417 viafb_lcd_set_mode(crt_timing
, viaparinfo
->
2419 &viaparinfo
->chip_info
->lvds_chip_info
);
2422 if (viafb_LCD2_ON
) {
2423 if (viafb_SAMM_ON
&&
2424 (viaparinfo
->lvds_setting_info2
->iga_path
== IGA2
)) {
2425 viaparinfo
->lvds_setting_info2
->bpp
= video_bpp1
;
2426 viafb_lcd_set_mode(crt_timing1
, viaparinfo
->
2428 &viaparinfo
->chip_info
->lvds_chip_info2
);
2430 /* IGA1 doesn't have LCD scaling, so set it center. */
2431 if (viaparinfo
->lvds_setting_info2
->iga_path
== IGA1
) {
2432 viaparinfo
->lvds_setting_info2
->display_method
=
2435 viaparinfo
->lvds_setting_info2
->bpp
= video_bpp
;
2436 viafb_lcd_set_mode(crt_timing
, viaparinfo
->
2438 &viaparinfo
->chip_info
->lvds_chip_info2
);
2442 if ((viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
)
2443 && (viafb_LCD_ON
|| viafb_DVI_ON
))
2444 set_display_channel();
2446 /* If set mode normally, save resolution information for hot-plug . */
2447 if (!viafb_hotplug
) {
2448 viafb_hotplug_Xres
= hor_res
;
2449 viafb_hotplug_Yres
= ver_res
;
2450 viafb_hotplug_bpp
= video_bpp
;
2451 viafb_hotplug_refresh
= viafb_refresh
;
2454 viafb_DeviceStatus
= DVI_Device
;
2456 viafb_DeviceStatus
= CRT_Device
;
2460 if (viafb_SAMM_ON
== 1)
2461 viafb_write_reg_mask(CR6A
, VIACR
, 0xC0, BIT6
+ BIT7
);
2467 int viafb_get_pixclock(int hres
, int vres
, int vmode_refresh
)
2471 for (i
= 0; i
< NUM_TOTAL_RES_MAP_REFRESH
; i
++) {
2472 if ((hres
== res_map_refresh_tbl
[i
].hres
)
2473 && (vres
== res_map_refresh_tbl
[i
].vres
)
2474 && (vmode_refresh
== res_map_refresh_tbl
[i
].vmode_refresh
))
2475 return res_map_refresh_tbl
[i
].pixclock
;
2477 return RES_640X480_60HZ_PIXCLOCK
;
2481 int viafb_get_refresh(int hres
, int vres
, u32 long_refresh
)
2483 #define REFRESH_TOLERANCE 3
2484 int i
, nearest
= -1, diff
= REFRESH_TOLERANCE
;
2485 for (i
= 0; i
< NUM_TOTAL_RES_MAP_REFRESH
; i
++) {
2486 if ((hres
== res_map_refresh_tbl
[i
].hres
)
2487 && (vres
== res_map_refresh_tbl
[i
].vres
)
2488 && (diff
> (abs(long_refresh
-
2489 res_map_refresh_tbl
[i
].vmode_refresh
)))) {
2490 diff
= abs(long_refresh
- res_map_refresh_tbl
[i
].
2495 #undef REFRESH_TOLERANCE
2497 return res_map_refresh_tbl
[nearest
].vmode_refresh
;
2501 static void device_off(void)
2503 viafb_crt_disable();
2504 viafb_dvi_disable();
2505 viafb_lcd_disable();
2508 static void device_on(void)
2510 if (viafb_CRT_ON
== 1)
2512 if (viafb_DVI_ON
== 1)
2514 if (viafb_LCD_ON
== 1)
2518 void viafb_crt_disable(void)
2520 viafb_write_reg_mask(CR36
, VIACR
, BIT5
+ BIT4
, BIT5
+ BIT4
);
2523 void viafb_crt_enable(void)
2525 viafb_write_reg_mask(CR36
, VIACR
, 0x0, BIT5
+ BIT4
);
2528 static void enable_second_display_channel(void)
2530 /* to enable second display channel. */
2531 viafb_write_reg_mask(CR6A
, VIACR
, 0x00, BIT6
);
2532 viafb_write_reg_mask(CR6A
, VIACR
, BIT7
, BIT7
);
2533 viafb_write_reg_mask(CR6A
, VIACR
, BIT6
, BIT6
);
2536 static void disable_second_display_channel(void)
2538 /* to disable second display channel. */
2539 viafb_write_reg_mask(CR6A
, VIACR
, 0x00, BIT6
);
2540 viafb_write_reg_mask(CR6A
, VIACR
, 0x00, BIT7
);
2541 viafb_write_reg_mask(CR6A
, VIACR
, BIT6
, BIT6
);
2544 int viafb_get_fb_size_from_pci(void)
2546 unsigned long configid
, deviceid
, FBSize
= 0;
2548 int DeviceFound
= false;
2550 for (configid
= 0x80000000; configid
< 0x80010800; configid
+= 0x100) {
2551 outl(configid
, (unsigned long)0xCF8);
2552 deviceid
= (inl((unsigned long)0xCFC) >> 16) & 0xffff;
2557 outl(configid
+ 0xE0, (unsigned long)0xCF8);
2558 FBSize
= inl((unsigned long)0xCFC);
2559 DeviceFound
= true; /* Found device id */
2562 case CN400_FUNCTION3
:
2563 case CN700_FUNCTION3
:
2564 case CX700_FUNCTION3
:
2565 case KM800_FUNCTION3
:
2566 case KM890_FUNCTION3
:
2567 case P4M890_FUNCTION3
:
2568 case P4M900_FUNCTION3
:
2569 case VX800_FUNCTION3
:
2570 case VX855_FUNCTION3
:
2571 /*case CN750_FUNCTION3: */
2572 outl(configid
+ 0xA0, (unsigned long)0xCF8);
2573 FBSize
= inl((unsigned long)0xCFC);
2574 DeviceFound
= true; /* Found device id */
2585 DEBUG_MSG(KERN_INFO
"Device ID = %lx\n", deviceid
);
2587 FBSize
= FBSize
& 0x00007000;
2588 DEBUG_MSG(KERN_INFO
"FB Size = %x\n", FBSize
);
2590 if (viaparinfo
->chip_info
->gfx_chip_name
< UNICHROME_CX700
) {
2593 VideoMemSize
= (16 << 20); /*16M */
2597 VideoMemSize
= (32 << 20); /*32M */
2601 VideoMemSize
= (64 << 20); /*64M */
2605 VideoMemSize
= (32 << 20); /*32M */
2611 VideoMemSize
= (8 << 20); /*8M */
2615 VideoMemSize
= (16 << 20); /*16M */
2619 VideoMemSize
= (32 << 20); /*32M */
2623 VideoMemSize
= (64 << 20); /*64M */
2627 VideoMemSize
= (128 << 20); /*128M */
2631 VideoMemSize
= (256 << 20); /*256M */
2634 case 0x00007000: /* Only on VX855/875 */
2635 VideoMemSize
= (512 << 20); /*512M */
2639 VideoMemSize
= (32 << 20); /*32M */
2644 return VideoMemSize
;
2647 void viafb_set_dpa_gfx(int output_interface
, struct GFX_DPA_SETTING\
2650 switch (output_interface
) {
2651 case INTERFACE_DVP0
:
2653 /* DVP0 Clock Polarity and Adjust: */
2654 viafb_write_reg_mask(CR96
, VIACR
,
2655 p_gfx_dpa_setting
->DVP0
, 0x0F);
2657 /* DVP0 Clock and Data Pads Driving: */
2658 viafb_write_reg_mask(SR1E
, VIASR
,
2659 p_gfx_dpa_setting
->DVP0ClockDri_S
, BIT2
);
2660 viafb_write_reg_mask(SR2A
, VIASR
,
2661 p_gfx_dpa_setting
->DVP0ClockDri_S1
,
2663 viafb_write_reg_mask(SR1B
, VIASR
,
2664 p_gfx_dpa_setting
->DVP0DataDri_S
, BIT1
);
2665 viafb_write_reg_mask(SR2A
, VIASR
,
2666 p_gfx_dpa_setting
->DVP0DataDri_S1
, BIT5
);
2670 case INTERFACE_DVP1
:
2672 /* DVP1 Clock Polarity and Adjust: */
2673 viafb_write_reg_mask(CR9B
, VIACR
,
2674 p_gfx_dpa_setting
->DVP1
, 0x0F);
2676 /* DVP1 Clock and Data Pads Driving: */
2677 viafb_write_reg_mask(SR65
, VIASR
,
2678 p_gfx_dpa_setting
->DVP1Driving
, 0x0F);
2682 case INTERFACE_DFP_HIGH
:
2684 viafb_write_reg_mask(CR97
, VIACR
,
2685 p_gfx_dpa_setting
->DFPHigh
, 0x0F);
2689 case INTERFACE_DFP_LOW
:
2691 viafb_write_reg_mask(CR99
, VIACR
,
2692 p_gfx_dpa_setting
->DFPLow
, 0x0F);
2698 viafb_write_reg_mask(CR97
, VIACR
,
2699 p_gfx_dpa_setting
->DFPHigh
, 0x0F);
2700 viafb_write_reg_mask(CR99
, VIACR
,
2701 p_gfx_dpa_setting
->DFPLow
, 0x0F);
2707 /*According var's xres, yres fill var's other timing information*/
2708 void viafb_fill_var_timing_info(struct fb_var_screeninfo
*var
, int refresh
,
2711 struct VideoModeTable
*vmode_tbl
= NULL
;
2712 struct crt_mode_table
*crt_timing
= NULL
;
2713 struct display_timing crt_reg
;
2714 int i
= 0, index
= 0;
2715 vmode_tbl
= &CLE266Modes
[search_mode_setting(mode_index
)];
2716 crt_timing
= vmode_tbl
->crtc
;
2717 for (i
= 0; i
< vmode_tbl
->mode_array
; i
++) {
2719 if (crt_timing
[i
].refresh_rate
== refresh
)
2723 crt_reg
= crt_timing
[index
].crtc
;
2724 switch (var
->bits_per_pixel
) {
2726 var
->red
.offset
= 0;
2727 var
->green
.offset
= 0;
2728 var
->blue
.offset
= 0;
2729 var
->red
.length
= 6;
2730 var
->green
.length
= 6;
2731 var
->blue
.length
= 6;
2734 var
->red
.offset
= 11;
2735 var
->green
.offset
= 5;
2736 var
->blue
.offset
= 0;
2737 var
->red
.length
= 5;
2738 var
->green
.length
= 6;
2739 var
->blue
.length
= 5;
2742 var
->red
.offset
= 16;
2743 var
->green
.offset
= 8;
2744 var
->blue
.offset
= 0;
2745 var
->red
.length
= 8;
2746 var
->green
.length
= 8;
2747 var
->blue
.length
= 8;
2750 /* never happed, put here to keep consistent */
2754 var
->pixclock
= viafb_get_pixclock(var
->xres
, var
->yres
, refresh
);
2756 crt_reg
.hor_total
- (crt_reg
.hor_sync_start
+ crt_reg
.hor_sync_end
);
2757 var
->right_margin
= crt_reg
.hor_sync_start
- crt_reg
.hor_addr
;
2758 var
->hsync_len
= crt_reg
.hor_sync_end
;
2760 crt_reg
.ver_total
- (crt_reg
.ver_sync_start
+ crt_reg
.ver_sync_end
);
2761 var
->lower_margin
= crt_reg
.ver_sync_start
- crt_reg
.ver_addr
;
2762 var
->vsync_len
= crt_reg
.ver_sync_end
;