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