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 const struct pci_device_id_info pciidlist
[] = {
25 {PCI_VIA_VENDOR_ID
, UNICHROME_CLE266_DID
, UNICHROME_CLE266
},
26 {PCI_VIA_VENDOR_ID
, UNICHROME_PM800_DID
, UNICHROME_PM800
},
27 {PCI_VIA_VENDOR_ID
, UNICHROME_K400_DID
, UNICHROME_K400
},
28 {PCI_VIA_VENDOR_ID
, UNICHROME_K800_DID
, UNICHROME_K800
},
29 {PCI_VIA_VENDOR_ID
, UNICHROME_CN700_DID
, UNICHROME_CN700
},
30 {PCI_VIA_VENDOR_ID
, UNICHROME_P4M890_DID
, UNICHROME_P4M890
},
31 {PCI_VIA_VENDOR_ID
, UNICHROME_K8M890_DID
, UNICHROME_K8M890
},
32 {PCI_VIA_VENDOR_ID
, UNICHROME_CX700_DID
, UNICHROME_CX700
},
33 {PCI_VIA_VENDOR_ID
, UNICHROME_P4M900_DID
, UNICHROME_P4M900
},
34 {PCI_VIA_VENDOR_ID
, UNICHROME_CN750_DID
, UNICHROME_CN750
},
35 {PCI_VIA_VENDOR_ID
, UNICHROME_VX800_DID
, UNICHROME_VX800
},
36 {PCI_VIA_VENDOR_ID
, UNICHROME_VX855_DID
, UNICHROME_VX855
},
40 static struct pll_map pll_value
[] = {
41 {CLK_25_175M
, CLE266_PLL_25_175M
, K800_PLL_25_175M
,
42 CX700_25_175M
, VX855_25_175M
},
43 {CLK_29_581M
, CLE266_PLL_29_581M
, K800_PLL_29_581M
,
44 CX700_29_581M
, VX855_29_581M
},
45 {CLK_26_880M
, CLE266_PLL_26_880M
, K800_PLL_26_880M
,
46 CX700_26_880M
, VX855_26_880M
},
47 {CLK_31_490M
, CLE266_PLL_31_490M
, K800_PLL_31_490M
,
48 CX700_31_490M
, VX855_31_490M
},
49 {CLK_31_500M
, CLE266_PLL_31_500M
, K800_PLL_31_500M
,
50 CX700_31_500M
, VX855_31_500M
},
51 {CLK_31_728M
, CLE266_PLL_31_728M
, K800_PLL_31_728M
,
52 CX700_31_728M
, VX855_31_728M
},
53 {CLK_32_668M
, CLE266_PLL_32_668M
, K800_PLL_32_668M
,
54 CX700_32_668M
, VX855_32_668M
},
55 {CLK_36_000M
, CLE266_PLL_36_000M
, K800_PLL_36_000M
,
56 CX700_36_000M
, VX855_36_000M
},
57 {CLK_40_000M
, CLE266_PLL_40_000M
, K800_PLL_40_000M
,
58 CX700_40_000M
, VX855_40_000M
},
59 {CLK_41_291M
, CLE266_PLL_41_291M
, K800_PLL_41_291M
,
60 CX700_41_291M
, VX855_41_291M
},
61 {CLK_43_163M
, CLE266_PLL_43_163M
, K800_PLL_43_163M
,
62 CX700_43_163M
, VX855_43_163M
},
63 {CLK_45_250M
, CLE266_PLL_45_250M
, K800_PLL_45_250M
,
64 CX700_45_250M
, VX855_45_250M
},
65 {CLK_46_000M
, CLE266_PLL_46_000M
, K800_PLL_46_000M
,
66 CX700_46_000M
, VX855_46_000M
},
67 {CLK_46_996M
, CLE266_PLL_46_996M
, K800_PLL_46_996M
,
68 CX700_46_996M
, VX855_46_996M
},
69 {CLK_48_000M
, CLE266_PLL_48_000M
, K800_PLL_48_000M
,
70 CX700_48_000M
, VX855_48_000M
},
71 {CLK_48_875M
, CLE266_PLL_48_875M
, K800_PLL_48_875M
,
72 CX700_48_875M
, VX855_48_875M
},
73 {CLK_49_500M
, CLE266_PLL_49_500M
, K800_PLL_49_500M
,
74 CX700_49_500M
, VX855_49_500M
},
75 {CLK_52_406M
, CLE266_PLL_52_406M
, K800_PLL_52_406M
,
76 CX700_52_406M
, VX855_52_406M
},
77 {CLK_52_977M
, CLE266_PLL_52_977M
, K800_PLL_52_977M
,
78 CX700_52_977M
, VX855_52_977M
},
79 {CLK_56_250M
, CLE266_PLL_56_250M
, K800_PLL_56_250M
,
80 CX700_56_250M
, VX855_56_250M
},
81 {CLK_60_466M
, CLE266_PLL_60_466M
, K800_PLL_60_466M
,
82 CX700_60_466M
, VX855_60_466M
},
83 {CLK_61_500M
, CLE266_PLL_61_500M
, K800_PLL_61_500M
,
84 CX700_61_500M
, VX855_61_500M
},
85 {CLK_65_000M
, CLE266_PLL_65_000M
, K800_PLL_65_000M
,
86 CX700_65_000M
, VX855_65_000M
},
87 {CLK_65_178M
, CLE266_PLL_65_178M
, K800_PLL_65_178M
,
88 CX700_65_178M
, VX855_65_178M
},
89 {CLK_66_750M
, CLE266_PLL_66_750M
, K800_PLL_66_750M
,
90 CX700_66_750M
, VX855_66_750M
},
91 {CLK_68_179M
, CLE266_PLL_68_179M
, K800_PLL_68_179M
,
92 CX700_68_179M
, VX855_68_179M
},
93 {CLK_69_924M
, CLE266_PLL_69_924M
, K800_PLL_69_924M
,
94 CX700_69_924M
, VX855_69_924M
},
95 {CLK_70_159M
, CLE266_PLL_70_159M
, K800_PLL_70_159M
,
96 CX700_70_159M
, VX855_70_159M
},
97 {CLK_72_000M
, CLE266_PLL_72_000M
, K800_PLL_72_000M
,
98 CX700_72_000M
, VX855_72_000M
},
99 {CLK_78_750M
, CLE266_PLL_78_750M
, K800_PLL_78_750M
,
100 CX700_78_750M
, VX855_78_750M
},
101 {CLK_80_136M
, CLE266_PLL_80_136M
, K800_PLL_80_136M
,
102 CX700_80_136M
, VX855_80_136M
},
103 {CLK_83_375M
, CLE266_PLL_83_375M
, K800_PLL_83_375M
,
104 CX700_83_375M
, VX855_83_375M
},
105 {CLK_83_950M
, CLE266_PLL_83_950M
, K800_PLL_83_950M
,
106 CX700_83_950M
, VX855_83_950M
},
107 {CLK_84_750M
, CLE266_PLL_84_750M
, K800_PLL_84_750M
,
108 CX700_84_750M
, VX855_84_750M
},
109 {CLK_85_860M
, CLE266_PLL_85_860M
, K800_PLL_85_860M
,
110 CX700_85_860M
, VX855_85_860M
},
111 {CLK_88_750M
, CLE266_PLL_88_750M
, K800_PLL_88_750M
,
112 CX700_88_750M
, VX855_88_750M
},
113 {CLK_94_500M
, CLE266_PLL_94_500M
, K800_PLL_94_500M
,
114 CX700_94_500M
, VX855_94_500M
},
115 {CLK_97_750M
, CLE266_PLL_97_750M
, K800_PLL_97_750M
,
116 CX700_97_750M
, VX855_97_750M
},
117 {CLK_101_000M
, CLE266_PLL_101_000M
, K800_PLL_101_000M
,
118 CX700_101_000M
, VX855_101_000M
},
119 {CLK_106_500M
, CLE266_PLL_106_500M
, K800_PLL_106_500M
,
120 CX700_106_500M
, VX855_106_500M
},
121 {CLK_108_000M
, CLE266_PLL_108_000M
, K800_PLL_108_000M
,
122 CX700_108_000M
, VX855_108_000M
},
123 {CLK_113_309M
, CLE266_PLL_113_309M
, K800_PLL_113_309M
,
124 CX700_113_309M
, VX855_113_309M
},
125 {CLK_118_840M
, CLE266_PLL_118_840M
, K800_PLL_118_840M
,
126 CX700_118_840M
, VX855_118_840M
},
127 {CLK_119_000M
, CLE266_PLL_119_000M
, K800_PLL_119_000M
,
128 CX700_119_000M
, VX855_119_000M
},
129 {CLK_121_750M
, CLE266_PLL_121_750M
, K800_PLL_121_750M
,
131 {CLK_125_104M
, CLE266_PLL_125_104M
, K800_PLL_125_104M
,
133 {CLK_133_308M
, CLE266_PLL_133_308M
, K800_PLL_133_308M
,
135 {CLK_135_000M
, CLE266_PLL_135_000M
, K800_PLL_135_000M
,
136 CX700_135_000M
, VX855_135_000M
},
137 {CLK_136_700M
, CLE266_PLL_136_700M
, K800_PLL_136_700M
,
138 CX700_136_700M
, VX855_136_700M
},
139 {CLK_138_400M
, CLE266_PLL_138_400M
, K800_PLL_138_400M
,
140 CX700_138_400M
, VX855_138_400M
},
141 {CLK_146_760M
, CLE266_PLL_146_760M
, K800_PLL_146_760M
,
142 CX700_146_760M
, VX855_146_760M
},
143 {CLK_153_920M
, CLE266_PLL_153_920M
, K800_PLL_153_920M
,
144 CX700_153_920M
, VX855_153_920M
},
145 {CLK_156_000M
, CLE266_PLL_156_000M
, K800_PLL_156_000M
,
146 CX700_156_000M
, VX855_156_000M
},
147 {CLK_157_500M
, CLE266_PLL_157_500M
, K800_PLL_157_500M
,
148 CX700_157_500M
, VX855_157_500M
},
149 {CLK_162_000M
, CLE266_PLL_162_000M
, K800_PLL_162_000M
,
150 CX700_162_000M
, VX855_162_000M
},
151 {CLK_187_000M
, CLE266_PLL_187_000M
, K800_PLL_187_000M
,
152 CX700_187_000M
, VX855_187_000M
},
153 {CLK_193_295M
, CLE266_PLL_193_295M
, K800_PLL_193_295M
,
154 CX700_193_295M
, VX855_193_295M
},
155 {CLK_202_500M
, CLE266_PLL_202_500M
, K800_PLL_202_500M
,
156 CX700_202_500M
, VX855_202_500M
},
157 {CLK_204_000M
, CLE266_PLL_204_000M
, K800_PLL_204_000M
,
158 CX700_204_000M
, VX855_204_000M
},
159 {CLK_218_500M
, CLE266_PLL_218_500M
, K800_PLL_218_500M
,
160 CX700_218_500M
, VX855_218_500M
},
161 {CLK_234_000M
, CLE266_PLL_234_000M
, K800_PLL_234_000M
,
162 CX700_234_000M
, VX855_234_000M
},
163 {CLK_267_250M
, CLE266_PLL_267_250M
, K800_PLL_267_250M
,
164 CX700_267_250M
, VX855_267_250M
},
165 {CLK_297_500M
, CLE266_PLL_297_500M
, K800_PLL_297_500M
,
166 CX700_297_500M
, VX855_297_500M
},
167 {CLK_74_481M
, CLE266_PLL_74_481M
, K800_PLL_74_481M
,
168 CX700_74_481M
, VX855_74_481M
},
169 {CLK_172_798M
, CLE266_PLL_172_798M
, K800_PLL_172_798M
,
170 CX700_172_798M
, VX855_172_798M
},
171 {CLK_122_614M
, CLE266_PLL_122_614M
, K800_PLL_122_614M
,
172 CX700_122_614M
, VX855_122_614M
},
173 {CLK_74_270M
, CLE266_PLL_74_270M
, K800_PLL_74_270M
,
175 {CLK_148_500M
, CLE266_PLL_148_500M
, K800_PLL_148_500M
,
176 CX700_148_500M
, VX855_148_500M
}
179 static struct fifo_depth_select display_fifo_depth_reg
= {
180 /* IGA1 FIFO Depth_Select */
181 {IGA1_FIFO_DEPTH_SELECT_REG_NUM
, {{SR17
, 0, 7} } },
182 /* IGA2 FIFO Depth_Select */
183 {IGA2_FIFO_DEPTH_SELECT_REG_NUM
,
184 {{CR68
, 4, 7}, {CR94
, 7, 7}, {CR95
, 7, 7} } }
187 static struct fifo_threshold_select fifo_threshold_select_reg
= {
188 /* IGA1 FIFO Threshold Select */
189 {IGA1_FIFO_THRESHOLD_REG_NUM
, {{SR16
, 0, 5}, {SR16
, 7, 7} } },
190 /* IGA2 FIFO Threshold Select */
191 {IGA2_FIFO_THRESHOLD_REG_NUM
, {{CR68
, 0, 3}, {CR95
, 4, 6} } }
194 static struct fifo_high_threshold_select fifo_high_threshold_select_reg
= {
195 /* IGA1 FIFO High Threshold Select */
196 {IGA1_FIFO_HIGH_THRESHOLD_REG_NUM
, {{SR18
, 0, 5}, {SR18
, 7, 7} } },
197 /* IGA2 FIFO High Threshold Select */
198 {IGA2_FIFO_HIGH_THRESHOLD_REG_NUM
, {{CR92
, 0, 3}, {CR95
, 0, 2} } }
201 static struct display_queue_expire_num display_queue_expire_num_reg
= {
202 /* IGA1 Display Queue Expire Num */
203 {IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM
, {{SR22
, 0, 4} } },
204 /* IGA2 Display Queue Expire Num */
205 {IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM
, {{CR94
, 0, 6} } }
208 /* Definition Fetch Count Registers*/
209 static struct fetch_count fetch_count_reg
= {
210 /* IGA1 Fetch Count Register */
211 {IGA1_FETCH_COUNT_REG_NUM
, {{SR1C
, 0, 7}, {SR1D
, 0, 1} } },
212 /* IGA2 Fetch Count Register */
213 {IGA2_FETCH_COUNT_REG_NUM
, {{CR65
, 0, 7}, {CR67
, 2, 3} } }
216 static struct iga1_crtc_timing iga1_crtc_reg
= {
217 /* IGA1 Horizontal Total */
218 {IGA1_HOR_TOTAL_REG_NUM
, {{CR00
, 0, 7}, {CR36
, 3, 3} } },
219 /* IGA1 Horizontal Addressable Video */
220 {IGA1_HOR_ADDR_REG_NUM
, {{CR01
, 0, 7} } },
221 /* IGA1 Horizontal Blank Start */
222 {IGA1_HOR_BLANK_START_REG_NUM
, {{CR02
, 0, 7} } },
223 /* IGA1 Horizontal Blank End */
224 {IGA1_HOR_BLANK_END_REG_NUM
,
225 {{CR03
, 0, 4}, {CR05
, 7, 7}, {CR33
, 5, 5} } },
226 /* IGA1 Horizontal Sync Start */
227 {IGA1_HOR_SYNC_START_REG_NUM
, {{CR04
, 0, 7}, {CR33
, 4, 4} } },
228 /* IGA1 Horizontal Sync End */
229 {IGA1_HOR_SYNC_END_REG_NUM
, {{CR05
, 0, 4} } },
230 /* IGA1 Vertical Total */
231 {IGA1_VER_TOTAL_REG_NUM
,
232 {{CR06
, 0, 7}, {CR07
, 0, 0}, {CR07
, 5, 5}, {CR35
, 0, 0} } },
233 /* IGA1 Vertical Addressable Video */
234 {IGA1_VER_ADDR_REG_NUM
,
235 {{CR12
, 0, 7}, {CR07
, 1, 1}, {CR07
, 6, 6}, {CR35
, 2, 2} } },
236 /* IGA1 Vertical Blank Start */
237 {IGA1_VER_BLANK_START_REG_NUM
,
238 {{CR15
, 0, 7}, {CR07
, 3, 3}, {CR09
, 5, 5}, {CR35
, 3, 3} } },
239 /* IGA1 Vertical Blank End */
240 {IGA1_VER_BLANK_END_REG_NUM
, {{CR16
, 0, 7} } },
241 /* IGA1 Vertical Sync Start */
242 {IGA1_VER_SYNC_START_REG_NUM
,
243 {{CR10
, 0, 7}, {CR07
, 2, 2}, {CR07
, 7, 7}, {CR35
, 1, 1} } },
244 /* IGA1 Vertical Sync End */
245 {IGA1_VER_SYNC_END_REG_NUM
, {{CR11
, 0, 3} } }
248 static struct iga2_crtc_timing iga2_crtc_reg
= {
249 /* IGA2 Horizontal Total */
250 {IGA2_HOR_TOTAL_REG_NUM
, {{CR50
, 0, 7}, {CR55
, 0, 3} } },
251 /* IGA2 Horizontal Addressable Video */
252 {IGA2_HOR_ADDR_REG_NUM
, {{CR51
, 0, 7}, {CR55
, 4, 6} } },
253 /* IGA2 Horizontal Blank Start */
254 {IGA2_HOR_BLANK_START_REG_NUM
, {{CR52
, 0, 7}, {CR54
, 0, 2} } },
255 /* IGA2 Horizontal Blank End */
256 {IGA2_HOR_BLANK_END_REG_NUM
,
257 {{CR53
, 0, 7}, {CR54
, 3, 5}, {CR5D
, 6, 6} } },
258 /* IGA2 Horizontal Sync Start */
259 {IGA2_HOR_SYNC_START_REG_NUM
,
260 {{CR56
, 0, 7}, {CR54
, 6, 7}, {CR5C
, 7, 7}, {CR5D
, 7, 7} } },
261 /* IGA2 Horizontal Sync End */
262 {IGA2_HOR_SYNC_END_REG_NUM
, {{CR57
, 0, 7}, {CR5C
, 6, 6} } },
263 /* IGA2 Vertical Total */
264 {IGA2_VER_TOTAL_REG_NUM
, {{CR58
, 0, 7}, {CR5D
, 0, 2} } },
265 /* IGA2 Vertical Addressable Video */
266 {IGA2_VER_ADDR_REG_NUM
, {{CR59
, 0, 7}, {CR5D
, 3, 5} } },
267 /* IGA2 Vertical Blank Start */
268 {IGA2_VER_BLANK_START_REG_NUM
, {{CR5A
, 0, 7}, {CR5C
, 0, 2} } },
269 /* IGA2 Vertical Blank End */
270 {IGA2_VER_BLANK_END_REG_NUM
, {{CR5B
, 0, 7}, {CR5C
, 3, 5} } },
271 /* IGA2 Vertical Sync Start */
272 {IGA2_VER_SYNC_START_REG_NUM
, {{CR5E
, 0, 7}, {CR5F
, 5, 7} } },
273 /* IGA2 Vertical Sync End */
274 {IGA2_VER_SYNC_END_REG_NUM
, {{CR5F
, 0, 4} } }
277 static struct rgbLUT palLUT_table
[] = {
279 /* Index 0x00~0x03 */
280 {0x00, 0x00, 0x00}, {0x00, 0x00, 0x2A}, {0x00, 0x2A, 0x00}, {0x00,
283 /* Index 0x04~0x07 */
284 {0x2A, 0x00, 0x00}, {0x2A, 0x00, 0x2A}, {0x2A, 0x15, 0x00}, {0x2A,
287 /* Index 0x08~0x0B */
288 {0x15, 0x15, 0x15}, {0x15, 0x15, 0x3F}, {0x15, 0x3F, 0x15}, {0x15,
291 /* Index 0x0C~0x0F */
292 {0x3F, 0x15, 0x15}, {0x3F, 0x15, 0x3F}, {0x3F, 0x3F, 0x15}, {0x3F,
295 /* Index 0x10~0x13 */
296 {0x00, 0x00, 0x00}, {0x05, 0x05, 0x05}, {0x08, 0x08, 0x08}, {0x0B,
299 /* Index 0x14~0x17 */
300 {0x0E, 0x0E, 0x0E}, {0x11, 0x11, 0x11}, {0x14, 0x14, 0x14}, {0x18,
303 /* Index 0x18~0x1B */
304 {0x1C, 0x1C, 0x1C}, {0x20, 0x20, 0x20}, {0x24, 0x24, 0x24}, {0x28,
307 /* Index 0x1C~0x1F */
308 {0x2D, 0x2D, 0x2D}, {0x32, 0x32, 0x32}, {0x38, 0x38, 0x38}, {0x3F,
311 /* Index 0x20~0x23 */
312 {0x00, 0x00, 0x3F}, {0x10, 0x00, 0x3F}, {0x1F, 0x00, 0x3F}, {0x2F,
315 /* Index 0x24~0x27 */
316 {0x3F, 0x00, 0x3F}, {0x3F, 0x00, 0x2F}, {0x3F, 0x00, 0x1F}, {0x3F,
319 /* Index 0x28~0x2B */
320 {0x3F, 0x00, 0x00}, {0x3F, 0x10, 0x00}, {0x3F, 0x1F, 0x00}, {0x3F,
323 /* Index 0x2C~0x2F */
324 {0x3F, 0x3F, 0x00}, {0x2F, 0x3F, 0x00}, {0x1F, 0x3F, 0x00}, {0x10,
327 /* Index 0x30~0x33 */
328 {0x00, 0x3F, 0x00}, {0x00, 0x3F, 0x10}, {0x00, 0x3F, 0x1F}, {0x00,
331 /* Index 0x34~0x37 */
332 {0x00, 0x3F, 0x3F}, {0x00, 0x2F, 0x3F}, {0x00, 0x1F, 0x3F}, {0x00,
335 /* Index 0x38~0x3B */
336 {0x1F, 0x1F, 0x3F}, {0x27, 0x1F, 0x3F}, {0x2F, 0x1F, 0x3F}, {0x37,
339 /* Index 0x3C~0x3F */
340 {0x3F, 0x1F, 0x3F}, {0x3F, 0x1F, 0x37}, {0x3F, 0x1F, 0x2F}, {0x3F,
343 /* Index 0x40~0x43 */
344 {0x3F, 0x1F, 0x1F}, {0x3F, 0x27, 0x1F}, {0x3F, 0x2F, 0x1F}, {0x3F,
347 /* Index 0x44~0x47 */
348 {0x3F, 0x3F, 0x1F}, {0x37, 0x3F, 0x1F}, {0x2F, 0x3F, 0x1F}, {0x27,
351 /* Index 0x48~0x4B */
352 {0x1F, 0x3F, 0x1F}, {0x1F, 0x3F, 0x27}, {0x1F, 0x3F, 0x2F}, {0x1F,
355 /* Index 0x4C~0x4F */
356 {0x1F, 0x3F, 0x3F}, {0x1F, 0x37, 0x3F}, {0x1F, 0x2F, 0x3F}, {0x1F,
359 /* Index 0x50~0x53 */
360 {0x2D, 0x2D, 0x3F}, {0x31, 0x2D, 0x3F}, {0x36, 0x2D, 0x3F}, {0x3A,
363 /* Index 0x54~0x57 */
364 {0x3F, 0x2D, 0x3F}, {0x3F, 0x2D, 0x3A}, {0x3F, 0x2D, 0x36}, {0x3F,
367 /* Index 0x58~0x5B */
368 {0x3F, 0x2D, 0x2D}, {0x3F, 0x31, 0x2D}, {0x3F, 0x36, 0x2D}, {0x3F,
371 /* Index 0x5C~0x5F */
372 {0x3F, 0x3F, 0x2D}, {0x3A, 0x3F, 0x2D}, {0x36, 0x3F, 0x2D}, {0x31,
375 /* Index 0x60~0x63 */
376 {0x2D, 0x3F, 0x2D}, {0x2D, 0x3F, 0x31}, {0x2D, 0x3F, 0x36}, {0x2D,
379 /* Index 0x64~0x67 */
380 {0x2D, 0x3F, 0x3F}, {0x2D, 0x3A, 0x3F}, {0x2D, 0x36, 0x3F}, {0x2D,
383 /* Index 0x68~0x6B */
384 {0x00, 0x00, 0x1C}, {0x07, 0x00, 0x1C}, {0x0E, 0x00, 0x1C}, {0x15,
387 /* Index 0x6C~0x6F */
388 {0x1C, 0x00, 0x1C}, {0x1C, 0x00, 0x15}, {0x1C, 0x00, 0x0E}, {0x1C,
391 /* Index 0x70~0x73 */
392 {0x1C, 0x00, 0x00}, {0x1C, 0x07, 0x00}, {0x1C, 0x0E, 0x00}, {0x1C,
395 /* Index 0x74~0x77 */
396 {0x1C, 0x1C, 0x00}, {0x15, 0x1C, 0x00}, {0x0E, 0x1C, 0x00}, {0x07,
399 /* Index 0x78~0x7B */
400 {0x00, 0x1C, 0x00}, {0x00, 0x1C, 0x07}, {0x00, 0x1C, 0x0E}, {0x00,
403 /* Index 0x7C~0x7F */
404 {0x00, 0x1C, 0x1C}, {0x00, 0x15, 0x1C}, {0x00, 0x0E, 0x1C}, {0x00,
407 /* Index 0x80~0x83 */
408 {0x0E, 0x0E, 0x1C}, {0x11, 0x0E, 0x1C}, {0x15, 0x0E, 0x1C}, {0x18,
411 /* Index 0x84~0x87 */
412 {0x1C, 0x0E, 0x1C}, {0x1C, 0x0E, 0x18}, {0x1C, 0x0E, 0x15}, {0x1C,
415 /* Index 0x88~0x8B */
416 {0x1C, 0x0E, 0x0E}, {0x1C, 0x11, 0x0E}, {0x1C, 0x15, 0x0E}, {0x1C,
419 /* Index 0x8C~0x8F */
420 {0x1C, 0x1C, 0x0E}, {0x18, 0x1C, 0x0E}, {0x15, 0x1C, 0x0E}, {0x11,
423 /* Index 0x90~0x93 */
424 {0x0E, 0x1C, 0x0E}, {0x0E, 0x1C, 0x11}, {0x0E, 0x1C, 0x15}, {0x0E,
427 /* Index 0x94~0x97 */
428 {0x0E, 0x1C, 0x1C}, {0x0E, 0x18, 0x1C}, {0x0E, 0x15, 0x1C}, {0x0E,
431 /* Index 0x98~0x9B */
432 {0x14, 0x14, 0x1C}, {0x16, 0x14, 0x1C}, {0x18, 0x14, 0x1C}, {0x1A,
435 /* Index 0x9C~0x9F */
436 {0x1C, 0x14, 0x1C}, {0x1C, 0x14, 0x1A}, {0x1C, 0x14, 0x18}, {0x1C,
439 /* Index 0xA0~0xA3 */
440 {0x1C, 0x14, 0x14}, {0x1C, 0x16, 0x14}, {0x1C, 0x18, 0x14}, {0x1C,
443 /* Index 0xA4~0xA7 */
444 {0x1C, 0x1C, 0x14}, {0x1A, 0x1C, 0x14}, {0x18, 0x1C, 0x14}, {0x16,
447 /* Index 0xA8~0xAB */
448 {0x14, 0x1C, 0x14}, {0x14, 0x1C, 0x16}, {0x14, 0x1C, 0x18}, {0x14,
451 /* Index 0xAC~0xAF */
452 {0x14, 0x1C, 0x1C}, {0x14, 0x1A, 0x1C}, {0x14, 0x18, 0x1C}, {0x14,
455 /* Index 0xB0~0xB3 */
456 {0x00, 0x00, 0x10}, {0x04, 0x00, 0x10}, {0x08, 0x00, 0x10}, {0x0C,
459 /* Index 0xB4~0xB7 */
460 {0x10, 0x00, 0x10}, {0x10, 0x00, 0x0C}, {0x10, 0x00, 0x08}, {0x10,
463 /* Index 0xB8~0xBB */
464 {0x10, 0x00, 0x00}, {0x10, 0x04, 0x00}, {0x10, 0x08, 0x00}, {0x10,
467 /* Index 0xBC~0xBF */
468 {0x10, 0x10, 0x00}, {0x0C, 0x10, 0x00}, {0x08, 0x10, 0x00}, {0x04,
471 /* Index 0xC0~0xC3 */
472 {0x00, 0x10, 0x00}, {0x00, 0x10, 0x04}, {0x00, 0x10, 0x08}, {0x00,
475 /* Index 0xC4~0xC7 */
476 {0x00, 0x10, 0x10}, {0x00, 0x0C, 0x10}, {0x00, 0x08, 0x10}, {0x00,
479 /* Index 0xC8~0xCB */
480 {0x08, 0x08, 0x10}, {0x0A, 0x08, 0x10}, {0x0C, 0x08, 0x10}, {0x0E,
483 /* Index 0xCC~0xCF */
484 {0x10, 0x08, 0x10}, {0x10, 0x08, 0x0E}, {0x10, 0x08, 0x0C}, {0x10,
487 /* Index 0xD0~0xD3 */
488 {0x10, 0x08, 0x08}, {0x10, 0x0A, 0x08}, {0x10, 0x0C, 0x08}, {0x10,
491 /* Index 0xD4~0xD7 */
492 {0x10, 0x10, 0x08}, {0x0E, 0x10, 0x08}, {0x0C, 0x10, 0x08}, {0x0A,
495 /* Index 0xD8~0xDB */
496 {0x08, 0x10, 0x08}, {0x08, 0x10, 0x0A}, {0x08, 0x10, 0x0C}, {0x08,
499 /* Index 0xDC~0xDF */
500 {0x08, 0x10, 0x10}, {0x08, 0x0E, 0x10}, {0x08, 0x0C, 0x10}, {0x08,
503 /* Index 0xE0~0xE3 */
504 {0x0B, 0x0B, 0x10}, {0x0C, 0x0B, 0x10}, {0x0D, 0x0B, 0x10}, {0x0F,
507 /* Index 0xE4~0xE7 */
508 {0x10, 0x0B, 0x10}, {0x10, 0x0B, 0x0F}, {0x10, 0x0B, 0x0D}, {0x10,
511 /* Index 0xE8~0xEB */
512 {0x10, 0x0B, 0x0B}, {0x10, 0x0C, 0x0B}, {0x10, 0x0D, 0x0B}, {0x10,
515 /* Index 0xEC~0xEF */
516 {0x10, 0x10, 0x0B}, {0x0F, 0x10, 0x0B}, {0x0D, 0x10, 0x0B}, {0x0C,
519 /* Index 0xF0~0xF3 */
520 {0x0B, 0x10, 0x0B}, {0x0B, 0x10, 0x0C}, {0x0B, 0x10, 0x0D}, {0x0B,
523 /* Index 0xF4~0xF7 */
524 {0x0B, 0x10, 0x10}, {0x0B, 0x0F, 0x10}, {0x0B, 0x0D, 0x10}, {0x0B,
527 /* Index 0xF8~0xFB */
528 {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
531 /* Index 0xFC~0xFF */
532 {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
537 static void set_crt_output_path(int set_iga
);
538 static void dvi_patch_skew_dvp0(void);
539 static void dvi_patch_skew_dvp1(void);
540 static void dvi_patch_skew_dvp_low(void);
541 static void set_dvi_output_path(int set_iga
, int output_interface
);
542 static void set_lcd_output_path(int set_iga
, int output_interface
);
543 static int search_mode_setting(int ModeInfoIndex
);
544 static void load_fix_bit_crtc_reg(void);
545 static void init_gfx_chip_info(void);
546 static void init_tmds_chip_info(void);
547 static void init_lvds_chip_info(void);
548 static void device_screen_off(void);
549 static void device_screen_on(void);
550 static void set_display_channel(void);
551 static void device_off(void);
552 static void device_on(void);
553 static void enable_second_display_channel(void);
554 static void disable_second_display_channel(void);
555 static int get_fb_size_from_pci(void);
557 void viafb_write_reg(u8 index
, u16 io_port
, u8 data
)
559 outb(index
, io_port
);
560 outb(data
, io_port
+ 1);
561 /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, data); */
563 u8
viafb_read_reg(int io_port
, u8 index
)
565 outb(index
, io_port
);
566 return inb(io_port
+ 1);
569 void viafb_lock_crt(void)
571 viafb_write_reg_mask(CR11
, VIACR
, BIT7
, BIT7
);
574 void viafb_unlock_crt(void)
576 viafb_write_reg_mask(CR11
, VIACR
, 0, BIT7
);
577 viafb_write_reg_mask(CR47
, VIACR
, 0, BIT0
);
580 void viafb_write_reg_mask(u8 index
, int io_port
, u8 data
, u8 mask
)
584 outb(index
, io_port
);
585 tmp
= inb(io_port
+ 1);
586 outb((data
& mask
) | (tmp
& (~mask
)), io_port
+ 1);
587 /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, tmp); */
590 void write_dac_reg(u8 index
, u8 r
, u8 g
, u8 b
)
592 outb(index
, LUT_INDEX_WRITE
);
598 /*Set IGA path for each device*/
599 void viafb_set_iga_path(void)
602 if (viafb_SAMM_ON
== 1) {
604 if (viafb_primary_dev
== CRT_Device
)
605 viaparinfo
->crt_setting_info
->iga_path
= IGA1
;
607 viaparinfo
->crt_setting_info
->iga_path
= IGA2
;
611 if (viafb_primary_dev
== DVI_Device
)
612 viaparinfo
->tmds_setting_info
->iga_path
= IGA1
;
614 viaparinfo
->tmds_setting_info
->iga_path
= IGA2
;
618 if (viafb_primary_dev
== LCD_Device
) {
620 (viaparinfo
->chip_info
->gfx_chip_name
==
623 lvds_setting_info
->iga_path
= IGA2
;
625 crt_setting_info
->iga_path
= IGA1
;
627 tmds_setting_info
->iga_path
= IGA1
;
630 lvds_setting_info
->iga_path
= IGA1
;
632 viaparinfo
->lvds_setting_info
->iga_path
= IGA2
;
636 if (LCD2_Device
== viafb_primary_dev
)
637 viaparinfo
->lvds_setting_info2
->iga_path
= IGA1
;
639 viaparinfo
->lvds_setting_info2
->iga_path
= IGA2
;
644 if (viafb_CRT_ON
&& viafb_LCD_ON
) {
645 viaparinfo
->crt_setting_info
->iga_path
= IGA1
;
646 viaparinfo
->lvds_setting_info
->iga_path
= IGA2
;
647 } else if (viafb_CRT_ON
&& viafb_DVI_ON
) {
648 viaparinfo
->crt_setting_info
->iga_path
= IGA1
;
649 viaparinfo
->tmds_setting_info
->iga_path
= IGA2
;
650 } else if (viafb_LCD_ON
&& viafb_DVI_ON
) {
651 viaparinfo
->tmds_setting_info
->iga_path
= IGA1
;
652 viaparinfo
->lvds_setting_info
->iga_path
= IGA2
;
653 } else if (viafb_LCD_ON
&& viafb_LCD2_ON
) {
654 viaparinfo
->lvds_setting_info
->iga_path
= IGA2
;
655 viaparinfo
->lvds_setting_info2
->iga_path
= IGA2
;
656 } else if (viafb_CRT_ON
) {
657 viaparinfo
->crt_setting_info
->iga_path
= IGA1
;
658 } else if (viafb_LCD_ON
) {
659 viaparinfo
->lvds_setting_info
->iga_path
= IGA2
;
660 } else if (viafb_DVI_ON
) {
661 viaparinfo
->tmds_setting_info
->iga_path
= IGA1
;
666 void viafb_set_primary_address(u32 addr
)
668 DEBUG_MSG(KERN_DEBUG
"viafb_set_primary_address(0x%08X)\n", addr
);
669 viafb_write_reg(CR0D
, VIACR
, addr
& 0xFF);
670 viafb_write_reg(CR0C
, VIACR
, (addr
>> 8) & 0xFF);
671 viafb_write_reg(CR34
, VIACR
, (addr
>> 16) & 0xFF);
672 viafb_write_reg_mask(CR48
, VIACR
, (addr
>> 24) & 0x1F, 0x1F);
675 void viafb_set_secondary_address(u32 addr
)
677 DEBUG_MSG(KERN_DEBUG
"viafb_set_secondary_address(0x%08X)\n", addr
);
678 /* secondary display supports only quadword aligned memory */
679 viafb_write_reg_mask(CR62
, VIACR
, (addr
>> 2) & 0xFE, 0xFE);
680 viafb_write_reg(CR63
, VIACR
, (addr
>> 10) & 0xFF);
681 viafb_write_reg(CR64
, VIACR
, (addr
>> 18) & 0xFF);
682 viafb_write_reg_mask(CRA3
, VIACR
, (addr
>> 26) & 0x07, 0x07);
685 void viafb_set_primary_pitch(u32 pitch
)
687 DEBUG_MSG(KERN_DEBUG
"viafb_set_primary_pitch(0x%08X)\n", pitch
);
688 /* spec does not say that first adapter skips 3 bits but old
689 * code did it and seems to be reasonable in analogy to 2nd adapter
692 viafb_write_reg(0x13, VIACR
, pitch
& 0xFF);
693 viafb_write_reg_mask(0x35, VIACR
, (pitch
>> (8 - 5)) & 0xE0, 0xE0);
696 void viafb_set_secondary_pitch(u32 pitch
)
698 DEBUG_MSG(KERN_DEBUG
"viafb_set_secondary_pitch(0x%08X)\n", pitch
);
700 viafb_write_reg(0x66, VIACR
, pitch
& 0xFF);
701 viafb_write_reg_mask(0x67, VIACR
, (pitch
>> 8) & 0x03, 0x03);
702 viafb_write_reg_mask(0x71, VIACR
, (pitch
>> (10 - 7)) & 0x80, 0x80);
705 void viafb_set_output_path(int device
, int set_iga
, int output_interface
)
709 set_crt_output_path(set_iga
);
712 set_dvi_output_path(set_iga
, output_interface
);
715 set_lcd_output_path(set_iga
, output_interface
);
720 static void set_crt_output_path(int set_iga
)
722 viafb_write_reg_mask(CR36
, VIACR
, 0x00, BIT4
+ BIT5
);
726 viafb_write_reg_mask(SR16
, VIASR
, 0x00, BIT6
);
730 viafb_write_reg_mask(CR6A
, VIACR
, 0xC0, BIT6
+ BIT7
);
731 viafb_write_reg_mask(SR16
, VIASR
, 0x40, BIT6
);
732 if (set_iga
== IGA1_IGA2
)
733 viafb_write_reg_mask(CR6B
, VIACR
, 0x08, BIT3
);
738 static void dvi_patch_skew_dvp0(void)
740 /* Reset data driving first: */
741 viafb_write_reg_mask(SR1B
, VIASR
, 0, BIT1
);
742 viafb_write_reg_mask(SR2A
, VIASR
, 0, BIT4
);
744 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
745 case UNICHROME_P4M890
:
747 if ((viaparinfo
->tmds_setting_info
->h_active
== 1600) &&
748 (viaparinfo
->tmds_setting_info
->v_active
==
750 viafb_write_reg_mask(CR96
, VIACR
, 0x03,
753 viafb_write_reg_mask(CR96
, VIACR
, 0x07,
758 case UNICHROME_P4M900
:
760 viafb_write_reg_mask(CR96
, VIACR
, 0x07,
761 BIT0
+ BIT1
+ BIT2
+ BIT3
);
762 viafb_write_reg_mask(SR1B
, VIASR
, 0x02, BIT1
);
763 viafb_write_reg_mask(SR2A
, VIASR
, 0x10, BIT4
);
774 static void dvi_patch_skew_dvp1(void)
776 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
777 case UNICHROME_CX700
:
789 static void dvi_patch_skew_dvp_low(void)
791 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
792 case UNICHROME_K8M890
:
794 viafb_write_reg_mask(CR99
, VIACR
, 0x03, BIT0
+ BIT1
);
798 case UNICHROME_P4M900
:
800 viafb_write_reg_mask(CR99
, VIACR
, 0x08,
801 BIT0
+ BIT1
+ BIT2
+ BIT3
);
805 case UNICHROME_P4M890
:
807 viafb_write_reg_mask(CR99
, VIACR
, 0x0F,
808 BIT0
+ BIT1
+ BIT2
+ BIT3
);
819 static void set_dvi_output_path(int set_iga
, int output_interface
)
821 switch (output_interface
) {
823 viafb_write_reg_mask(CR6B
, VIACR
, 0x01, BIT0
);
825 if (set_iga
== IGA1
) {
826 viafb_write_reg_mask(CR96
, VIACR
, 0x00, BIT4
);
827 viafb_write_reg_mask(CR6C
, VIACR
, 0x21, BIT0
+
830 viafb_write_reg_mask(CR96
, VIACR
, 0x10, BIT4
);
831 viafb_write_reg_mask(CR6C
, VIACR
, 0xA1, BIT0
+
835 viafb_write_reg_mask(SR1E
, VIASR
, 0xC0, BIT7
+ BIT6
);
837 dvi_patch_skew_dvp0();
841 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
) {
843 viafb_write_reg_mask(CR93
, VIACR
, 0x21,
846 viafb_write_reg_mask(CR93
, VIACR
, 0xA1,
850 viafb_write_reg_mask(CR9B
, VIACR
, 0x00, BIT4
);
852 viafb_write_reg_mask(CR9B
, VIACR
, 0x10, BIT4
);
855 viafb_write_reg_mask(SR1E
, VIASR
, 0x30, BIT4
+ BIT5
);
856 dvi_patch_skew_dvp1();
858 case INTERFACE_DFP_HIGH
:
859 if (viaparinfo
->chip_info
->gfx_chip_name
!= UNICHROME_CLE266
) {
860 if (set_iga
== IGA1
) {
861 viafb_write_reg_mask(CR96
, VIACR
, 0x00, BIT4
);
862 viafb_write_reg_mask(CR97
, VIACR
, 0x03,
865 viafb_write_reg_mask(CR96
, VIACR
, 0x10, BIT4
);
866 viafb_write_reg_mask(CR97
, VIACR
, 0x13,
870 viafb_write_reg_mask(SR2A
, VIASR
, 0x0C, BIT2
+ BIT3
);
873 case INTERFACE_DFP_LOW
:
874 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
)
877 if (set_iga
== IGA1
) {
878 viafb_write_reg_mask(CR99
, VIACR
, 0x00, BIT4
);
879 viafb_write_reg_mask(CR9B
, VIACR
, 0x00, BIT4
);
881 viafb_write_reg_mask(CR99
, VIACR
, 0x10, BIT4
);
882 viafb_write_reg_mask(CR9B
, VIACR
, 0x10, BIT4
);
885 viafb_write_reg_mask(SR2A
, VIASR
, 0x03, BIT0
+ BIT1
);
886 dvi_patch_skew_dvp_low();
891 viafb_write_reg_mask(CR99
, VIACR
, 0x00, BIT4
);
893 viafb_write_reg_mask(CR99
, VIACR
, 0x10, BIT4
);
897 if (set_iga
== IGA2
) {
898 enable_second_display_channel();
899 /* Disable LCD Scaling */
900 viafb_write_reg_mask(CR79
, VIACR
, 0x00, BIT0
);
904 static void set_lcd_output_path(int set_iga
, int output_interface
)
907 "set_lcd_output_path, iga:%d,out_interface:%d\n",
908 set_iga
, output_interface
);
911 viafb_write_reg_mask(CR6B
, VIACR
, 0x00, BIT3
);
912 viafb_write_reg_mask(CR6A
, VIACR
, 0x08, BIT3
);
914 disable_second_display_channel();
918 viafb_write_reg_mask(CR6B
, VIACR
, 0x00, BIT3
);
919 viafb_write_reg_mask(CR6A
, VIACR
, 0x08, BIT3
);
921 enable_second_display_channel();
925 viafb_write_reg_mask(CR6B
, VIACR
, 0x08, BIT3
);
926 viafb_write_reg_mask(CR6A
, VIACR
, 0x08, BIT3
);
928 disable_second_display_channel();
932 switch (output_interface
) {
934 if (set_iga
== IGA1
) {
935 viafb_write_reg_mask(CR96
, VIACR
, 0x00, BIT4
);
937 viafb_write_reg(CR91
, VIACR
, 0x00);
938 viafb_write_reg_mask(CR96
, VIACR
, 0x10, BIT4
);
944 viafb_write_reg_mask(CR9B
, VIACR
, 0x00, BIT4
);
946 viafb_write_reg(CR91
, VIACR
, 0x00);
947 viafb_write_reg_mask(CR9B
, VIACR
, 0x10, BIT4
);
951 case INTERFACE_DFP_HIGH
:
953 viafb_write_reg_mask(CR97
, VIACR
, 0x00, BIT4
);
955 viafb_write_reg(CR91
, VIACR
, 0x00);
956 viafb_write_reg_mask(CR97
, VIACR
, 0x10, BIT4
);
957 viafb_write_reg_mask(CR96
, VIACR
, 0x10, BIT4
);
961 case INTERFACE_DFP_LOW
:
963 viafb_write_reg_mask(CR99
, VIACR
, 0x00, BIT4
);
965 viafb_write_reg(CR91
, VIACR
, 0x00);
966 viafb_write_reg_mask(CR99
, VIACR
, 0x10, BIT4
);
967 viafb_write_reg_mask(CR9B
, VIACR
, 0x10, BIT4
);
973 if ((UNICHROME_K8M890
== viaparinfo
->chip_info
->gfx_chip_name
)
974 || (UNICHROME_P4M890
==
975 viaparinfo
->chip_info
->gfx_chip_name
))
976 viafb_write_reg_mask(CR97
, VIACR
, 0x84,
977 BIT7
+ BIT2
+ BIT1
+ BIT0
);
978 if (set_iga
== IGA1
) {
979 viafb_write_reg_mask(CR97
, VIACR
, 0x00, BIT4
);
980 viafb_write_reg_mask(CR99
, VIACR
, 0x00, BIT4
);
982 viafb_write_reg(CR91
, VIACR
, 0x00);
983 viafb_write_reg_mask(CR97
, VIACR
, 0x10, BIT4
);
984 viafb_write_reg_mask(CR99
, VIACR
, 0x10, BIT4
);
988 case INTERFACE_LVDS0
:
989 case INTERFACE_LVDS0LVDS1
:
991 viafb_write_reg_mask(CR99
, VIACR
, 0x00, BIT4
);
993 viafb_write_reg_mask(CR99
, VIACR
, 0x10, BIT4
);
997 case INTERFACE_LVDS1
:
999 viafb_write_reg_mask(CR97
, VIACR
, 0x00, BIT4
);
1001 viafb_write_reg_mask(CR97
, VIACR
, 0x10, BIT4
);
1006 /* Search Mode Index */
1007 static int search_mode_setting(int ModeInfoIndex
)
1011 while ((i
< NUM_TOTAL_MODETABLE
) &&
1012 (ModeInfoIndex
!= CLE266Modes
[i
].ModeIndex
))
1014 if (i
>= NUM_TOTAL_MODETABLE
)
1020 struct VideoModeTable
*viafb_get_modetbl_pointer(int Index
)
1022 struct VideoModeTable
*TmpTbl
= NULL
;
1023 TmpTbl
= &CLE266Modes
[search_mode_setting(Index
)];
1027 struct VideoModeTable
*viafb_get_cea_mode_tbl_pointer(int Index
)
1029 struct VideoModeTable
*TmpTbl
= NULL
;
1031 while ((i
< NUM_TOTAL_CEA_MODES
) &&
1032 (Index
!= CEA_HDMI_Modes
[i
].ModeIndex
))
1034 if ((i
< NUM_TOTAL_CEA_MODES
))
1035 TmpTbl
= &CEA_HDMI_Modes
[i
];
1037 /*Still use general timing if don't find CEA timing */
1039 while ((i
< NUM_TOTAL_MODETABLE
) &&
1040 (Index
!= CLE266Modes
[i
].ModeIndex
))
1042 if (i
>= NUM_TOTAL_MODETABLE
)
1044 TmpTbl
= &CLE266Modes
[i
];
1049 static void load_fix_bit_crtc_reg(void)
1051 /* always set to 1 */
1052 viafb_write_reg_mask(CR03
, VIACR
, 0x80, BIT7
);
1053 /* line compare should set all bits = 1 (extend modes) */
1054 viafb_write_reg(CR18
, VIACR
, 0xff);
1055 /* line compare should set all bits = 1 (extend modes) */
1056 viafb_write_reg_mask(CR07
, VIACR
, 0x10, BIT4
);
1057 /* line compare should set all bits = 1 (extend modes) */
1058 viafb_write_reg_mask(CR09
, VIACR
, 0x40, BIT6
);
1059 /* line compare should set all bits = 1 (extend modes) */
1060 viafb_write_reg_mask(CR35
, VIACR
, 0x10, BIT4
);
1061 /* line compare should set all bits = 1 (extend modes) */
1062 viafb_write_reg_mask(CR33
, VIACR
, 0x06, BIT0
+ BIT1
+ BIT2
);
1063 /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */
1064 /* extend mode always set to e3h */
1065 viafb_write_reg(CR17
, VIACR
, 0xe3);
1066 /* extend mode always set to 0h */
1067 viafb_write_reg(CR08
, VIACR
, 0x00);
1068 /* extend mode always set to 0h */
1069 viafb_write_reg(CR14
, VIACR
, 0x00);
1071 /* If K8M800, enable Prefetch Mode. */
1072 if ((viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K800
)
1073 || (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K8M890
))
1074 viafb_write_reg_mask(CR33
, VIACR
, 0x08, BIT3
);
1075 if ((viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
)
1076 && (viaparinfo
->chip_info
->gfx_chip_revision
== CLE266_REVISION_AX
))
1077 viafb_write_reg_mask(SR1A
, VIASR
, 0x02, BIT1
);
1081 void viafb_load_reg(int timing_value
, int viafb_load_reg_num
,
1082 struct io_register
*reg
,
1090 int start_index
, end_index
, cr_index
;
1093 for (i
= 0; i
< viafb_load_reg_num
; i
++) {
1096 start_index
= reg
[i
].start_bit
;
1097 end_index
= reg
[i
].end_bit
;
1098 cr_index
= reg
[i
].io_addr
;
1100 shift_next_reg
= bit_num
;
1101 for (j
= start_index
; j
<= end_index
; j
++) {
1102 /*if (bit_num==8) timing_value = timing_value >>8; */
1103 reg_mask
= reg_mask
| (BIT0
<< j
);
1104 get_bit
= (timing_value
& (BIT0
<< bit_num
));
1106 data
| ((get_bit
>> shift_next_reg
) << start_index
);
1109 if (io_type
== VIACR
)
1110 viafb_write_reg_mask(cr_index
, VIACR
, data
, reg_mask
);
1112 viafb_write_reg_mask(cr_index
, VIASR
, data
, reg_mask
);
1117 /* Write Registers */
1118 void viafb_write_regx(struct io_reg RegTable
[], int ItemNum
)
1121 unsigned char RegTemp
;
1123 /*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */
1125 for (i
= 0; i
< ItemNum
; i
++) {
1126 outb(RegTable
[i
].index
, RegTable
[i
].port
);
1127 RegTemp
= inb(RegTable
[i
].port
+ 1);
1128 RegTemp
= (RegTemp
& (~RegTable
[i
].mask
)) | RegTable
[i
].value
;
1129 outb(RegTemp
, RegTable
[i
].port
+ 1);
1133 void viafb_load_fetch_count_reg(int h_addr
, int bpp_byte
, int set_iga
)
1136 int viafb_load_reg_num
;
1137 struct io_register
*reg
= NULL
;
1142 reg_value
= IGA1_FETCH_COUNT_FORMULA(h_addr
, bpp_byte
);
1143 viafb_load_reg_num
= fetch_count_reg
.
1144 iga1_fetch_count_reg
.reg_num
;
1145 reg
= fetch_count_reg
.iga1_fetch_count_reg
.reg
;
1146 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIASR
);
1147 if (set_iga
== IGA1
)
1150 reg_value
= IGA2_FETCH_COUNT_FORMULA(h_addr
, bpp_byte
);
1151 viafb_load_reg_num
= fetch_count_reg
.
1152 iga2_fetch_count_reg
.reg_num
;
1153 reg
= fetch_count_reg
.iga2_fetch_count_reg
.reg
;
1154 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIACR
);
1160 void viafb_load_FIFO_reg(int set_iga
, int hor_active
, int ver_active
)
1163 int viafb_load_reg_num
;
1164 struct io_register
*reg
= NULL
;
1165 int iga1_fifo_max_depth
= 0, iga1_fifo_threshold
=
1166 0, iga1_fifo_high_threshold
= 0, iga1_display_queue_expire_num
= 0;
1167 int iga2_fifo_max_depth
= 0, iga2_fifo_threshold
=
1168 0, iga2_fifo_high_threshold
= 0, iga2_display_queue_expire_num
= 0;
1170 if (set_iga
== IGA1
) {
1171 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K800
) {
1172 iga1_fifo_max_depth
= K800_IGA1_FIFO_MAX_DEPTH
;
1173 iga1_fifo_threshold
= K800_IGA1_FIFO_THRESHOLD
;
1174 iga1_fifo_high_threshold
=
1175 K800_IGA1_FIFO_HIGH_THRESHOLD
;
1176 /* If resolution > 1280x1024, expire length = 64, else
1177 expire length = 128 */
1178 if ((hor_active
> 1280) && (ver_active
> 1024))
1179 iga1_display_queue_expire_num
= 16;
1181 iga1_display_queue_expire_num
=
1182 K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1186 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_PM800
) {
1187 iga1_fifo_max_depth
= P880_IGA1_FIFO_MAX_DEPTH
;
1188 iga1_fifo_threshold
= P880_IGA1_FIFO_THRESHOLD
;
1189 iga1_fifo_high_threshold
=
1190 P880_IGA1_FIFO_HIGH_THRESHOLD
;
1191 iga1_display_queue_expire_num
=
1192 P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1194 /* If resolution > 1280x1024, expire length = 64, else
1195 expire length = 128 */
1196 if ((hor_active
> 1280) && (ver_active
> 1024))
1197 iga1_display_queue_expire_num
= 16;
1199 iga1_display_queue_expire_num
=
1200 P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1203 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CN700
) {
1204 iga1_fifo_max_depth
= CN700_IGA1_FIFO_MAX_DEPTH
;
1205 iga1_fifo_threshold
= CN700_IGA1_FIFO_THRESHOLD
;
1206 iga1_fifo_high_threshold
=
1207 CN700_IGA1_FIFO_HIGH_THRESHOLD
;
1209 /* If resolution > 1280x1024, expire length = 64,
1210 else expire length = 128 */
1211 if ((hor_active
> 1280) && (ver_active
> 1024))
1212 iga1_display_queue_expire_num
= 16;
1214 iga1_display_queue_expire_num
=
1215 CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1218 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
) {
1219 iga1_fifo_max_depth
= CX700_IGA1_FIFO_MAX_DEPTH
;
1220 iga1_fifo_threshold
= CX700_IGA1_FIFO_THRESHOLD
;
1221 iga1_fifo_high_threshold
=
1222 CX700_IGA1_FIFO_HIGH_THRESHOLD
;
1223 iga1_display_queue_expire_num
=
1224 CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1227 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K8M890
) {
1228 iga1_fifo_max_depth
= K8M890_IGA1_FIFO_MAX_DEPTH
;
1229 iga1_fifo_threshold
= K8M890_IGA1_FIFO_THRESHOLD
;
1230 iga1_fifo_high_threshold
=
1231 K8M890_IGA1_FIFO_HIGH_THRESHOLD
;
1232 iga1_display_queue_expire_num
=
1233 K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1236 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_P4M890
) {
1237 iga1_fifo_max_depth
= P4M890_IGA1_FIFO_MAX_DEPTH
;
1238 iga1_fifo_threshold
= P4M890_IGA1_FIFO_THRESHOLD
;
1239 iga1_fifo_high_threshold
=
1240 P4M890_IGA1_FIFO_HIGH_THRESHOLD
;
1241 iga1_display_queue_expire_num
=
1242 P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1245 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_P4M900
) {
1246 iga1_fifo_max_depth
= P4M900_IGA1_FIFO_MAX_DEPTH
;
1247 iga1_fifo_threshold
= P4M900_IGA1_FIFO_THRESHOLD
;
1248 iga1_fifo_high_threshold
=
1249 P4M900_IGA1_FIFO_HIGH_THRESHOLD
;
1250 iga1_display_queue_expire_num
=
1251 P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1254 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_VX800
) {
1255 iga1_fifo_max_depth
= VX800_IGA1_FIFO_MAX_DEPTH
;
1256 iga1_fifo_threshold
= VX800_IGA1_FIFO_THRESHOLD
;
1257 iga1_fifo_high_threshold
=
1258 VX800_IGA1_FIFO_HIGH_THRESHOLD
;
1259 iga1_display_queue_expire_num
=
1260 VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1263 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_VX855
) {
1264 iga1_fifo_max_depth
= VX855_IGA1_FIFO_MAX_DEPTH
;
1265 iga1_fifo_threshold
= VX855_IGA1_FIFO_THRESHOLD
;
1266 iga1_fifo_high_threshold
=
1267 VX855_IGA1_FIFO_HIGH_THRESHOLD
;
1268 iga1_display_queue_expire_num
=
1269 VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM
;
1272 /* Set Display FIFO Depath Select */
1273 reg_value
= IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth
);
1274 viafb_load_reg_num
=
1275 display_fifo_depth_reg
.iga1_fifo_depth_select_reg
.reg_num
;
1276 reg
= display_fifo_depth_reg
.iga1_fifo_depth_select_reg
.reg
;
1277 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIASR
);
1279 /* Set Display FIFO Threshold Select */
1280 reg_value
= IGA1_FIFO_THRESHOLD_FORMULA(iga1_fifo_threshold
);
1281 viafb_load_reg_num
=
1282 fifo_threshold_select_reg
.
1283 iga1_fifo_threshold_select_reg
.reg_num
;
1285 fifo_threshold_select_reg
.
1286 iga1_fifo_threshold_select_reg
.reg
;
1287 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIASR
);
1289 /* Set FIFO High Threshold Select */
1291 IGA1_FIFO_HIGH_THRESHOLD_FORMULA(iga1_fifo_high_threshold
);
1292 viafb_load_reg_num
=
1293 fifo_high_threshold_select_reg
.
1294 iga1_fifo_high_threshold_select_reg
.reg_num
;
1296 fifo_high_threshold_select_reg
.
1297 iga1_fifo_high_threshold_select_reg
.reg
;
1298 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIASR
);
1300 /* Set Display Queue Expire Num */
1302 IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
1303 (iga1_display_queue_expire_num
);
1304 viafb_load_reg_num
=
1305 display_queue_expire_num_reg
.
1306 iga1_display_queue_expire_num_reg
.reg_num
;
1308 display_queue_expire_num_reg
.
1309 iga1_display_queue_expire_num_reg
.reg
;
1310 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIASR
);
1313 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K800
) {
1314 iga2_fifo_max_depth
= K800_IGA2_FIFO_MAX_DEPTH
;
1315 iga2_fifo_threshold
= K800_IGA2_FIFO_THRESHOLD
;
1316 iga2_fifo_high_threshold
=
1317 K800_IGA2_FIFO_HIGH_THRESHOLD
;
1319 /* If resolution > 1280x1024, expire length = 64,
1320 else expire length = 128 */
1321 if ((hor_active
> 1280) && (ver_active
> 1024))
1322 iga2_display_queue_expire_num
= 16;
1324 iga2_display_queue_expire_num
=
1325 K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1328 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_PM800
) {
1329 iga2_fifo_max_depth
= P880_IGA2_FIFO_MAX_DEPTH
;
1330 iga2_fifo_threshold
= P880_IGA2_FIFO_THRESHOLD
;
1331 iga2_fifo_high_threshold
=
1332 P880_IGA2_FIFO_HIGH_THRESHOLD
;
1334 /* If resolution > 1280x1024, expire length = 64,
1335 else expire length = 128 */
1336 if ((hor_active
> 1280) && (ver_active
> 1024))
1337 iga2_display_queue_expire_num
= 16;
1339 iga2_display_queue_expire_num
=
1340 P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1343 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CN700
) {
1344 iga2_fifo_max_depth
= CN700_IGA2_FIFO_MAX_DEPTH
;
1345 iga2_fifo_threshold
= CN700_IGA2_FIFO_THRESHOLD
;
1346 iga2_fifo_high_threshold
=
1347 CN700_IGA2_FIFO_HIGH_THRESHOLD
;
1349 /* If resolution > 1280x1024, expire length = 64,
1350 else expire length = 128 */
1351 if ((hor_active
> 1280) && (ver_active
> 1024))
1352 iga2_display_queue_expire_num
= 16;
1354 iga2_display_queue_expire_num
=
1355 CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1358 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
) {
1359 iga2_fifo_max_depth
= CX700_IGA2_FIFO_MAX_DEPTH
;
1360 iga2_fifo_threshold
= CX700_IGA2_FIFO_THRESHOLD
;
1361 iga2_fifo_high_threshold
=
1362 CX700_IGA2_FIFO_HIGH_THRESHOLD
;
1363 iga2_display_queue_expire_num
=
1364 CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1367 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K8M890
) {
1368 iga2_fifo_max_depth
= K8M890_IGA2_FIFO_MAX_DEPTH
;
1369 iga2_fifo_threshold
= K8M890_IGA2_FIFO_THRESHOLD
;
1370 iga2_fifo_high_threshold
=
1371 K8M890_IGA2_FIFO_HIGH_THRESHOLD
;
1372 iga2_display_queue_expire_num
=
1373 K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1376 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_P4M890
) {
1377 iga2_fifo_max_depth
= P4M890_IGA2_FIFO_MAX_DEPTH
;
1378 iga2_fifo_threshold
= P4M890_IGA2_FIFO_THRESHOLD
;
1379 iga2_fifo_high_threshold
=
1380 P4M890_IGA2_FIFO_HIGH_THRESHOLD
;
1381 iga2_display_queue_expire_num
=
1382 P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1385 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_P4M900
) {
1386 iga2_fifo_max_depth
= P4M900_IGA2_FIFO_MAX_DEPTH
;
1387 iga2_fifo_threshold
= P4M900_IGA2_FIFO_THRESHOLD
;
1388 iga2_fifo_high_threshold
=
1389 P4M900_IGA2_FIFO_HIGH_THRESHOLD
;
1390 iga2_display_queue_expire_num
=
1391 P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1394 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_VX800
) {
1395 iga2_fifo_max_depth
= VX800_IGA2_FIFO_MAX_DEPTH
;
1396 iga2_fifo_threshold
= VX800_IGA2_FIFO_THRESHOLD
;
1397 iga2_fifo_high_threshold
=
1398 VX800_IGA2_FIFO_HIGH_THRESHOLD
;
1399 iga2_display_queue_expire_num
=
1400 VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1403 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_VX855
) {
1404 iga2_fifo_max_depth
= VX855_IGA2_FIFO_MAX_DEPTH
;
1405 iga2_fifo_threshold
= VX855_IGA2_FIFO_THRESHOLD
;
1406 iga2_fifo_high_threshold
=
1407 VX855_IGA2_FIFO_HIGH_THRESHOLD
;
1408 iga2_display_queue_expire_num
=
1409 VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM
;
1412 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K800
) {
1413 /* Set Display FIFO Depath Select */
1415 IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth
)
1417 /* Patch LCD in IGA2 case */
1418 viafb_load_reg_num
=
1419 display_fifo_depth_reg
.
1420 iga2_fifo_depth_select_reg
.reg_num
;
1422 display_fifo_depth_reg
.
1423 iga2_fifo_depth_select_reg
.reg
;
1424 viafb_load_reg(reg_value
,
1425 viafb_load_reg_num
, reg
, VIACR
);
1428 /* Set Display FIFO Depath Select */
1430 IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth
);
1431 viafb_load_reg_num
=
1432 display_fifo_depth_reg
.
1433 iga2_fifo_depth_select_reg
.reg_num
;
1435 display_fifo_depth_reg
.
1436 iga2_fifo_depth_select_reg
.reg
;
1437 viafb_load_reg(reg_value
,
1438 viafb_load_reg_num
, reg
, VIACR
);
1441 /* Set Display FIFO Threshold Select */
1442 reg_value
= IGA2_FIFO_THRESHOLD_FORMULA(iga2_fifo_threshold
);
1443 viafb_load_reg_num
=
1444 fifo_threshold_select_reg
.
1445 iga2_fifo_threshold_select_reg
.reg_num
;
1447 fifo_threshold_select_reg
.
1448 iga2_fifo_threshold_select_reg
.reg
;
1449 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIACR
);
1451 /* Set FIFO High Threshold Select */
1453 IGA2_FIFO_HIGH_THRESHOLD_FORMULA(iga2_fifo_high_threshold
);
1454 viafb_load_reg_num
=
1455 fifo_high_threshold_select_reg
.
1456 iga2_fifo_high_threshold_select_reg
.reg_num
;
1458 fifo_high_threshold_select_reg
.
1459 iga2_fifo_high_threshold_select_reg
.reg
;
1460 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIACR
);
1462 /* Set Display Queue Expire Num */
1464 IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
1465 (iga2_display_queue_expire_num
);
1466 viafb_load_reg_num
=
1467 display_queue_expire_num_reg
.
1468 iga2_display_queue_expire_num_reg
.reg_num
;
1470 display_queue_expire_num_reg
.
1471 iga2_display_queue_expire_num_reg
.reg
;
1472 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIACR
);
1478 u32
viafb_get_clk_value(int clk
)
1482 for (i
= 0; i
< NUM_TOTAL_PLL_TABLE
; i
++) {
1483 if (clk
== pll_value
[i
].clk
) {
1484 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
1485 case UNICHROME_CLE266
:
1486 case UNICHROME_K400
:
1487 return pll_value
[i
].cle266_pll
;
1489 case UNICHROME_K800
:
1490 case UNICHROME_PM800
:
1491 case UNICHROME_CN700
:
1492 return pll_value
[i
].k800_pll
;
1494 case UNICHROME_CX700
:
1495 case UNICHROME_K8M890
:
1496 case UNICHROME_P4M890
:
1497 case UNICHROME_P4M900
:
1498 case UNICHROME_VX800
:
1499 return pll_value
[i
].cx700_pll
;
1500 case UNICHROME_VX855
:
1501 return pll_value
[i
].vx855_pll
;
1506 DEBUG_MSG(KERN_INFO
"Can't find match PLL value\n\n");
1511 void viafb_set_vclock(u32 CLK
, int set_iga
)
1513 unsigned char RegTemp
;
1515 /* H.W. Reset : ON */
1516 viafb_write_reg_mask(CR17
, VIACR
, 0x00, BIT7
);
1518 if ((set_iga
== IGA1
) || (set_iga
== IGA1_IGA2
)) {
1519 /* Change D,N FOR VCLK */
1520 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
1521 case UNICHROME_CLE266
:
1522 case UNICHROME_K400
:
1523 viafb_write_reg(SR46
, VIASR
, CLK
/ 0x100);
1524 viafb_write_reg(SR47
, VIASR
, CLK
% 0x100);
1527 case UNICHROME_K800
:
1528 case UNICHROME_PM800
:
1529 case UNICHROME_CN700
:
1530 case UNICHROME_CX700
:
1531 case UNICHROME_K8M890
:
1532 case UNICHROME_P4M890
:
1533 case UNICHROME_P4M900
:
1534 case UNICHROME_VX800
:
1535 case UNICHROME_VX855
:
1536 viafb_write_reg(SR44
, VIASR
, CLK
/ 0x10000);
1537 DEBUG_MSG(KERN_INFO
"\nSR44=%x", CLK
/ 0x10000);
1538 viafb_write_reg(SR45
, VIASR
, (CLK
& 0xFFFF) / 0x100);
1539 DEBUG_MSG(KERN_INFO
"\nSR45=%x",
1540 (CLK
& 0xFFFF) / 0x100);
1541 viafb_write_reg(SR46
, VIASR
, CLK
% 0x100);
1542 DEBUG_MSG(KERN_INFO
"\nSR46=%x", CLK
% 0x100);
1547 if ((set_iga
== IGA2
) || (set_iga
== IGA1_IGA2
)) {
1548 /* Change D,N FOR LCK */
1549 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
1550 case UNICHROME_CLE266
:
1551 case UNICHROME_K400
:
1552 viafb_write_reg(SR44
, VIASR
, CLK
/ 0x100);
1553 viafb_write_reg(SR45
, VIASR
, CLK
% 0x100);
1556 case UNICHROME_K800
:
1557 case UNICHROME_PM800
:
1558 case UNICHROME_CN700
:
1559 case UNICHROME_CX700
:
1560 case UNICHROME_K8M890
:
1561 case UNICHROME_P4M890
:
1562 case UNICHROME_P4M900
:
1563 case UNICHROME_VX800
:
1564 case UNICHROME_VX855
:
1565 viafb_write_reg(SR4A
, VIASR
, CLK
/ 0x10000);
1566 viafb_write_reg(SR4B
, VIASR
, (CLK
& 0xFFFF) / 0x100);
1567 viafb_write_reg(SR4C
, VIASR
, CLK
% 0x100);
1572 /* H.W. Reset : OFF */
1573 viafb_write_reg_mask(CR17
, VIACR
, 0x80, BIT7
);
1576 if ((set_iga
== IGA1
) || (set_iga
== IGA1_IGA2
)) {
1577 viafb_write_reg_mask(SR40
, VIASR
, 0x02, BIT1
);
1578 viafb_write_reg_mask(SR40
, VIASR
, 0x00, BIT1
);
1581 if ((set_iga
== IGA2
) || (set_iga
== IGA1_IGA2
)) {
1582 viafb_write_reg_mask(SR40
, VIASR
, 0x01, BIT0
);
1583 viafb_write_reg_mask(SR40
, VIASR
, 0x00, BIT0
);
1587 RegTemp
= inb(VIARMisc
);
1588 outb(RegTemp
| (BIT2
+ BIT3
), VIAWMisc
);
1591 void viafb_load_crtc_timing(struct display_timing device_timing
,
1595 int viafb_load_reg_num
= 0;
1597 struct io_register
*reg
= NULL
;
1601 for (i
= 0; i
< 12; i
++) {
1602 if (set_iga
== IGA1
) {
1606 IGA1_HOR_TOTAL_FORMULA(device_timing
.
1608 viafb_load_reg_num
=
1609 iga1_crtc_reg
.hor_total
.reg_num
;
1610 reg
= iga1_crtc_reg
.hor_total
.reg
;
1614 IGA1_HOR_ADDR_FORMULA(device_timing
.
1616 viafb_load_reg_num
=
1617 iga1_crtc_reg
.hor_addr
.reg_num
;
1618 reg
= iga1_crtc_reg
.hor_addr
.reg
;
1620 case H_BLANK_START_INDEX
:
1622 IGA1_HOR_BLANK_START_FORMULA
1623 (device_timing
.hor_blank_start
);
1624 viafb_load_reg_num
=
1625 iga1_crtc_reg
.hor_blank_start
.reg_num
;
1626 reg
= iga1_crtc_reg
.hor_blank_start
.reg
;
1628 case H_BLANK_END_INDEX
:
1630 IGA1_HOR_BLANK_END_FORMULA
1631 (device_timing
.hor_blank_start
,
1632 device_timing
.hor_blank_end
);
1633 viafb_load_reg_num
=
1634 iga1_crtc_reg
.hor_blank_end
.reg_num
;
1635 reg
= iga1_crtc_reg
.hor_blank_end
.reg
;
1637 case H_SYNC_START_INDEX
:
1639 IGA1_HOR_SYNC_START_FORMULA
1640 (device_timing
.hor_sync_start
);
1641 viafb_load_reg_num
=
1642 iga1_crtc_reg
.hor_sync_start
.reg_num
;
1643 reg
= iga1_crtc_reg
.hor_sync_start
.reg
;
1645 case H_SYNC_END_INDEX
:
1647 IGA1_HOR_SYNC_END_FORMULA
1648 (device_timing
.hor_sync_start
,
1649 device_timing
.hor_sync_end
);
1650 viafb_load_reg_num
=
1651 iga1_crtc_reg
.hor_sync_end
.reg_num
;
1652 reg
= iga1_crtc_reg
.hor_sync_end
.reg
;
1656 IGA1_VER_TOTAL_FORMULA(device_timing
.
1658 viafb_load_reg_num
=
1659 iga1_crtc_reg
.ver_total
.reg_num
;
1660 reg
= iga1_crtc_reg
.ver_total
.reg
;
1664 IGA1_VER_ADDR_FORMULA(device_timing
.
1666 viafb_load_reg_num
=
1667 iga1_crtc_reg
.ver_addr
.reg_num
;
1668 reg
= iga1_crtc_reg
.ver_addr
.reg
;
1670 case V_BLANK_START_INDEX
:
1672 IGA1_VER_BLANK_START_FORMULA
1673 (device_timing
.ver_blank_start
);
1674 viafb_load_reg_num
=
1675 iga1_crtc_reg
.ver_blank_start
.reg_num
;
1676 reg
= iga1_crtc_reg
.ver_blank_start
.reg
;
1678 case V_BLANK_END_INDEX
:
1680 IGA1_VER_BLANK_END_FORMULA
1681 (device_timing
.ver_blank_start
,
1682 device_timing
.ver_blank_end
);
1683 viafb_load_reg_num
=
1684 iga1_crtc_reg
.ver_blank_end
.reg_num
;
1685 reg
= iga1_crtc_reg
.ver_blank_end
.reg
;
1687 case V_SYNC_START_INDEX
:
1689 IGA1_VER_SYNC_START_FORMULA
1690 (device_timing
.ver_sync_start
);
1691 viafb_load_reg_num
=
1692 iga1_crtc_reg
.ver_sync_start
.reg_num
;
1693 reg
= iga1_crtc_reg
.ver_sync_start
.reg
;
1695 case V_SYNC_END_INDEX
:
1697 IGA1_VER_SYNC_END_FORMULA
1698 (device_timing
.ver_sync_start
,
1699 device_timing
.ver_sync_end
);
1700 viafb_load_reg_num
=
1701 iga1_crtc_reg
.ver_sync_end
.reg_num
;
1702 reg
= iga1_crtc_reg
.ver_sync_end
.reg
;
1708 if (set_iga
== IGA2
) {
1712 IGA2_HOR_TOTAL_FORMULA(device_timing
.
1714 viafb_load_reg_num
=
1715 iga2_crtc_reg
.hor_total
.reg_num
;
1716 reg
= iga2_crtc_reg
.hor_total
.reg
;
1720 IGA2_HOR_ADDR_FORMULA(device_timing
.
1722 viafb_load_reg_num
=
1723 iga2_crtc_reg
.hor_addr
.reg_num
;
1724 reg
= iga2_crtc_reg
.hor_addr
.reg
;
1726 case H_BLANK_START_INDEX
:
1728 IGA2_HOR_BLANK_START_FORMULA
1729 (device_timing
.hor_blank_start
);
1730 viafb_load_reg_num
=
1731 iga2_crtc_reg
.hor_blank_start
.reg_num
;
1732 reg
= iga2_crtc_reg
.hor_blank_start
.reg
;
1734 case H_BLANK_END_INDEX
:
1736 IGA2_HOR_BLANK_END_FORMULA
1737 (device_timing
.hor_blank_start
,
1738 device_timing
.hor_blank_end
);
1739 viafb_load_reg_num
=
1740 iga2_crtc_reg
.hor_blank_end
.reg_num
;
1741 reg
= iga2_crtc_reg
.hor_blank_end
.reg
;
1743 case H_SYNC_START_INDEX
:
1745 IGA2_HOR_SYNC_START_FORMULA
1746 (device_timing
.hor_sync_start
);
1747 if (UNICHROME_CN700
<=
1748 viaparinfo
->chip_info
->gfx_chip_name
)
1749 viafb_load_reg_num
=
1750 iga2_crtc_reg
.hor_sync_start
.
1753 viafb_load_reg_num
= 3;
1754 reg
= iga2_crtc_reg
.hor_sync_start
.reg
;
1756 case H_SYNC_END_INDEX
:
1758 IGA2_HOR_SYNC_END_FORMULA
1759 (device_timing
.hor_sync_start
,
1760 device_timing
.hor_sync_end
);
1761 viafb_load_reg_num
=
1762 iga2_crtc_reg
.hor_sync_end
.reg_num
;
1763 reg
= iga2_crtc_reg
.hor_sync_end
.reg
;
1767 IGA2_VER_TOTAL_FORMULA(device_timing
.
1769 viafb_load_reg_num
=
1770 iga2_crtc_reg
.ver_total
.reg_num
;
1771 reg
= iga2_crtc_reg
.ver_total
.reg
;
1775 IGA2_VER_ADDR_FORMULA(device_timing
.
1777 viafb_load_reg_num
=
1778 iga2_crtc_reg
.ver_addr
.reg_num
;
1779 reg
= iga2_crtc_reg
.ver_addr
.reg
;
1781 case V_BLANK_START_INDEX
:
1783 IGA2_VER_BLANK_START_FORMULA
1784 (device_timing
.ver_blank_start
);
1785 viafb_load_reg_num
=
1786 iga2_crtc_reg
.ver_blank_start
.reg_num
;
1787 reg
= iga2_crtc_reg
.ver_blank_start
.reg
;
1789 case V_BLANK_END_INDEX
:
1791 IGA2_VER_BLANK_END_FORMULA
1792 (device_timing
.ver_blank_start
,
1793 device_timing
.ver_blank_end
);
1794 viafb_load_reg_num
=
1795 iga2_crtc_reg
.ver_blank_end
.reg_num
;
1796 reg
= iga2_crtc_reg
.ver_blank_end
.reg
;
1798 case V_SYNC_START_INDEX
:
1800 IGA2_VER_SYNC_START_FORMULA
1801 (device_timing
.ver_sync_start
);
1802 viafb_load_reg_num
=
1803 iga2_crtc_reg
.ver_sync_start
.reg_num
;
1804 reg
= iga2_crtc_reg
.ver_sync_start
.reg
;
1806 case V_SYNC_END_INDEX
:
1808 IGA2_VER_SYNC_END_FORMULA
1809 (device_timing
.ver_sync_start
,
1810 device_timing
.ver_sync_end
);
1811 viafb_load_reg_num
=
1812 iga2_crtc_reg
.ver_sync_end
.reg_num
;
1813 reg
= iga2_crtc_reg
.ver_sync_end
.reg
;
1818 viafb_load_reg(reg_value
, viafb_load_reg_num
, reg
, VIACR
);
1824 void viafb_set_color_depth(int bpp_byte
, int set_iga
)
1826 if (set_iga
== IGA1
) {
1829 viafb_write_reg_mask(SR15
, VIASR
, 0x22, 0x7E);
1832 viafb_write_reg_mask(SR15
, VIASR
, 0xB6, 0xFE);
1835 viafb_write_reg_mask(SR15
, VIASR
, 0xAE, 0xFE);
1841 viafb_write_reg_mask(CR67
, VIACR
, 0x00, BIT6
+ BIT7
);
1844 viafb_write_reg_mask(CR67
, VIACR
, 0x40, BIT6
+ BIT7
);
1847 viafb_write_reg_mask(CR67
, VIACR
, 0xC0, BIT6
+ BIT7
);
1853 void viafb_fill_crtc_timing(struct crt_mode_table
*crt_table
,
1854 int mode_index
, int bpp_byte
, int set_iga
)
1856 struct VideoModeTable
*video_mode
;
1857 struct display_timing crt_reg
;
1863 video_mode
= &CLE266Modes
[search_mode_setting(mode_index
)];
1865 for (i
= 0; i
< video_mode
->mode_array
; i
++) {
1868 if (crt_table
[i
].refresh_rate
== viaparinfo
->
1869 crt_setting_info
->refresh_rate
)
1873 crt_reg
= crt_table
[index
].crtc
;
1875 /* Mode 640x480 has border, but LCD/DFP didn't have border. */
1876 /* So we would delete border. */
1877 if ((viafb_LCD_ON
| viafb_DVI_ON
) && (mode_index
== VIA_RES_640X480
)
1878 && (viaparinfo
->crt_setting_info
->refresh_rate
== 60)) {
1879 /* The border is 8 pixels. */
1880 crt_reg
.hor_blank_start
= crt_reg
.hor_blank_start
- 8;
1882 /* Blanking time should add left and right borders. */
1883 crt_reg
.hor_blank_end
= crt_reg
.hor_blank_end
+ 16;
1886 h_addr
= crt_reg
.hor_addr
;
1887 v_addr
= crt_reg
.ver_addr
;
1889 /* update polarity for CRT timing */
1890 if (crt_table
[index
].h_sync_polarity
== NEGATIVE
) {
1891 if (crt_table
[index
].v_sync_polarity
== NEGATIVE
)
1892 outb((inb(VIARMisc
) & (~(BIT6
+ BIT7
))) |
1893 (BIT6
+ BIT7
), VIAWMisc
);
1895 outb((inb(VIARMisc
) & (~(BIT6
+ BIT7
))) | (BIT6
),
1898 if (crt_table
[index
].v_sync_polarity
== NEGATIVE
)
1899 outb((inb(VIARMisc
) & (~(BIT6
+ BIT7
))) | (BIT7
),
1902 outb((inb(VIARMisc
) & (~(BIT6
+ BIT7
))), VIAWMisc
);
1905 if (set_iga
== IGA1
) {
1907 viafb_write_reg(CR09
, VIACR
, 0x00); /*initial CR09=0 */
1908 viafb_write_reg_mask(CR11
, VIACR
, 0x00, BIT4
+ BIT5
+ BIT6
);
1909 viafb_write_reg_mask(CR17
, VIACR
, 0x00, BIT7
);
1914 viafb_load_crtc_timing(crt_reg
, IGA1
);
1917 viafb_load_crtc_timing(crt_reg
, IGA2
);
1921 load_fix_bit_crtc_reg();
1923 viafb_write_reg_mask(CR17
, VIACR
, 0x80, BIT7
);
1924 viafb_load_fetch_count_reg(h_addr
, bpp_byte
, set_iga
);
1927 if ((viaparinfo
->chip_info
->gfx_chip_name
!= UNICHROME_CLE266
)
1928 && (viaparinfo
->chip_info
->gfx_chip_name
!= UNICHROME_K400
))
1929 viafb_load_FIFO_reg(set_iga
, h_addr
, v_addr
);
1931 /* load SR Register About Memory and Color part */
1932 viafb_set_color_depth(bpp_byte
, set_iga
);
1934 pll_D_N
= viafb_get_clk_value(crt_table
[index
].clk
);
1935 DEBUG_MSG(KERN_INFO
"PLL=%x", pll_D_N
);
1936 viafb_set_vclock(pll_D_N
, set_iga
);
1940 void viafb_init_chip_info(void)
1942 init_gfx_chip_info();
1943 init_tmds_chip_info();
1944 init_lvds_chip_info();
1946 viaparinfo
->crt_setting_info
->iga_path
= IGA1
;
1947 viaparinfo
->crt_setting_info
->refresh_rate
= viafb_refresh
;
1949 /*Set IGA path for each device */
1950 viafb_set_iga_path();
1952 viaparinfo
->lvds_setting_info
->display_method
= viafb_lcd_dsp_method
;
1953 viaparinfo
->lvds_setting_info
->get_lcd_size_method
=
1954 GET_LCD_SIZE_BY_USER_SETTING
;
1955 viaparinfo
->lvds_setting_info
->lcd_mode
= viafb_lcd_mode
;
1956 viaparinfo
->lvds_setting_info2
->display_method
=
1957 viaparinfo
->lvds_setting_info
->display_method
;
1958 viaparinfo
->lvds_setting_info2
->lcd_mode
=
1959 viaparinfo
->lvds_setting_info
->lcd_mode
;
1962 void viafb_update_device_setting(int hres
, int vres
,
1963 int bpp
, int vmode_refresh
, int flag
)
1966 viaparinfo
->crt_setting_info
->h_active
= hres
;
1967 viaparinfo
->crt_setting_info
->v_active
= vres
;
1968 viaparinfo
->crt_setting_info
->bpp
= bpp
;
1969 viaparinfo
->crt_setting_info
->refresh_rate
=
1972 viaparinfo
->tmds_setting_info
->h_active
= hres
;
1973 viaparinfo
->tmds_setting_info
->v_active
= vres
;
1974 viaparinfo
->tmds_setting_info
->bpp
= bpp
;
1975 viaparinfo
->tmds_setting_info
->refresh_rate
=
1978 viaparinfo
->lvds_setting_info
->h_active
= hres
;
1979 viaparinfo
->lvds_setting_info
->v_active
= vres
;
1980 viaparinfo
->lvds_setting_info
->bpp
= bpp
;
1981 viaparinfo
->lvds_setting_info
->refresh_rate
=
1983 viaparinfo
->lvds_setting_info2
->h_active
= hres
;
1984 viaparinfo
->lvds_setting_info2
->v_active
= vres
;
1985 viaparinfo
->lvds_setting_info2
->bpp
= bpp
;
1986 viaparinfo
->lvds_setting_info2
->refresh_rate
=
1990 if (viaparinfo
->tmds_setting_info
->iga_path
== IGA2
) {
1991 viaparinfo
->tmds_setting_info
->h_active
= hres
;
1992 viaparinfo
->tmds_setting_info
->v_active
= vres
;
1993 viaparinfo
->tmds_setting_info
->bpp
= bpp
;
1994 viaparinfo
->tmds_setting_info
->refresh_rate
=
1998 if (viaparinfo
->lvds_setting_info
->iga_path
== IGA2
) {
1999 viaparinfo
->lvds_setting_info
->h_active
= hres
;
2000 viaparinfo
->lvds_setting_info
->v_active
= vres
;
2001 viaparinfo
->lvds_setting_info
->bpp
= bpp
;
2002 viaparinfo
->lvds_setting_info
->refresh_rate
=
2005 if (IGA2
== viaparinfo
->lvds_setting_info2
->iga_path
) {
2006 viaparinfo
->lvds_setting_info2
->h_active
= hres
;
2007 viaparinfo
->lvds_setting_info2
->v_active
= vres
;
2008 viaparinfo
->lvds_setting_info2
->bpp
= bpp
;
2009 viaparinfo
->lvds_setting_info2
->refresh_rate
=
2015 static void init_gfx_chip_info(void)
2017 struct pci_dev
*pdev
= NULL
;
2021 /* Indentify GFX Chip Name */
2022 for (i
= 0; pciidlist
[i
].vendor
!= 0; i
++) {
2023 pdev
= pci_get_device(pciidlist
[i
].vendor
,
2024 pciidlist
[i
].device
, 0);
2029 if (!pciidlist
[i
].vendor
)
2032 viaparinfo
->chip_info
->gfx_chip_name
= pciidlist
[i
].chip_index
;
2034 /* Check revision of CLE266 Chip */
2035 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
) {
2036 /* CR4F only define in CLE266.CX chip */
2037 tmp
= viafb_read_reg(VIACR
, CR4F
);
2038 viafb_write_reg(CR4F
, VIACR
, 0x55);
2039 if (viafb_read_reg(VIACR
, CR4F
) != 0x55)
2040 viaparinfo
->chip_info
->gfx_chip_revision
=
2043 viaparinfo
->chip_info
->gfx_chip_revision
=
2045 /* restore orignal CR4F value */
2046 viafb_write_reg(CR4F
, VIACR
, tmp
);
2049 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
) {
2050 tmp
= viafb_read_reg(VIASR
, SR43
);
2051 DEBUG_MSG(KERN_INFO
"SR43:%X\n", tmp
);
2053 viaparinfo
->chip_info
->gfx_chip_revision
=
2054 CX700_REVISION_700M2
;
2055 } else if (tmp
& 0x40) {
2056 viaparinfo
->chip_info
->gfx_chip_revision
=
2057 CX700_REVISION_700M
;
2059 viaparinfo
->chip_info
->gfx_chip_revision
=
2067 static void init_tmds_chip_info(void)
2069 viafb_tmds_trasmitter_identify();
2071 if (INTERFACE_NONE
== viaparinfo
->chip_info
->tmds_chip_info
.
2073 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
2074 case UNICHROME_CX700
:
2076 /* we should check support by hardware layout.*/
2077 if ((viafb_display_hardware_layout
==
2079 || (viafb_display_hardware_layout
==
2080 HW_LAYOUT_LCD_DVI
)) {
2081 viaparinfo
->chip_info
->tmds_chip_info
.
2082 output_interface
= INTERFACE_TMDS
;
2084 viaparinfo
->chip_info
->tmds_chip_info
.
2090 case UNICHROME_K8M890
:
2091 case UNICHROME_P4M900
:
2092 case UNICHROME_P4M890
:
2093 /* TMDS on PCIE, we set DFPLOW as default. */
2094 viaparinfo
->chip_info
->tmds_chip_info
.output_interface
=
2099 /* set DVP1 default for DVI */
2100 viaparinfo
->chip_info
->tmds_chip_info
2101 .output_interface
= INTERFACE_DVP1
;
2106 DEBUG_MSG(KERN_INFO
"TMDS Chip = %d\n",
2107 viaparinfo
->chip_info
->tmds_chip_info
.tmds_chip_name
);
2108 viaparinfo
->tmds_setting_info
->get_dvi_size_method
=
2109 GET_DVI_SIZE_BY_VGA_BIOS
;
2110 viafb_init_dvi_size();
2113 static void init_lvds_chip_info(void)
2115 if (viafb_lcd_panel_id
> LCD_PANEL_ID_MAXIMUM
)
2116 viaparinfo
->lvds_setting_info
->get_lcd_size_method
=
2117 GET_LCD_SIZE_BY_VGA_BIOS
;
2119 viaparinfo
->lvds_setting_info
->get_lcd_size_method
=
2120 GET_LCD_SIZE_BY_USER_SETTING
;
2122 viafb_lvds_trasmitter_identify();
2123 viafb_init_lcd_size();
2124 viafb_init_lvds_output_interface(&viaparinfo
->chip_info
->lvds_chip_info
,
2125 viaparinfo
->lvds_setting_info
);
2126 if (viaparinfo
->chip_info
->lvds_chip_info2
.lvds_chip_name
) {
2127 viafb_init_lvds_output_interface(&viaparinfo
->chip_info
->
2128 lvds_chip_info2
, viaparinfo
->lvds_setting_info2
);
2130 /*If CX700,two singel LCD, we need to reassign
2131 LCD interface to different LVDS port */
2132 if ((UNICHROME_CX700
== viaparinfo
->chip_info
->gfx_chip_name
)
2133 && (HW_LAYOUT_LCD1_LCD2
== viafb_display_hardware_layout
)) {
2134 if ((INTEGRATED_LVDS
== viaparinfo
->chip_info
->lvds_chip_info
.
2135 lvds_chip_name
) && (INTEGRATED_LVDS
==
2136 viaparinfo
->chip_info
->
2137 lvds_chip_info2
.lvds_chip_name
)) {
2138 viaparinfo
->chip_info
->lvds_chip_info
.output_interface
=
2140 viaparinfo
->chip_info
->lvds_chip_info2
.
2146 DEBUG_MSG(KERN_INFO
"LVDS Chip = %d\n",
2147 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
);
2148 DEBUG_MSG(KERN_INFO
"LVDS1 output_interface = %d\n",
2149 viaparinfo
->chip_info
->lvds_chip_info
.output_interface
);
2150 DEBUG_MSG(KERN_INFO
"LVDS2 output_interface = %d\n",
2151 viaparinfo
->chip_info
->lvds_chip_info
.output_interface
);
2154 void viafb_init_dac(int set_iga
)
2159 if (set_iga
== IGA1
) {
2160 /* access Primary Display's LUT */
2161 viafb_write_reg_mask(SR1A
, VIASR
, 0x00, BIT0
);
2163 viafb_write_reg_mask(SR1B
, VIASR
, 0x00, BIT7
+ BIT6
);
2164 for (i
= 0; i
< 256; i
++) {
2165 write_dac_reg(i
, palLUT_table
[i
].red
,
2166 palLUT_table
[i
].green
,
2167 palLUT_table
[i
].blue
);
2170 viafb_write_reg_mask(SR1B
, VIASR
, 0xC0, BIT7
+ BIT6
);
2172 tmp
= viafb_read_reg(VIACR
, CR6A
);
2173 /* access Secondary Display's LUT */
2174 viafb_write_reg_mask(CR6A
, VIACR
, 0x40, BIT6
);
2175 viafb_write_reg_mask(SR1A
, VIASR
, 0x01, BIT0
);
2176 for (i
= 0; i
< 256; i
++) {
2177 write_dac_reg(i
, palLUT_table
[i
].red
,
2178 palLUT_table
[i
].green
,
2179 palLUT_table
[i
].blue
);
2181 /* set IGA1 DAC for default */
2182 viafb_write_reg_mask(SR1A
, VIASR
, 0x00, BIT0
);
2183 viafb_write_reg(CR6A
, VIACR
, tmp
);
2187 static void device_screen_off(void)
2189 /* turn off CRT screen (IGA1) */
2190 viafb_write_reg_mask(SR01
, VIASR
, 0x20, BIT5
);
2193 static void device_screen_on(void)
2195 /* turn on CRT screen (IGA1) */
2196 viafb_write_reg_mask(SR01
, VIASR
, 0x00, BIT5
);
2199 static void set_display_channel(void)
2201 /*If viafb_LCD2_ON, on cx700, internal lvds's information
2202 is keeped on lvds_setting_info2 */
2203 if (viafb_LCD2_ON
&&
2204 viaparinfo
->lvds_setting_info2
->device_lcd_dualedge
) {
2205 /* For dual channel LCD: */
2206 /* Set to Dual LVDS channel. */
2207 viafb_write_reg_mask(CRD2
, VIACR
, 0x20, BIT4
+ BIT5
);
2208 } else if (viafb_LCD_ON
&& viafb_DVI_ON
) {
2210 /* Set to LVDS1 + TMDS channel. */
2211 viafb_write_reg_mask(CRD2
, VIACR
, 0x10, BIT4
+ BIT5
);
2212 } else if (viafb_DVI_ON
) {
2213 /* Set to single TMDS channel. */
2214 viafb_write_reg_mask(CRD2
, VIACR
, 0x30, BIT4
+ BIT5
);
2215 } else if (viafb_LCD_ON
) {
2216 if (viaparinfo
->lvds_setting_info
->device_lcd_dualedge
) {
2217 /* For dual channel LCD: */
2218 /* Set to Dual LVDS channel. */
2219 viafb_write_reg_mask(CRD2
, VIACR
, 0x20, BIT4
+ BIT5
);
2221 /* Set to LVDS0 + LVDS1 channel. */
2222 viafb_write_reg_mask(CRD2
, VIACR
, 0x00, BIT4
+ BIT5
);
2227 int viafb_setmode(int vmode_index
, int hor_res
, int ver_res
, int video_bpp
,
2228 int vmode_index1
, int hor_res1
, int ver_res1
, int video_bpp1
)
2232 u8 value
, index
, mask
;
2233 struct VideoModeTable
*vmode_tbl
;
2234 struct crt_mode_table
*crt_timing
;
2235 struct VideoModeTable
*vmode_tbl1
= NULL
;
2236 struct crt_mode_table
*crt_timing1
= NULL
;
2238 DEBUG_MSG(KERN_INFO
"Set Mode!!\n");
2240 "vmode_index=%d hor_res=%d ver_res=%d video_bpp=%d\n",
2241 vmode_index
, hor_res
, ver_res
, video_bpp
);
2243 device_screen_off();
2244 vmode_tbl
= &CLE266Modes
[search_mode_setting(vmode_index
)];
2245 crt_timing
= vmode_tbl
->crtc
;
2247 if (viafb_SAMM_ON
== 1) {
2248 vmode_tbl1
= &CLE266Modes
[search_mode_setting(vmode_index1
)];
2249 crt_timing1
= vmode_tbl1
->crtc
;
2255 /* Write Common Setting for Video Mode */
2256 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
2257 case UNICHROME_CLE266
:
2258 viafb_write_regx(CLE266_ModeXregs
, NUM_TOTAL_CLE266_ModeXregs
);
2261 case UNICHROME_K400
:
2262 viafb_write_regx(KM400_ModeXregs
, NUM_TOTAL_KM400_ModeXregs
);
2265 case UNICHROME_K800
:
2266 case UNICHROME_PM800
:
2267 viafb_write_regx(CN400_ModeXregs
, NUM_TOTAL_CN400_ModeXregs
);
2270 case UNICHROME_CN700
:
2271 case UNICHROME_K8M890
:
2272 case UNICHROME_P4M890
:
2273 case UNICHROME_P4M900
:
2274 viafb_write_regx(CN700_ModeXregs
, NUM_TOTAL_CN700_ModeXregs
);
2277 case UNICHROME_CX700
:
2278 case UNICHROME_VX800
:
2279 viafb_write_regx(CX700_ModeXregs
, NUM_TOTAL_CX700_ModeXregs
);
2282 case UNICHROME_VX855
:
2283 viafb_write_regx(VX855_ModeXregs
, NUM_TOTAL_VX855_ModeXregs
);
2289 /* Fill VPIT Parameters */
2290 /* Write Misc Register */
2291 outb(VPIT
.Misc
, VIAWMisc
);
2293 /* Write Sequencer */
2294 for (i
= 1; i
<= StdSR
; i
++) {
2296 outb(VPIT
.SR
[i
- 1], VIASR
+ 1);
2299 viafb_set_primary_address(0);
2300 viafb_set_secondary_address(viafb_SAMM_ON
? viafb_second_offset
: 0);
2301 viafb_set_iga_path();
2304 viafb_fill_crtc_timing(crt_timing
, vmode_index
, video_bpp
/ 8, IGA1
);
2306 /* Write Graphic Controller */
2307 for (i
= 0; i
< StdGR
; i
++) {
2309 outb(VPIT
.GR
[i
], VIAGR
+ 1);
2312 /* Write Attribute Controller */
2313 for (i
= 0; i
< StdAR
; i
++) {
2316 outb(VPIT
.AR
[i
], VIAAR
);
2322 /* Update Patch Register */
2324 if ((viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
)
2325 || (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K400
)) {
2326 for (i
= 0; i
< NUM_TOTAL_PATCH_MODE
; i
++) {
2327 if (res_patch_table
[i
].mode_index
== vmode_index
) {
2329 j
< res_patch_table
[i
].table_length
; j
++) {
2332 io_reg_table
[j
].index
;
2335 io_reg_table
[j
].port
;
2338 io_reg_table
[j
].value
;
2341 io_reg_table
[j
].mask
;
2342 viafb_write_reg_mask(index
, port
, value
,
2349 if (viafb_SAMM_ON
== 1) {
2350 if ((viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
)
2351 || (viaparinfo
->chip_info
->gfx_chip_name
==
2353 for (i
= 0; i
< NUM_TOTAL_PATCH_MODE
; i
++) {
2354 if (res_patch_table
[i
].mode_index
==
2359 table_length
; j
++) {
2362 io_reg_table
[j
].index
;
2365 io_reg_table
[j
].port
;
2368 io_reg_table
[j
].value
;
2371 io_reg_table
[j
].mask
;
2372 viafb_write_reg_mask(index
,
2380 viafb_set_primary_pitch(viafbinfo
->fix
.line_length
);
2381 viafb_set_secondary_pitch(viafb_dual_fb
? viafbinfo1
->fix
.line_length
2382 : viafbinfo
->fix
.line_length
);
2383 /* Update Refresh Rate Setting */
2385 /* Clear On Screen */
2389 if (viafb_SAMM_ON
&& (viaparinfo
->crt_setting_info
->iga_path
==
2391 viafb_fill_crtc_timing(crt_timing1
, vmode_index1
,
2393 viaparinfo
->crt_setting_info
->iga_path
);
2395 viafb_fill_crtc_timing(crt_timing
, vmode_index
,
2397 viaparinfo
->crt_setting_info
->iga_path
);
2400 set_crt_output_path(viaparinfo
->crt_setting_info
->iga_path
);
2402 /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
2403 to 8 alignment (1368),there is several pixels (2 pixels)
2404 on right side of screen. */
2407 viafb_write_reg(CR02
, VIACR
,
2408 viafb_read_reg(VIACR
, CR02
) - 1);
2414 if (viafb_SAMM_ON
&&
2415 (viaparinfo
->tmds_setting_info
->iga_path
== IGA2
)) {
2416 viafb_dvi_set_mode(viafb_get_mode_index
2417 (viaparinfo
->tmds_setting_info
->h_active
,
2418 viaparinfo
->tmds_setting_info
->
2420 video_bpp1
, viaparinfo
->
2421 tmds_setting_info
->iga_path
);
2423 viafb_dvi_set_mode(viafb_get_mode_index
2424 (viaparinfo
->tmds_setting_info
->h_active
,
2426 tmds_setting_info
->v_active
),
2427 video_bpp
, viaparinfo
->
2428 tmds_setting_info
->iga_path
);
2433 if (viafb_SAMM_ON
&&
2434 (viaparinfo
->lvds_setting_info
->iga_path
== IGA2
)) {
2435 viaparinfo
->lvds_setting_info
->bpp
= video_bpp1
;
2436 viafb_lcd_set_mode(crt_timing1
, viaparinfo
->
2438 &viaparinfo
->chip_info
->lvds_chip_info
);
2440 /* IGA1 doesn't have LCD scaling, so set it center. */
2441 if (viaparinfo
->lvds_setting_info
->iga_path
== IGA1
) {
2442 viaparinfo
->lvds_setting_info
->display_method
=
2445 viaparinfo
->lvds_setting_info
->bpp
= video_bpp
;
2446 viafb_lcd_set_mode(crt_timing
, viaparinfo
->
2448 &viaparinfo
->chip_info
->lvds_chip_info
);
2451 if (viafb_LCD2_ON
) {
2452 if (viafb_SAMM_ON
&&
2453 (viaparinfo
->lvds_setting_info2
->iga_path
== IGA2
)) {
2454 viaparinfo
->lvds_setting_info2
->bpp
= video_bpp1
;
2455 viafb_lcd_set_mode(crt_timing1
, viaparinfo
->
2457 &viaparinfo
->chip_info
->lvds_chip_info2
);
2459 /* IGA1 doesn't have LCD scaling, so set it center. */
2460 if (viaparinfo
->lvds_setting_info2
->iga_path
== IGA1
) {
2461 viaparinfo
->lvds_setting_info2
->display_method
=
2464 viaparinfo
->lvds_setting_info2
->bpp
= video_bpp
;
2465 viafb_lcd_set_mode(crt_timing
, viaparinfo
->
2467 &viaparinfo
->chip_info
->lvds_chip_info2
);
2471 if ((viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
)
2472 && (viafb_LCD_ON
|| viafb_DVI_ON
))
2473 set_display_channel();
2475 /* If set mode normally, save resolution information for hot-plug . */
2476 if (!viafb_hotplug
) {
2477 viafb_hotplug_Xres
= hor_res
;
2478 viafb_hotplug_Yres
= ver_res
;
2479 viafb_hotplug_bpp
= video_bpp
;
2480 viafb_hotplug_refresh
= viafb_refresh
;
2483 viafb_DeviceStatus
= DVI_Device
;
2485 viafb_DeviceStatus
= CRT_Device
;
2489 if (viafb_SAMM_ON
== 1)
2490 viafb_write_reg_mask(CR6A
, VIACR
, 0xC0, BIT6
+ BIT7
);
2496 int viafb_get_pixclock(int hres
, int vres
, int vmode_refresh
)
2500 for (i
= 0; i
< NUM_TOTAL_RES_MAP_REFRESH
; i
++) {
2501 if ((hres
== res_map_refresh_tbl
[i
].hres
)
2502 && (vres
== res_map_refresh_tbl
[i
].vres
)
2503 && (vmode_refresh
== res_map_refresh_tbl
[i
].vmode_refresh
))
2504 return res_map_refresh_tbl
[i
].pixclock
;
2506 return RES_640X480_60HZ_PIXCLOCK
;
2510 int viafb_get_refresh(int hres
, int vres
, u32 long_refresh
)
2512 #define REFRESH_TOLERANCE 3
2513 int i
, nearest
= -1, diff
= REFRESH_TOLERANCE
;
2514 for (i
= 0; i
< NUM_TOTAL_RES_MAP_REFRESH
; i
++) {
2515 if ((hres
== res_map_refresh_tbl
[i
].hres
)
2516 && (vres
== res_map_refresh_tbl
[i
].vres
)
2517 && (diff
> (abs(long_refresh
-
2518 res_map_refresh_tbl
[i
].vmode_refresh
)))) {
2519 diff
= abs(long_refresh
- res_map_refresh_tbl
[i
].
2524 #undef REFRESH_TOLERANCE
2526 return res_map_refresh_tbl
[nearest
].vmode_refresh
;
2530 static void device_off(void)
2532 viafb_crt_disable();
2533 viafb_dvi_disable();
2534 viafb_lcd_disable();
2537 static void device_on(void)
2539 if (viafb_CRT_ON
== 1)
2541 if (viafb_DVI_ON
== 1)
2543 if (viafb_LCD_ON
== 1)
2547 void viafb_crt_disable(void)
2549 viafb_write_reg_mask(CR36
, VIACR
, BIT5
+ BIT4
, BIT5
+ BIT4
);
2552 void viafb_crt_enable(void)
2554 viafb_write_reg_mask(CR36
, VIACR
, 0x0, BIT5
+ BIT4
);
2557 void viafb_get_mmio_info(unsigned long *mmio_base
, u32
*mmio_len
)
2559 struct pci_dev
*pdev
= NULL
;
2563 for (i
= 0; pciidlist
[i
].vendor
!= 0; i
++)
2564 if (viaparinfo
->chip_info
->gfx_chip_name
==
2565 pciidlist
[i
].chip_index
)
2568 if (!pciidlist
[i
].vendor
)
2571 vendor
= pciidlist
[i
].vendor
;
2572 device
= pciidlist
[i
].device
;
2574 pdev
= pci_get_device(vendor
, device
, NULL
);
2582 *mmio_base
= pci_resource_start(pdev
, 1);
2583 *mmio_len
= pci_resource_len(pdev
, 1);
2588 static void enable_second_display_channel(void)
2590 /* to enable second display channel. */
2591 viafb_write_reg_mask(CR6A
, VIACR
, 0x00, BIT6
);
2592 viafb_write_reg_mask(CR6A
, VIACR
, BIT7
, BIT7
);
2593 viafb_write_reg_mask(CR6A
, VIACR
, BIT6
, BIT6
);
2596 static void disable_second_display_channel(void)
2598 /* to disable second display channel. */
2599 viafb_write_reg_mask(CR6A
, VIACR
, 0x00, BIT6
);
2600 viafb_write_reg_mask(CR6A
, VIACR
, 0x00, BIT7
);
2601 viafb_write_reg_mask(CR6A
, VIACR
, BIT6
, BIT6
);
2604 void viafb_get_fb_info(unsigned int *fb_base
, unsigned int *fb_len
)
2606 struct pci_dev
*pdev
= NULL
;
2610 for (i
= 0; pciidlist
[i
].vendor
!= 0; i
++)
2611 if (viaparinfo
->chip_info
->gfx_chip_name
==
2612 pciidlist
[i
].chip_index
)
2615 if (!pciidlist
[i
].vendor
)
2618 vendor
= pciidlist
[i
].vendor
;
2619 device
= pciidlist
[i
].device
;
2621 pdev
= pci_get_device(vendor
, device
, NULL
);
2624 *fb_base
= viafb_read_reg(VIASR
, SR30
) << 24;
2625 *fb_len
= viafb_get_memsize();
2626 DEBUG_MSG(KERN_INFO
"Get FB info from SR30!\n");
2627 DEBUG_MSG(KERN_INFO
"fb_base = %08x\n", *fb_base
);
2628 DEBUG_MSG(KERN_INFO
"fb_len = %08x\n", *fb_len
);
2632 *fb_base
= (unsigned int)pci_resource_start(pdev
, 0);
2633 *fb_len
= get_fb_size_from_pci();
2634 DEBUG_MSG(KERN_INFO
"Get FB info from PCI system!\n");
2635 DEBUG_MSG(KERN_INFO
"fb_base = %08x\n", *fb_base
);
2636 DEBUG_MSG(KERN_INFO
"fb_len = %08x\n", *fb_len
);
2641 static int get_fb_size_from_pci(void)
2643 unsigned long configid
, deviceid
, FBSize
= 0;
2645 int DeviceFound
= false;
2647 for (configid
= 0x80000000; configid
< 0x80010800; configid
+= 0x100) {
2648 outl(configid
, (unsigned long)0xCF8);
2649 deviceid
= (inl((unsigned long)0xCFC) >> 16) & 0xffff;
2654 outl(configid
+ 0xE0, (unsigned long)0xCF8);
2655 FBSize
= inl((unsigned long)0xCFC);
2656 DeviceFound
= true; /* Found device id */
2659 case CN400_FUNCTION3
:
2660 case CN700_FUNCTION3
:
2661 case CX700_FUNCTION3
:
2662 case KM800_FUNCTION3
:
2663 case KM890_FUNCTION3
:
2664 case P4M890_FUNCTION3
:
2665 case P4M900_FUNCTION3
:
2666 case VX800_FUNCTION3
:
2667 case VX855_FUNCTION3
:
2668 /*case CN750_FUNCTION3: */
2669 outl(configid
+ 0xA0, (unsigned long)0xCF8);
2670 FBSize
= inl((unsigned long)0xCFC);
2671 DeviceFound
= true; /* Found device id */
2682 DEBUG_MSG(KERN_INFO
"Device ID = %lx\n", deviceid
);
2684 FBSize
= FBSize
& 0x00007000;
2685 DEBUG_MSG(KERN_INFO
"FB Size = %x\n", FBSize
);
2687 if (viaparinfo
->chip_info
->gfx_chip_name
< UNICHROME_CX700
) {
2690 VideoMemSize
= (16 << 20); /*16M */
2694 VideoMemSize
= (32 << 20); /*32M */
2698 VideoMemSize
= (64 << 20); /*64M */
2702 VideoMemSize
= (32 << 20); /*32M */
2708 VideoMemSize
= (8 << 20); /*8M */
2712 VideoMemSize
= (16 << 20); /*16M */
2716 VideoMemSize
= (32 << 20); /*32M */
2720 VideoMemSize
= (64 << 20); /*64M */
2724 VideoMemSize
= (128 << 20); /*128M */
2728 VideoMemSize
= (256 << 20); /*256M */
2731 case 0x00007000: /* Only on VX855/875 */
2732 VideoMemSize
= (512 << 20); /*512M */
2736 VideoMemSize
= (32 << 20); /*32M */
2741 return VideoMemSize
;
2744 void viafb_set_dpa_gfx(int output_interface
, struct GFX_DPA_SETTING\
2747 switch (output_interface
) {
2748 case INTERFACE_DVP0
:
2750 /* DVP0 Clock Polarity and Adjust: */
2751 viafb_write_reg_mask(CR96
, VIACR
,
2752 p_gfx_dpa_setting
->DVP0
, 0x0F);
2754 /* DVP0 Clock and Data Pads Driving: */
2755 viafb_write_reg_mask(SR1E
, VIASR
,
2756 p_gfx_dpa_setting
->DVP0ClockDri_S
, BIT2
);
2757 viafb_write_reg_mask(SR2A
, VIASR
,
2758 p_gfx_dpa_setting
->DVP0ClockDri_S1
,
2760 viafb_write_reg_mask(SR1B
, VIASR
,
2761 p_gfx_dpa_setting
->DVP0DataDri_S
, BIT1
);
2762 viafb_write_reg_mask(SR2A
, VIASR
,
2763 p_gfx_dpa_setting
->DVP0DataDri_S1
, BIT5
);
2767 case INTERFACE_DVP1
:
2769 /* DVP1 Clock Polarity and Adjust: */
2770 viafb_write_reg_mask(CR9B
, VIACR
,
2771 p_gfx_dpa_setting
->DVP1
, 0x0F);
2773 /* DVP1 Clock and Data Pads Driving: */
2774 viafb_write_reg_mask(SR65
, VIASR
,
2775 p_gfx_dpa_setting
->DVP1Driving
, 0x0F);
2779 case INTERFACE_DFP_HIGH
:
2781 viafb_write_reg_mask(CR97
, VIACR
,
2782 p_gfx_dpa_setting
->DFPHigh
, 0x0F);
2786 case INTERFACE_DFP_LOW
:
2788 viafb_write_reg_mask(CR99
, VIACR
,
2789 p_gfx_dpa_setting
->DFPLow
, 0x0F);
2795 viafb_write_reg_mask(CR97
, VIACR
,
2796 p_gfx_dpa_setting
->DFPHigh
, 0x0F);
2797 viafb_write_reg_mask(CR99
, VIACR
,
2798 p_gfx_dpa_setting
->DFPLow
, 0x0F);
2804 /*According var's xres, yres fill var's other timing information*/
2805 void viafb_fill_var_timing_info(struct fb_var_screeninfo
*var
, int refresh
,
2808 struct VideoModeTable
*vmode_tbl
= NULL
;
2809 struct crt_mode_table
*crt_timing
= NULL
;
2810 struct display_timing crt_reg
;
2811 int i
= 0, index
= 0;
2812 vmode_tbl
= &CLE266Modes
[search_mode_setting(mode_index
)];
2813 crt_timing
= vmode_tbl
->crtc
;
2814 for (i
= 0; i
< vmode_tbl
->mode_array
; i
++) {
2816 if (crt_timing
[i
].refresh_rate
== refresh
)
2820 crt_reg
= crt_timing
[index
].crtc
;
2821 switch (var
->bits_per_pixel
) {
2823 var
->red
.offset
= 0;
2824 var
->green
.offset
= 0;
2825 var
->blue
.offset
= 0;
2826 var
->red
.length
= 6;
2827 var
->green
.length
= 6;
2828 var
->blue
.length
= 6;
2831 var
->red
.offset
= 11;
2832 var
->green
.offset
= 5;
2833 var
->blue
.offset
= 0;
2834 var
->red
.length
= 5;
2835 var
->green
.length
= 6;
2836 var
->blue
.length
= 5;
2839 var
->red
.offset
= 16;
2840 var
->green
.offset
= 8;
2841 var
->blue
.offset
= 0;
2842 var
->red
.length
= 8;
2843 var
->green
.length
= 8;
2844 var
->blue
.length
= 8;
2847 /* never happed, put here to keep consistent */
2851 var
->pixclock
= viafb_get_pixclock(var
->xres
, var
->yres
, refresh
);
2853 crt_reg
.hor_total
- (crt_reg
.hor_sync_start
+ crt_reg
.hor_sync_end
);
2854 var
->right_margin
= crt_reg
.hor_sync_start
- crt_reg
.hor_addr
;
2855 var
->hsync_len
= crt_reg
.hor_sync_end
;
2857 crt_reg
.ver_total
- (crt_reg
.ver_sync_start
+ crt_reg
.ver_sync_end
);
2858 var
->lower_margin
= crt_reg
.ver_sync_start
- crt_reg
.ver_addr
;
2859 var
->vsync_len
= crt_reg
.ver_sync_end
;