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