39c3b860a797d4bc493529af82c493040d2a1095
[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", 57, 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 = (struct atafb_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         switch (external_card_type) {
2210         case IS_VGA:
2211                 OUTB(0x3c8, regno);
2212                 DACDelay;
2213                 OUTB(0x3c9, red & colmask);
2214                 DACDelay;
2215                 OUTB(0x3c9, green & colmask);
2216                 DACDelay;
2217                 OUTB(0x3c9, blue & colmask);
2218                 DACDelay;
2219                 return 0;
2220
2221         case IS_MV300:
2222                 OUTB((MV300_reg[regno] << 2) + 1, red);
2223                 OUTB((MV300_reg[regno] << 2) + 1, green);
2224                 OUTB((MV300_reg[regno] << 2) + 1, blue);
2225                 return 0;
2226
2227         default:
2228                 return 1;
2229         }
2230 }
2231
2232 static int ext_detect(void)
2233 {
2234         struct fb_var_screeninfo *myvar = &atafb_predefined[0];
2235         struct atafb_par dummy_par;
2236
2237         myvar->xres = external_xres;
2238         myvar->xres_virtual = external_xres_virtual;
2239         myvar->yres = external_yres;
2240         myvar->bits_per_pixel = external_depth;
2241         ext_encode_var(myvar, &dummy_par);
2242         return 1;
2243 }
2244
2245 #endif /* ATAFB_EXT */
2246
2247 /* ------ This is the same for most hardware types -------- */
2248
2249 static void set_screen_base(void *s_base)
2250 {
2251         unsigned long addr;
2252
2253         addr = atari_stram_to_phys(s_base);
2254         /* Setup Screen Memory */
2255         shifter_st.bas_hi = (unsigned char)((addr & 0xff0000) >> 16);
2256         shifter_st.bas_md = (unsigned char)((addr & 0x00ff00) >> 8);
2257         shifter_st.bas_lo = (unsigned char)(addr & 0x0000ff);
2258 }
2259
2260 static int pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
2261 {
2262         struct atafb_par *par = (struct atafb_par *)info->par;
2263
2264         if (!fbhw->set_screen_base ||
2265             (!ATARIHW_PRESENT(EXTD_SHIFTER) && var->xoffset))
2266                 return -EINVAL;
2267         var->xoffset = round_up(var->xoffset, 16);
2268         par->screen_base = screen_base +
2269                 (var->yoffset * info->var.xres_virtual + var->xoffset)
2270                 * info->var.bits_per_pixel / 8;
2271         fbhw->set_screen_base(par->screen_base);
2272         return 0;
2273 }
2274
2275 /* ------------ Interfaces to hardware functions ------------ */
2276
2277 #ifdef ATAFB_TT
2278 static struct fb_hwswitch tt_switch = {
2279         .detect         = tt_detect,
2280         .encode_fix     = tt_encode_fix,
2281         .decode_var     = tt_decode_var,
2282         .encode_var     = tt_encode_var,
2283         .get_par        = tt_get_par,
2284         .set_par        = tt_set_par,
2285         .set_screen_base = set_screen_base,
2286         .pan_display    = pan_display,
2287 };
2288 #endif
2289
2290 #ifdef ATAFB_FALCON
2291 static struct fb_hwswitch falcon_switch = {
2292         .detect         = falcon_detect,
2293         .encode_fix     = falcon_encode_fix,
2294         .decode_var     = falcon_decode_var,
2295         .encode_var     = falcon_encode_var,
2296         .get_par        = falcon_get_par,
2297         .set_par        = falcon_set_par,
2298         .set_screen_base = set_screen_base,
2299         .blank          = falcon_blank,
2300         .pan_display    = falcon_pan_display,
2301 };
2302 #endif
2303
2304 #ifdef ATAFB_STE
2305 static struct fb_hwswitch st_switch = {
2306         .detect         = stste_detect,
2307         .encode_fix     = stste_encode_fix,
2308         .decode_var     = stste_decode_var,
2309         .encode_var     = stste_encode_var,
2310         .get_par        = stste_get_par,
2311         .set_par        = stste_set_par,
2312         .set_screen_base = stste_set_screen_base,
2313         .pan_display    = pan_display
2314 };
2315 #endif
2316
2317 #ifdef ATAFB_EXT
2318 static struct fb_hwswitch ext_switch = {
2319         .detect         = ext_detect,
2320         .encode_fix     = ext_encode_fix,
2321         .decode_var     = ext_decode_var,
2322         .encode_var     = ext_encode_var,
2323         .get_par        = ext_get_par,
2324         .set_par        = ext_set_par,
2325 };
2326 #endif
2327
2328 static void ata_get_par(struct atafb_par *par)
2329 {
2330         if (current_par_valid)
2331                 *par = current_par;
2332         else
2333                 fbhw->get_par(par);
2334 }
2335
2336 static void ata_set_par(struct atafb_par *par)
2337 {
2338         fbhw->set_par(par);
2339         current_par = *par;
2340         current_par_valid = 1;
2341 }
2342
2343
2344 /* =========================================================== */
2345 /* ============== Hardware Independent Functions ============= */
2346 /* =========================================================== */
2347
2348 /* used for hardware scrolling */
2349
2350 static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
2351 {
2352         int err, activate;
2353         struct atafb_par par;
2354
2355         err = fbhw->decode_var(var, &par);
2356         if (err)
2357                 return err;
2358         activate = var->activate;
2359         if (((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive)
2360                 ata_set_par(&par);
2361         fbhw->encode_var(var, &par);
2362         var->activate = activate;
2363         return 0;
2364 }
2365
2366 /* fbhw->encode_fix() must be called with fb_info->mm_lock held
2367  * if it is called after the register_framebuffer() - not a case here
2368  */
2369 static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
2370 {
2371         struct atafb_par par;
2372         int err;
2373         // Get fix directly (case con == -1 before)??
2374         err = fbhw->decode_var(&info->var, &par);
2375         if (err)
2376                 return err;
2377         memset(fix, 0, sizeof(struct fb_fix_screeninfo));
2378         err = fbhw->encode_fix(fix, &par);
2379         return err;
2380 }
2381
2382 static int atafb_get_var(struct fb_var_screeninfo *var, struct fb_info *info)
2383 {
2384         struct atafb_par par;
2385
2386         ata_get_par(&par);
2387         fbhw->encode_var(var, &par);
2388
2389         return 0;
2390 }
2391
2392 // No longer called by fbcon!
2393 // Still called by set_var internally
2394
2395 static void atafb_set_disp(struct fb_info *info)
2396 {
2397         atafb_get_var(&info->var, info);
2398         atafb_get_fix(&info->fix, info);
2399
2400         /* Note: smem_start derives from phys_screen_base, not screen_base! */
2401         info->screen_base = (external_addr ? external_screen_base :
2402                                 atari_stram_to_virt(info->fix.smem_start));
2403 }
2404
2405 static int
2406 atafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
2407 {
2408         if (!fbhw->pan_display)
2409                 return -EINVAL;
2410
2411         return fbhw->pan_display(var, info);
2412 }
2413
2414 /*
2415  * generic drawing routines; imageblit needs updating for image depth > 1
2416  */
2417
2418 #if BITS_PER_LONG == 32
2419 #define BYTES_PER_LONG  4
2420 #define SHIFT_PER_LONG  5
2421 #elif BITS_PER_LONG == 64
2422 #define BYTES_PER_LONG  8
2423 #define SHIFT_PER_LONG  6
2424 #else
2425 #define Please update me
2426 #endif
2427
2428
2429 static void atafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
2430 {
2431         struct atafb_par *par = (struct atafb_par *)info->par;
2432         int x2, y2;
2433         u32 width, height;
2434
2435         if (!rect->width || !rect->height)
2436                 return;
2437
2438 #ifdef ATAFB_FALCON
2439         if (info->var.bits_per_pixel == 16) {
2440                 cfb_fillrect(info, rect);
2441                 return;
2442         }
2443 #endif
2444
2445         /*
2446          * We could use hardware clipping but on many cards you get around
2447          * hardware clipping by writing to framebuffer directly.
2448          * */
2449         x2 = rect->dx + rect->width;
2450         y2 = rect->dy + rect->height;
2451         x2 = x2 < info->var.xres_virtual ? x2 : info->var.xres_virtual;
2452         y2 = y2 < info->var.yres_virtual ? y2 : info->var.yres_virtual;
2453         width = x2 - rect->dx;
2454         height = y2 - rect->dy;
2455
2456         if (info->var.bits_per_pixel == 1)
2457                 atafb_mfb_fillrect(info, par->next_line, rect->color,
2458                                    rect->dy, rect->dx, height, width);
2459         else if (info->var.bits_per_pixel == 2)
2460                 atafb_iplan2p2_fillrect(info, par->next_line, rect->color,
2461                                         rect->dy, rect->dx, height, width);
2462         else if (info->var.bits_per_pixel == 4)
2463                 atafb_iplan2p4_fillrect(info, par->next_line, rect->color,
2464                                         rect->dy, rect->dx, height, width);
2465         else
2466                 atafb_iplan2p8_fillrect(info, par->next_line, rect->color,
2467                                         rect->dy, rect->dx, height, width);
2468
2469         return;
2470 }
2471
2472 static void atafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
2473 {
2474         struct atafb_par *par = (struct atafb_par *)info->par;
2475         int x2, y2;
2476         u32 dx, dy, sx, sy, width, height;
2477         int rev_copy = 0;
2478
2479 #ifdef ATAFB_FALCON
2480         if (info->var.bits_per_pixel == 16) {
2481                 cfb_copyarea(info, area);
2482                 return;
2483         }
2484 #endif
2485
2486         /* clip the destination */
2487         x2 = area->dx + area->width;
2488         y2 = area->dy + area->height;
2489         dx = area->dx > 0 ? area->dx : 0;
2490         dy = area->dy > 0 ? area->dy : 0;
2491         x2 = x2 < info->var.xres_virtual ? x2 : info->var.xres_virtual;
2492         y2 = y2 < info->var.yres_virtual ? y2 : info->var.yres_virtual;
2493         width = x2 - dx;
2494         height = y2 - dy;
2495
2496         if (area->sx + dx < area->dx || area->sy + dy < area->dy)
2497                 return;
2498
2499         /* update sx,sy */
2500         sx = area->sx + (dx - area->dx);
2501         sy = area->sy + (dy - area->dy);
2502
2503         /* the source must be completely inside the virtual screen */
2504         if (sx + width > info->var.xres_virtual ||
2505                         sy + height > info->var.yres_virtual)
2506                 return;
2507
2508         if (dy > sy || (dy == sy && dx > sx)) {
2509                 dy += height;
2510                 sy += height;
2511                 rev_copy = 1;
2512         }
2513
2514         if (info->var.bits_per_pixel == 1)
2515                 atafb_mfb_copyarea(info, par->next_line, sy, sx, dy, dx, height, width);
2516         else if (info->var.bits_per_pixel == 2)
2517                 atafb_iplan2p2_copyarea(info, par->next_line, sy, sx, dy, dx, height, width);
2518         else if (info->var.bits_per_pixel == 4)
2519                 atafb_iplan2p4_copyarea(info, par->next_line, sy, sx, dy, dx, height, width);
2520         else
2521                 atafb_iplan2p8_copyarea(info, par->next_line, sy, sx, dy, dx, height, width);
2522
2523         return;
2524 }
2525
2526 static void atafb_imageblit(struct fb_info *info, const struct fb_image *image)
2527 {
2528         struct atafb_par *par = (struct atafb_par *)info->par;
2529         int x2, y2;
2530         unsigned long *dst;
2531         int dst_idx;
2532         const char *src;
2533         u32 dx, dy, width, height, pitch;
2534
2535 #ifdef ATAFB_FALCON
2536         if (info->var.bits_per_pixel == 16) {
2537                 cfb_imageblit(info, image);
2538                 return;
2539         }
2540 #endif
2541
2542         /*
2543          * We could use hardware clipping but on many cards you get around
2544          * hardware clipping by writing to framebuffer directly like we are
2545          * doing here.
2546          */
2547         x2 = image->dx + image->width;
2548         y2 = image->dy + image->height;
2549         dx = image->dx;
2550         dy = image->dy;
2551         x2 = x2 < info->var.xres_virtual ? x2 : info->var.xres_virtual;
2552         y2 = y2 < info->var.yres_virtual ? y2 : info->var.yres_virtual;
2553         width = x2 - dx;
2554         height = y2 - dy;
2555
2556         if (image->depth == 1) {
2557                 // used for font data
2558                 dst = (unsigned long *)
2559                         ((unsigned long)info->screen_base & ~(BYTES_PER_LONG - 1));
2560                 dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG - 1)) * 8;
2561                 dst_idx += dy * par->next_line * 8 + dx;
2562                 src = image->data;
2563                 pitch = (image->width + 7) / 8;
2564                 while (height--) {
2565
2566                         if (info->var.bits_per_pixel == 1)
2567                                 atafb_mfb_linefill(info, par->next_line,
2568                                                    dy, dx, width, src,
2569                                                    image->bg_color, image->fg_color);
2570                         else if (info->var.bits_per_pixel == 2)
2571                                 atafb_iplan2p2_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 == 4)
2575                                 atafb_iplan2p4_linefill(info, par->next_line,
2576                                                         dy, dx, width, src,
2577                                                         image->bg_color, image->fg_color);
2578                         else
2579                                 atafb_iplan2p8_linefill(info, par->next_line,
2580                                                         dy, dx, width, src,
2581                                                         image->bg_color, image->fg_color);
2582                         dy++;
2583                         src += pitch;
2584                 }
2585         } else {
2586                 c2p_iplan2(info->screen_base, image->data, dx, dy, width,
2587                            height, par->next_line, image->width,
2588                            info->var.bits_per_pixel);
2589         }
2590 }
2591
2592 static int
2593 atafb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
2594 {
2595         switch (cmd) {
2596 #ifdef FBCMD_GET_CURRENTPAR
2597         case FBCMD_GET_CURRENTPAR:
2598                 if (copy_to_user((void *)arg, (void *)&current_par,
2599                                  sizeof(struct atafb_par)))
2600                         return -EFAULT;
2601                 return 0;
2602 #endif
2603 #ifdef FBCMD_SET_CURRENTPAR
2604         case FBCMD_SET_CURRENTPAR:
2605                 if (copy_from_user((void *)&current_par, (void *)arg,
2606                                    sizeof(struct atafb_par)))
2607                         return -EFAULT;
2608                 ata_set_par(&current_par);
2609                 return 0;
2610 #endif
2611         }
2612         return -EINVAL;
2613 }
2614
2615 /* (un)blank/poweroff
2616  * 0 = unblank
2617  * 1 = blank
2618  * 2 = suspend vsync
2619  * 3 = suspend hsync
2620  * 4 = off
2621  */
2622 static int atafb_blank(int blank, struct fb_info *info)
2623 {
2624         unsigned short black[16];
2625         struct fb_cmap cmap;
2626         if (fbhw->blank && !fbhw->blank(blank))
2627                 return 1;
2628         if (blank) {
2629                 memset(black, 0, 16 * sizeof(unsigned short));
2630                 cmap.red = black;
2631                 cmap.green = black;
2632                 cmap.blue = black;
2633                 cmap.transp = NULL;
2634                 cmap.start = 0;
2635                 cmap.len = 16;
2636                 fb_set_cmap(&cmap, info);
2637         }
2638 #if 0
2639         else
2640                 do_install_cmap(info);
2641 #endif
2642         return 0;
2643 }
2644
2645         /*
2646          * New fbcon interface ...
2647          */
2648
2649          /* check var by decoding var into hw par, rounding if necessary,
2650           * then encoding hw par back into new, validated var */
2651 static int atafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
2652 {
2653         int err;
2654         struct atafb_par par;
2655
2656         /* Validate wanted screen parameters */
2657         // if ((err = ata_decode_var(var, &par)))
2658         err = fbhw->decode_var(var, &par);
2659         if (err)
2660                 return err;
2661
2662         /* Encode (possibly rounded) screen parameters */
2663         fbhw->encode_var(var, &par);
2664         return 0;
2665 }
2666
2667         /* actually set hw par by decoding var, then setting hardware from
2668          * hw par just decoded */
2669 static int atafb_set_par(struct fb_info *info)
2670 {
2671         struct atafb_par *par = (struct atafb_par *)info->par;
2672
2673         /* Decode wanted screen parameters */
2674         fbhw->decode_var(&info->var, par);
2675         mutex_lock(&info->mm_lock);
2676         fbhw->encode_fix(&info->fix, par);
2677         mutex_unlock(&info->mm_lock);
2678
2679         /* Set new videomode */
2680         ata_set_par(par);
2681
2682         return 0;
2683 }
2684
2685
2686 static struct fb_ops atafb_ops = {
2687         .owner =        THIS_MODULE,
2688         .fb_check_var   = atafb_check_var,
2689         .fb_set_par     = atafb_set_par,
2690         .fb_blank =     atafb_blank,
2691         .fb_pan_display = atafb_pan_display,
2692         .fb_fillrect    = atafb_fillrect,
2693         .fb_copyarea    = atafb_copyarea,
2694         .fb_imageblit   = atafb_imageblit,
2695         .fb_ioctl =     atafb_ioctl,
2696 };
2697
2698 static void check_default_par(int detected_mode)
2699 {
2700         char default_name[10];
2701         int i;
2702         struct fb_var_screeninfo var;
2703         unsigned long min_mem;
2704
2705         /* First try the user supplied mode */
2706         if (default_par) {
2707                 var = atafb_predefined[default_par - 1];
2708                 var.activate = FB_ACTIVATE_TEST;
2709                 if (do_fb_set_var(&var, 1))
2710                         default_par = 0;        /* failed */
2711         }
2712         /* Next is the autodetected one */
2713         if (!default_par) {
2714                 var = atafb_predefined[detected_mode - 1]; /* autodetect */
2715                 var.activate = FB_ACTIVATE_TEST;
2716                 if (!do_fb_set_var(&var, 1))
2717                         default_par = detected_mode;
2718         }
2719         /* If that also failed, try some default modes... */
2720         if (!default_par) {
2721                 /* try default1, default2... */
2722                 for (i = 1; i < 10; i++) {
2723                         sprintf(default_name,"default%d", i);
2724                         default_par = get_video_mode(default_name);
2725                         if (!default_par)
2726                                 panic("can't set default video mode");
2727                         var = atafb_predefined[default_par - 1];
2728                         var.activate = FB_ACTIVATE_TEST;
2729                         if (!do_fb_set_var(&var,1))
2730                                 break;  /* ok */
2731                 }
2732         }
2733         min_mem = var.xres_virtual * var.yres_virtual * var.bits_per_pixel / 8;
2734         if (default_mem_req < min_mem)
2735                 default_mem_req = min_mem;
2736 }
2737
2738 #ifdef ATAFB_EXT
2739 static void __init atafb_setup_ext(char *spec)
2740 {
2741         int xres, xres_virtual, yres, depth, planes;
2742         unsigned long addr, len;
2743         char *p;
2744
2745         /* Format is: <xres>;<yres>;<depth>;<plane organ.>;
2746          *            <screen mem addr>
2747          *            [;<screen mem length>[;<vgaiobase>[;<bits-per-col>[;<colorreg-type>
2748          *            [;<xres-virtual>]]]]]
2749          *
2750          * 09/23/97     Juergen
2751          * <xres_virtual>:      hardware's x-resolution (f.e. ProMST)
2752          *
2753          * Even xres_virtual is available, we neither support panning nor hw-scrolling!
2754          */
2755         p = strsep(&spec, ";");
2756         if (!p || !*p)
2757                 return;
2758         xres_virtual = xres = simple_strtoul(p, NULL, 10);
2759         if (xres <= 0)
2760                 return;
2761
2762         p = strsep(&spec, ";");
2763         if (!p || !*p)
2764                 return;
2765         yres = simple_strtoul(p, NULL, 10);
2766         if (yres <= 0)
2767                 return;
2768
2769         p = strsep(&spec, ";");
2770         if (!p || !*p)
2771                 return;
2772         depth = simple_strtoul(p, NULL, 10);
2773         if (depth != 1 && depth != 2 && depth != 4 && depth != 8 &&
2774             depth != 16 && depth != 24)
2775                 return;
2776
2777         p = strsep(&spec, ";");
2778         if (!p || !*p)
2779                 return;
2780         if (*p == 'i')
2781                 planes = FB_TYPE_INTERLEAVED_PLANES;
2782         else if (*p == 'p')
2783                 planes = FB_TYPE_PACKED_PIXELS;
2784         else if (*p == 'n')
2785                 planes = FB_TYPE_PLANES;
2786         else if (*p == 't')
2787                 planes = -1;            /* true color */
2788         else
2789                 return;
2790
2791         p = strsep(&spec, ";");
2792         if (!p || !*p)
2793                 return;
2794         addr = simple_strtoul(p, NULL, 0);
2795
2796         p = strsep(&spec, ";");
2797         if (!p || !*p)
2798                 len = xres * yres * depth / 8;
2799         else
2800                 len = simple_strtoul(p, NULL, 0);
2801
2802         p = strsep(&spec, ";");
2803         if (p && *p)
2804                 external_vgaiobase = simple_strtoul(p, NULL, 0);
2805
2806         p = strsep(&spec, ";");
2807         if (p && *p) {
2808                 external_bitspercol = simple_strtoul(p, NULL, 0);
2809                 if (external_bitspercol > 8)
2810                         external_bitspercol = 8;
2811                 else if (external_bitspercol < 1)
2812                         external_bitspercol = 1;
2813         }
2814
2815         p = strsep(&spec, ";");
2816         if (p && *p) {
2817                 if (!strcmp(p, "vga"))
2818                         external_card_type = IS_VGA;
2819                 if (!strcmp(p, "mv300"))
2820                         external_card_type = IS_MV300;
2821         }
2822
2823         p = strsep(&spec, ";");
2824         if (p && *p) {
2825                 xres_virtual = simple_strtoul(p, NULL, 10);
2826                 if (xres_virtual < xres)
2827                         xres_virtual = xres;
2828                 if (xres_virtual * yres * depth / 8 > len)
2829                         len = xres_virtual * yres * depth / 8;
2830         }
2831
2832         external_xres = xres;
2833         external_xres_virtual = xres_virtual;
2834         external_yres = yres;
2835         external_depth = depth;
2836         external_pmode = planes;
2837         external_addr = addr;
2838         external_len = len;
2839
2840         if (external_card_type == IS_MV300) {
2841                 switch (external_depth) {
2842                 case 1:
2843                         MV300_reg = MV300_reg_1bit;
2844                         break;
2845                 case 4:
2846                         MV300_reg = MV300_reg_4bit;
2847                         break;
2848                 case 8:
2849                         MV300_reg = MV300_reg_8bit;
2850                         break;
2851                 }
2852         }
2853 }
2854 #endif /* ATAFB_EXT */
2855
2856 static void __init atafb_setup_int(char *spec)
2857 {
2858         /* Format to config extended internal video hardware like OverScan:
2859          * "internal:<xres>;<yres>;<xres_max>;<yres_max>;<offset>"
2860          * Explanation:
2861          * <xres>: x-resolution
2862          * <yres>: y-resolution
2863          * The following are only needed if you have an overscan which
2864          * needs a black border:
2865          * <xres_max>: max. length of a line in pixels your OverScan hardware would allow
2866          * <yres_max>: max. number of lines your OverScan hardware would allow
2867          * <offset>: Offset from physical beginning to visible beginning
2868          *        of screen in bytes
2869          */
2870         int xres;
2871         char *p;
2872
2873         if (!(p = strsep(&spec, ";")) || !*p)
2874                 return;
2875         xres = simple_strtoul(p, NULL, 10);
2876         if (!(p = strsep(&spec, ";")) || !*p)
2877                 return;
2878         sttt_xres = xres;
2879         tt_yres = st_yres = simple_strtoul(p, NULL, 10);
2880         if ((p = strsep(&spec, ";")) && *p)
2881                 sttt_xres_virtual = simple_strtoul(p, NULL, 10);
2882         if ((p = strsep(&spec, ";")) && *p)
2883                 sttt_yres_virtual = simple_strtoul(p, NULL, 0);
2884         if ((p = strsep(&spec, ";")) && *p)
2885                 ovsc_offset = simple_strtoul(p, NULL, 0);
2886
2887         if (ovsc_offset || (sttt_yres_virtual != st_yres))
2888                 use_hwscroll = 0;
2889 }
2890
2891 #ifdef ATAFB_FALCON
2892 static void __init atafb_setup_mcap(char *spec)
2893 {
2894         char *p;
2895         int vmin, vmax, hmin, hmax;
2896
2897         /* Format for monitor capabilities is: <Vmin>;<Vmax>;<Hmin>;<Hmax>
2898          * <V*> vertical freq. in Hz
2899          * <H*> horizontal freq. in kHz
2900          */
2901         if (!(p = strsep(&spec, ";")) || !*p)
2902                 return;
2903         vmin = simple_strtoul(p, NULL, 10);
2904         if (vmin <= 0)
2905                 return;
2906         if (!(p = strsep(&spec, ";")) || !*p)
2907                 return;
2908         vmax = simple_strtoul(p, NULL, 10);
2909         if (vmax <= 0 || vmax <= vmin)
2910                 return;
2911         if (!(p = strsep(&spec, ";")) || !*p)
2912                 return;
2913         hmin = 1000 * simple_strtoul(p, NULL, 10);
2914         if (hmin <= 0)
2915                 return;
2916         if (!(p = strsep(&spec, "")) || !*p)
2917                 return;
2918         hmax = 1000 * simple_strtoul(p, NULL, 10);
2919         if (hmax <= 0 || hmax <= hmin)
2920                 return;
2921
2922         fb_info.monspecs.vfmin = vmin;
2923         fb_info.monspecs.vfmax = vmax;
2924         fb_info.monspecs.hfmin = hmin;
2925         fb_info.monspecs.hfmax = hmax;
2926 }
2927 #endif /* ATAFB_FALCON */
2928
2929 static void __init atafb_setup_user(char *spec)
2930 {
2931         /* Format of user defined video mode is: <xres>;<yres>;<depth>
2932          */
2933         char *p;
2934         int xres, yres, depth, temp;
2935
2936         p = strsep(&spec, ";");
2937         if (!p || !*p)
2938                 return;
2939         xres = simple_strtoul(p, NULL, 10);
2940         p = strsep(&spec, ";");
2941         if (!p || !*p)
2942                 return;
2943         yres = simple_strtoul(p, NULL, 10);
2944         p = strsep(&spec, "");
2945         if (!p || !*p)
2946                 return;
2947         depth = simple_strtoul(p, NULL, 10);
2948         temp = get_video_mode("user0");
2949         if (temp) {
2950                 default_par = temp;
2951                 atafb_predefined[default_par - 1].xres = xres;
2952                 atafb_predefined[default_par - 1].yres = yres;
2953                 atafb_predefined[default_par - 1].bits_per_pixel = depth;
2954         }
2955 }
2956
2957 static int __init atafb_setup(char *options)
2958 {
2959         char *this_opt;
2960         int temp;
2961
2962         if (!options || !*options)
2963                 return 0;
2964
2965         while ((this_opt = strsep(&options, ",")) != NULL) {
2966                 if (!*this_opt)
2967                         continue;
2968                 if ((temp = get_video_mode(this_opt))) {
2969                         default_par = temp;
2970                         mode_option = this_opt;
2971                 } else if (!strcmp(this_opt, "inverse"))
2972                         fb_invert_cmaps();
2973                 else if (!strncmp(this_opt, "hwscroll_", 9)) {
2974                         hwscroll = simple_strtoul(this_opt + 9, NULL, 10);
2975                         if (hwscroll < 0)
2976                                 hwscroll = 0;
2977                         if (hwscroll > 200)
2978                                 hwscroll = 200;
2979                 }
2980 #ifdef ATAFB_EXT
2981                 else if (!strcmp(this_opt, "mv300")) {
2982                         external_bitspercol = 8;
2983                         external_card_type = IS_MV300;
2984                 } else if (!strncmp(this_opt, "external:", 9))
2985                         atafb_setup_ext(this_opt + 9);
2986 #endif
2987                 else if (!strncmp(this_opt, "internal:", 9))
2988                         atafb_setup_int(this_opt + 9);
2989 #ifdef ATAFB_FALCON
2990                 else if (!strncmp(this_opt, "eclock:", 7)) {
2991                         fext.f = simple_strtoul(this_opt + 7, NULL, 10);
2992                         /* external pixelclock in kHz --> ps */
2993                         fext.t = 1000000000 / fext.f;
2994                         fext.f *= 1000;
2995                 } else if (!strncmp(this_opt, "monitorcap:", 11))
2996                         atafb_setup_mcap(this_opt + 11);
2997 #endif
2998                 else if (!strcmp(this_opt, "keep"))
2999                         DontCalcRes = 1;
3000                 else if (!strncmp(this_opt, "R", 1))
3001                         atafb_setup_user(this_opt + 1);
3002         }
3003         return 0;
3004 }
3005
3006 static int __init atafb_probe(struct platform_device *pdev)
3007 {
3008         int pad, detected_mode, error;
3009         unsigned int defmode = 0;
3010         unsigned long mem_req;
3011         char *option = NULL;
3012
3013         if (fb_get_options("atafb", &option))
3014                 return -ENODEV;
3015         atafb_setup(option);
3016         dev_dbg(&pdev->dev, "%s: start\n", __func__);
3017
3018         do {
3019 #ifdef ATAFB_EXT
3020                 if (external_addr) {
3021                         dev_dbg(&pdev->dev, "initializing external hw\n");
3022                         fbhw = &ext_switch;
3023                         atafb_ops.fb_setcolreg = &ext_setcolreg;
3024                         defmode = DEFMODE_EXT;
3025                         break;
3026                 }
3027 #endif
3028 #ifdef ATAFB_TT
3029                 if (ATARIHW_PRESENT(TT_SHIFTER)) {
3030                         dev_dbg(&pdev->dev, "initializing TT hw\n");
3031                         fbhw = &tt_switch;
3032                         atafb_ops.fb_setcolreg = &tt_setcolreg;
3033                         defmode = DEFMODE_TT;
3034                         break;
3035                 }
3036 #endif
3037 #ifdef ATAFB_FALCON
3038                 if (ATARIHW_PRESENT(VIDEL_SHIFTER)) {
3039                         dev_dbg(&pdev->dev, "initializing Falcon hw\n");
3040                         fbhw = &falcon_switch;
3041                         atafb_ops.fb_setcolreg = &falcon_setcolreg;
3042                         error = request_irq(IRQ_AUTO_4, falcon_vbl_switcher, 0,
3043                                             "framebuffer:modeswitch",
3044                                             falcon_vbl_switcher);
3045                         if (error)
3046                                 return error;
3047                         defmode = DEFMODE_F30;
3048                         break;
3049                 }
3050 #endif
3051 #ifdef ATAFB_STE
3052                 if (ATARIHW_PRESENT(STND_SHIFTER) ||
3053                     ATARIHW_PRESENT(EXTD_SHIFTER)) {
3054                         dev_dbg(&pdev->dev, "initializing ST/E hw\n");
3055                         fbhw = &st_switch;
3056                         atafb_ops.fb_setcolreg = &stste_setcolreg;
3057                         defmode = DEFMODE_STE;
3058                         break;
3059                 }
3060                 fbhw = &st_switch;
3061                 atafb_ops.fb_setcolreg = &stste_setcolreg;
3062                 dev_warn(&pdev->dev,
3063                          "Cannot determine video hardware; defaulting to ST(e)\n");
3064 #else /* ATAFB_STE */
3065                 /* no default driver included */
3066                 /* Nobody will ever see this message :-) */
3067                 panic("Cannot initialize video hardware");
3068 #endif
3069         } while (0);
3070
3071         /* Multisync monitor capabilities */
3072         /* Atari-TOS defaults if no boot option present */
3073         if (fb_info.monspecs.hfmin == 0) {
3074                 fb_info.monspecs.hfmin = 31000;
3075                 fb_info.monspecs.hfmax = 32000;
3076                 fb_info.monspecs.vfmin = 58;
3077                 fb_info.monspecs.vfmax = 62;
3078         }
3079
3080         detected_mode = fbhw->detect();
3081         check_default_par(detected_mode);
3082 #ifdef ATAFB_EXT
3083         if (!external_addr) {
3084 #endif /* ATAFB_EXT */
3085                 mem_req = default_mem_req + ovsc_offset + ovsc_addlen;
3086                 mem_req = PAGE_ALIGN(mem_req) + PAGE_SIZE;
3087                 screen_base = atari_stram_alloc(mem_req, "atafb");
3088                 if (!screen_base)
3089                         panic("Cannot allocate screen memory");
3090                 memset(screen_base, 0, mem_req);
3091                 pad = -(unsigned long)screen_base & (PAGE_SIZE - 1);
3092                 screen_base += pad;
3093                 phys_screen_base = atari_stram_to_phys(screen_base + ovsc_offset);
3094                 screen_len = (mem_req - pad - ovsc_offset) & PAGE_MASK;
3095                 st_ovsc_switch();
3096                 if (CPU_IS_040_OR_060) {
3097                         /* On a '040+, the cache mode of video RAM must be set to
3098                          * write-through also for internal video hardware! */
3099                         cache_push(atari_stram_to_phys(screen_base), screen_len);
3100                         kernel_set_cachemode(screen_base, screen_len,
3101                                              IOMAP_WRITETHROUGH);
3102                 }
3103                 dev_info(&pdev->dev, "phys_screen_base %lx screen_len %d\n",
3104                          phys_screen_base, screen_len);
3105 #ifdef ATAFB_EXT
3106         } else {
3107                 /* Map the video memory (physical address given) to somewhere
3108                  * in the kernel address space.
3109                  */
3110                 external_screen_base = ioremap_wt(external_addr, external_len);
3111                 if (external_vgaiobase)
3112                         external_vgaiobase =
3113                           (unsigned long)ioremap(external_vgaiobase, 0x10000);
3114                 screen_base = external_screen_base;
3115                 phys_screen_base = external_addr;
3116                 screen_len = external_len & PAGE_MASK;
3117                 memset (screen_base, 0, external_len);
3118         }
3119 #endif /* ATAFB_EXT */
3120
3121 //      strcpy(fb_info.mode->name, "Atari Builtin ");
3122         fb_info.fbops = &atafb_ops;
3123         // try to set default (detected; requested) var
3124         do_fb_set_var(&atafb_predefined[default_par - 1], 1);
3125         // reads hw state into current par, which may not be sane yet
3126         ata_get_par(&current_par);
3127         fb_info.par = &current_par;
3128         // tries to read from HW which may not be initialized yet
3129         // so set sane var first, then call atafb_set_par
3130         atafb_get_var(&fb_info.var, &fb_info);
3131
3132 #ifdef ATAFB_FALCON
3133         fb_info.pseudo_palette = current_par.hw.falcon.pseudo_palette;
3134 #endif
3135         fb_info.flags = FBINFO_FLAG_DEFAULT;
3136
3137         if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, atafb_modedb,
3138                           NUM_TOTAL_MODES, &atafb_modedb[defmode],
3139                           fb_info.var.bits_per_pixel)) {
3140                 return -EINVAL;
3141         }
3142
3143         fb_videomode_to_modelist(atafb_modedb, NUM_TOTAL_MODES,
3144                                  &fb_info.modelist);
3145
3146         atafb_set_disp(&fb_info);
3147
3148         fb_alloc_cmap(&(fb_info.cmap), 1 << fb_info.var.bits_per_pixel, 0);
3149
3150
3151         dev_info(&pdev->dev, "Determined %dx%d, depth %d\n", fb_info.var.xres,
3152                  fb_info.var.yres, fb_info.var.bits_per_pixel);
3153         if ((fb_info.var.xres != fb_info.var.xres_virtual) ||
3154             (fb_info.var.yres != fb_info.var.yres_virtual))
3155                 dev_info(&pdev->dev, "   virtual %dx%d\n",
3156                          fb_info.var.xres_virtual, fb_info.var.yres_virtual);
3157
3158         if (register_framebuffer(&fb_info) < 0) {
3159 #ifdef ATAFB_EXT
3160                 if (external_addr) {
3161                         iounmap(external_screen_base);
3162                         external_addr = 0;
3163                 }
3164                 if (external_vgaiobase) {
3165                         iounmap((void*)external_vgaiobase);
3166                         external_vgaiobase = 0;
3167                 }
3168 #endif
3169                 return -EINVAL;
3170         }
3171
3172         fb_info(&fb_info, "frame buffer device, using %dK of video memory\n",
3173                 screen_len >> 10);
3174
3175         /* TODO: This driver cannot be unloaded yet */
3176         return 0;
3177 }
3178
3179 static void atafb_shutdown(struct platform_device *pdev)
3180 {
3181         /* Unblank before kexec */
3182         if (fbhw->blank)
3183                 fbhw->blank(0);
3184 }
3185
3186 static struct platform_driver atafb_driver = {
3187         .shutdown       = atafb_shutdown,
3188         .driver = {
3189                 .name   = "atafb",
3190         },
3191 };
3192
3193 static int __init atafb_init(void)
3194 {
3195         struct platform_device *pdev;
3196
3197         if (!MACH_IS_ATARI)
3198                 return -ENODEV;
3199
3200         pdev = platform_device_register_simple("atafb", -1, NULL, 0);
3201         if (IS_ERR(pdev))
3202                 return PTR_ERR(pdev);
3203
3204         return platform_driver_probe(&atafb_driver, atafb_probe);
3205 }
3206
3207 device_initcall(atafb_init);