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