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