Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
i810_dvt.c
Go to the documentation of this file.
1 /*-*- linux-c -*-
2  * linux/drivers/video/i810_dvt.c -- Intel 810 Discrete Video Timings (Intel)
3  *
4  * Copyright (C) 2001 Antonino Daplas<[email protected]>
5  * All Rights Reserved
6  *
7  *
8  * This file is subject to the terms and conditions of the GNU General Public
9  * License. See the file COPYING in the main directory of this archive for
10  * more details.
11  */
12 
13 #include <linux/kernel.h>
14 
15 #include "i810_regs.h"
16 #include "i810.h"
17 
19  /* 640x480 @ 60Hz */
20  { 25000, 0x0013, 0x0003, 0x40, 0x5F, 0x4F, 0x50, 0x82, 0x51, 0x9D,
21  0x0B, 0x10, 0x40, 0xE9, 0x0B, 0xDF, 0x50, 0xE7, 0x04, 0x02,
22  0x01, 0x01, 0x01, 0x00, 0x01, 0x22002000, 0x22004000, 0x22006000,
23  0x22002000, 0x22004000, 0x22006000, 0xC0 },
24 
25  /* 640x480 @ 70Hz */
26  { 28000, 0x0053, 0x0010, 0x40, 0x61, 0x4F, 0x4F, 0x85, 0x52, 0x9A,
27  0xF2, 0x10, 0x40, 0xE0, 0x03, 0xDF, 0x50, 0xDF, 0xF3, 0x01,
28  0x01, 0x01, 0x01, 0x00, 0x01, 0x22002000, 0x22004000, 0x22005000,
29  0x22002000, 0x22004000, 0x22005000, 0xC0 },
30 
31  /* 640x480 @ 72Hz */
32  { 31000, 0x0013, 0x0002, 0x40, 0x63, 0x4F, 0x4F, 0x87, 0x52, 0x97,
33  0x06, 0x0F, 0x40, 0xE8, 0x0B, 0xDF, 0x50, 0xDF, 0x07, 0x02,
34  0x01, 0x01, 0x01, 0x00, 0x01, 0x22003000, 0x22005000, 0x22007000,
35  0x22003000, 0x22005000, 0x22007000, 0xC0 },
36 
37  /* 640x480 @ 75Hz */
38  { 31000, 0x0013, 0x0002, 0x40, 0x64, 0x4F, 0x4F, 0x88, 0x51, 0x99,
39  0xF2, 0x10, 0x40, 0xE0, 0x03, 0xDF, 0x50, 0xDF, 0xF3, 0x01,
40  0x01, 0x01, 0x01, 0x00, 0x01, 0x22003000, 0x22005000, 0x22007000,
41  0x22003000, 0x22005000, 0x22007000, 0xC0 },
42 
43  /* 640x480 @ 85Hz */
44  { 36000, 0x0010, 0x0001, 0x40, 0x63, 0x4F, 0x4F, 0x87, 0x56, 0x9D,
45  0xFB, 0x10, 0x40, 0xE0, 0x03, 0xDF, 0x50, 0xDF, 0xFC, 0x01,
46  0x01, 0x01, 0x01, 0x00, 0x01, 0x22003000, 0x22005000, 0x22107000,
47  0x22003000, 0x22005000, 0x22107000, 0xC0 },
48 
49  /* 800x600 @ 56Hz */
50  { 36000, 0x0010, 0x0001, 0x40, 0x7B, 0x63, 0x63, 0x9F, 0x66, 0x8F,
51  0x6F, 0x10, 0x40, 0x58, 0x0A, 0x57, 0xC8, 0x57, 0x70, 0x02,
52  0x02, 0x02, 0x02, 0x00, 0x01, 0x22003000, 0x22005000, 0x22107000,
53  0x22003000, 0x22005000, 0x22107000, 0x00 },
54 
55  /* 800x600 @ 60Hz */
56  { 40000, 0x0008, 0x0001, 0x30, 0x7F, 0x63, 0x63, 0x83, 0x68, 0x18,
57  0x72, 0x10, 0x40, 0x58, 0x0C, 0x57, 0xC8, 0x57, 0x73, 0x02,
58  0x02, 0x02, 0x02, 0x00, 0x00, 0x22003000, 0x22006000, 0x22108000,
59  0x22003000, 0x22006000, 0x22108000, 0x00 },
60 
61  /* 800x600 @ 70Hz */
62  { 45000, 0x0054, 0x0015, 0x30, 0x7D, 0x63, 0x63, 0x81, 0x68, 0x12,
63  0x6f, 0x10, 0x40, 0x58, 0x0b, 0x57, 0x64, 0x57, 0x70, 0x02,
64  0x02, 0x02, 0x02, 0x00, 0x00, 0x22004000, 0x22007000, 0x2210A000,
65  0x22004000, 0x22007000, 0x2210A000, 0x00 },
66 
67  /* 800x600 @ 72Hz */
68  { 50000, 0x0017, 0x0004, 0x30, 0x7D, 0x63, 0x63, 0x81, 0x6A, 0x19,
69  0x98, 0x10, 0x40, 0x7C, 0x02, 0x57, 0xC8, 0x57, 0x99, 0x02,
70  0x02, 0x02, 0x02, 0x00, 0x00, 0x22004000, 0x22007000, 0x2210A000,
71  0x22004000, 0x22007000, 0x2210A000, 0x00 },
72 
73  /* 800x600 @ 75Hz */
74  { 49000, 0x001F, 0x0006, 0x30, 0x7F, 0x63, 0x63, 0x83, 0x65, 0x0F,
75  0x6F, 0x10, 0x40, 0x58, 0x0B, 0x57, 0xC8, 0x57, 0x70, 0x02,
76  0x02, 0x02, 0x02, 0x00, 0x00, 0x22004000, 0x22007000, 0x2210B000,
77  0x22004000, 0x22007000, 0x2210B000, 0x00 },
78 
79  /* 800x600 @ 85Hz */
80  { 56000, 0x0049, 0x000E, 0x30, 0x7E, 0x63, 0x63, 0x82, 0x67, 0x0F,
81  0x75, 0x10, 0x40, 0x58, 0x0B, 0x57, 0xC8, 0x57, 0x76, 0x02,
82  0x02, 0x02, 0x02, 0x00, 0x00, 0x22004000, 0x22108000, 0x2210b000,
83  0x22004000, 0x22108000, 0x2210b000, 0x00 },
84 
85  /* 1024x768 @ 60Hz */
86  { 65000, 0x003F, 0x000A, 0x30, 0xA3, 0x7F, 0x7F, 0x87, 0x83, 0x94,
87  0x24, 0x10, 0x40, 0x02, 0x08, 0xFF, 0x80, 0xFF, 0x25, 0x03,
88  0x02, 0x03, 0x02, 0x00, 0x00, 0x22005000, 0x22109000, 0x2220D000,
89  0x22005000, 0x22109000, 0x2220D000, 0xC0 },
90 
91  /* 1024x768 @ 70Hz */
92  { 75000, 0x0017, 0x0002, 0x30, 0xA1, 0x7F, 0x7F, 0x85, 0x82, 0x93,
93  0x24, 0x10, 0x40, 0x02, 0x08, 0xFF, 0x80, 0xFF, 0x25, 0x03,
94  0x02, 0x03, 0x02, 0x00, 0x00, 0x22005000, 0x2210A000, 0x2220F000,
95  0x22005000, 0x2210A000, 0x2220F000, 0xC0 },
96 
97  /* 1024x768 @ 75Hz */
98  { 78000, 0x0050, 0x0017, 0x20, 0x9F, 0x7F, 0x7F, 0x83, 0x81, 0x8D,
99  0x1E, 0x10, 0x40, 0x00, 0x03, 0xFF, 0x80, 0xFF, 0x1F, 0x03,
100  0x02, 0x03, 0x02, 0x00, 0x00, 0x22006000, 0x2210B000, 0x22210000,
101  0x22006000, 0x2210B000, 0x22210000, 0x00 },
102 
103  /* 1024x768 @ 85Hz */
104  { 94000, 0x003D, 0x000E, 0x20, 0xA7, 0x7F, 0x7F, 0x8B, 0x85, 0x91,
105  0x26, 0x10, 0x40, 0x00, 0x03, 0xFF, 0x80, 0xFF, 0x27, 0x03,
106  0x02, 0x03, 0x02, 0x00, 0x00, 0x22007000, 0x2220E000, 0x22212000,
107  0x22007000, 0x2220E000, 0x22212000, 0x00 },
108 
109  /* 1152x864 @ 60Hz */
110  { 80000, 0x0008, 0x0001, 0x20, 0xB3, 0x8F, 0x8F, 0x97, 0x93, 0x9f,
111  0x87, 0x10, 0x40, 0x60, 0x03, 0x5F, 0x90, 0x5f, 0x88, 0x03,
112  0x03, 0x03, 0x03, 0x00, 0x00, 0x2220C000, 0x22210000, 0x22415000,
113  0x2220C000, 0x22210000, 0x22415000, 0x00 },
114 
115  /* 1152x864 @ 70Hz */
116  { 96000, 0x000a, 0x0001, 0x20, 0xbb, 0x8F, 0x8F, 0x9f, 0x98, 0x87,
117  0x82, 0x10, 0x40, 0x60, 0x03, 0x5F, 0x90, 0x5F, 0x83, 0x03,
118  0x03, 0x03, 0x03, 0x00, 0x00, 0x22107000, 0x22210000, 0x22415000,
119  0x22107000, 0x22210000, 0x22415000, 0x00 },
120 
121  /* 1152x864 @ 72Hz */
122  { 99000, 0x001f, 0x0006, 0x20, 0xbb, 0x8F, 0x8F, 0x9f, 0x98, 0x87,
123  0x83, 0x10, 0x40, 0x60, 0x03, 0x5F, 0x90, 0x5F, 0x84, 0x03,
124  0x03, 0x03, 0x03, 0x00, 0x00, 0x22107000, 0x22210000, 0x22415000,
125  0x22107000, 0x22210000, 0x22415000, 0x00 },
126 
127  /* 1152x864 @ 75Hz */
128  { 108000, 0x0010, 0x0002, 0x20, 0xC3, 0x8F, 0x8F, 0x87, 0x97, 0x07,
129  0x82, 0x10, 0x40, 0x60, 0x03, 0x5F, 0x90, 0x5F, 0x83, 0x03,
130  0x03, 0x03, 0x03, 0x00, 0x01, 0x22107000, 0x22210000, 0x22415000,
131  0x22107000, 0x22210000, 0x22415000, 0x00 },
132 
133  /* 1152x864 @ 85Hz */
134  { 121000, 0x006D, 0x0014, 0x20, 0xc0, 0x8F, 0x8F, 0x84, 0x97, 0x07,
135  0x93, 0x10, 0x40, 0x60, 0x03, 0x5F, 0x90, 0x5F, 0x94, 0x03,
136  0x03, 0x03, 0x03, 0x00, 0x01, 0x2220C000, 0x22210000, 0x22415000,
137  0x2220C000, 0x22210000, 0x22415000, 0x0 },
138 
139  /* 1280x960 @ 60Hz */
140  { 108000, 0x0010, 0x0002, 0x20, 0xDC, 0x9F, 0x9F, 0x80, 0xAB, 0x99,
141  0xE6, 0x10, 0x40, 0xC0, 0x03, 0xBF, 0xA0, 0xBF, 0xE7, 0x03,
142  0x03, 0x03, 0x03, 0x00, 0x01, 0x2210A000, 0x22210000, 0x22415000,
143  0x2210A000, 0x22210000, 0x22415000, 0x00 },
144 
145  /* 1280x960 @ 75Hz */
146  { 129000, 0x0029, 0x0006, 0x20, 0xD3, 0x9F, 0x9F, 0x97, 0xaa, 0x1b,
147  0xE8, 0x10, 0x40, 0xC0, 0x03, 0xBF, 0xA0, 0xBF, 0xE9, 0x03,
148  0x03, 0x03, 0x03, 0x00, 0x01, 0x2210A000, 0x22210000, 0x2241B000,
149  0x2210A000, 0x22210000, 0x2241B000, 0x00 },
150 
151  /* 1280x960 @ 85Hz */
152  { 148000, 0x0042, 0x0009, 0x20, 0xD3, 0x9F, 0x9F, 0x97, 0xA7, 0x1B,
153  0xF1, 0x10, 0x40, 0xC0, 0x03, 0xBF, 0xA0, 0xBF, 0xF2, 0x03,
154  0x03, 0x03, 0x03, 0x00, 0x01, 0x2210A000, 0x22220000, 0x2241D000,
155  0x2210A000, 0x22220000, 0x2241D000, 0x00 },
156 
157  /* 1600x1200 @ 60Hz */
158  { 162000, 0x0019, 0x0006, 0x10, 0x09, 0xC7, 0xC7, 0x8D, 0xcf, 0x07,
159  0xE0, 0x10, 0x40, 0xB0, 0x03, 0xAF, 0xC8, 0xAF, 0xE1, 0x04,
160  0x04, 0x04, 0x04, 0x01, 0x00, 0x2210b000, 0x22416000, 0x44419000,
161  0x2210b000, 0x22416000, 0x44419000, 0x00 },
162 
163  /* 1600x1200 @ 65 Hz */
164  { 175000, 0x005d, 0x0018, 0x10, 0x09, 0xC7, 0xC7, 0x8D, 0xcf, 0x07,
165  0xE0, 0x10, 0x40, 0xB0, 0x03, 0xAF, 0xC8, 0xAF, 0xE1, 0x04,
166  0x04, 0x04, 0x04, 0x01, 0x00, 0x2210c000, 0x22416000, 0x44419000,
167  0x2210c000, 0x22416000, 0x44419000, 0x00 },
168 
169  /* 1600x1200 @ 70 Hz */
170  { 189000, 0x003D, 0x000e, 0x10, 0x09, 0xC7, 0xC7, 0x8d, 0xcf, 0x07,
171  0xE0, 0x10, 0x40, 0xb0, 0x03, 0xAF, 0xC8, 0xaf, 0xE1, 0x04,
172  0x04, 0x04, 0x04, 0x01, 0x00, 0x2220e000, 0x22416000, 0x44419000,
173  0x2220e000, 0x22416000, 0x44419000, 0x00 },
174 
175  /* 1600x1200 @ 72 Hz */
176  { 195000, 0x003f, 0x000e, 0x10, 0x0b, 0xC7, 0xC7, 0x8f, 0xd5, 0x0b,
177  0xE1, 0x10, 0x40, 0xb0, 0x03, 0xAF, 0xC8, 0xaf, 0xe2, 0x04, 0x04,
178  0x04, 0x04, 0x01, 0x00, 0x2220e000, 0x22416000, 0x44419000,
179  0x2220e000, 0x22416000, 0x44419000, 0x00 },
180 
181  /* 1600x1200 @ 75 Hz */
182  { 202000, 0x0024, 0x0007, 0x10, 0x09, 0xC7, 0xC7, 0x8d, 0xcf, 0x07,
183  0xE0, 0x10, 0x40, 0xb0, 0x03, 0xAF, 0xC8, 0xaf, 0xE1, 0x04, 0x04,
184  0x04, 0x04, 0x01, 0x00, 0x2220e000, 0x22416000, 0x44419000,
185  0x2220e000, 0x22416000, 0x44419000, 0x00 },
186 
187  /* 1600x1200 @ 85 Hz */
188  { 229000, 0x0029, 0x0007, 0x10, 0x09, 0xC7, 0xC7, 0x8d, 0xcf, 0x07,
189  0xE0, 0x10, 0x40, 0xb0, 0x03, 0xAF, 0xC8, 0xaf, 0xE1, 0x04, 0x04,
190  0x04, 0x04, 0x01, 0x00, 0x22210000, 0x22416000, 0x0,
191  0x22210000, 0x22416000, 0x0, 0x00 },
192 };
193 
194 void round_off_xres(u32 *xres)
195 {
196  if (*xres <= 640)
197  *xres = 640;
198  else if (*xres <= 800)
199  *xres = 800;
200  else if (*xres <= 1024)
201  *xres = 1024;
202  else if (*xres <= 1152)
203  *xres = 1152;
204  else if (*xres <= 1280)
205  *xres = 1280;
206  else
207  *xres = 1600;
208 }
209 
210 inline void round_off_yres(u32 *xres, u32 *yres)
211 {
212  *yres = (*xres * 3) >> 2;
213 }
214 
215 static int i810fb_find_best_mode(u32 xres, u32 yres, u32 pixclock)
216 {
217  u32 diff = 0, diff_best = 0xFFFFFFFF, i = 0, i_best = 0;
218  u8 hfl = (u8) ((xres >> 3) - 1);
219 
220  for (i = 0; i < ARRAY_SIZE(std_modes); i++) {
221  if (std_modes[i].cr01 == hfl) {
222  if (std_modes[i].pixclock <= pixclock)
223  diff = pixclock - std_modes[i].pixclock;
224  if (diff < diff_best) {
225  i_best = i;
226  diff_best = diff;
227  }
228  }
229  }
230  return i_best;
231 }
232 
234  struct i810fb_par *par, u32 xres, u32 yres)
235 {
236  u32 i_best = i810fb_find_best_mode(xres, yres, par->regs.pixclock);
237 
238  par->regs = std_modes[i_best];
239 
240  /* overlay */
241  par->ovract = ((xres + var->right_margin + var->hsync_len +
242  var->left_margin - 32) | ((xres - 32) << 16));
243 }
244 
246 {
247  u32 total, xres, yres;
248  u32 mode, pixclock;
249 
250  xres = var->xres;
251  yres = var->yres;
252 
253  pixclock = 1000000000 / var->pixclock;
254  mode = i810fb_find_best_mode(xres, yres, pixclock);
255 
256  total = (std_modes[mode].cr00 | (std_modes[mode].cr35 & 1) << 8) + 3;
257  total <<= 3;
258 
259  var->pixclock = 1000000000 / std_modes[mode].pixclock;
260  var->right_margin = (std_modes[mode].cr04 << 3) - xres;
261  var->hsync_len = ((std_modes[mode].cr05 & 0x1F) -
262  (std_modes[mode].cr04 & 0x1F)) << 3;
263  var->left_margin = (total - (xres + var->right_margin +
264  var->hsync_len));
265  var->sync = FB_SYNC_ON_GREEN;
266  if (~(std_modes[mode].msr & (1 << 6)))
267  var->sync |= FB_SYNC_HOR_HIGH_ACT;
268  if (~(std_modes[mode].msr & (1 << 7)))
269  var->sync |= FB_SYNC_VERT_HIGH_ACT;
270 
271  total = (std_modes[mode].cr06 | (std_modes[mode].cr30 & 0xF) << 8) + 2;
272  var->lower_margin = (std_modes[mode].cr10 |
273  (std_modes[mode].cr32 & 0x0F) << 8) - yres;
274  var->vsync_len = (std_modes[mode].cr11 & 0x0F) -
275  (var->lower_margin & 0x0F);
276  var->upper_margin = total - (yres + var->lower_margin + var->vsync_len);
277 }
278 
280  struct i810fb_par *par)
281 {
282  struct mode_registers *params = &par->regs;
283  u32 wmark = 0;
284 
285  if (par->mem_freq == 100) {
286  switch (var->bits_per_pixel) {
287  case 8:
288  wmark = params->bpp8_100;
289  break;
290  case 16:
291  wmark = params->bpp16_100;
292  break;
293  case 24:
294  case 32:
295  wmark = params->bpp24_100;
296  }
297  } else {
298  switch (var->bits_per_pixel) {
299  case 8:
300  wmark = params->bpp8_133;
301  break;
302  case 16:
303  wmark = params->bpp16_133;
304  break;
305  case 24:
306  case 32:
307  wmark = params->bpp24_133;
308  }
309  }
310  return wmark;
311 }
312