diff options
author | Adrian Bunk <bunk@stusta.de> | 2007-02-12 03:54:50 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-12 12:48:41 -0500 |
commit | e019630e78e3482c2386d18cbdc7a4c54f7a809c (patch) | |
tree | 4b4bac38f1b501bac9a54ce8f08a1a6f1b26123f /drivers/video/sun3fb.c | |
parent | a268422de8bf1b4c0cb97987b6c329c9f6a3da4b (diff) |
[PATCH] remove broken video drivers
Remove some video drivers that:
- had already been marked as BROKEN in 2.6.0 three years ago and
- are still marked as BROKEN.
These are the following drivers:
- FB_CYBER
- FB_VIRGE
- FB_RETINAZ3
- FB_SUN3
Drivers that had been marked as BROKEN for such a long time seem to be
unlikely to be revived in the forseeable future.
But if anyone wants to ever revive any of these drivers, the code is
still present in the older kernel releases.
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Acked-By: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: James Simmons <jsimmons@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/sun3fb.c')
-rw-r--r-- | drivers/video/sun3fb.c | 702 |
1 files changed, 0 insertions, 702 deletions
diff --git a/drivers/video/sun3fb.c b/drivers/video/sun3fb.c deleted file mode 100644 index f80356dfa8e8..000000000000 --- a/drivers/video/sun3fb.c +++ /dev/null | |||
@@ -1,702 +0,0 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/sun3fb.c -- Frame buffer driver for Sun3 | ||
3 | * | ||
4 | * (C) 1998 Thomas Bogendoerfer | ||
5 | * | ||
6 | * This driver is bases on sbusfb.c, which is | ||
7 | * | ||
8 | * Copyright (C) 1998 Jakub Jelinek | ||
9 | * | ||
10 | * This driver is partly based on the Open Firmware console driver | ||
11 | * | ||
12 | * Copyright (C) 1997 Geert Uytterhoeven | ||
13 | * | ||
14 | * and SPARC console subsystem | ||
15 | * | ||
16 | * Copyright (C) 1995 Peter Zaitcev (zaitcev@yahoo.com) | ||
17 | * Copyright (C) 1995-1997 David S. Miller (davem@caip.rutgers.edu) | ||
18 | * Copyright (C) 1995-1996 Miguel de Icaza (miguel@nuclecu.unam.mx) | ||
19 | * Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk) | ||
20 | * Copyright (C) 1996-1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
21 | * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) | ||
22 | * | ||
23 | * This file is subject to the terms and conditions of the GNU General Public | ||
24 | * License. See the file COPYING in the main directory of this archive for | ||
25 | * more details. | ||
26 | */ | ||
27 | |||
28 | #include <linux/module.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/errno.h> | ||
31 | #include <linux/string.h> | ||
32 | #include <linux/mm.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <linux/vmalloc.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | #include <linux/fb.h> | ||
38 | #include <linux/selection.h> | ||
39 | #include <linux/init.h> | ||
40 | #include <linux/console.h> | ||
41 | #include <linux/kd.h> | ||
42 | #include <linux/vt_kern.h> | ||
43 | |||
44 | #include <asm/uaccess.h> | ||
45 | #include <asm/pgtable.h> /* io_remap_page_range() */ | ||
46 | |||
47 | #ifdef CONFIG_SUN3 | ||
48 | #include <asm/oplib.h> | ||
49 | #include <asm/machines.h> | ||
50 | #include <asm/idprom.h> | ||
51 | |||
52 | #define CGFOUR_OBMEM_ADDR 0x1f300000 | ||
53 | #define BWTWO_OBMEM_ADDR 0x1f000000 | ||
54 | #define BWTWO_OBMEM50_ADDR 0x00100000 | ||
55 | |||
56 | #endif | ||
57 | #ifdef CONFIG_SUN3X | ||
58 | #include <asm/sun3x.h> | ||
59 | #endif | ||
60 | #include <video/sbusfb.h> | ||
61 | |||
62 | #define DEFAULT_CURSOR_BLINK_RATE (2*HZ/5) | ||
63 | |||
64 | #define CURSOR_SHAPE 1 | ||
65 | #define CURSOR_BLINK 2 | ||
66 | |||
67 | #define mymemset(x,y) memset(x,0,y) | ||
68 | |||
69 | /* | ||
70 | * Interface used by the world | ||
71 | */ | ||
72 | |||
73 | int sun3fb_init(void); | ||
74 | void sun3fb_setup(char *options); | ||
75 | |||
76 | static char fontname[40] __initdata = { 0 }; | ||
77 | static int curblink __initdata = 1; | ||
78 | |||
79 | static int sun3fb_get_fix(struct fb_fix_screeninfo *fix, int con, | ||
80 | struct fb_info *info); | ||
81 | static int sun3fb_get_var(struct fb_var_screeninfo *var, int con, | ||
82 | struct fb_info *info); | ||
83 | static int sun3fb_set_var(struct fb_var_screeninfo *var, int con, | ||
84 | struct fb_info *info); | ||
85 | static int sun3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, | ||
86 | struct fb_info *info); | ||
87 | static int sun3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, | ||
88 | struct fb_info *info); | ||
89 | static int sun3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
90 | u_int transp, struct fb_info *info); | ||
91 | static int sun3fb_blank(int blank, struct fb_info *info); | ||
92 | static void sun3fb_cursor(struct display *p, int mode, int x, int y); | ||
93 | static void sun3fb_clear_margin(struct display *p, int s); | ||
94 | |||
95 | /* | ||
96 | * Interface to the low level console driver | ||
97 | */ | ||
98 | |||
99 | static int sun3fbcon_switch(int con, struct fb_info *info); | ||
100 | static int sun3fbcon_updatevar(int con, struct fb_info *info); | ||
101 | |||
102 | /* | ||
103 | * Internal routines | ||
104 | */ | ||
105 | |||
106 | static int sun3fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, | ||
107 | u_int *transp, struct fb_info *info); | ||
108 | |||
109 | static struct fb_ops sun3fb_ops = { | ||
110 | .owner = THIS_MODULE, | ||
111 | .fb_get_fix = sun3fb_get_fix, | ||
112 | .fb_get_var = sun3fb_get_var, | ||
113 | .fb_set_var = sun3fb_set_var, | ||
114 | .fb_get_cmap = sun3fb_get_cmap, | ||
115 | .fb_set_cmap = sun3fb_set_cmap, | ||
116 | .fb_setcolreg = sun3fb_setcolreg, | ||
117 | .fb_blank = sun3fb_blank, | ||
118 | }; | ||
119 | |||
120 | static void sun3fb_clear_margin(struct display *p, int s) | ||
121 | { | ||
122 | struct fb_info_sbusfb *fb = sbusfbinfod(p); | ||
123 | |||
124 | return; | ||
125 | |||
126 | if (fb->switch_from_graph) | ||
127 | (*fb->switch_from_graph)(fb); | ||
128 | if (fb->fill) { | ||
129 | unsigned short rects [16]; | ||
130 | |||
131 | rects [0] = 0; | ||
132 | rects [1] = 0; | ||
133 | rects [2] = fb->var.xres_virtual; | ||
134 | rects [3] = fb->y_margin; | ||
135 | rects [4] = 0; | ||
136 | rects [5] = fb->y_margin; | ||
137 | rects [6] = fb->x_margin; | ||
138 | rects [7] = fb->var.yres_virtual; | ||
139 | rects [8] = fb->var.xres_virtual - fb->x_margin; | ||
140 | rects [9] = fb->y_margin; | ||
141 | rects [10] = fb->var.xres_virtual; | ||
142 | rects [11] = fb->var.yres_virtual; | ||
143 | rects [12] = fb->x_margin; | ||
144 | rects [13] = fb->var.yres_virtual - fb->y_margin; | ||
145 | rects [14] = fb->var.xres_virtual - fb->x_margin; | ||
146 | rects [15] = fb->var.yres_virtual; | ||
147 | (*fb->fill)(fb, p, s, 4, rects); | ||
148 | } else { | ||
149 | unsigned char *fb_base = fb->info.screen_base, *q; | ||
150 | int skip_bytes = fb->y_margin * fb->var.xres_virtual; | ||
151 | int scr_size = fb->var.xres_virtual * fb->var.yres_virtual; | ||
152 | int h, he, incr, size; | ||
153 | |||
154 | he = fb->var.yres; | ||
155 | if (fb->var.bits_per_pixel == 1) { | ||
156 | fb_base -= (skip_bytes + fb->x_margin) / 8; | ||
157 | skip_bytes /= 8; | ||
158 | scr_size /= 8; | ||
159 | mymemset (fb_base, skip_bytes - fb->x_margin / 8); | ||
160 | mymemset (fb_base + scr_size - skip_bytes + fb->x_margin / 8, skip_bytes - fb->x_margin / 8); | ||
161 | incr = fb->var.xres_virtual / 8; | ||
162 | size = fb->x_margin / 8 * 2; | ||
163 | for (q = fb_base + skip_bytes - fb->x_margin / 8, h = 0; | ||
164 | h <= he; q += incr, h++) | ||
165 | mymemset (q, size); | ||
166 | } else { | ||
167 | fb_base -= (skip_bytes + fb->x_margin); | ||
168 | memset (fb_base, attr_bgcol(p,s), skip_bytes - fb->x_margin); | ||
169 | memset (fb_base + scr_size - skip_bytes + fb->x_margin, attr_bgcol(p,s), skip_bytes - fb->x_margin); | ||
170 | incr = fb->var.xres_virtual; | ||
171 | size = fb->x_margin * 2; | ||
172 | for (q = fb_base + skip_bytes - fb->x_margin, h = 0; | ||
173 | h <= he; q += incr, h++) | ||
174 | memset (q, attr_bgcol(p,s), size); | ||
175 | } | ||
176 | } | ||
177 | } | ||
178 | |||
179 | static void sun3fb_disp_setup(struct display *p) | ||
180 | { | ||
181 | struct fb_info_sbusfb *fb = sbusfbinfod(p); | ||
182 | |||
183 | if (fb->setup) | ||
184 | fb->setup(p); | ||
185 | sun3fb_clear_margin(p, 0); | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * Get the Fixed Part of the Display | ||
190 | */ | ||
191 | |||
192 | static int sun3fb_get_fix(struct fb_fix_screeninfo *fix, int con, | ||
193 | struct fb_info *info) | ||
194 | { | ||
195 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
196 | |||
197 | memcpy(fix, &fb->fix, sizeof(struct fb_fix_screeninfo)); | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * Get the User Defined Part of the Display | ||
203 | */ | ||
204 | |||
205 | static int sun3fb_get_var(struct fb_var_screeninfo *var, int con, | ||
206 | struct fb_info *info) | ||
207 | { | ||
208 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
209 | |||
210 | memcpy(var, &fb->var, sizeof(struct fb_var_screeninfo)); | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Set the User Defined Part of the Display | ||
216 | */ | ||
217 | |||
218 | static int sun3fb_set_var(struct fb_var_screeninfo *var, int con, | ||
219 | struct fb_info *info) | ||
220 | { | ||
221 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
222 | |||
223 | if (var->xres > fb->var.xres || var->yres > fb->var.yres || | ||
224 | var->xres_virtual > fb->var.xres_virtual || | ||
225 | var->yres_virtual > fb->var.yres_virtual || | ||
226 | var->bits_per_pixel != fb->var.bits_per_pixel || | ||
227 | var->nonstd || | ||
228 | (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) | ||
229 | return -EINVAL; | ||
230 | memcpy(var, &fb->var, sizeof(struct fb_var_screeninfo)); | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | /* | ||
235 | * Hardware cursor | ||
236 | */ | ||
237 | |||
238 | static unsigned char hw_cursor_cmap[2] = { 0, 0xff }; | ||
239 | |||
240 | static void | ||
241 | sun3fb_cursor_timer_handler(unsigned long dev_addr) | ||
242 | { | ||
243 | struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)dev_addr; | ||
244 | |||
245 | if (!fb->setcursor) return; | ||
246 | |||
247 | if (fb->cursor.mode & CURSOR_BLINK) { | ||
248 | fb->cursor.enable ^= 1; | ||
249 | fb->setcursor(fb); | ||
250 | } | ||
251 | |||
252 | fb->cursor.timer.expires = jiffies + fb->cursor.blink_rate; | ||
253 | add_timer(&fb->cursor.timer); | ||
254 | } | ||
255 | |||
256 | static void sun3fb_cursor(struct display *p, int mode, int x, int y) | ||
257 | { | ||
258 | struct fb_info_sbusfb *fb = sbusfbinfod(p); | ||
259 | |||
260 | switch (mode) { | ||
261 | case CM_ERASE: | ||
262 | fb->cursor.mode &= ~CURSOR_BLINK; | ||
263 | fb->cursor.enable = 0; | ||
264 | (*fb->setcursor)(fb); | ||
265 | break; | ||
266 | |||
267 | case CM_MOVE: | ||
268 | case CM_DRAW: | ||
269 | if (fb->cursor.mode & CURSOR_SHAPE) { | ||
270 | fb->cursor.size.fbx = fontwidth(p); | ||
271 | fb->cursor.size.fby = fontheight(p); | ||
272 | fb->cursor.chot.fbx = 0; | ||
273 | fb->cursor.chot.fby = 0; | ||
274 | fb->cursor.enable = 1; | ||
275 | memset (fb->cursor.bits, 0, sizeof (fb->cursor.bits)); | ||
276 | fb->cursor.bits[0][fontheight(p) - 2] = (0xffffffff << (32 - fontwidth(p))); | ||
277 | fb->cursor.bits[1][fontheight(p) - 2] = (0xffffffff << (32 - fontwidth(p))); | ||
278 | fb->cursor.bits[0][fontheight(p) - 1] = (0xffffffff << (32 - fontwidth(p))); | ||
279 | fb->cursor.bits[1][fontheight(p) - 1] = (0xffffffff << (32 - fontwidth(p))); | ||
280 | (*fb->setcursormap) (fb, hw_cursor_cmap, hw_cursor_cmap, hw_cursor_cmap); | ||
281 | (*fb->setcurshape) (fb); | ||
282 | } | ||
283 | fb->cursor.mode = CURSOR_BLINK; | ||
284 | if (fontwidthlog(p)) | ||
285 | fb->cursor.cpos.fbx = (x << fontwidthlog(p)) + fb->x_margin; | ||
286 | else | ||
287 | fb->cursor.cpos.fbx = (x * fontwidth(p)) + fb->x_margin; | ||
288 | if (fontheightlog(p)) | ||
289 | fb->cursor.cpos.fby = (y << fontheightlog(p)) + fb->y_margin; | ||
290 | else | ||
291 | fb->cursor.cpos.fby = (y * fontheight(p)) + fb->y_margin; | ||
292 | (*fb->setcursor)(fb); | ||
293 | break; | ||
294 | } | ||
295 | } | ||
296 | |||
297 | /* | ||
298 | * Get the Colormap | ||
299 | */ | ||
300 | |||
301 | static int sun3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, | ||
302 | struct fb_info *info) | ||
303 | { | ||
304 | if (con == info->currcon) /* current console? */ | ||
305 | return fb_get_cmap(cmap, kspc, sun3fb_getcolreg, info); | ||
306 | else if (fb_display[con].cmap.len) /* non default colormap? */ | ||
307 | fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2); | ||
308 | else | ||
309 | fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), cmap, kspc ? 0 : 2); | ||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | /* | ||
314 | * Set the Colormap | ||
315 | */ | ||
316 | |||
317 | static int sun3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, | ||
318 | struct fb_info *info) | ||
319 | { | ||
320 | int err; | ||
321 | |||
322 | if (!fb_display[con].cmap.len) { /* no colormap allocated? */ | ||
323 | if ((err = fb_alloc_cmap(&fb_display[con].cmap, 1<<fb_display[con].var.bits_per_pixel, 0))) | ||
324 | return err; | ||
325 | } | ||
326 | if (con == info->currcon) { /* current console? */ | ||
327 | err = fb_set_cmap(cmap, kspc, info); | ||
328 | if (!err) { | ||
329 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
330 | |||
331 | if (fb->loadcmap) | ||
332 | (*fb->loadcmap)(fb, &fb_display[con], cmap->start, cmap->len); | ||
333 | } | ||
334 | return err; | ||
335 | } else | ||
336 | fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); | ||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | /* | ||
341 | * Setup: parse used options | ||
342 | */ | ||
343 | |||
344 | void __init sun3fb_setup(char *options) | ||
345 | { | ||
346 | char *p; | ||
347 | |||
348 | for (p = options;;) { | ||
349 | if (!strncmp(p, "font=", 5)) { | ||
350 | int i; | ||
351 | |||
352 | for (i = 0; i < sizeof(fontname) - 1; i++) | ||
353 | if (p[i+5] == ' ' || !p[i+5]) | ||
354 | break; | ||
355 | memcpy(fontname, p+5, i); | ||
356 | fontname[i] = 0; | ||
357 | } else if (!strncmp(p, "noblink", 7)) | ||
358 | curblink = 0; | ||
359 | while (*p && *p != ' ' && *p != ',') p++; | ||
360 | if (*p != ',') break; | ||
361 | p++; | ||
362 | } | ||
363 | |||
364 | return; | ||
365 | } | ||
366 | |||
367 | static int sun3fbcon_switch(int con, struct fb_info *info) | ||
368 | { | ||
369 | int x_margin, y_margin; | ||
370 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
371 | int lastconsole; | ||
372 | |||
373 | /* Do we have to save the colormap? */ | ||
374 | if (fb_display[info->currcon].cmap.len) | ||
375 | fb_get_cmap(&fb_display[info->currcon].cmap, 1, sun3fb_getcolreg, info); | ||
376 | |||
377 | if (info->display_fg) { | ||
378 | lastconsole = info->display_fg->vc_num; | ||
379 | if (lastconsole != con && | ||
380 | (fontwidth(&fb_display[lastconsole]) != fontwidth(&fb_display[con]) || | ||
381 | fontheight(&fb_display[lastconsole]) != fontheight(&fb_display[con]))) | ||
382 | fb->cursor.mode |= CURSOR_SHAPE; | ||
383 | } | ||
384 | x_margin = (fb_display[con].var.xres_virtual - fb_display[con].var.xres) / 2; | ||
385 | y_margin = (fb_display[con].var.yres_virtual - fb_display[con].var.yres) / 2; | ||
386 | if (fb->margins) | ||
387 | fb->margins(fb, &fb_display[con], x_margin, y_margin); | ||
388 | if (fb->graphmode || fb->x_margin != x_margin || fb->y_margin != y_margin) { | ||
389 | fb->x_margin = x_margin; fb->y_margin = y_margin; | ||
390 | sun3fb_clear_margin(&fb_display[con], 0); | ||
391 | } | ||
392 | info->currcon = con; | ||
393 | /* Install new colormap */ | ||
394 | do_install_cmap(con, info); | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | /* | ||
399 | * Update the `var' structure (called by fbcon.c) | ||
400 | */ | ||
401 | |||
402 | static int sun3fbcon_updatevar(int con, struct fb_info *info) | ||
403 | { | ||
404 | /* Nothing */ | ||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | /* | ||
409 | * Blank the display. | ||
410 | */ | ||
411 | |||
412 | static int sun3fb_blank(int blank, struct fb_info *info) | ||
413 | { | ||
414 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
415 | |||
416 | if (blank && fb->blank) | ||
417 | return fb->blank(fb); | ||
418 | else if (!blank && fb->unblank) | ||
419 | return fb->unblank(fb); | ||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | /* | ||
424 | * Read a single color register and split it into | ||
425 | * colors/transparent. Return != 0 for invalid regno. | ||
426 | */ | ||
427 | |||
428 | static int sun3fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, | ||
429 | u_int *transp, struct fb_info *info) | ||
430 | { | ||
431 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
432 | |||
433 | if (!fb->color_map || regno > 255) | ||
434 | return 1; | ||
435 | *red = (fb->color_map CM(regno, 0)<<8) | fb->color_map CM(regno, 0); | ||
436 | *green = (fb->color_map CM(regno, 1)<<8) | fb->color_map CM(regno, 1); | ||
437 | *blue = (fb->color_map CM(regno, 2)<<8) | fb->color_map CM(regno, 2); | ||
438 | *transp = 0; | ||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | |||
443 | /* | ||
444 | * Set a single color register. The values supplied are already | ||
445 | * rounded down to the hardware's capabilities (according to the | ||
446 | * entries in the var structure). Return != 0 for invalid regno. | ||
447 | */ | ||
448 | |||
449 | static int sun3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
450 | u_int transp, struct fb_info *info) | ||
451 | { | ||
452 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
453 | |||
454 | if (!fb->color_map || regno > 255) | ||
455 | return 1; | ||
456 | red >>= 8; | ||
457 | green >>= 8; | ||
458 | blue >>= 8; | ||
459 | fb->color_map CM(regno, 0) = red; | ||
460 | fb->color_map CM(regno, 1) = green; | ||
461 | fb->color_map CM(regno, 2) = blue; | ||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | static int sun3fb_set_font(struct display *p, int width, int height) | ||
466 | { | ||
467 | int w = p->var.xres_virtual, h = p->var.yres_virtual; | ||
468 | int depth = p->var.bits_per_pixel; | ||
469 | struct fb_info_sbusfb *fb = sbusfbinfod(p); | ||
470 | int x_margin, y_margin; | ||
471 | |||
472 | if (depth > 8) depth = 8; | ||
473 | x_margin = (w % width) / 2; | ||
474 | y_margin = (h % height) / 2; | ||
475 | |||
476 | p->var.xres = w - 2*x_margin; | ||
477 | p->var.yres = h - 2*y_margin; | ||
478 | |||
479 | fb->cursor.mode |= CURSOR_SHAPE; | ||
480 | |||
481 | if (fb->margins) | ||
482 | fb->margins(fb, p, x_margin, y_margin); | ||
483 | if (fb->x_margin != x_margin || fb->y_margin != y_margin) { | ||
484 | fb->x_margin = x_margin; fb->y_margin = y_margin; | ||
485 | sun3fb_clear_margin(p, 0); | ||
486 | } | ||
487 | |||
488 | return 1; | ||
489 | } | ||
490 | |||
491 | void sun3fb_palette(int enter) | ||
492 | { | ||
493 | int i; | ||
494 | struct display *p; | ||
495 | |||
496 | for (i = 0; i < MAX_NR_CONSOLES; i++) { | ||
497 | p = &fb_display[i]; | ||
498 | if (p->dispsw && p->dispsw->setup == sun3fb_disp_setup && | ||
499 | p->fb_info->display_fg && | ||
500 | p->fb_info->display_fg->vc_num == i) { | ||
501 | struct fb_info_sbusfb *fb = sbusfbinfod(p); | ||
502 | |||
503 | if (fb->restore_palette) { | ||
504 | if (enter) | ||
505 | fb->restore_palette(fb); | ||
506 | else if (vc_cons[i].d->vc_mode != KD_GRAPHICS) | ||
507 | vc_cons[i].d->vc_sw->con_set_palette(vc_cons[i].d, color_table); | ||
508 | } | ||
509 | } | ||
510 | } | ||
511 | } | ||
512 | |||
513 | /* | ||
514 | * Initialisation | ||
515 | */ | ||
516 | static int __init sun3fb_init_fb(int fbtype, unsigned long addr) | ||
517 | { | ||
518 | static struct sbus_dev sdb; | ||
519 | struct fb_fix_screeninfo *fix; | ||
520 | struct fb_var_screeninfo *var; | ||
521 | struct display *disp; | ||
522 | struct fb_info_sbusfb *fb; | ||
523 | struct fbtype *type; | ||
524 | int linebytes, w, h, depth; | ||
525 | char *p = NULL; | ||
526 | |||
527 | fb = kmalloc(sizeof(struct fb_info_sbusfb), GFP_ATOMIC); | ||
528 | if (!fb) | ||
529 | return -ENOMEM; | ||
530 | |||
531 | memset(fb, 0, sizeof(struct fb_info_sbusfb)); | ||
532 | fix = &fb->fix; | ||
533 | var = &fb->var; | ||
534 | disp = &fb->disp; | ||
535 | type = &fb->type; | ||
536 | |||
537 | sdb.reg_addrs[0].phys_addr = addr; | ||
538 | fb->sbdp = &sdb; | ||
539 | |||
540 | type->fb_type = fbtype; | ||
541 | |||
542 | type->fb_height = h = 900; | ||
543 | type->fb_width = w = 1152; | ||
544 | sizechange: | ||
545 | type->fb_depth = depth = (fbtype == FBTYPE_SUN2BW) ? 1 : 8; | ||
546 | linebytes = w * depth / 8; | ||
547 | type->fb_size = PAGE_ALIGN((linebytes) * h); | ||
548 | /* | ||
549 | fb->x_margin = (w & 7) / 2; | ||
550 | fb->y_margin = (h & 15) / 2; | ||
551 | */ | ||
552 | fb->x_margin = fb->y_margin = 0; | ||
553 | |||
554 | var->xres_virtual = w; | ||
555 | var->yres_virtual = h; | ||
556 | var->xres = w - 2*fb->x_margin; | ||
557 | var->yres = h - 2*fb->y_margin; | ||
558 | |||
559 | var->bits_per_pixel = depth; | ||
560 | var->height = var->width = -1; | ||
561 | var->pixclock = 10000; | ||
562 | var->vmode = FB_VMODE_NONINTERLACED; | ||
563 | var->red.length = var->green.length = var->blue.length = 8; | ||
564 | |||
565 | fix->line_length = linebytes; | ||
566 | fix->smem_len = type->fb_size; | ||
567 | fix->type = FB_TYPE_PACKED_PIXELS; | ||
568 | fix->visual = FB_VISUAL_PSEUDOCOLOR; | ||
569 | |||
570 | fb->info.fbops = &sun3fb_ops; | ||
571 | fb->info.disp = disp; | ||
572 | fb->info.currcon = -1; | ||
573 | strcpy(fb->info.fontname, fontname); | ||
574 | fb->info.changevar = NULL; | ||
575 | fb->info.switch_con = &sun3fbcon_switch; | ||
576 | fb->info.updatevar = &sun3fbcon_updatevar; | ||
577 | fb->info.flags = FBINFO_FLAG_DEFAULT; | ||
578 | |||
579 | fb->cursor.hwsize.fbx = 32; | ||
580 | fb->cursor.hwsize.fby = 32; | ||
581 | |||
582 | if (depth > 1 && !fb->color_map) { | ||
583 | if((fb->color_map = kmalloc(256 * 3, GFP_ATOMIC))==NULL) | ||
584 | return -ENOMEM; | ||
585 | } | ||
586 | |||
587 | switch(fbtype) { | ||
588 | #ifdef CONFIG_FB_CGSIX | ||
589 | case FBTYPE_SUNFAST_COLOR: | ||
590 | p = cgsixfb_init(fb); break; | ||
591 | #endif | ||
592 | #ifdef CONFIG_FB_BWTWO | ||
593 | case FBTYPE_SUN2BW: | ||
594 | p = bwtwofb_init(fb); break; | ||
595 | #endif | ||
596 | #ifdef CONFIG_FB_CGTHREE | ||
597 | case FBTYPE_SUN4COLOR: | ||
598 | case FBTYPE_SUN3COLOR: | ||
599 | type->fb_size = 0x100000; | ||
600 | p = cgthreefb_init(fb); break; | ||
601 | #endif | ||
602 | } | ||
603 | fix->smem_start = (unsigned long)fb->info.screen_base; // FIXME | ||
604 | |||
605 | if (!p) { | ||
606 | kfree(fb); | ||
607 | return -ENODEV; | ||
608 | } | ||
609 | |||
610 | if (p == SBUSFBINIT_SIZECHANGE) | ||
611 | goto sizechange; | ||
612 | |||
613 | disp->dispsw = &fb->dispsw; | ||
614 | if (fb->setcursor) { | ||
615 | fb->dispsw.cursor = sun3fb_cursor; | ||
616 | if (curblink) { | ||
617 | fb->cursor.blink_rate = DEFAULT_CURSOR_BLINK_RATE; | ||
618 | init_timer(&fb->cursor.timer); | ||
619 | fb->cursor.timer.expires = jiffies + fb->cursor.blink_rate; | ||
620 | fb->cursor.timer.data = (unsigned long)fb; | ||
621 | fb->cursor.timer.function = sun3fb_cursor_timer_handler; | ||
622 | add_timer(&fb->cursor.timer); | ||
623 | } | ||
624 | } | ||
625 | fb->cursor.mode = CURSOR_SHAPE; | ||
626 | fb->dispsw.set_font = sun3fb_set_font; | ||
627 | fb->setup = fb->dispsw.setup; | ||
628 | fb->dispsw.setup = sun3fb_disp_setup; | ||
629 | fb->dispsw.clear_margins = NULL; | ||
630 | |||
631 | disp->var = *var; | ||
632 | disp->visual = fix->visual; | ||
633 | disp->type = fix->type; | ||
634 | disp->type_aux = fix->type_aux; | ||
635 | disp->line_length = fix->line_length; | ||
636 | |||
637 | if (fb->blank) | ||
638 | disp->can_soft_blank = 1; | ||
639 | |||
640 | sun3fb_set_var(var, -1, &fb->info); | ||
641 | |||
642 | if (register_framebuffer(&fb->info) < 0) { | ||
643 | kfree(fb); | ||
644 | return -EINVAL; | ||
645 | } | ||
646 | printk("fb%d: %s\n", fb->info.node, p); | ||
647 | |||
648 | return 0; | ||
649 | } | ||
650 | |||
651 | |||
652 | int __init sun3fb_init(void) | ||
653 | { | ||
654 | extern int con_is_present(void); | ||
655 | unsigned long addr; | ||
656 | char p4id; | ||
657 | |||
658 | if (!con_is_present()) return -ENODEV; | ||
659 | #ifdef CONFIG_SUN3 | ||
660 | switch(*(romvec->pv_fbtype)) | ||
661 | { | ||
662 | case FBTYPE_SUN2BW: | ||
663 | addr = 0xfe20000; | ||
664 | return sun3fb_init_fb(FBTYPE_SUN2BW, addr); | ||
665 | case FBTYPE_SUN3COLOR: | ||
666 | case FBTYPE_SUN4COLOR: | ||
667 | if(idprom->id_machtype != (SM_SUN3|SM_3_60)) { | ||
668 | printk("sun3fb: cgthree/four only supported on 3/60\n"); | ||
669 | return -ENODEV; | ||
670 | } | ||
671 | |||
672 | addr = CGFOUR_OBMEM_ADDR; | ||
673 | return sun3fb_init_fb(*(romvec->pv_fbtype), addr); | ||
674 | default: | ||
675 | printk("sun3fb: unsupported framebuffer\n"); | ||
676 | return -ENODEV; | ||
677 | } | ||
678 | #else | ||
679 | addr = SUN3X_VIDEO_BASE; | ||
680 | p4id = *(char *)SUN3X_VIDEO_P4ID; | ||
681 | |||
682 | p4id = (p4id == 0x45) ? p4id : (p4id & 0xf0); | ||
683 | switch (p4id) { | ||
684 | case 0x00: | ||
685 | return sun3fb_init_fb(FBTYPE_SUN2BW, addr); | ||
686 | #if 0 /* not yet */ | ||
687 | case 0x40: | ||
688 | return sun3fb_init_fb(FBTYPE_SUN4COLOR, addr); | ||
689 | break; | ||
690 | case 0x45: | ||
691 | return sun3fb_init_fb(FBTYPE_SUN8COLOR, addr); | ||
692 | break; | ||
693 | #endif | ||
694 | case 0x60: | ||
695 | return sun3fb_init_fb(FBTYPE_SUNFAST_COLOR, addr); | ||
696 | } | ||
697 | #endif | ||
698 | |||
699 | return -ENODEV; | ||
700 | } | ||
701 | |||
702 | MODULE_LICENSE("GPL"); | ||