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