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