diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/video/i810/i810_gtf.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/video/i810/i810_gtf.c')
-rw-r--r-- | drivers/video/i810/i810_gtf.c | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/drivers/video/i810/i810_gtf.c b/drivers/video/i810/i810_gtf.c new file mode 100644 index 000000000000..64f087a4466b --- /dev/null +++ b/drivers/video/i810/i810_gtf.c | |||
@@ -0,0 +1,275 @@ | |||
1 | /*-*- linux-c -*- | ||
2 | * linux/drivers/video/i810_main.h -- Intel 810 Non-discrete Video Timings | ||
3 | * (VESA GTF) | ||
4 | * | ||
5 | * Copyright (C) 2001 Antonino Daplas<adaplas@pol.net> | ||
6 | * All Rights Reserved | ||
7 | * | ||
8 | * | ||
9 | * This file is subject to the terms and conditions of the GNU General Public | ||
10 | * License. See the file COPYING in the main directory of this archive for | ||
11 | * more details. | ||
12 | */ | ||
13 | #include <linux/kernel.h> | ||
14 | |||
15 | #include "i810_regs.h" | ||
16 | #include "i810.h" | ||
17 | |||
18 | /* | ||
19 | * FIFO and Watermark tables - based almost wholly on i810_wmark.c in | ||
20 | * XFree86 v4.03 by Precision Insight. Slightly modified for integer | ||
21 | * operation, instead of float | ||
22 | */ | ||
23 | |||
24 | struct wm_info { | ||
25 | u32 freq; | ||
26 | u32 wm; | ||
27 | }; | ||
28 | |||
29 | static struct wm_info i810_wm_8_100[] = { | ||
30 | { 15, 0x0070c000 }, { 19, 0x0070c000 }, { 25, 0x22003000 }, | ||
31 | { 28, 0x22003000 }, { 31, 0x22003000 }, { 36, 0x22007000 }, | ||
32 | { 40, 0x22007000 }, { 45, 0x22007000 }, { 49, 0x22008000 }, | ||
33 | { 50, 0x22008000 }, { 56, 0x22008000 }, { 65, 0x22008000 }, | ||
34 | { 75, 0x22008000 }, { 78, 0x22008000 }, { 80, 0x22008000 }, | ||
35 | { 94, 0x22008000 }, { 96, 0x22107000 }, { 99, 0x22107000 }, | ||
36 | { 108, 0x22107000 }, { 121, 0x22107000 }, { 128, 0x22107000 }, | ||
37 | { 132, 0x22109000 }, { 135, 0x22109000 }, { 157, 0x2210b000 }, | ||
38 | { 162, 0x2210b000 }, { 175, 0x2210b000 }, { 189, 0x2220e000 }, | ||
39 | { 195, 0x2220e000 }, { 202, 0x2220e000 }, { 204, 0x2220e000 }, | ||
40 | { 218, 0x2220f000 }, { 229, 0x22210000 }, { 234, 0x22210000 }, | ||
41 | }; | ||
42 | |||
43 | static struct wm_info i810_wm_16_100[] = { | ||
44 | { 15, 0x0070c000 }, { 19, 0x0020c000 }, { 25, 0x22006000 }, | ||
45 | { 28, 0x22006000 }, { 31, 0x22007000 }, { 36, 0x22007000 }, | ||
46 | { 40, 0x22007000 }, { 45, 0x22007000 }, { 49, 0x22009000 }, | ||
47 | { 50, 0x22009000 }, { 56, 0x22108000 }, { 65, 0x2210e000 }, | ||
48 | { 75, 0x2210e000 }, { 78, 0x2210e000 }, { 80, 0x22210000 }, | ||
49 | { 94, 0x22210000 }, { 96, 0x22210000 }, { 99, 0x22210000 }, | ||
50 | { 108, 0x22210000 }, { 121, 0x22210000 }, { 128, 0x22210000 }, | ||
51 | { 132, 0x22314000 }, { 135, 0x22314000 }, { 157, 0x22415000 }, | ||
52 | { 162, 0x22416000 }, { 175, 0x22416000 }, { 189, 0x22416000 }, | ||
53 | { 195, 0x22416000 }, { 202, 0x22416000 }, { 204, 0x22416000 }, | ||
54 | { 218, 0x22416000 }, { 229, 0x22416000 }, | ||
55 | }; | ||
56 | |||
57 | static struct wm_info i810_wm_24_100[] = { | ||
58 | { 15, 0x0020c000 }, { 19, 0x0040c000 }, { 25, 0x22009000 }, | ||
59 | { 28, 0x22009000 }, { 31, 0x2200a000 }, { 36, 0x2210c000 }, | ||
60 | { 40, 0x2210c000 }, { 45, 0x2210c000 }, { 49, 0x22111000 }, | ||
61 | { 50, 0x22111000 }, { 56, 0x22111000 }, { 65, 0x22214000 }, | ||
62 | { 75, 0x22214000 }, { 78, 0x22215000 }, { 80, 0x22216000 }, | ||
63 | { 94, 0x22218000 }, { 96, 0x22418000 }, { 99, 0x22418000 }, | ||
64 | { 108, 0x22418000 }, { 121, 0x22418000 }, { 128, 0x22419000 }, | ||
65 | { 132, 0x22519000 }, { 135, 0x4441d000 }, { 157, 0x44419000 }, | ||
66 | { 162, 0x44419000 }, { 175, 0x44419000 }, { 189, 0x44419000 }, | ||
67 | { 195, 0x44419000 }, { 202, 0x44419000 }, { 204, 0x44419000 }, | ||
68 | }; | ||
69 | |||
70 | static struct wm_info i810_wm_8_133[] = { | ||
71 | { 15, 0x0070c000 }, { 19, 0x0070c000 }, { 25, 0x22003000 }, | ||
72 | { 28, 0x22003000 }, { 31, 0x22003000 }, { 36, 0x22007000 }, | ||
73 | { 40, 0x22007000 }, { 45, 0x22007000 }, { 49, 0x22008000 }, | ||
74 | { 50, 0x22008000 }, { 56, 0x22008000 }, { 65, 0x22008000 }, | ||
75 | { 75, 0x22008000 }, { 78, 0x22008000 }, { 80, 0x22008000 }, | ||
76 | { 94, 0x22008000 }, { 96, 0x22107000 }, { 99, 0x22107000 }, | ||
77 | { 108, 0x22107000 }, { 121, 0x22107000 }, { 128, 0x22107000 }, | ||
78 | { 132, 0x22109000 }, { 135, 0x22109000 }, { 157, 0x2210b000 }, | ||
79 | { 162, 0x2210b000 }, { 175, 0x2210b000 }, { 189, 0x2220e000 }, | ||
80 | { 195, 0x2220e000 }, { 202, 0x2220e000 }, { 204, 0x2220e000 }, | ||
81 | { 218, 0x2220f000 }, { 229, 0x22210000 }, { 234, 0x22210000 }, | ||
82 | }; | ||
83 | |||
84 | static struct wm_info i810_wm_16_133[] = { | ||
85 | { 15, 0x0020c000 }, { 19, 0x0020c000 }, { 25, 0x22006000 }, | ||
86 | { 28, 0x22006000 }, { 31, 0x22007000 }, { 36, 0x22007000 }, | ||
87 | { 40, 0x22007000 }, { 45, 0x22007000 }, { 49, 0x22009000 }, | ||
88 | { 50, 0x22009000 }, { 56, 0x22108000 }, { 65, 0x2210e000 }, | ||
89 | { 75, 0x2210e000 }, { 78, 0x2210e000 }, { 80, 0x22210000 }, | ||
90 | { 94, 0x22210000 }, { 96, 0x22210000 }, { 99, 0x22210000 }, | ||
91 | { 108, 0x22210000 }, { 121, 0x22210000 }, { 128, 0x22210000 }, | ||
92 | { 132, 0x22314000 }, { 135, 0x22314000 }, { 157, 0x22415000 }, | ||
93 | { 162, 0x22416000 }, { 175, 0x22416000 }, { 189, 0x22416000 }, | ||
94 | { 195, 0x22416000 }, { 202, 0x22416000 }, { 204, 0x22416000 }, | ||
95 | { 218, 0x22416000 }, { 229, 0x22416000 }, | ||
96 | }; | ||
97 | |||
98 | static struct wm_info i810_wm_24_133[] = { | ||
99 | { 15, 0x0020c000 }, { 19, 0x00408000 }, { 25, 0x22009000 }, | ||
100 | { 28, 0x22009000 }, { 31, 0x2200a000 }, { 36, 0x2210c000 }, | ||
101 | { 40, 0x2210c000 }, { 45, 0x2210c000 }, { 49, 0x22111000 }, | ||
102 | { 50, 0x22111000 }, { 56, 0x22111000 }, { 65, 0x22214000 }, | ||
103 | { 75, 0x22214000 }, { 78, 0x22215000 }, { 80, 0x22216000 }, | ||
104 | { 94, 0x22218000 }, { 96, 0x22418000 }, { 99, 0x22418000 }, | ||
105 | { 108, 0x22418000 }, { 121, 0x22418000 }, { 128, 0x22419000 }, | ||
106 | { 132, 0x22519000 }, { 135, 0x4441d000 }, { 157, 0x44419000 }, | ||
107 | { 162, 0x44419000 }, { 175, 0x44419000 }, { 189, 0x44419000 }, | ||
108 | { 195, 0x44419000 }, { 202, 0x44419000 }, { 204, 0x44419000 }, | ||
109 | }; | ||
110 | |||
111 | void round_off_xres(u32 *xres) { } | ||
112 | void round_off_yres(u32 *xres, u32 *yres) { } | ||
113 | |||
114 | /** | ||
115 | * i810fb_encode_registers - encode @var to hardware register values | ||
116 | * @var: pointer to var structure | ||
117 | * @par: pointer to hardware par structure | ||
118 | * | ||
119 | * DESCRIPTION: | ||
120 | * Timing values in @var will be converted to appropriate | ||
121 | * register values of @par. | ||
122 | */ | ||
123 | void i810fb_encode_registers(const struct fb_var_screeninfo *var, | ||
124 | struct i810fb_par *par, u32 xres, u32 yres) | ||
125 | { | ||
126 | int n, blank_s, blank_e; | ||
127 | u8 __iomem *mmio = par->mmio_start_virtual; | ||
128 | u8 msr = 0; | ||
129 | |||
130 | /* Horizontal */ | ||
131 | /* htotal */ | ||
132 | n = ((xres + var->right_margin + var->hsync_len + | ||
133 | var->left_margin) >> 3) - 5; | ||
134 | par->regs.cr00 = (u8) n; | ||
135 | par->regs.cr35 = (u8) ((n >> 8) & 1); | ||
136 | |||
137 | /* xres */ | ||
138 | par->regs.cr01 = (u8) ((xres >> 3) - 1); | ||
139 | |||
140 | /* hblank */ | ||
141 | blank_e = (xres + var->right_margin + var->hsync_len + | ||
142 | var->left_margin) >> 3; | ||
143 | blank_e--; | ||
144 | blank_s = blank_e - 127; | ||
145 | if (blank_s < (xres >> 3)) | ||
146 | blank_s = xres >> 3; | ||
147 | par->regs.cr02 = (u8) blank_s; | ||
148 | par->regs.cr03 = (u8) (blank_e & 0x1F); | ||
149 | par->regs.cr05 = (u8) ((blank_e & (1 << 5)) << 2); | ||
150 | par->regs.cr39 = (u8) ((blank_e >> 6) & 1); | ||
151 | |||
152 | /* hsync */ | ||
153 | par->regs.cr04 = (u8) ((xres + var->right_margin) >> 3); | ||
154 | par->regs.cr05 |= (u8) (((xres + var->right_margin + | ||
155 | var->hsync_len) >> 3) & 0x1F); | ||
156 | |||
157 | /* Vertical */ | ||
158 | /* vtotal */ | ||
159 | n = yres + var->lower_margin + var->vsync_len + var->upper_margin - 2; | ||
160 | par->regs.cr06 = (u8) (n & 0xFF); | ||
161 | par->regs.cr30 = (u8) ((n >> 8) & 0x0F); | ||
162 | |||
163 | /* vsync */ | ||
164 | n = yres + var->lower_margin; | ||
165 | par->regs.cr10 = (u8) (n & 0xFF); | ||
166 | par->regs.cr32 = (u8) ((n >> 8) & 0x0F); | ||
167 | par->regs.cr11 = i810_readb(CR11, mmio) & ~0x0F; | ||
168 | par->regs.cr11 |= (u8) ((yres + var->lower_margin + | ||
169 | var->vsync_len) & 0x0F); | ||
170 | |||
171 | /* yres */ | ||
172 | n = yres - 1; | ||
173 | par->regs.cr12 = (u8) (n & 0xFF); | ||
174 | par->regs.cr31 = (u8) ((n >> 8) & 0x0F); | ||
175 | |||
176 | /* vblank */ | ||
177 | blank_e = yres + var->lower_margin + var->vsync_len + | ||
178 | var->upper_margin; | ||
179 | blank_e--; | ||
180 | blank_s = blank_e - 127; | ||
181 | if (blank_s < yres) | ||
182 | blank_s = yres; | ||
183 | par->regs.cr15 = (u8) (blank_s & 0xFF); | ||
184 | par->regs.cr33 = (u8) ((blank_s >> 8) & 0x0F); | ||
185 | par->regs.cr16 = (u8) (blank_e & 0xFF); | ||
186 | par->regs.cr09 = 0; | ||
187 | |||
188 | /* sync polarity */ | ||
189 | if (!(var->sync & FB_SYNC_HOR_HIGH_ACT)) | ||
190 | msr |= 1 << 6; | ||
191 | if (!(var->sync & FB_SYNC_VERT_HIGH_ACT)) | ||
192 | msr |= 1 << 7; | ||
193 | par->regs.msr = msr; | ||
194 | |||
195 | /* interlace */ | ||
196 | if (var->vmode & FB_VMODE_INTERLACED) | ||
197 | par->interlace = (1 << 7) | ((u8) (var->yres >> 4)); | ||
198 | else | ||
199 | par->interlace = 0; | ||
200 | |||
201 | if (var->vmode & FB_VMODE_DOUBLE) | ||
202 | par->regs.cr09 |= 1 << 7; | ||
203 | |||
204 | /* overlay */ | ||
205 | par->ovract = ((var->xres + var->right_margin + var->hsync_len + | ||
206 | var->left_margin - 32) | ((var->xres - 32) << 16)); | ||
207 | } | ||
208 | |||
209 | void i810fb_fill_var_timings(struct fb_var_screeninfo *var) { } | ||
210 | |||
211 | /** | ||
212 | * i810_get_watermark - gets watermark | ||
213 | * @var: pointer to fb_var_screeninfo | ||
214 | * @par: pointer to i810fb_par structure | ||
215 | * | ||
216 | * DESCRIPTION: | ||
217 | * Gets the required watermark based on | ||
218 | * pixelclock and RAMBUS frequency. | ||
219 | * | ||
220 | * RETURNS: | ||
221 | * watermark | ||
222 | */ | ||
223 | u32 i810_get_watermark(const struct fb_var_screeninfo *var, | ||
224 | struct i810fb_par *par) | ||
225 | { | ||
226 | struct wm_info *wmark = NULL; | ||
227 | u32 i, size = 0, pixclock, wm_best = 0, min, diff; | ||
228 | |||
229 | if (par->mem_freq == 100) { | ||
230 | switch (var->bits_per_pixel) { | ||
231 | case 8: | ||
232 | wmark = i810_wm_8_100; | ||
233 | size = ARRAY_SIZE(i810_wm_8_100); | ||
234 | break; | ||
235 | case 16: | ||
236 | wmark = i810_wm_16_100; | ||
237 | size = ARRAY_SIZE(i810_wm_16_100); | ||
238 | break; | ||
239 | case 24: | ||
240 | case 32: | ||
241 | wmark = i810_wm_24_100; | ||
242 | size = ARRAY_SIZE(i810_wm_24_100); | ||
243 | } | ||
244 | } else { | ||
245 | switch(var->bits_per_pixel) { | ||
246 | case 8: | ||
247 | wmark = i810_wm_8_133; | ||
248 | size = ARRAY_SIZE(i810_wm_8_133); | ||
249 | break; | ||
250 | case 16: | ||
251 | wmark = i810_wm_16_133; | ||
252 | size = ARRAY_SIZE(i810_wm_16_133); | ||
253 | break; | ||
254 | case 24: | ||
255 | case 32: | ||
256 | wmark = i810_wm_24_133; | ||
257 | size = ARRAY_SIZE(i810_wm_24_133); | ||
258 | } | ||
259 | } | ||
260 | |||
261 | pixclock = 1000000/var->pixclock; | ||
262 | min = ~0; | ||
263 | for (i = 0; i < size; i++) { | ||
264 | if (pixclock <= wmark[i].freq) | ||
265 | diff = wmark[i].freq - pixclock; | ||
266 | else | ||
267 | diff = pixclock - wmark[i].freq; | ||
268 | if (diff < min) { | ||
269 | wm_best = wmark[i].wm; | ||
270 | min = diff; | ||
271 | } | ||
272 | } | ||
273 | return wm_best; | ||
274 | } | ||
275 | |||