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