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