xref: /openbmc/linux/drivers/video/fbdev/via/viamode.c (revision 6d99a79c)
1 /*
2  * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3  * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4 
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.
9 
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
14  * for more details.
15 
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
18  * Foundation, Inc.,
19  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 #include <linux/via-core.h>
23 #include "global.h"
24 
25 struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
26 {VIASR, SR15, 0x02, 0x02},
27 {VIASR, SR16, 0xBF, 0x08},
28 {VIASR, SR17, 0xFF, 0x1F},
29 {VIASR, SR18, 0xFF, 0x4E},
30 {VIASR, SR1A, 0xFB, 0x08},
31 {VIASR, SR1E, 0x0F, 0x01},
32 {VIASR, SR2A, 0xFF, 0x00},
33 {VIACR, CR32, 0xFF, 0x00},
34 {VIACR, CR33, 0xFF, 0x00},
35 {VIACR, CR35, 0xFF, 0x00},
36 {VIACR, CR36, 0x08, 0x00},
37 {VIACR, CR69, 0xFF, 0x00},
38 {VIACR, CR6A, 0xFF, 0x40},
39 {VIACR, CR6B, 0xFF, 0x00},
40 {VIACR, CR88, 0xFF, 0x40},	/* LCD Panel Type                      */
41 {VIACR, CR89, 0xFF, 0x00},	/* LCD Timing Control 0                */
42 {VIACR, CR8A, 0xFF, 0x88},	/* LCD Timing Control 1                */
43 {VIACR, CR8B, 0xFF, 0x69},	/* LCD Power Sequence Control 0        */
44 {VIACR, CR8C, 0xFF, 0x57},	/* LCD Power Sequence Control 1        */
45 {VIACR, CR8D, 0xFF, 0x00},	/* LCD Power Sequence Control 2        */
46 {VIACR, CR8E, 0xFF, 0x7B},	/* LCD Power Sequence Control 3        */
47 {VIACR, CR8F, 0xFF, 0x03},	/* LCD Power Sequence Control 4        */
48 {VIACR, CR90, 0xFF, 0x30},	/* LCD Power Sequence Control 5        */
49 {VIACR, CR91, 0xFF, 0xA0},	/* 24/12 bit LVDS Data off             */
50 {VIACR, CR96, 0xFF, 0x00},
51 {VIACR, CR97, 0xFF, 0x00},
52 {VIACR, CR99, 0xFF, 0x00},
53 {VIACR, CR9B, 0xFF, 0x00}
54 };
55 
56 /* Video Mode Table for VT3314 chipset*/
57 /* Common Setting for Video Mode */
58 struct io_reg CN700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
59 {VIASR, SR15, 0x02, 0x02},
60 {VIASR, SR16, 0xBF, 0x08},
61 {VIASR, SR17, 0xFF, 0x1F},
62 {VIASR, SR18, 0xFF, 0x4E},
63 {VIASR, SR1A, 0xFB, 0x82},
64 {VIASR, SR1B, 0xFF, 0xF0},
65 {VIASR, SR1F, 0xFF, 0x00},
66 {VIASR, SR1E, 0xFF, 0x01},
67 {VIASR, SR22, 0xFF, 0x1F},
68 {VIASR, SR2A, 0x0F, 0x00},
69 {VIASR, SR2E, 0xFF, 0xFF},
70 {VIASR, SR3F, 0xFF, 0xFF},
71 {VIASR, SR40, 0xF7, 0x00},
72 {VIASR, CR30, 0xFF, 0x04},
73 {VIACR, CR32, 0xFF, 0x00},
74 {VIACR, CR33, 0x7F, 0x00},
75 {VIACR, CR35, 0xFF, 0x00},
76 {VIACR, CR36, 0xFF, 0x31},
77 {VIACR, CR41, 0xFF, 0x80},
78 {VIACR, CR42, 0xFF, 0x00},
79 {VIACR, CR55, 0x80, 0x00},
80 {VIACR, CR5D, 0x80, 0x00},	/*Horizontal Retrace Start bit[11] should be 0*/
81 {VIACR, CR68, 0xFF, 0x67},	/* Default FIFO For IGA2 */
82 {VIACR, CR69, 0xFF, 0x00},
83 {VIACR, CR6A, 0xFD, 0x40},
84 {VIACR, CR6B, 0xFF, 0x00},
85 {VIACR, CR77, 0xFF, 0x00},	/* LCD scaling Factor */
86 {VIACR, CR78, 0xFF, 0x00},	/* LCD scaling Factor */
87 {VIACR, CR79, 0xFF, 0x00},	/* LCD scaling Factor */
88 {VIACR, CR9F, 0x03, 0x00},	/* LCD scaling Factor */
89 {VIACR, CR88, 0xFF, 0x40},	/* LCD Panel Type */
90 {VIACR, CR89, 0xFF, 0x00},	/* LCD Timing Control 0 */
91 {VIACR, CR8A, 0xFF, 0x88},	/* LCD Timing Control 1 */
92 {VIACR, CR8B, 0xFF, 0x5D},	/* LCD Power Sequence Control 0 */
93 {VIACR, CR8C, 0xFF, 0x2B},	/* LCD Power Sequence Control 1 */
94 {VIACR, CR8D, 0xFF, 0x6F},	/* LCD Power Sequence Control 2 */
95 {VIACR, CR8E, 0xFF, 0x2B},	/* LCD Power Sequence Control 3 */
96 {VIACR, CR8F, 0xFF, 0x01},	/* LCD Power Sequence Control 4 */
97 {VIACR, CR90, 0xFF, 0x01},	/* LCD Power Sequence Control 5 */
98 {VIACR, CR91, 0xFF, 0xA0},	/* 24/12 bit LVDS Data off */
99 {VIACR, CR96, 0xFF, 0x00},
100 {VIACR, CR97, 0xFF, 0x00},
101 {VIACR, CR99, 0xFF, 0x00},
102 {VIACR, CR9B, 0xFF, 0x00},
103 {VIACR, CR9D, 0xFF, 0x80},
104 {VIACR, CR9E, 0xFF, 0x80}
105 };
106 
107 struct io_reg KM400_ModeXregs[] = {
108 	{VIASR, SR10, 0xFF, 0x01},	/* Unlock Register                 */
109 	{VIASR, SR16, 0xFF, 0x08},	/* Display FIFO threshold Control  */
110 	{VIASR, SR17, 0xFF, 0x1F},	/* Display FIFO Control            */
111 	{VIASR, SR18, 0xFF, 0x4E},	/* GFX PREQ threshold              */
112 	{VIASR, SR1A, 0xFF, 0x0a},	/* GFX PREQ threshold              */
113 	{VIASR, SR1F, 0xFF, 0x00},	/* Memory Control 0                */
114 	{VIASR, SR1B, 0xFF, 0xF0},	/* Power Management Control 0      */
115 	{VIASR, SR1E, 0xFF, 0x01},	/* Power Management Control        */
116 	{VIASR, SR20, 0xFF, 0x00},	/* Sequencer Arbiter Control 0     */
117 	{VIASR, SR21, 0xFF, 0x00},	/* Sequencer Arbiter Control 1     */
118 	{VIASR, SR22, 0xFF, 0x1F},	/* Display Arbiter Control 1       */
119 	{VIASR, SR2A, 0xFF, 0x00},	/* Power Management Control 5      */
120 	{VIASR, SR2D, 0xFF, 0xFF},	/* Power Management Control 1      */
121 	{VIASR, SR2E, 0xFF, 0xFF},	/* Power Management Control 2      */
122 	{VIACR, CR33, 0xFF, 0x00},
123 	{VIACR, CR55, 0x80, 0x00},
124 	{VIACR, CR5D, 0x80, 0x00},
125 	{VIACR, CR36, 0xFF, 0x01},	/* Power Mangement 3                  */
126 	{VIACR, CR68, 0xFF, 0x67},	/* Default FIFO For IGA2              */
127 	{VIACR, CR6A, 0x20, 0x20},	/* Extended FIFO On                   */
128 	{VIACR, CR88, 0xFF, 0x40},	/* LCD Panel Type                     */
129 	{VIACR, CR89, 0xFF, 0x00},	/* LCD Timing Control 0               */
130 	{VIACR, CR8A, 0xFF, 0x88},	/* LCD Timing Control 1               */
131 	{VIACR, CR8B, 0xFF, 0x2D},	/* LCD Power Sequence Control 0       */
132 	{VIACR, CR8C, 0xFF, 0x2D},	/* LCD Power Sequence Control 1       */
133 	{VIACR, CR8D, 0xFF, 0xC8},	/* LCD Power Sequence Control 2       */
134 	{VIACR, CR8E, 0xFF, 0x36},	/* LCD Power Sequence Control 3       */
135 	{VIACR, CR8F, 0xFF, 0x00},	/* LCD Power Sequence Control 4       */
136 	{VIACR, CR90, 0xFF, 0x10},	/* LCD Power Sequence Control 5       */
137 	{VIACR, CR91, 0xFF, 0xA0},	/* 24/12 bit LVDS Data off            */
138 	{VIACR, CR96, 0xFF, 0x03},	/* DVP0        ; DVP0 Clock Skew */
139 	{VIACR, CR97, 0xFF, 0x03},	/* DFP high    ; DFPH Clock Skew */
140 	{VIACR, CR99, 0xFF, 0x03},	/* DFP low           ; DFPL Clock Skew*/
141 	{VIACR, CR9B, 0xFF, 0x07}	/* DVI on DVP1       ; DVP1 Clock Skew*/
142 };
143 
144 /* For VT3324: Common Setting for Video Mode */
145 struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
146 {VIASR, SR15, 0x02, 0x02},
147 {VIASR, SR16, 0xBF, 0x08},
148 {VIASR, SR17, 0xFF, 0x1F},
149 {VIASR, SR18, 0xFF, 0x4E},
150 {VIASR, SR1A, 0xFB, 0x08},
151 {VIASR, SR1B, 0xFF, 0xF0},
152 {VIASR, SR1E, 0xFF, 0x01},
153 {VIASR, SR2A, 0xFF, 0x00},
154 {VIASR, SR2D, 0xC0, 0xC0},	/* delayed E3_ECK */
155 {VIACR, CR32, 0xFF, 0x00},
156 {VIACR, CR33, 0xFF, 0x00},
157 {VIACR, CR35, 0xFF, 0x00},
158 {VIACR, CR36, 0x08, 0x00},
159 {VIACR, CR47, 0xC8, 0x00},	/* Clear VCK Plus. */
160 {VIACR, CR69, 0xFF, 0x00},
161 {VIACR, CR6A, 0xFF, 0x40},
162 {VIACR, CR6B, 0xFF, 0x00},
163 {VIACR, CR88, 0xFF, 0x40},	/* LCD Panel Type                      */
164 {VIACR, CR89, 0xFF, 0x00},	/* LCD Timing Control 0                */
165 {VIACR, CR8A, 0xFF, 0x88},	/* LCD Timing Control 1                */
166 {VIACR, CRD4, 0xFF, 0x81},	/* Second power sequence control       */
167 {VIACR, CR8B, 0xFF, 0x5D},	/* LCD Power Sequence Control 0        */
168 {VIACR, CR8C, 0xFF, 0x2B},	/* LCD Power Sequence Control 1        */
169 {VIACR, CR8D, 0xFF, 0x6F},	/* LCD Power Sequence Control 2        */
170 {VIACR, CR8E, 0xFF, 0x2B},	/* LCD Power Sequence Control 3        */
171 {VIACR, CR8F, 0xFF, 0x01},	/* LCD Power Sequence Control 4        */
172 {VIACR, CR90, 0xFF, 0x01},	/* LCD Power Sequence Control 5        */
173 {VIACR, CR91, 0xFF, 0x80},	/* 24/12 bit LVDS Data off             */
174 {VIACR, CR96, 0xFF, 0x00},
175 {VIACR, CR97, 0xFF, 0x00},
176 {VIACR, CR99, 0xFF, 0x00},
177 {VIACR, CR9B, 0xFF, 0x00}
178 };
179 
180 struct io_reg VX855_ModeXregs[] = {
181 {VIASR, SR10, 0xFF, 0x01},
182 {VIASR, SR15, 0x02, 0x02},
183 {VIASR, SR16, 0xBF, 0x08},
184 {VIASR, SR17, 0xFF, 0x1F},
185 {VIASR, SR18, 0xFF, 0x4E},
186 {VIASR, SR1A, 0xFB, 0x08},
187 {VIASR, SR1B, 0xFF, 0xF0},
188 {VIASR, SR1E, 0x07, 0x01},
189 {VIASR, SR2A, 0xF0, 0x00},
190 {VIASR, SR58, 0xFF, 0x00},
191 {VIASR, SR59, 0xFF, 0x00},
192 {VIASR, SR2D, 0xC0, 0xC0},	/* delayed E3_ECK */
193 {VIACR, CR32, 0xFF, 0x00},
194 {VIACR, CR33, 0x7F, 0x00},
195 {VIACR, CR35, 0xFF, 0x00},
196 {VIACR, CR36, 0x08, 0x00},
197 {VIACR, CR69, 0xFF, 0x00},
198 {VIACR, CR6A, 0xFD, 0x60},
199 {VIACR, CR6B, 0xFF, 0x00},
200 {VIACR, CR88, 0xFF, 0x40},          /* LCD Panel Type                      */
201 {VIACR, CR89, 0xFF, 0x00},          /* LCD Timing Control 0                */
202 {VIACR, CR8A, 0xFF, 0x88},          /* LCD Timing Control 1                */
203 {VIACR, CRD4, 0xFF, 0x81},          /* Second power sequence control       */
204 {VIACR, CR91, 0xFF, 0x80},          /* 24/12 bit LVDS Data off             */
205 {VIACR, CR96, 0xFF, 0x00},
206 {VIACR, CR97, 0xFF, 0x00},
207 {VIACR, CR99, 0xFF, 0x00},
208 {VIACR, CR9B, 0xFF, 0x00},
209 {VIACR, CRD2, 0xFF, 0xFF}           /* TMDS/LVDS control register.         */
210 };
211 
212 /* Video Mode Table */
213 /* Common Setting for Video Mode */
214 struct io_reg CLE266_ModeXregs[] = { {VIASR, SR1E, 0xF0, 0x00},
215 {VIASR, SR2A, 0x0F, 0x00},
216 {VIASR, SR15, 0x02, 0x02},
217 {VIASR, SR16, 0xBF, 0x08},
218 {VIASR, SR17, 0xFF, 0x1F},
219 {VIASR, SR18, 0xFF, 0x4E},
220 {VIASR, SR1A, 0xFB, 0x08},
221 
222 {VIACR, CR32, 0xFF, 0x00},
223 {VIACR, CR35, 0xFF, 0x00},
224 {VIACR, CR36, 0x08, 0x00},
225 {VIACR, CR6A, 0xFF, 0x80},
226 {VIACR, CR6A, 0xFF, 0xC0},
227 
228 {VIACR, CR55, 0x80, 0x00},
229 {VIACR, CR5D, 0x80, 0x00},
230 
231 {VIAGR, GR20, 0xFF, 0x00},
232 {VIAGR, GR21, 0xFF, 0x00},
233 {VIAGR, GR22, 0xFF, 0x00},
234 
235 };
236 
237 /* Mode:1024X768 */
238 struct io_reg PM1024x768[] = { {VIASR, 0x16, 0xBF, 0x0C},
239 {VIASR, 0x18, 0xFF, 0x4C}
240 };
241 
242 struct patch_table res_patch_table[] = {
243 	{ARRAY_SIZE(PM1024x768), PM1024x768}
244 };
245 
246 /* struct VPITTable {
247 	unsigned char  Misc;
248 	unsigned char  SR[StdSR];
249 	unsigned char  CR[StdCR];
250 	unsigned char  GR[StdGR];
251 	unsigned char  AR[StdAR];
252  };*/
253 
254 struct VPITTable VPIT = {
255 	/* Msic */
256 	0xC7,
257 	/* Sequencer */
258 	{0x01, 0x0F, 0x00, 0x0E},
259 	/* Graphic Controller */
260 	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
261 	/* Attribute Controller */
262 	{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
263 	 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
264 	 0x01, 0x00, 0x0F, 0x00}
265 };
266 
267 /********************/
268 /* Mode Table       */
269 /********************/
270 
271 static const struct fb_videomode viafb_modes[] = {
272 	{NULL, 60, 480, 640, 40285, 72, 24, 19, 1, 48, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
273 	{NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2, 0, 0, 0},
274 	{NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, 0, 0, 0},
275 	{NULL, 85, 640, 480, 27780, 80, 56, 25, 1, 56, 3, 0, 0, 0},
276 	{NULL, 100, 640, 480, 23167, 104, 40, 25, 1, 64, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
277 	{NULL, 120, 640, 480, 19081, 104, 40, 31, 1, 64, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
278 	{NULL, 60, 720, 480, 37426, 88, 16, 13, 1, 72, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
279 	{NULL, 60, 720, 576, 30611, 96, 24, 17, 1, 72, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
280 	{NULL, 60, 800, 600, 25131, 88, 40, 23, 1, 128, 4, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0},
281 	{NULL, 75, 800, 600, 20202, 160, 16, 21, 1, 80, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0},
282 	{NULL, 85, 800, 600, 17790, 152, 32, 27, 1, 64, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0},
283 	{NULL, 100, 800, 600, 14667, 136, 48, 32, 1, 88, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
284 	{NULL, 120, 800, 600, 11911, 144, 56, 39, 1, 88, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
285 	{NULL, 60, 800, 480, 33602, 96, 24, 10, 3, 72, 7, FB_SYNC_VERT_HIGH_ACT, 0, 0},
286 	{NULL, 60, 848, 480, 31565, 104, 24, 12, 3, 80, 5, FB_SYNC_VERT_HIGH_ACT, 0, 0},
287 	{NULL, 60, 856, 480, 31517, 104, 16, 13, 1, 88, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
288 	{NULL, 60, 1024, 512, 24218, 136, 32, 15, 1, 104, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
289 	{NULL, 60, 1024, 600, 20423, 144, 40, 18, 1, 104, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
290 	{NULL, 60, 1024, 768, 15385, 160, 24, 29, 3, 136, 6, 0, 0, 0},
291 	{NULL, 75, 1024, 768, 12703, 176, 16, 28, 1, 96, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0},
292 	{NULL, 85, 1024, 768, 10581, 208, 48, 36, 1, 96, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0},
293 	{NULL, 100, 1024, 768, 8825, 184, 72, 42, 1, 112, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
294 	{NULL, 75, 1152, 864, 9259, 256, 64, 32, 1, 128, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0},
295 	{NULL, 60, 1280, 768, 12478, 200, 64, 23, 1, 136, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
296 	{NULL, 50, 1280, 768, 15342, 184, 56, 19, 1, 128, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
297 	{NULL, 60, 960, 600, 21964, 128, 32, 15, 3, 96, 6, FB_SYNC_VERT_HIGH_ACT, 0, 0},
298 	{NULL, 60, 1000, 600, 20803, 144, 40, 18, 1, 104, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
299 	{NULL, 60, 1024, 576, 21278, 144, 40, 17, 1, 104, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
300 	{NULL, 60, 1088, 612, 18825, 152, 48, 16, 3, 104, 5, FB_SYNC_VERT_HIGH_ACT, 0, 0},
301 	{NULL, 60, 1152, 720, 14974, 168, 56, 19, 3, 112, 6, FB_SYNC_VERT_HIGH_ACT, 0, 0},
302 	{NULL, 60, 1200, 720, 14248, 184, 56, 22, 1, 128, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
303 	{NULL, 49, 1200, 900, 17703, 21, 11, 1, 1, 32, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0},
304 	{NULL, 60, 1280, 600, 16259, 184, 56, 18, 1, 128, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
305 	{NULL, 60, 1280, 800, 11938, 200, 72, 22, 3, 128, 6, FB_SYNC_VERT_HIGH_ACT, 0, 0},
306 	{NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0},
307 	{NULL, 60, 1280, 1024, 9262, 248, 48, 38, 1, 112, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0},
308 	{NULL, 75, 1280, 1024, 7409, 248, 16, 38, 1, 144, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0},
309 	{NULL, 85, 1280, 1024, 6351, 224, 64, 44, 1, 160, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0},
310 	{NULL, 60, 1360, 768, 11759, 208, 72, 22, 3, 136, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0},
311 	{NULL, 60, 1368, 768, 11646, 216, 72, 23, 1, 144, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
312 	{NULL, 50, 1368, 768, 14301, 200, 56, 19, 1, 144, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
313 	{NULL, 60, 1368, 768, 11646, 216, 72, 23, 1, 144, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
314 	{NULL, 60, 1440, 900, 9372, 232, 80, 25, 3, 152, 6, FB_SYNC_VERT_HIGH_ACT, 0, 0},
315 	{NULL, 75, 1440, 900, 7311, 248, 96, 33, 3, 152, 6, FB_SYNC_VERT_HIGH_ACT, 0, 0},
316 	{NULL, 60, 1440, 1040, 7993, 248, 96, 33, 1, 152, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
317 	{NULL, 60, 1600, 900, 8449, 256, 88, 26, 3, 168, 5, FB_SYNC_VERT_HIGH_ACT, 0, 0},
318 	{NULL, 60, 1600, 1024, 7333, 272, 104, 32, 1, 168, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
319 	{NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0},
320 	{NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0},
321 	{NULL, 60, 1680, 1050, 6832, 280, 104, 30, 3, 176, 6, 0, 0, 0},
322 	{NULL, 75, 1680, 1050, 5339, 296, 120, 40, 3, 176, 6, FB_SYNC_VERT_HIGH_ACT, 0, 0},
323 	{NULL, 60, 1792, 1344, 4883, 328, 128, 46, 1, 200, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
324 	{NULL, 60, 1856, 1392, 4581, 352, 96, 43, 1, 224, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
325 	{NULL, 60, 1920, 1440, 4273, 344, 128, 56, 1, 208, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
326 	{NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
327 	{NULL, 60, 2048, 1536, 3738, 376, 152, 49, 3, 224, 4, FB_SYNC_VERT_HIGH_ACT, 0, 0},
328 	{NULL, 60, 1280, 720, 13484, 216, 112, 20, 5, 40, 5, FB_SYNC_VERT_HIGH_ACT, 0, 0},
329 	{NULL, 50, 1280, 720, 16538, 176, 48, 17, 1, 128, 3, FB_SYNC_VERT_HIGH_ACT, 0, 0},
330 	{NULL, 60, 1920, 1080, 5776, 328, 128, 32, 3, 200, 5, FB_SYNC_VERT_HIGH_ACT, 0, 0},
331 	{NULL, 60, 1920, 1200, 5164, 336, 136, 36, 3, 200, 6, FB_SYNC_VERT_HIGH_ACT, 0, 0},
332 	{NULL, 60, 1400, 1050, 8210, 232, 88, 32, 3, 144, 4, FB_SYNC_VERT_HIGH_ACT, 0, 0},
333 	{NULL, 75, 1400, 1050, 6398, 248, 104, 42, 3, 144, 4, FB_SYNC_VERT_HIGH_ACT, 0, 0} };
334 
335 static const struct fb_videomode viafb_rb_modes[] = {
336 	{NULL, 60, 1360, 768, 13879, 80, 48, 14, 3, 32, 5, FB_SYNC_HOR_HIGH_ACT, 0, 0},
337 	{NULL, 60, 1440, 900, 11249, 80, 48, 17, 3, 32, 6, FB_SYNC_HOR_HIGH_ACT, 0, 0},
338 	{NULL, 60, 1400, 1050, 9892, 80, 48, 23, 3, 32, 4, FB_SYNC_HOR_HIGH_ACT, 0, 0},
339 	{NULL, 60, 1600, 900, 10226, 80, 48, 18, 3, 32, 5, FB_SYNC_HOR_HIGH_ACT, 0, 0},
340 	{NULL, 60, 1680, 1050, 8387, 80, 48, 21, 3, 32, 6, FB_SYNC_HOR_HIGH_ACT, 0, 0},
341 	{NULL, 60, 1920, 1080, 7212, 80, 48, 23, 3, 32, 5, FB_SYNC_HOR_HIGH_ACT, 0, 0},
342 	{NULL, 60, 1920, 1200, 6488, 80, 48, 26, 3, 32, 6, FB_SYNC_HOR_HIGH_ACT, 0, 0} };
343 
344 int NUM_TOTAL_CN400_ModeXregs = ARRAY_SIZE(CN400_ModeXregs);
345 int NUM_TOTAL_CN700_ModeXregs = ARRAY_SIZE(CN700_ModeXregs);
346 int NUM_TOTAL_KM400_ModeXregs = ARRAY_SIZE(KM400_ModeXregs);
347 int NUM_TOTAL_CX700_ModeXregs = ARRAY_SIZE(CX700_ModeXregs);
348 int NUM_TOTAL_VX855_ModeXregs = ARRAY_SIZE(VX855_ModeXregs);
349 int NUM_TOTAL_CLE266_ModeXregs = ARRAY_SIZE(CLE266_ModeXregs);
350 int NUM_TOTAL_PATCH_MODE = ARRAY_SIZE(res_patch_table);
351 
352 
353 static const struct fb_videomode *get_best_mode(
354 	const struct fb_videomode *modes, int n,
355 	int hres, int vres, int refresh)
356 {
357 	const struct fb_videomode *best = NULL;
358 	int i;
359 
360 	for (i = 0; i < n; i++) {
361 		if (modes[i].xres != hres || modes[i].yres != vres)
362 			continue;
363 
364 		if (!best || abs(modes[i].refresh - refresh) <
365 			abs(best->refresh - refresh))
366 			best = &modes[i];
367 	}
368 
369 	return best;
370 }
371 
372 const struct fb_videomode *viafb_get_best_mode(int hres, int vres, int refresh)
373 {
374 	return get_best_mode(viafb_modes, ARRAY_SIZE(viafb_modes),
375 		hres, vres, refresh);
376 }
377 
378 const struct fb_videomode *viafb_get_best_rb_mode(int hres, int vres,
379 	int refresh)
380 {
381 	return get_best_mode(viafb_rb_modes, ARRAY_SIZE(viafb_rb_modes),
382 		hres, vres, refresh);
383 }
384