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