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