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