xref: /linux/drivers/video/fbdev/atafb.c (revision b85d45947951d23cb22d90caecf4c1eb81342c96)
1 /*
2  * linux/drivers/video/atafb.c -- Atari builtin chipset frame buffer device
3  *
4  *  Copyright (C) 1994 Martin Schaller & Roman Hodek
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License.  See the file COPYING in the main directory of this archive
8  * for more details.
9  *
10  * History:
11  *   - 03 Jan 95: Original version by Martin Schaller: The TT driver and
12  *                all the device independent stuff
13  *   - 09 Jan 95: Roman: I've added the hardware abstraction (hw_switch)
14  *                and wrote the Falcon, ST(E), and External drivers
15  *                based on the original TT driver.
16  *   - 07 May 95: Martin: Added colormap operations for the external driver
17  *   - 21 May 95: Martin: Added support for overscan
18  *		  Andreas: some bug fixes for this
19  *   -    Jul 95: Guenther Kelleter <guenther@pool.informatik.rwth-aachen.de>:
20  *                Programmable Falcon video modes
21  *                (thanks to Christian Cartus for documentation
22  *                of VIDEL registers).
23  *   - 27 Dec 95: Guenther: Implemented user definable video modes "user[0-7]"
24  *                on minor 24...31. "user0" may be set on commandline by
25  *                "R<x>;<y>;<depth>". (Makes sense only on Falcon)
26  *                Video mode switch on Falcon now done at next VBL interrupt
27  *                to avoid the annoying right shift of the screen.
28  *   - 23 Sep 97: Juergen: added xres_virtual for cards like ProMST
29  *                The external-part is legacy, therefore hardware-specific
30  *                functions like panning/hardwarescrolling/blanking isn't
31  *				  supported.
32  *   - 29 Sep 97: Juergen: added Romans suggestion for pan_display
33  *				  (var->xoffset was changed even if no set_screen_base avail.)
34  *	 - 05 Oct 97: Juergen: extfb (PACKED_PIXEL) is FB_PSEUDOCOLOR 'cause
35  *				  we know how to set the colors
36  *				  ext_*palette: read from ext_colors (former MV300_colors)
37  *							    write to ext_colors and RAMDAC
38  *
39  * To do:
40  *   - For the Falcon it is not possible to set random video modes on
41  *     SM124 and SC/TV, only the bootup resolution is supported.
42  *
43  */
44 
45 #define ATAFB_TT
46 #define ATAFB_STE
47 #define ATAFB_EXT
48 #define ATAFB_FALCON
49 
50 #include <linux/module.h>
51 #include <linux/kernel.h>
52 #include <linux/errno.h>
53 #include <linux/string.h>
54 #include <linux/mm.h>
55 #include <linux/delay.h>
56 #include <linux/init.h>
57 #include <linux/interrupt.h>
58 
59 #include <asm/setup.h>
60 #include <linux/uaccess.h>
61 #include <asm/pgtable.h>
62 #include <asm/irq.h>
63 #include <asm/io.h>
64 
65 #include <asm/atarihw.h>
66 #include <asm/atariints.h>
67 #include <asm/atari_stram.h>
68 
69 #include <linux/fb.h>
70 #include <asm/atarikb.h>
71 
72 #include "c2p.h"
73 #include "atafb.h"
74 
75 #define SWITCH_ACIA 0x01		/* modes for switch on OverScan */
76 #define SWITCH_SND6 0x40
77 #define SWITCH_SND7 0x80
78 #define SWITCH_NONE 0x00
79 
80 
81 #define up(x, r) (((x) + (r) - 1) & ~((r)-1))
82 
83 	/*
84 	 * Interface to the world
85 	 */
86 
87 static int atafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
88 static int atafb_set_par(struct fb_info *info);
89 static int atafb_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
90 			   unsigned int blue, unsigned int transp,
91 			   struct fb_info *info);
92 static int atafb_blank(int blank, struct fb_info *info);
93 static int atafb_pan_display(struct fb_var_screeninfo *var,
94 			     struct fb_info *info);
95 static void atafb_fillrect(struct fb_info *info,
96 			   const struct fb_fillrect *rect);
97 static void atafb_copyarea(struct fb_info *info,
98 			   const struct fb_copyarea *region);
99 static void atafb_imageblit(struct fb_info *info, const struct fb_image *image);
100 static int atafb_ioctl(struct fb_info *info, unsigned int cmd,
101 		       unsigned long arg);
102 
103 
104 static int default_par;		/* default resolution (0=none) */
105 
106 static unsigned long default_mem_req;
107 
108 static int hwscroll = -1;
109 
110 static int use_hwscroll = 1;
111 
112 static int sttt_xres = 640, st_yres = 400, tt_yres = 480;
113 static int sttt_xres_virtual = 640, sttt_yres_virtual = 400;
114 static int ovsc_offset, ovsc_addlen;
115 
116 	/*
117 	 * Hardware parameters for current mode
118 	 */
119 
120 static struct atafb_par {
121 	void *screen_base;
122 	int yres_virtual;
123 	u_long next_line;
124 #if defined ATAFB_TT || defined ATAFB_STE
125 	union {
126 		struct {
127 			int mode;
128 			int sync;
129 		} tt, st;
130 #endif
131 #ifdef ATAFB_FALCON
132 		struct falcon_hw {
133 			/* Here are fields for storing a video mode, as direct
134 			 * parameters for the hardware.
135 			 */
136 			short sync;
137 			short line_width;
138 			short line_offset;
139 			short st_shift;
140 			short f_shift;
141 			short vid_control;
142 			short vid_mode;
143 			short xoffset;
144 			short hht, hbb, hbe, hdb, hde, hss;
145 			short vft, vbb, vbe, vdb, vde, vss;
146 			/* auxiliary information */
147 			short mono;
148 			short ste_mode;
149 			short bpp;
150 			u32 pseudo_palette[16];
151 		} falcon;
152 #endif
153 		/* Nothing needed for external mode */
154 	} hw;
155 } current_par;
156 
157 /* Don't calculate an own resolution, and thus don't change the one found when
158  * booting (currently used for the Falcon to keep settings for internal video
159  * hardware extensions (e.g. ScreenBlaster)  */
160 static int DontCalcRes = 0;
161 
162 #ifdef ATAFB_FALCON
163 #define HHT hw.falcon.hht
164 #define HBB hw.falcon.hbb
165 #define HBE hw.falcon.hbe
166 #define HDB hw.falcon.hdb
167 #define HDE hw.falcon.hde
168 #define HSS hw.falcon.hss
169 #define VFT hw.falcon.vft
170 #define VBB hw.falcon.vbb
171 #define VBE hw.falcon.vbe
172 #define VDB hw.falcon.vdb
173 #define VDE hw.falcon.vde
174 #define VSS hw.falcon.vss
175 #define VCO_CLOCK25		0x04
176 #define VCO_CSYPOS		0x10
177 #define VCO_VSYPOS		0x20
178 #define VCO_HSYPOS		0x40
179 #define VCO_SHORTOFFS	0x100
180 #define VMO_DOUBLE		0x01
181 #define VMO_INTER		0x02
182 #define VMO_PREMASK		0x0c
183 #endif
184 
185 static struct fb_info fb_info = {
186 	.fix = {
187 		.id	= "Atari ",
188 		.visual	= FB_VISUAL_PSEUDOCOLOR,
189 		.accel	= FB_ACCEL_NONE,
190 	}
191 };
192 
193 static void *screen_base;	/* base address of screen */
194 static unsigned long phys_screen_base;	/* (only for Overscan) */
195 
196 static int screen_len;
197 
198 static int current_par_valid;
199 
200 static int mono_moni;
201 
202 
203 #ifdef ATAFB_EXT
204 
205 /* external video handling */
206 static unsigned int external_xres;
207 static unsigned int external_xres_virtual;
208 static unsigned int external_yres;
209 
210 /*
211  * not needed - atafb will never support panning/hardwarescroll with external
212  * static unsigned int external_yres_virtual;
213  */
214 static unsigned int external_depth;
215 static int external_pmode;
216 static void *external_screen_base;
217 static unsigned long external_addr;
218 static unsigned long external_len;
219 static unsigned long external_vgaiobase;
220 static unsigned int external_bitspercol = 6;
221 
222 /*
223  * JOE <joe@amber.dinoco.de>:
224  * added card type for external driver, is only needed for
225  * colormap handling.
226  */
227 enum cardtype { IS_VGA, IS_MV300 };
228 static enum cardtype external_card_type = IS_VGA;
229 
230 /*
231  * The MV300 mixes the color registers. So we need an array of munged
232  * indices in order to access the correct reg.
233  */
234 static int MV300_reg_1bit[2] = {
235 	0, 1
236 };
237 static int MV300_reg_4bit[16] = {
238 	0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
239 };
240 static int MV300_reg_8bit[256] = {
241 	0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240,
242 	8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248,
243 	4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,
244 	12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252,
245 	2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
246 	10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250,
247 	6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246,
248 	14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254,
249 	1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241,
250 	9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
251 	5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245,
252 	13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
253 	3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
254 	11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
255 	7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
256 	15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255
257 };
258 
259 static int *MV300_reg = MV300_reg_8bit;
260 #endif /* ATAFB_EXT */
261 
262 
263 static int inverse;
264 
265 extern int fontheight_8x8;
266 extern int fontwidth_8x8;
267 extern unsigned char fontdata_8x8[];
268 
269 extern int fontheight_8x16;
270 extern int fontwidth_8x16;
271 extern unsigned char fontdata_8x16[];
272 
273 /*
274  * struct fb_ops {
275  *	* open/release and usage marking
276  *	struct module *owner;
277  *	int (*fb_open)(struct fb_info *info, int user);
278  *	int (*fb_release)(struct fb_info *info, int user);
279  *
280  *	* For framebuffers with strange non linear layouts or that do not
281  *	* work with normal memory mapped access
282  *	ssize_t (*fb_read)(struct file *file, char __user *buf, size_t count, loff_t *ppos);
283  *	ssize_t (*fb_write)(struct file *file, const char __user *buf, size_t count, loff_t *ppos);
284  *
285  *	* checks var and eventually tweaks it to something supported,
286  *	* DOES NOT MODIFY PAR *
287  *	int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
288  *
289  *	* set the video mode according to info->var *
290  *	int (*fb_set_par)(struct fb_info *info);
291  *
292  *	* set color register *
293  *	int (*fb_setcolreg)(unsigned int regno, unsigned int red, unsigned int green,
294  *			    unsigned int blue, unsigned int transp, struct fb_info *info);
295  *
296  *	* set color registers in batch *
297  *	int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
298  *
299  *	* blank display *
300  *	int (*fb_blank)(int blank, struct fb_info *info);
301  *
302  *	* pan display *
303  *	int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
304  *
305  *	*** The meat of the drawing engine ***
306  *	* Draws a rectangle *
307  *	void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
308  *	* Copy data from area to another *
309  *	void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
310  *	* Draws a image to the display *
311  *	void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
312  *
313  *	* Draws cursor *
314  *	int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
315  *
316  *	* Rotates the display *
317  *	void (*fb_rotate)(struct fb_info *info, int angle);
318  *
319  *	* wait for blit idle, optional *
320  *	int (*fb_sync)(struct fb_info *info);
321  *
322  *	* perform fb specific ioctl (optional) *
323  *	int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
324  *			unsigned long arg);
325  *
326  *	* Handle 32bit compat ioctl (optional) *
327  *	int (*fb_compat_ioctl)(struct fb_info *info, unsigned int cmd,
328  *			unsigned long arg);
329  *
330  *	* perform fb specific mmap *
331  *	int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
332  * } ;
333  */
334 
335 
336 /* ++roman: This structure abstracts from the underlying hardware (ST(e),
337  * TT, or Falcon.
338  *
339  * int (*detect)(void)
340  *   This function should detect the current video mode settings and
341  *   store them in atafb_predefined[0] for later reference by the
342  *   user. Return the index+1 of an equivalent predefined mode or 0
343  *   if there is no such.
344  *
345  * int (*encode_fix)(struct fb_fix_screeninfo *fix,
346  *                   struct atafb_par *par)
347  *   This function should fill in the 'fix' structure based on the
348  *   values in the 'par' structure.
349  * !!! Obsolete, perhaps !!!
350  *
351  * int (*decode_var)(struct fb_var_screeninfo *var,
352  *                   struct atafb_par *par)
353  *   Get the video params out of 'var'. If a value doesn't fit, round
354  *   it up, if it's too big, return EINVAL.
355  *   Round up in the following order: bits_per_pixel, xres, yres,
356  *   xres_virtual, yres_virtual, xoffset, yoffset, grayscale, bitfields,
357  *   horizontal timing, vertical timing.
358  *
359  * int (*encode_var)(struct fb_var_screeninfo *var,
360  *                   struct atafb_par *par);
361  *   Fill the 'var' structure based on the values in 'par' and maybe
362  *   other values read out of the hardware.
363  *
364  * void (*get_par)(struct atafb_par *par)
365  *   Fill the hardware's 'par' structure.
366  *   !!! Used only by detect() !!!
367  *
368  * void (*set_par)(struct atafb_par *par)
369  *   Set the hardware according to 'par'.
370  *
371  * void (*set_screen_base)(void *s_base)
372  *   Set the base address of the displayed frame buffer. Only called
373  *   if yres_virtual > yres or xres_virtual > xres.
374  *
375  * int (*blank)(int blank_mode)
376  *   Blank the screen if blank_mode != 0, else unblank. If blank == NULL then
377  *   the caller blanks by setting the CLUT to all black. Return 0 if blanking
378  *   succeeded, !=0 if un-/blanking failed due to e.g. a video mode which
379  *   doesn't support it. Implements VESA suspend and powerdown modes on
380  *   hardware that supports disabling hsync/vsync:
381  *       blank_mode == 2: suspend vsync, 3:suspend hsync, 4: powerdown.
382  */
383 
384 static struct fb_hwswitch {
385 	int (*detect)(void);
386 	int (*encode_fix)(struct fb_fix_screeninfo *fix,
387 			  struct atafb_par *par);
388 	int (*decode_var)(struct fb_var_screeninfo *var,
389 			  struct atafb_par *par);
390 	int (*encode_var)(struct fb_var_screeninfo *var,
391 			  struct atafb_par *par);
392 	void (*get_par)(struct atafb_par *par);
393 	void (*set_par)(struct atafb_par *par);
394 	void (*set_screen_base)(void *s_base);
395 	int (*blank)(int blank_mode);
396 	int (*pan_display)(struct fb_var_screeninfo *var,
397 			   struct fb_info *info);
398 } *fbhw;
399 
400 static char *autodetect_names[] = { "autodetect", NULL };
401 static char *stlow_names[] = { "stlow", NULL };
402 static char *stmid_names[] = { "stmid", "default5", NULL };
403 static char *sthigh_names[] = { "sthigh", "default4", NULL };
404 static char *ttlow_names[] = { "ttlow", NULL };
405 static char *ttmid_names[] = { "ttmid", "default1", NULL };
406 static char *tthigh_names[] = { "tthigh", "default2", NULL };
407 static char *vga2_names[] = { "vga2", NULL };
408 static char *vga4_names[] = { "vga4", NULL };
409 static char *vga16_names[] = { "vga16", "default3", NULL };
410 static char *vga256_names[] = { "vga256", NULL };
411 static char *falh2_names[] = { "falh2", NULL };
412 static char *falh16_names[] = { "falh16", NULL };
413 
414 static char **fb_var_names[] = {
415 	autodetect_names,
416 	stlow_names,
417 	stmid_names,
418 	sthigh_names,
419 	ttlow_names,
420 	ttmid_names,
421 	tthigh_names,
422 	vga2_names,
423 	vga4_names,
424 	vga16_names,
425 	vga256_names,
426 	falh2_names,
427 	falh16_names,
428 	NULL
429 };
430 
431 static struct fb_var_screeninfo atafb_predefined[] = {
432 	/*
433 	 * yres_virtual == 0 means use hw-scrolling if possible, else yres
434 	 */
435 	{ /* autodetect */
436 	  0, 0, 0, 0, 0, 0, 0, 0,		/* xres-grayscale */
437 	  {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},	/* red green blue tran*/
438 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
439 	{ /* st low */
440 	  320, 200, 320, 0, 0, 0, 4, 0,
441 	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
442 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
443 	{ /* st mid */
444 	  640, 200, 640, 0, 0, 0, 2, 0,
445 	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
446 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
447 	{ /* st high */
448 	  640, 400, 640, 0, 0, 0, 1, 0,
449 	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
450 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
451 	{ /* tt low */
452 	  320, 480, 320, 0, 0, 0, 8, 0,
453 	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
454 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
455 	{ /* tt mid */
456 	  640, 480, 640, 0, 0, 0, 4, 0,
457 	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
458 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
459 	{ /* tt high */
460 	  1280, 960, 1280, 0, 0, 0, 1, 0,
461 	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
462 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
463 	{ /* vga2 */
464 	  640, 480, 640, 0, 0, 0, 1, 0,
465 	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
466 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
467 	{ /* vga4 */
468 	  640, 480, 640, 0, 0, 0, 2, 0,
469 	  {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
470 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
471 	{ /* vga16 */
472 	  640, 480, 640, 0, 0, 0, 4, 0,
473 	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
474 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
475 	{ /* vga256 */
476 	  640, 480, 640, 0, 0, 0, 8, 0,
477 	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
478 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
479 	{ /* falh2 */
480 	  896, 608, 896, 0, 0, 0, 1, 0,
481 	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
482 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
483 	{ /* falh16 */
484 	  896, 608, 896, 0, 0, 0, 4, 0,
485 	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
486 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
487 };
488 
489 static int num_atafb_predefined = ARRAY_SIZE(atafb_predefined);
490 
491 static struct fb_videomode atafb_modedb[] __initdata = {
492 	/*
493 	 *  Atari Video Modes
494 	 *
495 	 *  If you change these, make sure to update DEFMODE_* as well!
496 	 */
497 
498 	/*
499 	 *  ST/TT Video Modes
500 	 */
501 
502 	{
503 		/* 320x200, 15 kHz, 60 Hz (ST low) */
504 		"st-low", 60, 320, 200, 32000, 32, 16, 31, 14, 96, 4,
505 		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
506 	}, {
507 		/* 640x200, 15 kHz, 60 Hz (ST medium) */
508 		"st-mid", 60, 640, 200, 32000, 32, 16, 31, 14, 96, 4,
509 		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
510 	}, {
511 		/* 640x400, 30.25 kHz, 63.5 Hz (ST high) */
512 		"st-high", 63, 640, 400, 32000, 128, 0, 40, 14, 128, 4,
513 		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
514 	}, {
515 		/* 320x480, 15 kHz, 60 Hz (TT low) */
516 		"tt-low", 60, 320, 480, 31041, 120, 100, 8, 16, 140, 30,
517 		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
518 	}, {
519 		/* 640x480, 29 kHz, 57 Hz (TT medium) */
520 		"tt-mid", 60, 640, 480, 31041, 120, 100, 8, 16, 140, 30,
521 		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
522 	}, {
523 		/* 1280x960, 29 kHz, 60 Hz (TT high) */
524 		"tt-high", 57, 640, 960, 31041, 120, 100, 8, 16, 140, 30,
525 		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
526 	},
527 
528 	/*
529 	 *  VGA Video Modes
530 	 */
531 
532 	{
533 		/* 640x480, 31 kHz, 60 Hz (VGA) */
534 		"vga", 63.5, 640, 480, 32000, 18, 42, 31, 11, 96, 3,
535 		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
536 	}, {
537 		/* 640x400, 31 kHz, 70 Hz (VGA) */
538 		"vga70", 70, 640, 400, 32000, 18, 42, 31, 11, 96, 3,
539 		FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
540 	},
541 
542 	/*
543 	 *  Falcon HiRes Video Modes
544 	 */
545 
546 	{
547 		/* 896x608, 31 kHz, 60 Hz (Falcon High) */
548 		"falh", 60, 896, 608, 32000, 18, 42, 31, 1, 96,3,
549 		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
550 	},
551 };
552 
553 #define NUM_TOTAL_MODES  ARRAY_SIZE(atafb_modedb)
554 
555 static char *mode_option __initdata = NULL;
556 
557  /* default modes */
558 
559 #define DEFMODE_TT	5		/* "tt-high" for TT */
560 #define DEFMODE_F30	7		/* "vga70" for Falcon */
561 #define DEFMODE_STE	2		/* "st-high" for ST/E */
562 #define DEFMODE_EXT	6		/* "vga" for external */
563 
564 
565 static int get_video_mode(char *vname)
566 {
567 	char ***name_list;
568 	char **name;
569 	int i;
570 
571 	name_list = fb_var_names;
572 	for (i = 0; i < num_atafb_predefined; i++) {
573 		name = *name_list++;
574 		if (!name || !*name)
575 			break;
576 		while (*name) {
577 			if (!strcmp(vname, *name))
578 				return i + 1;
579 			name++;
580 		}
581 	}
582 	return 0;
583 }
584 
585 
586 
587 /* ------------------- TT specific functions ---------------------- */
588 
589 #ifdef ATAFB_TT
590 
591 static int tt_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par)
592 {
593 	int mode;
594 
595 	strcpy(fix->id, "Atari Builtin");
596 	fix->smem_start = phys_screen_base;
597 	fix->smem_len = screen_len;
598 	fix->type = FB_TYPE_INTERLEAVED_PLANES;
599 	fix->type_aux = 2;
600 	fix->visual = FB_VISUAL_PSEUDOCOLOR;
601 	mode = par->hw.tt.mode & TT_SHIFTER_MODEMASK;
602 	if (mode == TT_SHIFTER_TTHIGH || mode == TT_SHIFTER_STHIGH) {
603 		fix->type = FB_TYPE_PACKED_PIXELS;
604 		fix->type_aux = 0;
605 		if (mode == TT_SHIFTER_TTHIGH)
606 			fix->visual = FB_VISUAL_MONO01;
607 	}
608 	fix->xpanstep = 0;
609 	fix->ypanstep = 1;
610 	fix->ywrapstep = 0;
611 	fix->line_length = par->next_line;
612 	fix->accel = FB_ACCEL_ATARIBLITT;
613 	return 0;
614 }
615 
616 static int tt_decode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
617 {
618 	int xres = var->xres;
619 	int yres = var->yres;
620 	int bpp = var->bits_per_pixel;
621 	int linelen;
622 	int yres_virtual = var->yres_virtual;
623 
624 	if (mono_moni) {
625 		if (bpp > 1 || xres > sttt_xres * 2 || yres > tt_yres * 2)
626 			return -EINVAL;
627 		par->hw.tt.mode = TT_SHIFTER_TTHIGH;
628 		xres = sttt_xres * 2;
629 		yres = tt_yres * 2;
630 		bpp = 1;
631 	} else {
632 		if (bpp > 8 || xres > sttt_xres || yres > tt_yres)
633 			return -EINVAL;
634 		if (bpp > 4) {
635 			if (xres > sttt_xres / 2 || yres > tt_yres)
636 				return -EINVAL;
637 			par->hw.tt.mode = TT_SHIFTER_TTLOW;
638 			xres = sttt_xres / 2;
639 			yres = tt_yres;
640 			bpp = 8;
641 		} else if (bpp > 2) {
642 			if (xres > sttt_xres || yres > tt_yres)
643 				return -EINVAL;
644 			if (xres > sttt_xres / 2 || yres > st_yres / 2) {
645 				par->hw.tt.mode = TT_SHIFTER_TTMID;
646 				xres = sttt_xres;
647 				yres = tt_yres;
648 				bpp = 4;
649 			} else {
650 				par->hw.tt.mode = TT_SHIFTER_STLOW;
651 				xres = sttt_xres / 2;
652 				yres = st_yres / 2;
653 				bpp = 4;
654 			}
655 		} else if (bpp > 1) {
656 			if (xres > sttt_xres || yres > st_yres / 2)
657 				return -EINVAL;
658 			par->hw.tt.mode = TT_SHIFTER_STMID;
659 			xres = sttt_xres;
660 			yres = st_yres / 2;
661 			bpp = 2;
662 		} else if (var->xres > sttt_xres || var->yres > st_yres) {
663 			return -EINVAL;
664 		} else {
665 			par->hw.tt.mode = TT_SHIFTER_STHIGH;
666 			xres = sttt_xres;
667 			yres = st_yres;
668 			bpp = 1;
669 		}
670 	}
671 	if (yres_virtual <= 0)
672 		yres_virtual = 0;
673 	else if (yres_virtual < yres)
674 		yres_virtual = yres;
675 	if (var->sync & FB_SYNC_EXT)
676 		par->hw.tt.sync = 0;
677 	else
678 		par->hw.tt.sync = 1;
679 	linelen = xres * bpp / 8;
680 	if (yres_virtual * linelen > screen_len && screen_len)
681 		return -EINVAL;
682 	if (yres * linelen > screen_len && screen_len)
683 		return -EINVAL;
684 	if (var->yoffset + yres > yres_virtual && yres_virtual)
685 		return -EINVAL;
686 	par->yres_virtual = yres_virtual;
687 	par->screen_base = screen_base + var->yoffset * linelen;
688 	par->next_line = linelen;
689 	return 0;
690 }
691 
692 static int tt_encode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
693 {
694 	int linelen;
695 	memset(var, 0, sizeof(struct fb_var_screeninfo));
696 	var->red.offset = 0;
697 	var->red.length = 4;
698 	var->red.msb_right = 0;
699 	var->grayscale = 0;
700 
701 	var->pixclock = 31041;
702 	var->left_margin = 120;		/* these may be incorrect */
703 	var->right_margin = 100;
704 	var->upper_margin = 8;
705 	var->lower_margin = 16;
706 	var->hsync_len = 140;
707 	var->vsync_len = 30;
708 
709 	var->height = -1;
710 	var->width = -1;
711 
712 	if (par->hw.tt.sync & 1)
713 		var->sync = 0;
714 	else
715 		var->sync = FB_SYNC_EXT;
716 
717 	switch (par->hw.tt.mode & TT_SHIFTER_MODEMASK) {
718 	case TT_SHIFTER_STLOW:
719 		var->xres = sttt_xres / 2;
720 		var->xres_virtual = sttt_xres_virtual / 2;
721 		var->yres = st_yres / 2;
722 		var->bits_per_pixel = 4;
723 		break;
724 	case TT_SHIFTER_STMID:
725 		var->xres = sttt_xres;
726 		var->xres_virtual = sttt_xres_virtual;
727 		var->yres = st_yres / 2;
728 		var->bits_per_pixel = 2;
729 		break;
730 	case TT_SHIFTER_STHIGH:
731 		var->xres = sttt_xres;
732 		var->xres_virtual = sttt_xres_virtual;
733 		var->yres = st_yres;
734 		var->bits_per_pixel = 1;
735 		break;
736 	case TT_SHIFTER_TTLOW:
737 		var->xres = sttt_xres / 2;
738 		var->xres_virtual = sttt_xres_virtual / 2;
739 		var->yres = tt_yres;
740 		var->bits_per_pixel = 8;
741 		break;
742 	case TT_SHIFTER_TTMID:
743 		var->xres = sttt_xres;
744 		var->xres_virtual = sttt_xres_virtual;
745 		var->yres = tt_yres;
746 		var->bits_per_pixel = 4;
747 		break;
748 	case TT_SHIFTER_TTHIGH:
749 		var->red.length = 0;
750 		var->xres = sttt_xres * 2;
751 		var->xres_virtual = sttt_xres_virtual * 2;
752 		var->yres = tt_yres * 2;
753 		var->bits_per_pixel = 1;
754 		break;
755 	}
756 	var->blue = var->green = var->red;
757 	var->transp.offset = 0;
758 	var->transp.length = 0;
759 	var->transp.msb_right = 0;
760 	linelen = var->xres_virtual * var->bits_per_pixel / 8;
761 	if (!use_hwscroll)
762 		var->yres_virtual = var->yres;
763 	else if (screen_len) {
764 		if (par->yres_virtual)
765 			var->yres_virtual = par->yres_virtual;
766 		else
767 			/* yres_virtual == 0 means use maximum */
768 			var->yres_virtual = screen_len / linelen;
769 	} else {
770 		if (hwscroll < 0)
771 			var->yres_virtual = 2 * var->yres;
772 		else
773 			var->yres_virtual = var->yres + hwscroll * 16;
774 	}
775 	var->xoffset = 0;
776 	if (screen_base)
777 		var->yoffset = (par->screen_base - screen_base) / linelen;
778 	else
779 		var->yoffset = 0;
780 	var->nonstd = 0;
781 	var->activate = 0;
782 	var->vmode = FB_VMODE_NONINTERLACED;
783 	return 0;
784 }
785 
786 static void tt_get_par(struct atafb_par *par)
787 {
788 	unsigned long addr;
789 	par->hw.tt.mode = shifter_tt.tt_shiftmode;
790 	par->hw.tt.sync = shifter.syncmode;
791 	addr = ((shifter.bas_hi & 0xff) << 16) |
792 	       ((shifter.bas_md & 0xff) << 8)  |
793 	       ((shifter.bas_lo & 0xff));
794 	par->screen_base = atari_stram_to_virt(addr);
795 }
796 
797 static void tt_set_par(struct atafb_par *par)
798 {
799 	shifter_tt.tt_shiftmode = par->hw.tt.mode;
800 	shifter.syncmode = par->hw.tt.sync;
801 	/* only set screen_base if really necessary */
802 	if (current_par.screen_base != par->screen_base)
803 		fbhw->set_screen_base(par->screen_base);
804 }
805 
806 static int tt_setcolreg(unsigned int regno, unsigned int red,
807 			unsigned int green, unsigned int blue,
808 			unsigned int transp, struct fb_info *info)
809 {
810 	if ((shifter_tt.tt_shiftmode & TT_SHIFTER_MODEMASK) == TT_SHIFTER_STHIGH)
811 		regno += 254;
812 	if (regno > 255)
813 		return 1;
814 	tt_palette[regno] = (((red >> 12) << 8) | ((green >> 12) << 4) |
815 			     (blue >> 12));
816 	if ((shifter_tt.tt_shiftmode & TT_SHIFTER_MODEMASK) ==
817 	    TT_SHIFTER_STHIGH && regno == 254)
818 		tt_palette[0] = 0;
819 	return 0;
820 }
821 
822 static int tt_detect(void)
823 {
824 	struct atafb_par par;
825 
826 	/* Determine the connected monitor: The DMA sound must be
827 	 * disabled before reading the MFP GPIP, because the Sound
828 	 * Done Signal and the Monochrome Detect are XORed together!
829 	 *
830 	 * Even on a TT, we should look if there is a DMA sound. It was
831 	 * announced that the Eagle is TT compatible, but only the PCM is
832 	 * missing...
833 	 */
834 	if (ATARIHW_PRESENT(PCM_8BIT)) {
835 		tt_dmasnd.ctrl = DMASND_CTRL_OFF;
836 		udelay(20);		/* wait a while for things to settle down */
837 	}
838 	mono_moni = (st_mfp.par_dt_reg & 0x80) == 0;
839 
840 	tt_get_par(&par);
841 	tt_encode_var(&atafb_predefined[0], &par);
842 
843 	return 1;
844 }
845 
846 #endif /* ATAFB_TT */
847 
848 /* ------------------- Falcon specific functions ---------------------- */
849 
850 #ifdef ATAFB_FALCON
851 
852 static int mon_type;		/* Falcon connected monitor */
853 static int f030_bus_width;	/* Falcon ram bus width (for vid_control) */
854 #define F_MON_SM	0
855 #define F_MON_SC	1
856 #define F_MON_VGA	2
857 #define F_MON_TV	3
858 
859 static struct pixel_clock {
860 	unsigned long f;	/* f/[Hz] */
861 	unsigned long t;	/* t/[ps] (=1/f) */
862 	int right, hsync, left;	/* standard timing in clock cycles, not pixel */
863 	/* hsync initialized in falcon_detect() */
864 	int sync_mask;		/* or-mask for hw.falcon.sync to set this clock */
865 	int control_mask;	/* ditto, for hw.falcon.vid_control */
866 } f25 = {
867 	25175000, 39721, 18, 0, 42, 0x0, VCO_CLOCK25
868 }, f32 = {
869 	32000000, 31250, 18, 0, 42, 0x0, 0
870 }, fext = {
871 	0, 0, 18, 0, 42, 0x1, 0
872 };
873 
874 /* VIDEL-prescale values [mon_type][pixel_length from VCO] */
875 static int vdl_prescale[4][3] = {
876 	{ 4,2,1 }, { 4,2,1 }, { 4,2,2 }, { 4,2,1 }
877 };
878 
879 /* Default hsync timing [mon_type] in picoseconds */
880 static long h_syncs[4] = { 3000000, 4875000, 4000000, 4875000 };
881 
882 static inline int hxx_prescale(struct falcon_hw *hw)
883 {
884 	return hw->ste_mode ? 16
885 			    : vdl_prescale[mon_type][hw->vid_mode >> 2 & 0x3];
886 }
887 
888 static int falcon_encode_fix(struct fb_fix_screeninfo *fix,
889 			     struct atafb_par *par)
890 {
891 	strcpy(fix->id, "Atari Builtin");
892 	fix->smem_start = phys_screen_base;
893 	fix->smem_len = screen_len;
894 	fix->type = FB_TYPE_INTERLEAVED_PLANES;
895 	fix->type_aux = 2;
896 	fix->visual = FB_VISUAL_PSEUDOCOLOR;
897 	fix->xpanstep = 1;
898 	fix->ypanstep = 1;
899 	fix->ywrapstep = 0;
900 	if (par->hw.falcon.mono) {
901 		fix->type = FB_TYPE_PACKED_PIXELS;
902 		fix->type_aux = 0;
903 		/* no smooth scrolling with longword aligned video mem */
904 		fix->xpanstep = 32;
905 	} else if (par->hw.falcon.f_shift & 0x100) {
906 		fix->type = FB_TYPE_PACKED_PIXELS;
907 		fix->type_aux = 0;
908 		/* Is this ok or should it be DIRECTCOLOR? */
909 		fix->visual = FB_VISUAL_TRUECOLOR;
910 		fix->xpanstep = 2;
911 	}
912 	fix->line_length = par->next_line;
913 	fix->accel = FB_ACCEL_ATARIBLITT;
914 	return 0;
915 }
916 
917 static int falcon_decode_var(struct fb_var_screeninfo *var,
918 			     struct atafb_par *par)
919 {
920 	int bpp = var->bits_per_pixel;
921 	int xres = var->xres;
922 	int yres = var->yres;
923 	int xres_virtual = var->xres_virtual;
924 	int yres_virtual = var->yres_virtual;
925 	int left_margin, right_margin, hsync_len;
926 	int upper_margin, lower_margin, vsync_len;
927 	int linelen;
928 	int interlace = 0, doubleline = 0;
929 	struct pixel_clock *pclock;
930 	int plen;			/* width of pixel in clock cycles */
931 	int xstretch;
932 	int prescale;
933 	int longoffset = 0;
934 	int hfreq, vfreq;
935 	int hdb_off, hde_off, base_off;
936 	int gstart, gend1, gend2, align;
937 
938 /*
939 	Get the video params out of 'var'. If a value doesn't fit, round
940 	it up, if it's too big, return EINVAL.
941 	Round up in the following order: bits_per_pixel, xres, yres,
942 	xres_virtual, yres_virtual, xoffset, yoffset, grayscale, bitfields,
943 	horizontal timing, vertical timing.
944 
945 	There is a maximum of screen resolution determined by pixelclock
946 	and minimum frame rate -- (X+hmarg.)*(Y+vmarg.)*vfmin <= pixelclock.
947 	In interlace mode this is     "     *    "     *vfmin <= pixelclock.
948 	Additional constraints: hfreq.
949 	Frequency range for multisync monitors is given via command line.
950 	For TV and SM124 both frequencies are fixed.
951 
952 	X % 16 == 0 to fit 8x?? font (except 1 bitplane modes must use X%32 == 0)
953 	Y % 16 == 0 to fit 8x16 font
954 	Y % 8 == 0 if Y<400
955 
956 	Currently interlace and doubleline mode in var are ignored.
957 	On SM124 and TV only the standard resolutions can be used.
958 */
959 
960 	/* Reject uninitialized mode */
961 	if (!xres || !yres || !bpp)
962 		return -EINVAL;
963 
964 	if (mon_type == F_MON_SM && bpp != 1)
965 		return -EINVAL;
966 
967 	if (bpp <= 1) {
968 		bpp = 1;
969 		par->hw.falcon.f_shift = 0x400;
970 		par->hw.falcon.st_shift = 0x200;
971 	} else if (bpp <= 2) {
972 		bpp = 2;
973 		par->hw.falcon.f_shift = 0x000;
974 		par->hw.falcon.st_shift = 0x100;
975 	} else if (bpp <= 4) {
976 		bpp = 4;
977 		par->hw.falcon.f_shift = 0x000;
978 		par->hw.falcon.st_shift = 0x000;
979 	} else if (bpp <= 8) {
980 		bpp = 8;
981 		par->hw.falcon.f_shift = 0x010;
982 	} else if (bpp <= 16) {
983 		bpp = 16;		/* packed pixel mode */
984 		par->hw.falcon.f_shift = 0x100;	/* hicolor, no overlay */
985 	} else
986 		return -EINVAL;
987 	par->hw.falcon.bpp = bpp;
988 
989 	if (mon_type == F_MON_SM || DontCalcRes) {
990 		/* Skip all calculations. VGA/TV/SC1224 only supported. */
991 		struct fb_var_screeninfo *myvar = &atafb_predefined[0];
992 
993 		if (bpp > myvar->bits_per_pixel ||
994 		    var->xres > myvar->xres ||
995 		    var->yres > myvar->yres)
996 			return -EINVAL;
997 		fbhw->get_par(par);	/* Current par will be new par */
998 		goto set_screen_base;	/* Don't forget this */
999 	}
1000 
1001 	/* Only some fixed resolutions < 640x400 */
1002 	if (xres <= 320)
1003 		xres = 320;
1004 	else if (xres <= 640 && bpp != 16)
1005 		xres = 640;
1006 	if (yres <= 200)
1007 		yres = 200;
1008 	else if (yres <= 240)
1009 		yres = 240;
1010 	else if (yres <= 400)
1011 		yres = 400;
1012 
1013 	/* 2 planes must use STE compatibility mode */
1014 	par->hw.falcon.ste_mode = bpp == 2;
1015 	par->hw.falcon.mono = bpp == 1;
1016 
1017 	/* Total and visible scanline length must be a multiple of one longword,
1018 	 * this and the console fontwidth yields the alignment for xres and
1019 	 * xres_virtual.
1020 	 * TODO: this way "odd" fontheights are not supported
1021 	 *
1022 	 * Special case in STE mode: blank and graphic positions don't align,
1023 	 * avoid trash at right margin
1024 	 */
1025 	if (par->hw.falcon.ste_mode)
1026 		xres = (xres + 63) & ~63;
1027 	else if (bpp == 1)
1028 		xres = (xres + 31) & ~31;
1029 	else
1030 		xres = (xres + 15) & ~15;
1031 	if (yres >= 400)
1032 		yres = (yres + 15) & ~15;
1033 	else
1034 		yres = (yres + 7) & ~7;
1035 
1036 	if (xres_virtual < xres)
1037 		xres_virtual = xres;
1038 	else if (bpp == 1)
1039 		xres_virtual = (xres_virtual + 31) & ~31;
1040 	else
1041 		xres_virtual = (xres_virtual + 15) & ~15;
1042 
1043 	if (yres_virtual <= 0)
1044 		yres_virtual = 0;
1045 	else if (yres_virtual < yres)
1046 		yres_virtual = yres;
1047 
1048 	/* backward bug-compatibility */
1049 	if (var->pixclock > 1)
1050 		var->pixclock -= 1;
1051 
1052 	par->hw.falcon.line_width = bpp * xres / 16;
1053 	par->hw.falcon.line_offset = bpp * (xres_virtual - xres) / 16;
1054 
1055 	/* single or double pixel width */
1056 	xstretch = (xres < 640) ? 2 : 1;
1057 
1058 #if 0 /* SM124 supports only 640x400, this is rejected above */
1059 	if (mon_type == F_MON_SM) {
1060 		if (xres != 640 && yres != 400)
1061 			return -EINVAL;
1062 		plen = 1;
1063 		pclock = &f32;
1064 		/* SM124-mode is special */
1065 		par->hw.falcon.ste_mode = 1;
1066 		par->hw.falcon.f_shift = 0x000;
1067 		par->hw.falcon.st_shift = 0x200;
1068 		left_margin = hsync_len = 128 / plen;
1069 		right_margin = 0;
1070 		/* TODO set all margins */
1071 	} else
1072 #endif
1073 	if (mon_type == F_MON_SC || mon_type == F_MON_TV) {
1074 		plen = 2 * xstretch;
1075 		if (var->pixclock > f32.t * plen)
1076 			return -EINVAL;
1077 		pclock = &f32;
1078 		if (yres > 240)
1079 			interlace = 1;
1080 		if (var->pixclock == 0) {
1081 			/* set some minimal margins which center the screen */
1082 			left_margin = 32;
1083 			right_margin = 18;
1084 			hsync_len = pclock->hsync / plen;
1085 			upper_margin = 31;
1086 			lower_margin = 14;
1087 			vsync_len = interlace ? 3 : 4;
1088 		} else {
1089 			left_margin = var->left_margin;
1090 			right_margin = var->right_margin;
1091 			hsync_len = var->hsync_len;
1092 			upper_margin = var->upper_margin;
1093 			lower_margin = var->lower_margin;
1094 			vsync_len = var->vsync_len;
1095 			if (var->vmode & FB_VMODE_INTERLACED) {
1096 				upper_margin = (upper_margin + 1) / 2;
1097 				lower_margin = (lower_margin + 1) / 2;
1098 				vsync_len = (vsync_len + 1) / 2;
1099 			} else if (var->vmode & FB_VMODE_DOUBLE) {
1100 				upper_margin *= 2;
1101 				lower_margin *= 2;
1102 				vsync_len *= 2;
1103 			}
1104 		}
1105 	} else {			/* F_MON_VGA */
1106 		if (bpp == 16)
1107 			xstretch = 2;	/* Double pixel width only for hicolor */
1108 		/* Default values are used for vert./hor. timing if no pixelclock given. */
1109 		if (var->pixclock == 0) {
1110 			int linesize;
1111 
1112 			/* Choose master pixelclock depending on hor. timing */
1113 			plen = 1 * xstretch;
1114 			if ((plen * xres + f25.right + f25.hsync + f25.left) *
1115 			    fb_info.monspecs.hfmin < f25.f)
1116 				pclock = &f25;
1117 			else if ((plen * xres + f32.right + f32.hsync +
1118 				  f32.left) * fb_info.monspecs.hfmin < f32.f)
1119 				pclock = &f32;
1120 			else if ((plen * xres + fext.right + fext.hsync +
1121 				  fext.left) * fb_info.monspecs.hfmin < fext.f &&
1122 			         fext.f)
1123 				pclock = &fext;
1124 			else
1125 				return -EINVAL;
1126 
1127 			left_margin = pclock->left / plen;
1128 			right_margin = pclock->right / plen;
1129 			hsync_len = pclock->hsync / plen;
1130 			linesize = left_margin + xres + right_margin + hsync_len;
1131 			upper_margin = 31;
1132 			lower_margin = 11;
1133 			vsync_len = 3;
1134 		} else {
1135 			/* Choose largest pixelclock <= wanted clock */
1136 			int i;
1137 			unsigned long pcl = ULONG_MAX;
1138 			pclock = 0;
1139 			for (i = 1; i <= 4; i *= 2) {
1140 				if (f25.t * i >= var->pixclock &&
1141 				    f25.t * i < pcl) {
1142 					pcl = f25.t * i;
1143 					pclock = &f25;
1144 				}
1145 				if (f32.t * i >= var->pixclock &&
1146 				    f32.t * i < pcl) {
1147 					pcl = f32.t * i;
1148 					pclock = &f32;
1149 				}
1150 				if (fext.t && fext.t * i >= var->pixclock &&
1151 				    fext.t * i < pcl) {
1152 					pcl = fext.t * i;
1153 					pclock = &fext;
1154 				}
1155 			}
1156 			if (!pclock)
1157 				return -EINVAL;
1158 			plen = pcl / pclock->t;
1159 
1160 			left_margin = var->left_margin;
1161 			right_margin = var->right_margin;
1162 			hsync_len = var->hsync_len;
1163 			upper_margin = var->upper_margin;
1164 			lower_margin = var->lower_margin;
1165 			vsync_len = var->vsync_len;
1166 			/* Internal unit is [single lines per (half-)frame] */
1167 			if (var->vmode & FB_VMODE_INTERLACED) {
1168 				/* # lines in half frame */
1169 				/* External unit is [lines per full frame] */
1170 				upper_margin = (upper_margin + 1) / 2;
1171 				lower_margin = (lower_margin + 1) / 2;
1172 				vsync_len = (vsync_len + 1) / 2;
1173 			} else if (var->vmode & FB_VMODE_DOUBLE) {
1174 				/* External unit is [double lines per frame] */
1175 				upper_margin *= 2;
1176 				lower_margin *= 2;
1177 				vsync_len *= 2;
1178 			}
1179 		}
1180 		if (pclock == &fext)
1181 			longoffset = 1;	/* VIDEL doesn't synchronize on short offset */
1182 	}
1183 	/* Is video bus bandwidth (32MB/s) too low for this resolution? */
1184 	/* this is definitely wrong if bus clock != 32MHz */
1185 	if (pclock->f / plen / 8 * bpp > 32000000L)
1186 		return -EINVAL;
1187 
1188 	if (vsync_len < 1)
1189 		vsync_len = 1;
1190 
1191 	/* include sync lengths in right/lower margin for all calculations */
1192 	right_margin += hsync_len;
1193 	lower_margin += vsync_len;
1194 
1195 	/* ! In all calculations of margins we use # of lines in half frame
1196 	 * (which is a full frame in non-interlace mode), so we can switch
1197 	 * between interlace and non-interlace without messing around
1198 	 * with these.
1199 	 */
1200 again:
1201 	/* Set base_offset 128 and video bus width */
1202 	par->hw.falcon.vid_control = mon_type | f030_bus_width;
1203 	if (!longoffset)
1204 		par->hw.falcon.vid_control |= VCO_SHORTOFFS;	/* base_offset 64 */
1205 	if (var->sync & FB_SYNC_HOR_HIGH_ACT)
1206 		par->hw.falcon.vid_control |= VCO_HSYPOS;
1207 	if (var->sync & FB_SYNC_VERT_HIGH_ACT)
1208 		par->hw.falcon.vid_control |= VCO_VSYPOS;
1209 	/* Pixelclock */
1210 	par->hw.falcon.vid_control |= pclock->control_mask;
1211 	/* External or internal clock */
1212 	par->hw.falcon.sync = pclock->sync_mask | 0x2;
1213 	/* Pixellength and prescale */
1214 	par->hw.falcon.vid_mode = (2 / plen) << 2;
1215 	if (doubleline)
1216 		par->hw.falcon.vid_mode |= VMO_DOUBLE;
1217 	if (interlace)
1218 		par->hw.falcon.vid_mode |= VMO_INTER;
1219 
1220 	/*********************
1221 	 * Horizontal timing: unit = [master clock cycles]
1222 	 * unit of hxx-registers: [master clock cycles * prescale]
1223 	 * Hxx-registers are 9 bit wide
1224 	 *
1225 	 * 1 line = ((hht + 2) * 2 * prescale) clock cycles
1226 	 *
1227 	 * graphic output = hdb & 0x200 ?
1228 	 *        ((hht + 2) * 2 - hdb + hde) * prescale - hdboff + hdeoff:
1229 	 *        (hht + 2  - hdb + hde) * prescale - hdboff + hdeoff
1230 	 * (this must be a multiple of plen*128/bpp, on VGA pixels
1231 	 *  to the right may be cut off with a bigger right margin)
1232 	 *
1233 	 * start of graphics relative to start of 1st halfline = hdb & 0x200 ?
1234 	 *        (hdb - hht - 2) * prescale + hdboff :
1235 	 *        hdb * prescale + hdboff
1236 	 *
1237 	 * end of graphics relative to start of 1st halfline =
1238 	 *        (hde + hht + 2) * prescale + hdeoff
1239 	 *********************/
1240 	/* Calculate VIDEL registers */
1241 {
1242 	prescale = hxx_prescale(&par->hw.falcon);
1243 	base_off = par->hw.falcon.vid_control & VCO_SHORTOFFS ? 64 : 128;
1244 
1245 	/* Offsets depend on video mode */
1246 	/* Offsets are in clock cycles, divide by prescale to
1247 	 * calculate hd[be]-registers
1248 	 */
1249 	if (par->hw.falcon.f_shift & 0x100) {
1250 		align = 1;
1251 		hde_off = 0;
1252 		hdb_off = (base_off + 16 * plen) + prescale;
1253 	} else {
1254 		align = 128 / bpp;
1255 		hde_off = ((128 / bpp + 2) * plen);
1256 		if (par->hw.falcon.ste_mode)
1257 			hdb_off = (64 + base_off + (128 / bpp + 2) * plen) + prescale;
1258 		else
1259 			hdb_off = (base_off + (128 / bpp + 18) * plen) + prescale;
1260 	}
1261 
1262 	gstart = (prescale / 2 + plen * left_margin) / prescale;
1263 	/* gend1 is for hde (gend-gstart multiple of align), shifter's xres */
1264 	gend1 = gstart + roundup(xres, align) * plen / prescale;
1265 	/* gend2 is for hbb, visible xres (rest to gend1 is cut off by hblank) */
1266 	gend2 = gstart + xres * plen / prescale;
1267 	par->HHT = plen * (left_margin + xres + right_margin) /
1268 			   (2 * prescale) - 2;
1269 /*	par->HHT = (gend2 + plen * right_margin / prescale) / 2 - 2;*/
1270 
1271 	par->HDB = gstart - hdb_off / prescale;
1272 	par->HBE = gstart;
1273 	if (par->HDB < 0)
1274 		par->HDB += par->HHT + 2 + 0x200;
1275 	par->HDE = gend1 - par->HHT - 2 - hde_off / prescale;
1276 	par->HBB = gend2 - par->HHT - 2;
1277 #if 0
1278 	/* One more Videl constraint: data fetch of two lines must not overlap */
1279 	if ((par->HDB & 0x200) && (par->HDB & ~0x200) - par->HDE <= 5) {
1280 		/* if this happens increase margins, decrease hfreq. */
1281 	}
1282 #endif
1283 	if (hde_off % prescale)
1284 		par->HBB++;		/* compensate for non matching hde and hbb */
1285 	par->HSS = par->HHT + 2 - plen * hsync_len / prescale;
1286 	if (par->HSS < par->HBB)
1287 		par->HSS = par->HBB;
1288 }
1289 
1290 	/*  check hor. frequency */
1291 	hfreq = pclock->f / ((par->HHT + 2) * prescale * 2);
1292 	if (hfreq > fb_info.monspecs.hfmax && mon_type != F_MON_VGA) {
1293 		/* ++guenther:   ^^^^^^^^^^^^^^^^^^^ can't remember why I did this */
1294 		/* Too high -> enlarge margin */
1295 		left_margin += 1;
1296 		right_margin += 1;
1297 		goto again;
1298 	}
1299 	if (hfreq > fb_info.monspecs.hfmax || hfreq < fb_info.monspecs.hfmin)
1300 		return -EINVAL;
1301 
1302 	/* Vxx-registers */
1303 	/* All Vxx must be odd in non-interlace, since frame starts in the middle
1304 	 * of the first displayed line!
1305 	 * One frame consists of VFT+1 half lines. VFT+1 must be even in
1306 	 * non-interlace, odd in interlace mode for synchronisation.
1307 	 * Vxx-registers are 11 bit wide
1308 	 */
1309 	par->VBE = (upper_margin * 2 + 1); /* must begin on odd halfline */
1310 	par->VDB = par->VBE;
1311 	par->VDE = yres;
1312 	if (!interlace)
1313 		par->VDE <<= 1;
1314 	if (doubleline)
1315 		par->VDE <<= 1;		/* VDE now half lines per (half-)frame */
1316 	par->VDE += par->VDB;
1317 	par->VBB = par->VDE;
1318 	par->VFT = par->VBB + (lower_margin * 2 - 1) - 1;
1319 	par->VSS = par->VFT + 1 - (vsync_len * 2 - 1);
1320 	/* vbb,vss,vft must be even in interlace mode */
1321 	if (interlace) {
1322 		par->VBB++;
1323 		par->VSS++;
1324 		par->VFT++;
1325 	}
1326 
1327 	/* V-frequency check, hope I didn't create any loop here. */
1328 	/* Interlace and doubleline are mutually exclusive. */
1329 	vfreq = (hfreq * 2) / (par->VFT + 1);
1330 	if (vfreq > fb_info.monspecs.vfmax && !doubleline && !interlace) {
1331 		/* Too high -> try again with doubleline */
1332 		doubleline = 1;
1333 		goto again;
1334 	} else if (vfreq < fb_info.monspecs.vfmin && !interlace && !doubleline) {
1335 		/* Too low -> try again with interlace */
1336 		interlace = 1;
1337 		goto again;
1338 	} else if (vfreq < fb_info.monspecs.vfmin && doubleline) {
1339 		/* Doubleline too low -> clear doubleline and enlarge margins */
1340 		int lines;
1341 		doubleline = 0;
1342 		for (lines = 0;
1343 		     (hfreq * 2) / (par->VFT + 1 + 4 * lines - 2 * yres) >
1344 		     fb_info.monspecs.vfmax;
1345 		     lines++)
1346 			;
1347 		upper_margin += lines;
1348 		lower_margin += lines;
1349 		goto again;
1350 	} else if (vfreq > fb_info.monspecs.vfmax && doubleline) {
1351 		/* Doubleline too high -> enlarge margins */
1352 		int lines;
1353 		for (lines = 0;
1354 		     (hfreq * 2) / (par->VFT + 1 + 4 * lines) >
1355 		     fb_info.monspecs.vfmax;
1356 		     lines += 2)
1357 			;
1358 		upper_margin += lines;
1359 		lower_margin += lines;
1360 		goto again;
1361 	} else if (vfreq > fb_info.monspecs.vfmax && interlace) {
1362 		/* Interlace, too high -> enlarge margins */
1363 		int lines;
1364 		for (lines = 0;
1365 		     (hfreq * 2) / (par->VFT + 1 + 4 * lines) >
1366 		     fb_info.monspecs.vfmax;
1367 		     lines++)
1368 			;
1369 		upper_margin += lines;
1370 		lower_margin += lines;
1371 		goto again;
1372 	} else if (vfreq < fb_info.monspecs.vfmin ||
1373 		   vfreq > fb_info.monspecs.vfmax)
1374 		return -EINVAL;
1375 
1376 set_screen_base:
1377 	linelen = xres_virtual * bpp / 8;
1378 	if (yres_virtual * linelen > screen_len && screen_len)
1379 		return -EINVAL;
1380 	if (yres * linelen > screen_len && screen_len)
1381 		return -EINVAL;
1382 	if (var->yoffset + yres > yres_virtual && yres_virtual)
1383 		return -EINVAL;
1384 	par->yres_virtual = yres_virtual;
1385 	par->screen_base = screen_base + var->yoffset * linelen;
1386 	par->hw.falcon.xoffset = 0;
1387 
1388 	par->next_line = linelen;
1389 
1390 	return 0;
1391 }
1392 
1393 static int falcon_encode_var(struct fb_var_screeninfo *var,
1394 			     struct atafb_par *par)
1395 {
1396 /* !!! only for VGA !!! */
1397 	int linelen;
1398 	int prescale, plen;
1399 	int hdb_off, hde_off, base_off;
1400 	struct falcon_hw *hw = &par->hw.falcon;
1401 
1402 	memset(var, 0, sizeof(struct fb_var_screeninfo));
1403 	/* possible frequencies: 25.175 or 32MHz */
1404 	var->pixclock = hw->sync & 0x1 ? fext.t :
1405 	                hw->vid_control & VCO_CLOCK25 ? f25.t : f32.t;
1406 
1407 	var->height = -1;
1408 	var->width = -1;
1409 
1410 	var->sync = 0;
1411 	if (hw->vid_control & VCO_HSYPOS)
1412 		var->sync |= FB_SYNC_HOR_HIGH_ACT;
1413 	if (hw->vid_control & VCO_VSYPOS)
1414 		var->sync |= FB_SYNC_VERT_HIGH_ACT;
1415 
1416 	var->vmode = FB_VMODE_NONINTERLACED;
1417 	if (hw->vid_mode & VMO_INTER)
1418 		var->vmode |= FB_VMODE_INTERLACED;
1419 	if (hw->vid_mode & VMO_DOUBLE)
1420 		var->vmode |= FB_VMODE_DOUBLE;
1421 
1422 	/* visible y resolution:
1423 	 * Graphics display starts at line VDB and ends at line
1424 	 * VDE. If interlace mode off unit of VC-registers is
1425 	 * half lines, else lines.
1426 	 */
1427 	var->yres = hw->vde - hw->vdb;
1428 	if (!(var->vmode & FB_VMODE_INTERLACED))
1429 		var->yres >>= 1;
1430 	if (var->vmode & FB_VMODE_DOUBLE)
1431 		var->yres >>= 1;
1432 
1433 	/*
1434 	 * to get bpp, we must examine f_shift and st_shift.
1435 	 * f_shift is valid if any of bits no. 10, 8 or 4
1436 	 * is set. Priority in f_shift is: 10 ">" 8 ">" 4, i.e.
1437 	 * if bit 10 set then bit 8 and bit 4 don't care...
1438 	 * If all these bits are 0 get display depth from st_shift
1439 	 * (as for ST and STE)
1440 	 */
1441 	if (hw->f_shift & 0x400)	/* 2 colors */
1442 		var->bits_per_pixel = 1;
1443 	else if (hw->f_shift & 0x100)	/* hicolor */
1444 		var->bits_per_pixel = 16;
1445 	else if (hw->f_shift & 0x010)	/* 8 bitplanes */
1446 		var->bits_per_pixel = 8;
1447 	else if (hw->st_shift == 0)
1448 		var->bits_per_pixel = 4;
1449 	else if (hw->st_shift == 0x100)
1450 		var->bits_per_pixel = 2;
1451 	else				/* if (hw->st_shift == 0x200) */
1452 		var->bits_per_pixel = 1;
1453 
1454 	var->xres = hw->line_width * 16 / var->bits_per_pixel;
1455 	var->xres_virtual = var->xres + hw->line_offset * 16 / var->bits_per_pixel;
1456 	if (hw->xoffset)
1457 		var->xres_virtual += 16;
1458 
1459 	if (var->bits_per_pixel == 16) {
1460 		var->red.offset = 11;
1461 		var->red.length = 5;
1462 		var->red.msb_right = 0;
1463 		var->green.offset = 5;
1464 		var->green.length = 6;
1465 		var->green.msb_right = 0;
1466 		var->blue.offset = 0;
1467 		var->blue.length = 5;
1468 		var->blue.msb_right = 0;
1469 	} else {
1470 		var->red.offset = 0;
1471 		var->red.length = hw->ste_mode ? 4 : 6;
1472 		if (var->red.length > var->bits_per_pixel)
1473 			var->red.length = var->bits_per_pixel;
1474 		var->red.msb_right = 0;
1475 		var->grayscale = 0;
1476 		var->blue = var->green = var->red;
1477 	}
1478 	var->transp.offset = 0;
1479 	var->transp.length = 0;
1480 	var->transp.msb_right = 0;
1481 
1482 	linelen = var->xres_virtual * var->bits_per_pixel / 8;
1483 	if (screen_len) {
1484 		if (par->yres_virtual)
1485 			var->yres_virtual = par->yres_virtual;
1486 		else
1487 			/* yres_virtual == 0 means use maximum */
1488 			var->yres_virtual = screen_len / linelen;
1489 	} else {
1490 		if (hwscroll < 0)
1491 			var->yres_virtual = 2 * var->yres;
1492 		else
1493 			var->yres_virtual = var->yres + hwscroll * 16;
1494 	}
1495 	var->xoffset = 0;		/* TODO change this */
1496 
1497 	/* hdX-offsets */
1498 	prescale = hxx_prescale(hw);
1499 	plen = 4 >> (hw->vid_mode >> 2 & 0x3);
1500 	base_off = hw->vid_control & VCO_SHORTOFFS ? 64 : 128;
1501 	if (hw->f_shift & 0x100) {
1502 		hde_off = 0;
1503 		hdb_off = (base_off + 16 * plen) + prescale;
1504 	} else {
1505 		hde_off = ((128 / var->bits_per_pixel + 2) * plen);
1506 		if (hw->ste_mode)
1507 			hdb_off = (64 + base_off + (128 / var->bits_per_pixel + 2) * plen)
1508 					 + prescale;
1509 		else
1510 			hdb_off = (base_off + (128 / var->bits_per_pixel + 18) * plen)
1511 					 + prescale;
1512 	}
1513 
1514 	/* Right margin includes hsync */
1515 	var->left_margin = hdb_off + prescale * ((hw->hdb & 0x1ff) -
1516 					   (hw->hdb & 0x200 ? 2 + hw->hht : 0));
1517 	if (hw->ste_mode || mon_type != F_MON_VGA)
1518 		var->right_margin = prescale * (hw->hht + 2 - hw->hde) - hde_off;
1519 	else
1520 		/* can't use this in ste_mode, because hbb is +1 off */
1521 		var->right_margin = prescale * (hw->hht + 2 - hw->hbb);
1522 	var->hsync_len = prescale * (hw->hht + 2 - hw->hss);
1523 
1524 	/* Lower margin includes vsync */
1525 	var->upper_margin = hw->vdb / 2;	/* round down to full lines */
1526 	var->lower_margin = (hw->vft + 1 - hw->vde + 1) / 2;	/* round up */
1527 	var->vsync_len = (hw->vft + 1 - hw->vss + 1) / 2;	/* round up */
1528 	if (var->vmode & FB_VMODE_INTERLACED) {
1529 		var->upper_margin *= 2;
1530 		var->lower_margin *= 2;
1531 		var->vsync_len *= 2;
1532 	} else if (var->vmode & FB_VMODE_DOUBLE) {
1533 		var->upper_margin = (var->upper_margin + 1) / 2;
1534 		var->lower_margin = (var->lower_margin + 1) / 2;
1535 		var->vsync_len = (var->vsync_len + 1) / 2;
1536 	}
1537 
1538 	var->pixclock *= plen;
1539 	var->left_margin /= plen;
1540 	var->right_margin /= plen;
1541 	var->hsync_len /= plen;
1542 
1543 	var->right_margin -= var->hsync_len;
1544 	var->lower_margin -= var->vsync_len;
1545 
1546 	if (screen_base)
1547 		var->yoffset = (par->screen_base - screen_base) / linelen;
1548 	else
1549 		var->yoffset = 0;
1550 	var->nonstd = 0;		/* what is this for? */
1551 	var->activate = 0;
1552 	return 0;
1553 }
1554 
1555 static int f_change_mode;
1556 static struct falcon_hw f_new_mode;
1557 static int f_pan_display;
1558 
1559 static void falcon_get_par(struct atafb_par *par)
1560 {
1561 	unsigned long addr;
1562 	struct falcon_hw *hw = &par->hw.falcon;
1563 
1564 	hw->line_width = shifter_f030.scn_width;
1565 	hw->line_offset = shifter_f030.off_next;
1566 	hw->st_shift = videl.st_shift & 0x300;
1567 	hw->f_shift = videl.f_shift;
1568 	hw->vid_control = videl.control;
1569 	hw->vid_mode = videl.mode;
1570 	hw->sync = shifter.syncmode & 0x1;
1571 	hw->xoffset = videl.xoffset & 0xf;
1572 	hw->hht = videl.hht;
1573 	hw->hbb = videl.hbb;
1574 	hw->hbe = videl.hbe;
1575 	hw->hdb = videl.hdb;
1576 	hw->hde = videl.hde;
1577 	hw->hss = videl.hss;
1578 	hw->vft = videl.vft;
1579 	hw->vbb = videl.vbb;
1580 	hw->vbe = videl.vbe;
1581 	hw->vdb = videl.vdb;
1582 	hw->vde = videl.vde;
1583 	hw->vss = videl.vss;
1584 
1585 	addr = (shifter.bas_hi & 0xff) << 16 |
1586 	       (shifter.bas_md & 0xff) << 8  |
1587 	       (shifter.bas_lo & 0xff);
1588 	par->screen_base = atari_stram_to_virt(addr);
1589 
1590 	/* derived parameters */
1591 	hw->ste_mode = (hw->f_shift & 0x510) == 0 && hw->st_shift == 0x100;
1592 	hw->mono = (hw->f_shift & 0x400) ||
1593 	           ((hw->f_shift & 0x510) == 0 && hw->st_shift == 0x200);
1594 }
1595 
1596 static void falcon_set_par(struct atafb_par *par)
1597 {
1598 	f_change_mode = 0;
1599 
1600 	/* only set screen_base if really necessary */
1601 	if (current_par.screen_base != par->screen_base)
1602 		fbhw->set_screen_base(par->screen_base);
1603 
1604 	/* Don't touch any other registers if we keep the default resolution */
1605 	if (DontCalcRes)
1606 		return;
1607 
1608 	/* Tell vbl-handler to change video mode.
1609 	 * We change modes only on next VBL, to avoid desynchronisation
1610 	 * (a shift to the right and wrap around by a random number of pixels
1611 	 * in all monochrome modes).
1612 	 * This seems to work on my Falcon.
1613 	 */
1614 	f_new_mode = par->hw.falcon;
1615 	f_change_mode = 1;
1616 }
1617 
1618 static irqreturn_t falcon_vbl_switcher(int irq, void *dummy)
1619 {
1620 	struct falcon_hw *hw = &f_new_mode;
1621 
1622 	if (f_change_mode) {
1623 		f_change_mode = 0;
1624 
1625 		if (hw->sync & 0x1) {
1626 			/* Enable external pixelclock. This code only for ScreenWonder */
1627 			*(volatile unsigned short *)0xffff9202 = 0xffbf;
1628 		} else {
1629 			/* Turn off external clocks. Read sets all output bits to 1. */
1630 			*(volatile unsigned short *)0xffff9202;
1631 		}
1632 		shifter.syncmode = hw->sync;
1633 
1634 		videl.hht = hw->hht;
1635 		videl.hbb = hw->hbb;
1636 		videl.hbe = hw->hbe;
1637 		videl.hdb = hw->hdb;
1638 		videl.hde = hw->hde;
1639 		videl.hss = hw->hss;
1640 		videl.vft = hw->vft;
1641 		videl.vbb = hw->vbb;
1642 		videl.vbe = hw->vbe;
1643 		videl.vdb = hw->vdb;
1644 		videl.vde = hw->vde;
1645 		videl.vss = hw->vss;
1646 
1647 		videl.f_shift = 0;	/* write enables Falcon palette, 0: 4 planes */
1648 		if (hw->ste_mode) {
1649 			videl.st_shift = hw->st_shift;	/* write enables STE palette */
1650 		} else {
1651 			/* IMPORTANT:
1652 			 * set st_shift 0, so we can tell the screen-depth if f_shift == 0.
1653 			 * Writing 0 to f_shift enables 4 plane Falcon mode but
1654 			 * doesn't set st_shift. st_shift != 0 (!= 4planes) is impossible
1655 			 * with Falcon palette.
1656 			 */
1657 			videl.st_shift = 0;
1658 			/* now back to Falcon palette mode */
1659 			videl.f_shift = hw->f_shift;
1660 		}
1661 		/* writing to st_shift changed scn_width and vid_mode */
1662 		videl.xoffset = hw->xoffset;
1663 		shifter_f030.scn_width = hw->line_width;
1664 		shifter_f030.off_next = hw->line_offset;
1665 		videl.control = hw->vid_control;
1666 		videl.mode = hw->vid_mode;
1667 	}
1668 	if (f_pan_display) {
1669 		f_pan_display = 0;
1670 		videl.xoffset = current_par.hw.falcon.xoffset;
1671 		shifter_f030.off_next = current_par.hw.falcon.line_offset;
1672 	}
1673 	return IRQ_HANDLED;
1674 }
1675 
1676 static int falcon_pan_display(struct fb_var_screeninfo *var,
1677 			      struct fb_info *info)
1678 {
1679 	struct atafb_par *par = (struct atafb_par *)info->par;
1680 
1681 	int xoffset;
1682 	int bpp = info->var.bits_per_pixel;
1683 
1684 	if (bpp == 1)
1685 		var->xoffset = up(var->xoffset, 32);
1686 	if (bpp != 16)
1687 		par->hw.falcon.xoffset = var->xoffset & 15;
1688 	else {
1689 		par->hw.falcon.xoffset = 0;
1690 		var->xoffset = up(var->xoffset, 2);
1691 	}
1692 	par->hw.falcon.line_offset = bpp *
1693 		(info->var.xres_virtual - info->var.xres) / 16;
1694 	if (par->hw.falcon.xoffset)
1695 		par->hw.falcon.line_offset -= bpp;
1696 	xoffset = var->xoffset - par->hw.falcon.xoffset;
1697 
1698 	par->screen_base = screen_base +
1699 	        (var->yoffset * info->var.xres_virtual + xoffset) * bpp / 8;
1700 	if (fbhw->set_screen_base)
1701 		fbhw->set_screen_base(par->screen_base);
1702 	else
1703 		return -EINVAL;		/* shouldn't happen */
1704 	f_pan_display = 1;
1705 	return 0;
1706 }
1707 
1708 static int falcon_setcolreg(unsigned int regno, unsigned int red,
1709 			    unsigned int green, unsigned int blue,
1710 			    unsigned int transp, struct fb_info *info)
1711 {
1712 	if (regno > 255)
1713 		return 1;
1714 	f030_col[regno] = (((red & 0xfc00) << 16) |
1715 			   ((green & 0xfc00) << 8) |
1716 			   ((blue & 0xfc00) >> 8));
1717 	if (regno < 16) {
1718 		shifter_tt.color_reg[regno] =
1719 			(((red & 0xe000) >> 13) | ((red & 0x1000) >> 12) << 8) |
1720 			(((green & 0xe000) >> 13) | ((green & 0x1000) >> 12) << 4) |
1721 			((blue & 0xe000) >> 13) | ((blue & 0x1000) >> 12);
1722 		((u32 *)info->pseudo_palette)[regno] = ((red & 0xf800) |
1723 						       ((green & 0xfc00) >> 5) |
1724 						       ((blue & 0xf800) >> 11));
1725 	}
1726 	return 0;
1727 }
1728 
1729 static int falcon_blank(int blank_mode)
1730 {
1731 	/* ++guenther: we can switch off graphics by changing VDB and VDE,
1732 	 * so VIDEL doesn't hog the bus while saving.
1733 	 * (this may affect usleep()).
1734 	 */
1735 	int vdb, vss, hbe, hss;
1736 
1737 	if (mon_type == F_MON_SM)	/* this doesn't work on SM124 */
1738 		return 1;
1739 
1740 	vdb = current_par.VDB;
1741 	vss = current_par.VSS;
1742 	hbe = current_par.HBE;
1743 	hss = current_par.HSS;
1744 
1745 	if (blank_mode >= 1) {
1746 		/* disable graphics output (this speeds up the CPU) ... */
1747 		vdb = current_par.VFT + 1;
1748 		/* ... and blank all lines */
1749 		hbe = current_par.HHT + 2;
1750 	}
1751 	/* use VESA suspend modes on VGA monitors */
1752 	if (mon_type == F_MON_VGA) {
1753 		if (blank_mode == 2 || blank_mode == 4)
1754 			vss = current_par.VFT + 1;
1755 		if (blank_mode == 3 || blank_mode == 4)
1756 			hss = current_par.HHT + 2;
1757 	}
1758 
1759 	videl.vdb = vdb;
1760 	videl.vss = vss;
1761 	videl.hbe = hbe;
1762 	videl.hss = hss;
1763 
1764 	return 0;
1765 }
1766 
1767 static int falcon_detect(void)
1768 {
1769 	struct atafb_par par;
1770 	unsigned char fhw;
1771 
1772 	/* Determine connected monitor and set monitor parameters */
1773 	fhw = *(unsigned char *)0xffff8006;
1774 	mon_type = fhw >> 6 & 0x3;
1775 	/* bit 1 of fhw: 1=32 bit ram bus, 0=16 bit */
1776 	f030_bus_width = fhw << 6 & 0x80;
1777 	switch (mon_type) {
1778 	case F_MON_SM:
1779 		fb_info.monspecs.vfmin = 70;
1780 		fb_info.monspecs.vfmax = 72;
1781 		fb_info.monspecs.hfmin = 35713;
1782 		fb_info.monspecs.hfmax = 35715;
1783 		break;
1784 	case F_MON_SC:
1785 	case F_MON_TV:
1786 		/* PAL...NTSC */
1787 		fb_info.monspecs.vfmin = 49;	/* not 50, since TOS defaults to 49.9x Hz */
1788 		fb_info.monspecs.vfmax = 60;
1789 		fb_info.monspecs.hfmin = 15620;
1790 		fb_info.monspecs.hfmax = 15755;
1791 		break;
1792 	}
1793 	/* initialize hsync-len */
1794 	f25.hsync = h_syncs[mon_type] / f25.t;
1795 	f32.hsync = h_syncs[mon_type] / f32.t;
1796 	if (fext.t)
1797 		fext.hsync = h_syncs[mon_type] / fext.t;
1798 
1799 	falcon_get_par(&par);
1800 	falcon_encode_var(&atafb_predefined[0], &par);
1801 
1802 	/* Detected mode is always the "autodetect" slot */
1803 	return 1;
1804 }
1805 
1806 #endif /* ATAFB_FALCON */
1807 
1808 /* ------------------- ST(E) specific functions ---------------------- */
1809 
1810 #ifdef ATAFB_STE
1811 
1812 static int stste_encode_fix(struct fb_fix_screeninfo *fix,
1813 			    struct atafb_par *par)
1814 {
1815 	int mode;
1816 
1817 	strcpy(fix->id, "Atari Builtin");
1818 	fix->smem_start = phys_screen_base;
1819 	fix->smem_len = screen_len;
1820 	fix->type = FB_TYPE_INTERLEAVED_PLANES;
1821 	fix->type_aux = 2;
1822 	fix->visual = FB_VISUAL_PSEUDOCOLOR;
1823 	mode = par->hw.st.mode & 3;
1824 	if (mode == ST_HIGH) {
1825 		fix->type = FB_TYPE_PACKED_PIXELS;
1826 		fix->type_aux = 0;
1827 		fix->visual = FB_VISUAL_MONO10;
1828 	}
1829 	if (ATARIHW_PRESENT(EXTD_SHIFTER)) {
1830 		fix->xpanstep = 16;
1831 		fix->ypanstep = 1;
1832 	} else {
1833 		fix->xpanstep = 0;
1834 		fix->ypanstep = 0;
1835 	}
1836 	fix->ywrapstep = 0;
1837 	fix->line_length = par->next_line;
1838 	fix->accel = FB_ACCEL_ATARIBLITT;
1839 	return 0;
1840 }
1841 
1842 static int stste_decode_var(struct fb_var_screeninfo *var,
1843 			    struct atafb_par *par)
1844 {
1845 	int xres = var->xres;
1846 	int yres = var->yres;
1847 	int bpp = var->bits_per_pixel;
1848 	int linelen;
1849 	int yres_virtual = var->yres_virtual;
1850 
1851 	if (mono_moni) {
1852 		if (bpp > 1 || xres > sttt_xres || yres > st_yres)
1853 			return -EINVAL;
1854 		par->hw.st.mode = ST_HIGH;
1855 		xres = sttt_xres;
1856 		yres = st_yres;
1857 		bpp = 1;
1858 	} else {
1859 		if (bpp > 4 || xres > sttt_xres || yres > st_yres)
1860 			return -EINVAL;
1861 		if (bpp > 2) {
1862 			if (xres > sttt_xres / 2 || yres > st_yres / 2)
1863 				return -EINVAL;
1864 			par->hw.st.mode = ST_LOW;
1865 			xres = sttt_xres / 2;
1866 			yres = st_yres / 2;
1867 			bpp = 4;
1868 		} else if (bpp > 1) {
1869 			if (xres > sttt_xres || yres > st_yres / 2)
1870 				return -EINVAL;
1871 			par->hw.st.mode = ST_MID;
1872 			xres = sttt_xres;
1873 			yres = st_yres / 2;
1874 			bpp = 2;
1875 		} else
1876 			return -EINVAL;
1877 	}
1878 	if (yres_virtual <= 0)
1879 		yres_virtual = 0;
1880 	else if (yres_virtual < yres)
1881 		yres_virtual = yres;
1882 	if (var->sync & FB_SYNC_EXT)
1883 		par->hw.st.sync = (par->hw.st.sync & ~1) | 1;
1884 	else
1885 		par->hw.st.sync = (par->hw.st.sync & ~1);
1886 	linelen = xres * bpp / 8;
1887 	if (yres_virtual * linelen > screen_len && screen_len)
1888 		return -EINVAL;
1889 	if (yres * linelen > screen_len && screen_len)
1890 		return -EINVAL;
1891 	if (var->yoffset + yres > yres_virtual && yres_virtual)
1892 		return -EINVAL;
1893 	par->yres_virtual = yres_virtual;
1894 	par->screen_base = screen_base + var->yoffset * linelen;
1895 	par->next_line = linelen;
1896 	return 0;
1897 }
1898 
1899 static int stste_encode_var(struct fb_var_screeninfo *var,
1900 			    struct atafb_par *par)
1901 {
1902 	int linelen;
1903 	memset(var, 0, sizeof(struct fb_var_screeninfo));
1904 	var->red.offset = 0;
1905 	var->red.length = ATARIHW_PRESENT(EXTD_SHIFTER) ? 4 : 3;
1906 	var->red.msb_right = 0;
1907 	var->grayscale = 0;
1908 
1909 	var->pixclock = 31041;
1910 	var->left_margin = 120;		/* these are incorrect */
1911 	var->right_margin = 100;
1912 	var->upper_margin = 8;
1913 	var->lower_margin = 16;
1914 	var->hsync_len = 140;
1915 	var->vsync_len = 30;
1916 
1917 	var->height = -1;
1918 	var->width = -1;
1919 
1920 	if (!(par->hw.st.sync & 1))
1921 		var->sync = 0;
1922 	else
1923 		var->sync = FB_SYNC_EXT;
1924 
1925 	switch (par->hw.st.mode & 3) {
1926 	case ST_LOW:
1927 		var->xres = sttt_xres / 2;
1928 		var->yres = st_yres / 2;
1929 		var->bits_per_pixel = 4;
1930 		break;
1931 	case ST_MID:
1932 		var->xres = sttt_xres;
1933 		var->yres = st_yres / 2;
1934 		var->bits_per_pixel = 2;
1935 		break;
1936 	case ST_HIGH:
1937 		var->xres = sttt_xres;
1938 		var->yres = st_yres;
1939 		var->bits_per_pixel = 1;
1940 		break;
1941 	}
1942 	var->blue = var->green = var->red;
1943 	var->transp.offset = 0;
1944 	var->transp.length = 0;
1945 	var->transp.msb_right = 0;
1946 	var->xres_virtual = sttt_xres_virtual;
1947 	linelen = var->xres_virtual * var->bits_per_pixel / 8;
1948 	ovsc_addlen = linelen * (sttt_yres_virtual - st_yres);
1949 
1950 	if (!use_hwscroll)
1951 		var->yres_virtual = var->yres;
1952 	else if (screen_len) {
1953 		if (par->yres_virtual)
1954 			var->yres_virtual = par->yres_virtual;
1955 		else
1956 			/* yres_virtual == 0 means use maximum */
1957 			var->yres_virtual = screen_len / linelen;
1958 	} else {
1959 		if (hwscroll < 0)
1960 			var->yres_virtual = 2 * var->yres;
1961 		else
1962 			var->yres_virtual = var->yres + hwscroll * 16;
1963 	}
1964 	var->xoffset = 0;
1965 	if (screen_base)
1966 		var->yoffset = (par->screen_base - screen_base) / linelen;
1967 	else
1968 		var->yoffset = 0;
1969 	var->nonstd = 0;
1970 	var->activate = 0;
1971 	var->vmode = FB_VMODE_NONINTERLACED;
1972 	return 0;
1973 }
1974 
1975 static void stste_get_par(struct atafb_par *par)
1976 {
1977 	unsigned long addr;
1978 	par->hw.st.mode = shifter_tt.st_shiftmode;
1979 	par->hw.st.sync = shifter.syncmode;
1980 	addr = ((shifter.bas_hi & 0xff) << 16) |
1981 	       ((shifter.bas_md & 0xff) << 8);
1982 	if (ATARIHW_PRESENT(EXTD_SHIFTER))
1983 		addr |= (shifter.bas_lo & 0xff);
1984 	par->screen_base = atari_stram_to_virt(addr);
1985 }
1986 
1987 static void stste_set_par(struct atafb_par *par)
1988 {
1989 	shifter_tt.st_shiftmode = par->hw.st.mode;
1990 	shifter.syncmode = par->hw.st.sync;
1991 	/* only set screen_base if really necessary */
1992 	if (current_par.screen_base != par->screen_base)
1993 		fbhw->set_screen_base(par->screen_base);
1994 }
1995 
1996 static int stste_setcolreg(unsigned int regno, unsigned int red,
1997 			   unsigned int green, unsigned int blue,
1998 			   unsigned int transp, struct fb_info *info)
1999 {
2000 	if (regno > 15)
2001 		return 1;
2002 	red >>= 12;
2003 	blue >>= 12;
2004 	green >>= 12;
2005 	if (ATARIHW_PRESENT(EXTD_SHIFTER))
2006 		shifter_tt.color_reg[regno] =
2007 			(((red & 0xe) >> 1) | ((red & 1) << 3) << 8) |
2008 			(((green & 0xe) >> 1) | ((green & 1) << 3) << 4) |
2009 			((blue & 0xe) >> 1) | ((blue & 1) << 3);
2010 	else
2011 		shifter_tt.color_reg[regno] =
2012 			((red & 0xe) << 7) |
2013 			((green & 0xe) << 3) |
2014 			((blue & 0xe) >> 1);
2015 	return 0;
2016 }
2017 
2018 static int stste_detect(void)
2019 {
2020 	struct atafb_par par;
2021 
2022 	/* Determine the connected monitor: The DMA sound must be
2023 	 * disabled before reading the MFP GPIP, because the Sound
2024 	 * Done Signal and the Monochrome Detect are XORed together!
2025 	 */
2026 	if (ATARIHW_PRESENT(PCM_8BIT)) {
2027 		tt_dmasnd.ctrl = DMASND_CTRL_OFF;
2028 		udelay(20);		/* wait a while for things to settle down */
2029 	}
2030 	mono_moni = (st_mfp.par_dt_reg & 0x80) == 0;
2031 
2032 	stste_get_par(&par);
2033 	stste_encode_var(&atafb_predefined[0], &par);
2034 
2035 	if (!ATARIHW_PRESENT(EXTD_SHIFTER))
2036 		use_hwscroll = 0;
2037 	return 1;
2038 }
2039 
2040 static void stste_set_screen_base(void *s_base)
2041 {
2042 	unsigned long addr;
2043 	addr = atari_stram_to_phys(s_base);
2044 	/* Setup Screen Memory */
2045 	shifter.bas_hi = (unsigned char)((addr & 0xff0000) >> 16);
2046 	shifter.bas_md = (unsigned char)((addr & 0x00ff00) >> 8);
2047 	if (ATARIHW_PRESENT(EXTD_SHIFTER))
2048 		shifter.bas_lo = (unsigned char)(addr & 0x0000ff);
2049 }
2050 
2051 #endif /* ATAFB_STE */
2052 
2053 /* Switching the screen size should be done during vsync, otherwise
2054  * the margins may get messed up. This is a well known problem of
2055  * the ST's video system.
2056  *
2057  * Unfortunately there is hardly any way to find the vsync, as the
2058  * vertical blank interrupt is no longer in time on machines with
2059  * overscan type modifications.
2060  *
2061  * We can, however, use Timer B to safely detect the black shoulder,
2062  * but then we've got to guess an appropriate delay to find the vsync.
2063  * This might not work on every machine.
2064  *
2065  * martin_rogge @ ki.maus.de, 8th Aug 1995
2066  */
2067 
2068 #define LINE_DELAY  (mono_moni ? 30 : 70)
2069 #define SYNC_DELAY  (mono_moni ? 1500 : 2000)
2070 
2071 /* SWITCH_ACIA may be used for Falcon (ScreenBlaster III internal!) */
2072 static void st_ovsc_switch(void)
2073 {
2074 	unsigned long flags;
2075 	register unsigned char old, new;
2076 
2077 	if (!(atari_switches & ATARI_SWITCH_OVSC_MASK))
2078 		return;
2079 	local_irq_save(flags);
2080 
2081 	st_mfp.tim_ct_b = 0x10;
2082 	st_mfp.active_edge |= 8;
2083 	st_mfp.tim_ct_b = 0;
2084 	st_mfp.tim_dt_b = 0xf0;
2085 	st_mfp.tim_ct_b = 8;
2086 	while (st_mfp.tim_dt_b > 1)	/* TOS does it this way, don't ask why */
2087 		;
2088 	new = st_mfp.tim_dt_b;
2089 	do {
2090 		udelay(LINE_DELAY);
2091 		old = new;
2092 		new = st_mfp.tim_dt_b;
2093 	} while (old != new);
2094 	st_mfp.tim_ct_b = 0x10;
2095 	udelay(SYNC_DELAY);
2096 
2097 	if (atari_switches & ATARI_SWITCH_OVSC_IKBD)
2098 		acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID | ACIA_RIE;
2099 	if (atari_switches & ATARI_SWITCH_OVSC_MIDI)
2100 		acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID;
2101 	if (atari_switches & (ATARI_SWITCH_OVSC_SND6|ATARI_SWITCH_OVSC_SND7)) {
2102 		sound_ym.rd_data_reg_sel = 14;
2103 		sound_ym.wd_data = sound_ym.rd_data_reg_sel |
2104 				   ((atari_switches & ATARI_SWITCH_OVSC_SND6) ? 0x40:0) |
2105 				   ((atari_switches & ATARI_SWITCH_OVSC_SND7) ? 0x80:0);
2106 	}
2107 	local_irq_restore(flags);
2108 }
2109 
2110 /* ------------------- External Video ---------------------- */
2111 
2112 #ifdef ATAFB_EXT
2113 
2114 static int ext_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par)
2115 {
2116 	strcpy(fix->id, "Unknown Extern");
2117 	fix->smem_start = external_addr;
2118 	fix->smem_len = PAGE_ALIGN(external_len);
2119 	if (external_depth == 1) {
2120 		fix->type = FB_TYPE_PACKED_PIXELS;
2121 		/* The letters 'n' and 'i' in the "atavideo=external:" stand
2122 		 * for "normal" and "inverted", rsp., in the monochrome case */
2123 		fix->visual =
2124 			(external_pmode == FB_TYPE_INTERLEAVED_PLANES ||
2125 			 external_pmode == FB_TYPE_PACKED_PIXELS) ?
2126 				FB_VISUAL_MONO10 : FB_VISUAL_MONO01;
2127 	} else {
2128 		/* Use STATIC if we don't know how to access color registers */
2129 		int visual = external_vgaiobase ?
2130 					 FB_VISUAL_PSEUDOCOLOR :
2131 					 FB_VISUAL_STATIC_PSEUDOCOLOR;
2132 		switch (external_pmode) {
2133 		case -1:		/* truecolor */
2134 			fix->type = FB_TYPE_PACKED_PIXELS;
2135 			fix->visual = FB_VISUAL_TRUECOLOR;
2136 			break;
2137 		case FB_TYPE_PACKED_PIXELS:
2138 			fix->type = FB_TYPE_PACKED_PIXELS;
2139 			fix->visual = visual;
2140 			break;
2141 		case FB_TYPE_PLANES:
2142 			fix->type = FB_TYPE_PLANES;
2143 			fix->visual = visual;
2144 			break;
2145 		case FB_TYPE_INTERLEAVED_PLANES:
2146 			fix->type = FB_TYPE_INTERLEAVED_PLANES;
2147 			fix->type_aux = 2;
2148 			fix->visual = visual;
2149 			break;
2150 		}
2151 	}
2152 	fix->xpanstep = 0;
2153 	fix->ypanstep = 0;
2154 	fix->ywrapstep = 0;
2155 	fix->line_length = par->next_line;
2156 	return 0;
2157 }
2158 
2159 static int ext_decode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
2160 {
2161 	struct fb_var_screeninfo *myvar = &atafb_predefined[0];
2162 
2163 	if (var->bits_per_pixel > myvar->bits_per_pixel ||
2164 	    var->xres > myvar->xres ||
2165 	    var->xres_virtual > myvar->xres_virtual ||
2166 	    var->yres > myvar->yres ||
2167 	    var->xoffset > 0 ||
2168 	    var->yoffset > 0)
2169 		return -EINVAL;
2170 
2171 	par->next_line = external_xres_virtual * external_depth / 8;
2172 	return 0;
2173 }
2174 
2175 static int ext_encode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
2176 {
2177 	memset(var, 0, sizeof(struct fb_var_screeninfo));
2178 	var->red.offset = 0;
2179 	var->red.length = (external_pmode == -1) ? external_depth / 3 :
2180 			(external_vgaiobase ? external_bitspercol : 0);
2181 	var->red.msb_right = 0;
2182 	var->grayscale = 0;
2183 
2184 	var->pixclock = 31041;
2185 	var->left_margin = 120;		/* these are surely incorrect */
2186 	var->right_margin = 100;
2187 	var->upper_margin = 8;
2188 	var->lower_margin = 16;
2189 	var->hsync_len = 140;
2190 	var->vsync_len = 30;
2191 
2192 	var->height = -1;
2193 	var->width = -1;
2194 
2195 	var->sync = 0;
2196 
2197 	var->xres = external_xres;
2198 	var->yres = external_yres;
2199 	var->xres_virtual = external_xres_virtual;
2200 	var->bits_per_pixel = external_depth;
2201 
2202 	var->blue = var->green = var->red;
2203 	var->transp.offset = 0;
2204 	var->transp.length = 0;
2205 	var->transp.msb_right = 0;
2206 	var->yres_virtual = var->yres;
2207 	var->xoffset = 0;
2208 	var->yoffset = 0;
2209 	var->nonstd = 0;
2210 	var->activate = 0;
2211 	var->vmode = FB_VMODE_NONINTERLACED;
2212 	return 0;
2213 }
2214 
2215 static void ext_get_par(struct atafb_par *par)
2216 {
2217 	par->screen_base = external_screen_base;
2218 }
2219 
2220 static void ext_set_par(struct atafb_par *par)
2221 {
2222 }
2223 
2224 #define OUTB(port,val) \
2225 	*((unsigned volatile char *) ((port)+external_vgaiobase)) = (val)
2226 #define INB(port) \
2227 	(*((unsigned volatile char *) ((port)+external_vgaiobase)))
2228 #define DACDelay				\
2229 	do {					\
2230 		unsigned char tmp = INB(0x3da);	\
2231 		tmp = INB(0x3da);			\
2232 	} while (0)
2233 
2234 static int ext_setcolreg(unsigned int regno, unsigned int red,
2235 			 unsigned int green, unsigned int blue,
2236 			 unsigned int transp, struct fb_info *info)
2237 {
2238 	unsigned char colmask = (1 << external_bitspercol) - 1;
2239 
2240 	if (!external_vgaiobase)
2241 		return 1;
2242 
2243 	if (regno > 255)
2244 		return 1;
2245 
2246 	switch (external_card_type) {
2247 	case IS_VGA:
2248 		OUTB(0x3c8, regno);
2249 		DACDelay;
2250 		OUTB(0x3c9, red & colmask);
2251 		DACDelay;
2252 		OUTB(0x3c9, green & colmask);
2253 		DACDelay;
2254 		OUTB(0x3c9, blue & colmask);
2255 		DACDelay;
2256 		return 0;
2257 
2258 	case IS_MV300:
2259 		OUTB((MV300_reg[regno] << 2) + 1, red);
2260 		OUTB((MV300_reg[regno] << 2) + 1, green);
2261 		OUTB((MV300_reg[regno] << 2) + 1, blue);
2262 		return 0;
2263 
2264 	default:
2265 		return 1;
2266 	}
2267 }
2268 
2269 static int ext_detect(void)
2270 {
2271 	struct fb_var_screeninfo *myvar = &atafb_predefined[0];
2272 	struct atafb_par dummy_par;
2273 
2274 	myvar->xres = external_xres;
2275 	myvar->xres_virtual = external_xres_virtual;
2276 	myvar->yres = external_yres;
2277 	myvar->bits_per_pixel = external_depth;
2278 	ext_encode_var(myvar, &dummy_par);
2279 	return 1;
2280 }
2281 
2282 #endif /* ATAFB_EXT */
2283 
2284 /* ------ This is the same for most hardware types -------- */
2285 
2286 static void set_screen_base(void *s_base)
2287 {
2288 	unsigned long addr;
2289 
2290 	addr = atari_stram_to_phys(s_base);
2291 	/* Setup Screen Memory */
2292 	shifter.bas_hi = (unsigned char)((addr & 0xff0000) >> 16);
2293 	shifter.bas_md = (unsigned char)((addr & 0x00ff00) >> 8);
2294 	shifter.bas_lo = (unsigned char)(addr & 0x0000ff);
2295 }
2296 
2297 static int pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
2298 {
2299 	struct atafb_par *par = (struct atafb_par *)info->par;
2300 
2301 	if (!fbhw->set_screen_base ||
2302 	    (!ATARIHW_PRESENT(EXTD_SHIFTER) && var->xoffset))
2303 		return -EINVAL;
2304 	var->xoffset = up(var->xoffset, 16);
2305 	par->screen_base = screen_base +
2306 	        (var->yoffset * info->var.xres_virtual + var->xoffset)
2307 	        * info->var.bits_per_pixel / 8;
2308 	fbhw->set_screen_base(par->screen_base);
2309 	return 0;
2310 }
2311 
2312 /* ------------ Interfaces to hardware functions ------------ */
2313 
2314 #ifdef ATAFB_TT
2315 static struct fb_hwswitch tt_switch = {
2316 	.detect		= tt_detect,
2317 	.encode_fix	= tt_encode_fix,
2318 	.decode_var	= tt_decode_var,
2319 	.encode_var	= tt_encode_var,
2320 	.get_par	= tt_get_par,
2321 	.set_par	= tt_set_par,
2322 	.set_screen_base = set_screen_base,
2323 	.pan_display	= pan_display,
2324 };
2325 #endif
2326 
2327 #ifdef ATAFB_FALCON
2328 static struct fb_hwswitch falcon_switch = {
2329 	.detect		= falcon_detect,
2330 	.encode_fix	= falcon_encode_fix,
2331 	.decode_var	= falcon_decode_var,
2332 	.encode_var	= falcon_encode_var,
2333 	.get_par	= falcon_get_par,
2334 	.set_par	= falcon_set_par,
2335 	.set_screen_base = set_screen_base,
2336 	.blank		= falcon_blank,
2337 	.pan_display	= falcon_pan_display,
2338 };
2339 #endif
2340 
2341 #ifdef ATAFB_STE
2342 static struct fb_hwswitch st_switch = {
2343 	.detect		= stste_detect,
2344 	.encode_fix	= stste_encode_fix,
2345 	.decode_var	= stste_decode_var,
2346 	.encode_var	= stste_encode_var,
2347 	.get_par	= stste_get_par,
2348 	.set_par	= stste_set_par,
2349 	.set_screen_base = stste_set_screen_base,
2350 	.pan_display	= pan_display
2351 };
2352 #endif
2353 
2354 #ifdef ATAFB_EXT
2355 static struct fb_hwswitch ext_switch = {
2356 	.detect		= ext_detect,
2357 	.encode_fix	= ext_encode_fix,
2358 	.decode_var	= ext_decode_var,
2359 	.encode_var	= ext_encode_var,
2360 	.get_par	= ext_get_par,
2361 	.set_par	= ext_set_par,
2362 };
2363 #endif
2364 
2365 static void ata_get_par(struct atafb_par *par)
2366 {
2367 	if (current_par_valid)
2368 		*par = current_par;
2369 	else
2370 		fbhw->get_par(par);
2371 }
2372 
2373 static void ata_set_par(struct atafb_par *par)
2374 {
2375 	fbhw->set_par(par);
2376 	current_par = *par;
2377 	current_par_valid = 1;
2378 }
2379 
2380 
2381 /* =========================================================== */
2382 /* ============== Hardware Independent Functions ============= */
2383 /* =========================================================== */
2384 
2385 /* used for hardware scrolling */
2386 
2387 static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
2388 {
2389 	int err, activate;
2390 	struct atafb_par par;
2391 
2392 	err = fbhw->decode_var(var, &par);
2393 	if (err)
2394 		return err;
2395 	activate = var->activate;
2396 	if (((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive)
2397 		ata_set_par(&par);
2398 	fbhw->encode_var(var, &par);
2399 	var->activate = activate;
2400 	return 0;
2401 }
2402 
2403 /* fbhw->encode_fix() must be called with fb_info->mm_lock held
2404  * if it is called after the register_framebuffer() - not a case here
2405  */
2406 static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
2407 {
2408 	struct atafb_par par;
2409 	int err;
2410 	// Get fix directly (case con == -1 before)??
2411 	err = fbhw->decode_var(&info->var, &par);
2412 	if (err)
2413 		return err;
2414 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
2415 	err = fbhw->encode_fix(fix, &par);
2416 	return err;
2417 }
2418 
2419 static int atafb_get_var(struct fb_var_screeninfo *var, struct fb_info *info)
2420 {
2421 	struct atafb_par par;
2422 
2423 	ata_get_par(&par);
2424 	fbhw->encode_var(var, &par);
2425 
2426 	return 0;
2427 }
2428 
2429 // No longer called by fbcon!
2430 // Still called by set_var internally
2431 
2432 static void atafb_set_disp(struct fb_info *info)
2433 {
2434 	atafb_get_var(&info->var, info);
2435 	atafb_get_fix(&info->fix, info);
2436 
2437 	/* Note: smem_start derives from phys_screen_base, not screen_base! */
2438 	info->screen_base = (external_addr ? external_screen_base :
2439 				atari_stram_to_virt(info->fix.smem_start));
2440 }
2441 
2442 static int atafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2443 			   u_int transp, struct fb_info *info)
2444 {
2445 	red >>= 8;
2446 	green >>= 8;
2447 	blue >>= 8;
2448 
2449 	return info->fbops->fb_setcolreg(regno, red, green, blue, transp, info);
2450 }
2451 
2452 static int
2453 atafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
2454 {
2455 	int xoffset = var->xoffset;
2456 	int yoffset = var->yoffset;
2457 	int err;
2458 
2459 	if (var->vmode & FB_VMODE_YWRAP) {
2460 		if (yoffset < 0 || yoffset >= info->var.yres_virtual || xoffset)
2461 			return -EINVAL;
2462 	} else {
2463 		if (xoffset + info->var.xres > info->var.xres_virtual ||
2464 		    yoffset + info->var.yres > info->var.yres_virtual)
2465 			return -EINVAL;
2466 	}
2467 
2468 	if (fbhw->pan_display) {
2469 		err = fbhw->pan_display(var, info);
2470 		if (err)
2471 			return err;
2472 	} else
2473 		return -EINVAL;
2474 
2475 	info->var.xoffset = xoffset;
2476 	info->var.yoffset = yoffset;
2477 
2478 	if (var->vmode & FB_VMODE_YWRAP)
2479 		info->var.vmode |= FB_VMODE_YWRAP;
2480 	else
2481 		info->var.vmode &= ~FB_VMODE_YWRAP;
2482 
2483 	return 0;
2484 }
2485 
2486 /*
2487  * generic drawing routines; imageblit needs updating for image depth > 1
2488  */
2489 
2490 #if BITS_PER_LONG == 32
2491 #define BYTES_PER_LONG	4
2492 #define SHIFT_PER_LONG	5
2493 #elif BITS_PER_LONG == 64
2494 #define BYTES_PER_LONG	8
2495 #define SHIFT_PER_LONG	6
2496 #else
2497 #define Please update me
2498 #endif
2499 
2500 
2501 static void atafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
2502 {
2503 	struct atafb_par *par = (struct atafb_par *)info->par;
2504 	int x2, y2;
2505 	u32 width, height;
2506 
2507 	if (!rect->width || !rect->height)
2508 		return;
2509 
2510 #ifdef ATAFB_FALCON
2511 	if (info->var.bits_per_pixel == 16) {
2512 		cfb_fillrect(info, rect);
2513 		return;
2514 	}
2515 #endif
2516 
2517 	/*
2518 	 * We could use hardware clipping but on many cards you get around
2519 	 * hardware clipping by writing to framebuffer directly.
2520 	 * */
2521 	x2 = rect->dx + rect->width;
2522 	y2 = rect->dy + rect->height;
2523 	x2 = x2 < info->var.xres_virtual ? x2 : info->var.xres_virtual;
2524 	y2 = y2 < info->var.yres_virtual ? y2 : info->var.yres_virtual;
2525 	width = x2 - rect->dx;
2526 	height = y2 - rect->dy;
2527 
2528 	if (info->var.bits_per_pixel == 1)
2529 		atafb_mfb_fillrect(info, par->next_line, rect->color,
2530 				   rect->dy, rect->dx, height, width);
2531 	else if (info->var.bits_per_pixel == 2)
2532 		atafb_iplan2p2_fillrect(info, par->next_line, rect->color,
2533 					rect->dy, rect->dx, height, width);
2534 	else if (info->var.bits_per_pixel == 4)
2535 		atafb_iplan2p4_fillrect(info, par->next_line, rect->color,
2536 					rect->dy, rect->dx, height, width);
2537 	else
2538 		atafb_iplan2p8_fillrect(info, par->next_line, rect->color,
2539 					rect->dy, rect->dx, height, width);
2540 
2541 	return;
2542 }
2543 
2544 static void atafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
2545 {
2546 	struct atafb_par *par = (struct atafb_par *)info->par;
2547 	int x2, y2;
2548 	u32 dx, dy, sx, sy, width, height;
2549 	int rev_copy = 0;
2550 
2551 #ifdef ATAFB_FALCON
2552 	if (info->var.bits_per_pixel == 16) {
2553 		cfb_copyarea(info, area);
2554 		return;
2555 	}
2556 #endif
2557 
2558 	/* clip the destination */
2559 	x2 = area->dx + area->width;
2560 	y2 = area->dy + area->height;
2561 	dx = area->dx > 0 ? area->dx : 0;
2562 	dy = area->dy > 0 ? area->dy : 0;
2563 	x2 = x2 < info->var.xres_virtual ? x2 : info->var.xres_virtual;
2564 	y2 = y2 < info->var.yres_virtual ? y2 : info->var.yres_virtual;
2565 	width = x2 - dx;
2566 	height = y2 - dy;
2567 
2568 	if (area->sx + dx < area->dx || area->sy + dy < area->dy)
2569 		return;
2570 
2571 	/* update sx,sy */
2572 	sx = area->sx + (dx - area->dx);
2573 	sy = area->sy + (dy - area->dy);
2574 
2575 	/* the source must be completely inside the virtual screen */
2576 	if (sx + width > info->var.xres_virtual ||
2577 			sy + height > info->var.yres_virtual)
2578 		return;
2579 
2580 	if (dy > sy || (dy == sy && dx > sx)) {
2581 		dy += height;
2582 		sy += height;
2583 		rev_copy = 1;
2584 	}
2585 
2586 	if (info->var.bits_per_pixel == 1)
2587 		atafb_mfb_copyarea(info, par->next_line, sy, sx, dy, dx, height, width);
2588 	else if (info->var.bits_per_pixel == 2)
2589 		atafb_iplan2p2_copyarea(info, par->next_line, sy, sx, dy, dx, height, width);
2590 	else if (info->var.bits_per_pixel == 4)
2591 		atafb_iplan2p4_copyarea(info, par->next_line, sy, sx, dy, dx, height, width);
2592 	else
2593 		atafb_iplan2p8_copyarea(info, par->next_line, sy, sx, dy, dx, height, width);
2594 
2595 	return;
2596 }
2597 
2598 static void atafb_imageblit(struct fb_info *info, const struct fb_image *image)
2599 {
2600 	struct atafb_par *par = (struct atafb_par *)info->par;
2601 	int x2, y2;
2602 	unsigned long *dst;
2603 	int dst_idx;
2604 	const char *src;
2605 	u32 dx, dy, width, height, pitch;
2606 
2607 #ifdef ATAFB_FALCON
2608 	if (info->var.bits_per_pixel == 16) {
2609 		cfb_imageblit(info, image);
2610 		return;
2611 	}
2612 #endif
2613 
2614 	/*
2615 	 * We could use hardware clipping but on many cards you get around
2616 	 * hardware clipping by writing to framebuffer directly like we are
2617 	 * doing here.
2618 	 */
2619 	x2 = image->dx + image->width;
2620 	y2 = image->dy + image->height;
2621 	dx = image->dx;
2622 	dy = image->dy;
2623 	x2 = x2 < info->var.xres_virtual ? x2 : info->var.xres_virtual;
2624 	y2 = y2 < info->var.yres_virtual ? y2 : info->var.yres_virtual;
2625 	width = x2 - dx;
2626 	height = y2 - dy;
2627 
2628 	if (image->depth == 1) {
2629 		// used for font data
2630 		dst = (unsigned long *)
2631 			((unsigned long)info->screen_base & ~(BYTES_PER_LONG - 1));
2632 		dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG - 1)) * 8;
2633 		dst_idx += dy * par->next_line * 8 + dx;
2634 		src = image->data;
2635 		pitch = (image->width + 7) / 8;
2636 		while (height--) {
2637 
2638 			if (info->var.bits_per_pixel == 1)
2639 				atafb_mfb_linefill(info, par->next_line,
2640 						   dy, dx, width, src,
2641 						   image->bg_color, image->fg_color);
2642 			else if (info->var.bits_per_pixel == 2)
2643 				atafb_iplan2p2_linefill(info, par->next_line,
2644 							dy, dx, width, src,
2645 							image->bg_color, image->fg_color);
2646 			else if (info->var.bits_per_pixel == 4)
2647 				atafb_iplan2p4_linefill(info, par->next_line,
2648 							dy, dx, width, src,
2649 							image->bg_color, image->fg_color);
2650 			else
2651 				atafb_iplan2p8_linefill(info, par->next_line,
2652 							dy, dx, width, src,
2653 							image->bg_color, image->fg_color);
2654 			dy++;
2655 			src += pitch;
2656 		}
2657 	} else {
2658 		c2p_iplan2(info->screen_base, image->data, dx, dy, width,
2659 			   height, par->next_line, image->width,
2660 			   info->var.bits_per_pixel);
2661 	}
2662 }
2663 
2664 static int
2665 atafb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
2666 {
2667 	switch (cmd) {
2668 #ifdef FBCMD_GET_CURRENTPAR
2669 	case FBCMD_GET_CURRENTPAR:
2670 		if (copy_to_user((void *)arg, (void *)&current_par,
2671 				 sizeof(struct atafb_par)))
2672 			return -EFAULT;
2673 		return 0;
2674 #endif
2675 #ifdef FBCMD_SET_CURRENTPAR
2676 	case FBCMD_SET_CURRENTPAR:
2677 		if (copy_from_user((void *)&current_par, (void *)arg,
2678 				   sizeof(struct atafb_par)))
2679 			return -EFAULT;
2680 		ata_set_par(&current_par);
2681 		return 0;
2682 #endif
2683 	}
2684 	return -EINVAL;
2685 }
2686 
2687 /* (un)blank/poweroff
2688  * 0 = unblank
2689  * 1 = blank
2690  * 2 = suspend vsync
2691  * 3 = suspend hsync
2692  * 4 = off
2693  */
2694 static int atafb_blank(int blank, struct fb_info *info)
2695 {
2696 	unsigned short black[16];
2697 	struct fb_cmap cmap;
2698 	if (fbhw->blank && !fbhw->blank(blank))
2699 		return 1;
2700 	if (blank) {
2701 		memset(black, 0, 16 * sizeof(unsigned short));
2702 		cmap.red = black;
2703 		cmap.green = black;
2704 		cmap.blue = black;
2705 		cmap.transp = NULL;
2706 		cmap.start = 0;
2707 		cmap.len = 16;
2708 		fb_set_cmap(&cmap, info);
2709 	}
2710 #if 0
2711 	else
2712 		do_install_cmap(info);
2713 #endif
2714 	return 0;
2715 }
2716 
2717 	/*
2718 	 * New fbcon interface ...
2719 	 */
2720 
2721 	 /* check var by decoding var into hw par, rounding if necessary,
2722 	  * then encoding hw par back into new, validated var */
2723 static int atafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
2724 {
2725 	int err;
2726 	struct atafb_par par;
2727 
2728 	/* Validate wanted screen parameters */
2729 	// if ((err = ata_decode_var(var, &par)))
2730 	err = fbhw->decode_var(var, &par);
2731 	if (err)
2732 		return err;
2733 
2734 	/* Encode (possibly rounded) screen parameters */
2735 	fbhw->encode_var(var, &par);
2736 	return 0;
2737 }
2738 
2739 	/* actually set hw par by decoding var, then setting hardware from
2740 	 * hw par just decoded */
2741 static int atafb_set_par(struct fb_info *info)
2742 {
2743 	struct atafb_par *par = (struct atafb_par *)info->par;
2744 
2745 	/* Decode wanted screen parameters */
2746 	fbhw->decode_var(&info->var, par);
2747 	mutex_lock(&info->mm_lock);
2748 	fbhw->encode_fix(&info->fix, par);
2749 	mutex_unlock(&info->mm_lock);
2750 
2751 	/* Set new videomode */
2752 	ata_set_par(par);
2753 
2754 	return 0;
2755 }
2756 
2757 
2758 static struct fb_ops atafb_ops = {
2759 	.owner =	THIS_MODULE,
2760 	.fb_check_var	= atafb_check_var,
2761 	.fb_set_par	= atafb_set_par,
2762 	.fb_setcolreg	= atafb_setcolreg,
2763 	.fb_blank =	atafb_blank,
2764 	.fb_pan_display	= atafb_pan_display,
2765 	.fb_fillrect	= atafb_fillrect,
2766 	.fb_copyarea	= atafb_copyarea,
2767 	.fb_imageblit	= atafb_imageblit,
2768 	.fb_ioctl =	atafb_ioctl,
2769 };
2770 
2771 static void check_default_par(int detected_mode)
2772 {
2773 	char default_name[10];
2774 	int i;
2775 	struct fb_var_screeninfo var;
2776 	unsigned long min_mem;
2777 
2778 	/* First try the user supplied mode */
2779 	if (default_par) {
2780 		var = atafb_predefined[default_par - 1];
2781 		var.activate = FB_ACTIVATE_TEST;
2782 		if (do_fb_set_var(&var, 1))
2783 			default_par = 0;	/* failed */
2784 	}
2785 	/* Next is the autodetected one */
2786 	if (!default_par) {
2787 		var = atafb_predefined[detected_mode - 1]; /* autodetect */
2788 		var.activate = FB_ACTIVATE_TEST;
2789 		if (!do_fb_set_var(&var, 1))
2790 			default_par = detected_mode;
2791 	}
2792 	/* If that also failed, try some default modes... */
2793 	if (!default_par) {
2794 		/* try default1, default2... */
2795 		for (i = 1; i < 10; i++) {
2796 			sprintf(default_name,"default%d", i);
2797 			default_par = get_video_mode(default_name);
2798 			if (!default_par)
2799 				panic("can't set default video mode");
2800 			var = atafb_predefined[default_par - 1];
2801 			var.activate = FB_ACTIVATE_TEST;
2802 			if (!do_fb_set_var(&var,1))
2803 				break;	/* ok */
2804 		}
2805 	}
2806 	min_mem = var.xres_virtual * var.yres_virtual * var.bits_per_pixel / 8;
2807 	if (default_mem_req < min_mem)
2808 		default_mem_req = min_mem;
2809 }
2810 
2811 #ifdef ATAFB_EXT
2812 static void __init atafb_setup_ext(char *spec)
2813 {
2814 	int xres, xres_virtual, yres, depth, planes;
2815 	unsigned long addr, len;
2816 	char *p;
2817 
2818 	/* Format is: <xres>;<yres>;<depth>;<plane organ.>;
2819 	 *            <screen mem addr>
2820 	 *	      [;<screen mem length>[;<vgaiobase>[;<bits-per-col>[;<colorreg-type>
2821 	 *	      [;<xres-virtual>]]]]]
2822 	 *
2823 	 * 09/23/97	Juergen
2824 	 * <xres_virtual>:	hardware's x-resolution (f.e. ProMST)
2825 	 *
2826 	 * Even xres_virtual is available, we neither support panning nor hw-scrolling!
2827 	 */
2828 	p = strsep(&spec, ";");
2829 	if (!p || !*p)
2830 		return;
2831 	xres_virtual = xres = simple_strtoul(p, NULL, 10);
2832 	if (xres <= 0)
2833 		return;
2834 
2835 	p = strsep(&spec, ";");
2836 	if (!p || !*p)
2837 		return;
2838 	yres = simple_strtoul(p, NULL, 10);
2839 	if (yres <= 0)
2840 		return;
2841 
2842 	p = strsep(&spec, ";");
2843 	if (!p || !*p)
2844 		return;
2845 	depth = simple_strtoul(p, NULL, 10);
2846 	if (depth != 1 && depth != 2 && depth != 4 && depth != 8 &&
2847 	    depth != 16 && depth != 24)
2848 		return;
2849 
2850 	p = strsep(&spec, ";");
2851 	if (!p || !*p)
2852 		return;
2853 	if (*p == 'i')
2854 		planes = FB_TYPE_INTERLEAVED_PLANES;
2855 	else if (*p == 'p')
2856 		planes = FB_TYPE_PACKED_PIXELS;
2857 	else if (*p == 'n')
2858 		planes = FB_TYPE_PLANES;
2859 	else if (*p == 't')
2860 		planes = -1;		/* true color */
2861 	else
2862 		return;
2863 
2864 	p = strsep(&spec, ";");
2865 	if (!p || !*p)
2866 		return;
2867 	addr = simple_strtoul(p, NULL, 0);
2868 
2869 	p = strsep(&spec, ";");
2870 	if (!p || !*p)
2871 		len = xres * yres * depth / 8;
2872 	else
2873 		len = simple_strtoul(p, NULL, 0);
2874 
2875 	p = strsep(&spec, ";");
2876 	if (p && *p)
2877 		external_vgaiobase = simple_strtoul(p, NULL, 0);
2878 
2879 	p = strsep(&spec, ";");
2880 	if (p && *p) {
2881 		external_bitspercol = simple_strtoul(p, NULL, 0);
2882 		if (external_bitspercol > 8)
2883 			external_bitspercol = 8;
2884 		else if (external_bitspercol < 1)
2885 			external_bitspercol = 1;
2886 	}
2887 
2888 	p = strsep(&spec, ";");
2889 	if (p && *p) {
2890 		if (!strcmp(p, "vga"))
2891 			external_card_type = IS_VGA;
2892 		if (!strcmp(p, "mv300"))
2893 			external_card_type = IS_MV300;
2894 	}
2895 
2896 	p = strsep(&spec, ";");
2897 	if (p && *p) {
2898 		xres_virtual = simple_strtoul(p, NULL, 10);
2899 		if (xres_virtual < xres)
2900 			xres_virtual = xres;
2901 		if (xres_virtual * yres * depth / 8 > len)
2902 			len = xres_virtual * yres * depth / 8;
2903 	}
2904 
2905 	external_xres = xres;
2906 	external_xres_virtual = xres_virtual;
2907 	external_yres = yres;
2908 	external_depth = depth;
2909 	external_pmode = planes;
2910 	external_addr = addr;
2911 	external_len = len;
2912 
2913 	if (external_card_type == IS_MV300) {
2914 		switch (external_depth) {
2915 		case 1:
2916 			MV300_reg = MV300_reg_1bit;
2917 			break;
2918 		case 4:
2919 			MV300_reg = MV300_reg_4bit;
2920 			break;
2921 		case 8:
2922 			MV300_reg = MV300_reg_8bit;
2923 			break;
2924 		}
2925 	}
2926 }
2927 #endif /* ATAFB_EXT */
2928 
2929 static void __init atafb_setup_int(char *spec)
2930 {
2931 	/* Format to config extended internal video hardware like OverScan:
2932 	 * "internal:<xres>;<yres>;<xres_max>;<yres_max>;<offset>"
2933 	 * Explanation:
2934 	 * <xres>: x-resolution
2935 	 * <yres>: y-resolution
2936 	 * The following are only needed if you have an overscan which
2937 	 * needs a black border:
2938 	 * <xres_max>: max. length of a line in pixels your OverScan hardware would allow
2939 	 * <yres_max>: max. number of lines your OverScan hardware would allow
2940 	 * <offset>: Offset from physical beginning to visible beginning
2941 	 *	  of screen in bytes
2942 	 */
2943 	int xres;
2944 	char *p;
2945 
2946 	if (!(p = strsep(&spec, ";")) || !*p)
2947 		return;
2948 	xres = simple_strtoul(p, NULL, 10);
2949 	if (!(p = strsep(&spec, ";")) || !*p)
2950 		return;
2951 	sttt_xres = xres;
2952 	tt_yres = st_yres = simple_strtoul(p, NULL, 10);
2953 	if ((p = strsep(&spec, ";")) && *p)
2954 		sttt_xres_virtual = simple_strtoul(p, NULL, 10);
2955 	if ((p = strsep(&spec, ";")) && *p)
2956 		sttt_yres_virtual = simple_strtoul(p, NULL, 0);
2957 	if ((p = strsep(&spec, ";")) && *p)
2958 		ovsc_offset = simple_strtoul(p, NULL, 0);
2959 
2960 	if (ovsc_offset || (sttt_yres_virtual != st_yres))
2961 		use_hwscroll = 0;
2962 }
2963 
2964 #ifdef ATAFB_FALCON
2965 static void __init atafb_setup_mcap(char *spec)
2966 {
2967 	char *p;
2968 	int vmin, vmax, hmin, hmax;
2969 
2970 	/* Format for monitor capabilities is: <Vmin>;<Vmax>;<Hmin>;<Hmax>
2971 	 * <V*> vertical freq. in Hz
2972 	 * <H*> horizontal freq. in kHz
2973 	 */
2974 	if (!(p = strsep(&spec, ";")) || !*p)
2975 		return;
2976 	vmin = simple_strtoul(p, NULL, 10);
2977 	if (vmin <= 0)
2978 		return;
2979 	if (!(p = strsep(&spec, ";")) || !*p)
2980 		return;
2981 	vmax = simple_strtoul(p, NULL, 10);
2982 	if (vmax <= 0 || vmax <= vmin)
2983 		return;
2984 	if (!(p = strsep(&spec, ";")) || !*p)
2985 		return;
2986 	hmin = 1000 * simple_strtoul(p, NULL, 10);
2987 	if (hmin <= 0)
2988 		return;
2989 	if (!(p = strsep(&spec, "")) || !*p)
2990 		return;
2991 	hmax = 1000 * simple_strtoul(p, NULL, 10);
2992 	if (hmax <= 0 || hmax <= hmin)
2993 		return;
2994 
2995 	fb_info.monspecs.vfmin = vmin;
2996 	fb_info.monspecs.vfmax = vmax;
2997 	fb_info.monspecs.hfmin = hmin;
2998 	fb_info.monspecs.hfmax = hmax;
2999 }
3000 #endif /* ATAFB_FALCON */
3001 
3002 static void __init atafb_setup_user(char *spec)
3003 {
3004 	/* Format of user defined video mode is: <xres>;<yres>;<depth>
3005 	 */
3006 	char *p;
3007 	int xres, yres, depth, temp;
3008 
3009 	p = strsep(&spec, ";");
3010 	if (!p || !*p)
3011 		return;
3012 	xres = simple_strtoul(p, NULL, 10);
3013 	p = strsep(&spec, ";");
3014 	if (!p || !*p)
3015 		return;
3016 	yres = simple_strtoul(p, NULL, 10);
3017 	p = strsep(&spec, "");
3018 	if (!p || !*p)
3019 		return;
3020 	depth = simple_strtoul(p, NULL, 10);
3021 	temp = get_video_mode("user0");
3022 	if (temp) {
3023 		default_par = temp;
3024 		atafb_predefined[default_par - 1].xres = xres;
3025 		atafb_predefined[default_par - 1].yres = yres;
3026 		atafb_predefined[default_par - 1].bits_per_pixel = depth;
3027 	}
3028 }
3029 
3030 int __init atafb_setup(char *options)
3031 {
3032 	char *this_opt;
3033 	int temp;
3034 
3035 	if (!options || !*options)
3036 		return 0;
3037 
3038 	while ((this_opt = strsep(&options, ",")) != NULL) {
3039 		if (!*this_opt)
3040 			continue;
3041 		if ((temp = get_video_mode(this_opt))) {
3042 			default_par = temp;
3043 			mode_option = this_opt;
3044 		} else if (!strcmp(this_opt, "inverse"))
3045 			inverse = 1;
3046 		else if (!strncmp(this_opt, "hwscroll_", 9)) {
3047 			hwscroll = simple_strtoul(this_opt + 9, NULL, 10);
3048 			if (hwscroll < 0)
3049 				hwscroll = 0;
3050 			if (hwscroll > 200)
3051 				hwscroll = 200;
3052 		}
3053 #ifdef ATAFB_EXT
3054 		else if (!strcmp(this_opt, "mv300")) {
3055 			external_bitspercol = 8;
3056 			external_card_type = IS_MV300;
3057 		} else if (!strncmp(this_opt, "external:", 9))
3058 			atafb_setup_ext(this_opt + 9);
3059 #endif
3060 		else if (!strncmp(this_opt, "internal:", 9))
3061 			atafb_setup_int(this_opt + 9);
3062 #ifdef ATAFB_FALCON
3063 		else if (!strncmp(this_opt, "eclock:", 7)) {
3064 			fext.f = simple_strtoul(this_opt + 7, NULL, 10);
3065 			/* external pixelclock in kHz --> ps */
3066 			fext.t = 1000000000 / fext.f;
3067 			fext.f *= 1000;
3068 		} else if (!strncmp(this_opt, "monitorcap:", 11))
3069 			atafb_setup_mcap(this_opt + 11);
3070 #endif
3071 		else if (!strcmp(this_opt, "keep"))
3072 			DontCalcRes = 1;
3073 		else if (!strncmp(this_opt, "R", 1))
3074 			atafb_setup_user(this_opt + 1);
3075 	}
3076 	return 0;
3077 }
3078 
3079 int __init atafb_init(void)
3080 {
3081 	int pad, detected_mode, error;
3082 	unsigned int defmode = 0;
3083 	unsigned long mem_req;
3084 
3085 #ifndef MODULE
3086 	char *option = NULL;
3087 
3088 	if (fb_get_options("atafb", &option))
3089 		return -ENODEV;
3090 	atafb_setup(option);
3091 #endif
3092 	printk("atafb_init: start\n");
3093 
3094 	if (!MACH_IS_ATARI)
3095 		return -ENODEV;
3096 
3097 	do {
3098 #ifdef ATAFB_EXT
3099 		if (external_addr) {
3100 			printk("atafb_init: initializing external hw\n");
3101 			fbhw = &ext_switch;
3102 			atafb_ops.fb_setcolreg = &ext_setcolreg;
3103 			defmode = DEFMODE_EXT;
3104 			break;
3105 		}
3106 #endif
3107 #ifdef ATAFB_TT
3108 		if (ATARIHW_PRESENT(TT_SHIFTER)) {
3109 			printk("atafb_init: initializing TT hw\n");
3110 			fbhw = &tt_switch;
3111 			atafb_ops.fb_setcolreg = &tt_setcolreg;
3112 			defmode = DEFMODE_TT;
3113 			break;
3114 		}
3115 #endif
3116 #ifdef ATAFB_FALCON
3117 		if (ATARIHW_PRESENT(VIDEL_SHIFTER)) {
3118 			printk("atafb_init: initializing Falcon hw\n");
3119 			fbhw = &falcon_switch;
3120 			atafb_ops.fb_setcolreg = &falcon_setcolreg;
3121 			error = request_irq(IRQ_AUTO_4, falcon_vbl_switcher, 0,
3122 					    "framebuffer:modeswitch",
3123 					    falcon_vbl_switcher);
3124 			if (error)
3125 				return error;
3126 			defmode = DEFMODE_F30;
3127 			break;
3128 		}
3129 #endif
3130 #ifdef ATAFB_STE
3131 		if (ATARIHW_PRESENT(STND_SHIFTER) ||
3132 		    ATARIHW_PRESENT(EXTD_SHIFTER)) {
3133 			printk("atafb_init: initializing ST/E hw\n");
3134 			fbhw = &st_switch;
3135 			atafb_ops.fb_setcolreg = &stste_setcolreg;
3136 			defmode = DEFMODE_STE;
3137 			break;
3138 		}
3139 		fbhw = &st_switch;
3140 		atafb_ops.fb_setcolreg = &stste_setcolreg;
3141 		printk("Cannot determine video hardware; defaulting to ST(e)\n");
3142 #else /* ATAFB_STE */
3143 		/* no default driver included */
3144 		/* Nobody will ever see this message :-) */
3145 		panic("Cannot initialize video hardware");
3146 #endif
3147 	} while (0);
3148 
3149 	/* Multisync monitor capabilities */
3150 	/* Atari-TOS defaults if no boot option present */
3151 	if (fb_info.monspecs.hfmin == 0) {
3152 		fb_info.monspecs.hfmin = 31000;
3153 		fb_info.monspecs.hfmax = 32000;
3154 		fb_info.monspecs.vfmin = 58;
3155 		fb_info.monspecs.vfmax = 62;
3156 	}
3157 
3158 	detected_mode = fbhw->detect();
3159 	check_default_par(detected_mode);
3160 #ifdef ATAFB_EXT
3161 	if (!external_addr) {
3162 #endif /* ATAFB_EXT */
3163 		mem_req = default_mem_req + ovsc_offset + ovsc_addlen;
3164 		mem_req = PAGE_ALIGN(mem_req) + PAGE_SIZE;
3165 		screen_base = atari_stram_alloc(mem_req, "atafb");
3166 		if (!screen_base)
3167 			panic("Cannot allocate screen memory");
3168 		memset(screen_base, 0, mem_req);
3169 		pad = -(unsigned long)screen_base & (PAGE_SIZE - 1);
3170 		screen_base += pad;
3171 		phys_screen_base = atari_stram_to_phys(screen_base + ovsc_offset);
3172 		screen_len = (mem_req - pad - ovsc_offset) & PAGE_MASK;
3173 		st_ovsc_switch();
3174 		if (CPU_IS_040_OR_060) {
3175 			/* On a '040+, the cache mode of video RAM must be set to
3176 			 * write-through also for internal video hardware! */
3177 			cache_push(atari_stram_to_phys(screen_base), screen_len);
3178 			kernel_set_cachemode(screen_base, screen_len,
3179 					     IOMAP_WRITETHROUGH);
3180 		}
3181 		printk("atafb: screen_base %p phys_screen_base %lx screen_len %d\n",
3182 			screen_base, phys_screen_base, screen_len);
3183 #ifdef ATAFB_EXT
3184 	} else {
3185 		/* Map the video memory (physical address given) to somewhere
3186 		 * in the kernel address space.
3187 		 */
3188 		external_screen_base = ioremap_wt(external_addr, external_len);
3189 		if (external_vgaiobase)
3190 			external_vgaiobase =
3191 			  (unsigned long)ioremap(external_vgaiobase, 0x10000);
3192 		screen_base = external_screen_base;
3193 		phys_screen_base = external_addr;
3194 		screen_len = external_len & PAGE_MASK;
3195 		memset (screen_base, 0, external_len);
3196 	}
3197 #endif /* ATAFB_EXT */
3198 
3199 //	strcpy(fb_info.mode->name, "Atari Builtin ");
3200 	fb_info.fbops = &atafb_ops;
3201 	// try to set default (detected; requested) var
3202 	do_fb_set_var(&atafb_predefined[default_par - 1], 1);
3203 	// reads hw state into current par, which may not be sane yet
3204 	ata_get_par(&current_par);
3205 	fb_info.par = &current_par;
3206 	// tries to read from HW which may not be initialized yet
3207 	// so set sane var first, then call atafb_set_par
3208 	atafb_get_var(&fb_info.var, &fb_info);
3209 
3210 #ifdef ATAFB_FALCON
3211 	fb_info.pseudo_palette = current_par.hw.falcon.pseudo_palette;
3212 #endif
3213 	fb_info.flags = FBINFO_FLAG_DEFAULT;
3214 
3215 	if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, atafb_modedb,
3216 			  NUM_TOTAL_MODES, &atafb_modedb[defmode],
3217 			  fb_info.var.bits_per_pixel)) {
3218 		return -EINVAL;
3219 	}
3220 
3221 	fb_videomode_to_modelist(atafb_modedb, NUM_TOTAL_MODES,
3222 				 &fb_info.modelist);
3223 
3224 	atafb_set_disp(&fb_info);
3225 
3226 	fb_alloc_cmap(&(fb_info.cmap), 1 << fb_info.var.bits_per_pixel, 0);
3227 
3228 
3229 	printk("Determined %dx%d, depth %d\n",
3230 	       fb_info.var.xres, fb_info.var.yres, fb_info.var.bits_per_pixel);
3231 	if ((fb_info.var.xres != fb_info.var.xres_virtual) ||
3232 	    (fb_info.var.yres != fb_info.var.yres_virtual))
3233 		printk("   virtual %dx%d\n", fb_info.var.xres_virtual,
3234 		       fb_info.var.yres_virtual);
3235 
3236 	if (register_framebuffer(&fb_info) < 0) {
3237 #ifdef ATAFB_EXT
3238 		if (external_addr) {
3239 			iounmap(external_screen_base);
3240 			external_addr = 0;
3241 		}
3242 		if (external_vgaiobase) {
3243 			iounmap((void*)external_vgaiobase);
3244 			external_vgaiobase = 0;
3245 		}
3246 #endif
3247 		return -EINVAL;
3248 	}
3249 
3250 	fb_info(&fb_info, "frame buffer device, using %dK of video memory\n",
3251 		screen_len >> 10);
3252 
3253 	/* TODO: This driver cannot be unloaded yet */
3254 	return 0;
3255 }
3256 
3257 module_init(atafb_init);
3258 
3259 #ifdef MODULE
3260 MODULE_LICENSE("GPL");
3261 
3262 int cleanup_module(void)
3263 {
3264 	unregister_framebuffer(&fb_info);
3265 	return atafb_deinit();
3266 }
3267 #endif /* MODULE */
3268