0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 #define ATAFB_TT
0046 #define ATAFB_STE
0047 #define ATAFB_EXT
0048 #define ATAFB_FALCON
0049
0050 #include <linux/kernel.h>
0051 #include <linux/errno.h>
0052 #include <linux/string.h>
0053 #include <linux/mm.h>
0054 #include <linux/delay.h>
0055 #include <linux/init.h>
0056 #include <linux/interrupt.h>
0057 #include <linux/platform_device.h>
0058
0059 #include <asm/setup.h>
0060 #include <linux/uaccess.h>
0061 #include <asm/irq.h>
0062 #include <asm/io.h>
0063
0064 #include <asm/atarihw.h>
0065 #include <asm/atariints.h>
0066 #include <asm/atari_stram.h>
0067
0068 #include <linux/fb.h>
0069 #include <asm/atarikb.h>
0070
0071 #include "c2p.h"
0072 #include "atafb.h"
0073
0074 #define SWITCH_ACIA 0x01
0075 #define SWITCH_SND6 0x40
0076 #define SWITCH_SND7 0x80
0077 #define SWITCH_NONE 0x00
0078
0079
0080 static int default_par;
0081
0082 static unsigned long default_mem_req;
0083
0084 static int hwscroll = -1;
0085
0086 static int use_hwscroll = 1;
0087
0088 static int sttt_xres = 640, st_yres = 400, tt_yres = 480;
0089 static int sttt_xres_virtual = 640, sttt_yres_virtual = 400;
0090 static int ovsc_offset, ovsc_addlen;
0091
0092
0093
0094
0095
0096 static struct atafb_par {
0097 void *screen_base;
0098 int yres_virtual;
0099 u_long next_line;
0100 #if defined ATAFB_TT || defined ATAFB_STE
0101 union {
0102 struct {
0103 int mode;
0104 int sync;
0105 } tt, st;
0106 #endif
0107 #ifdef ATAFB_FALCON
0108 struct falcon_hw {
0109
0110
0111
0112 short sync;
0113 short line_width;
0114 short line_offset;
0115 short st_shift;
0116 short f_shift;
0117 short vid_control;
0118 short vid_mode;
0119 short xoffset;
0120 short hht, hbb, hbe, hdb, hde, hss;
0121 short vft, vbb, vbe, vdb, vde, vss;
0122
0123 short mono;
0124 short ste_mode;
0125 short bpp;
0126 u32 pseudo_palette[16];
0127 } falcon;
0128 #endif
0129
0130 } hw;
0131 } current_par;
0132
0133
0134
0135
0136 static int DontCalcRes = 0;
0137
0138 #ifdef ATAFB_FALCON
0139 #define HHT hw.falcon.hht
0140 #define HBB hw.falcon.hbb
0141 #define HBE hw.falcon.hbe
0142 #define HDB hw.falcon.hdb
0143 #define HDE hw.falcon.hde
0144 #define HSS hw.falcon.hss
0145 #define VFT hw.falcon.vft
0146 #define VBB hw.falcon.vbb
0147 #define VBE hw.falcon.vbe
0148 #define VDB hw.falcon.vdb
0149 #define VDE hw.falcon.vde
0150 #define VSS hw.falcon.vss
0151 #define VCO_CLOCK25 0x04
0152 #define VCO_CSYPOS 0x10
0153 #define VCO_VSYPOS 0x20
0154 #define VCO_HSYPOS 0x40
0155 #define VCO_SHORTOFFS 0x100
0156 #define VMO_DOUBLE 0x01
0157 #define VMO_INTER 0x02
0158 #define VMO_PREMASK 0x0c
0159 #endif
0160
0161 static struct fb_info fb_info = {
0162 .fix = {
0163 .id = "Atari ",
0164 .visual = FB_VISUAL_PSEUDOCOLOR,
0165 .accel = FB_ACCEL_NONE,
0166 }
0167 };
0168
0169 static void *screen_base;
0170 static unsigned long phys_screen_base;
0171
0172 static int screen_len;
0173
0174 static int current_par_valid;
0175
0176 static int mono_moni;
0177
0178
0179 #ifdef ATAFB_EXT
0180
0181
0182 static unsigned int external_xres;
0183 static unsigned int external_xres_virtual;
0184 static unsigned int external_yres;
0185
0186
0187
0188
0189
0190 static unsigned int external_depth;
0191 static int external_pmode;
0192 static void *external_screen_base;
0193 static unsigned long external_addr;
0194 static unsigned long external_len;
0195 static unsigned long external_vgaiobase;
0196 static unsigned int external_bitspercol = 6;
0197
0198
0199
0200
0201
0202
0203 enum cardtype { IS_VGA, IS_MV300 };
0204 static enum cardtype external_card_type = IS_VGA;
0205
0206
0207
0208
0209
0210 static int MV300_reg_1bit[2] = {
0211 0, 1
0212 };
0213 static int MV300_reg_4bit[16] = {
0214 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
0215 };
0216 static int MV300_reg_8bit[256] = {
0217 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240,
0218 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248,
0219 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,
0220 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252,
0221 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
0222 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250,
0223 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246,
0224 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254,
0225 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241,
0226 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
0227 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245,
0228 13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
0229 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
0230 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
0231 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
0232 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255
0233 };
0234
0235 static int *MV300_reg = MV300_reg_8bit;
0236 #endif
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347 static struct fb_hwswitch {
0348 int (*detect)(void);
0349 int (*encode_fix)(struct fb_fix_screeninfo *fix,
0350 struct atafb_par *par);
0351 int (*decode_var)(struct fb_var_screeninfo *var,
0352 struct atafb_par *par);
0353 int (*encode_var)(struct fb_var_screeninfo *var,
0354 struct atafb_par *par);
0355 void (*get_par)(struct atafb_par *par);
0356 void (*set_par)(struct atafb_par *par);
0357 void (*set_screen_base)(void *s_base);
0358 int (*blank)(int blank_mode);
0359 int (*pan_display)(struct fb_var_screeninfo *var,
0360 struct fb_info *info);
0361 } *fbhw;
0362
0363 static char *autodetect_names[] = { "autodetect", NULL };
0364 static char *stlow_names[] = { "stlow", NULL };
0365 static char *stmid_names[] = { "stmid", "default5", NULL };
0366 static char *sthigh_names[] = { "sthigh", "default4", NULL };
0367 static char *ttlow_names[] = { "ttlow", NULL };
0368 static char *ttmid_names[] = { "ttmid", "default1", NULL };
0369 static char *tthigh_names[] = { "tthigh", "default2", NULL };
0370 static char *vga2_names[] = { "vga2", NULL };
0371 static char *vga4_names[] = { "vga4", NULL };
0372 static char *vga16_names[] = { "vga16", "default3", NULL };
0373 static char *vga256_names[] = { "vga256", NULL };
0374 static char *falh2_names[] = { "falh2", NULL };
0375 static char *falh16_names[] = { "falh16", NULL };
0376
0377 static char **fb_var_names[] = {
0378 autodetect_names,
0379 stlow_names,
0380 stmid_names,
0381 sthigh_names,
0382 ttlow_names,
0383 ttmid_names,
0384 tthigh_names,
0385 vga2_names,
0386 vga4_names,
0387 vga16_names,
0388 vga256_names,
0389 falh2_names,
0390 falh16_names,
0391 NULL
0392 };
0393
0394 static struct fb_var_screeninfo atafb_predefined[] = {
0395
0396
0397
0398 {
0399 0, 0, 0, 0, 0, 0, 0, 0,
0400 {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
0401 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
0402 {
0403 320, 200, 320, 0, 0, 0, 4, 0,
0404 {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
0405 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
0406 {
0407 640, 200, 640, 0, 0, 0, 2, 0,
0408 {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
0409 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
0410 {
0411 640, 400, 640, 0, 0, 0, 1, 0,
0412 {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
0413 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
0414 {
0415 320, 480, 320, 0, 0, 0, 8, 0,
0416 {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
0417 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
0418 {
0419 640, 480, 640, 0, 0, 0, 4, 0,
0420 {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
0421 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
0422 {
0423 1280, 960, 1280, 0, 0, 0, 1, 0,
0424 {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
0425 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
0426 {
0427 640, 480, 640, 0, 0, 0, 1, 0,
0428 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
0429 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
0430 {
0431 640, 480, 640, 0, 0, 0, 2, 0,
0432 {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
0433 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
0434 {
0435 640, 480, 640, 0, 0, 0, 4, 0,
0436 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
0437 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
0438 {
0439 640, 480, 640, 0, 0, 0, 8, 0,
0440 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
0441 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
0442 {
0443 896, 608, 896, 0, 0, 0, 1, 0,
0444 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
0445 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
0446 {
0447 896, 608, 896, 0, 0, 0, 4, 0,
0448 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
0449 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
0450 };
0451
0452 static int num_atafb_predefined = ARRAY_SIZE(atafb_predefined);
0453
0454 static struct fb_videomode atafb_modedb[] __initdata = {
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465 {
0466
0467 "st-low", 60, 320, 200, 32000, 32, 16, 31, 14, 96, 4,
0468 0, FB_VMODE_NONINTERLACED
0469 }, {
0470
0471 "st-mid", 60, 640, 200, 32000, 32, 16, 31, 14, 96, 4,
0472 0, FB_VMODE_NONINTERLACED
0473 }, {
0474
0475 "st-high", 63, 640, 400, 32000, 128, 0, 40, 14, 128, 4,
0476 0, FB_VMODE_NONINTERLACED
0477 }, {
0478
0479 "tt-low", 60, 320, 480, 31041, 120, 100, 8, 16, 140, 30,
0480 0, FB_VMODE_NONINTERLACED
0481 }, {
0482
0483 "tt-mid", 60, 640, 480, 31041, 120, 100, 8, 16, 140, 30,
0484 0, FB_VMODE_NONINTERLACED
0485 }, {
0486
0487 "tt-high", 72, 1280, 960, 7760, 260, 60, 36, 4, 192, 4,
0488 0, FB_VMODE_NONINTERLACED
0489 },
0490
0491
0492
0493
0494
0495 {
0496
0497 "vga", 60, 640, 480, 39721, 42, 18, 31, 11, 100, 3,
0498 0, FB_VMODE_NONINTERLACED
0499 }, {
0500
0501 "vga70", 70, 640, 400, 39721, 42, 18, 31, 11, 100, 3,
0502 FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED
0503 },
0504
0505
0506
0507
0508
0509 {
0510
0511 "falh", 60, 896, 608, 32000, 18, 42, 31, 1, 96,3,
0512 0, FB_VMODE_NONINTERLACED
0513 },
0514 };
0515
0516 #define NUM_TOTAL_MODES ARRAY_SIZE(atafb_modedb)
0517
0518 static char *mode_option __initdata = NULL;
0519
0520
0521
0522 #define DEFMODE_TT 5
0523 #define DEFMODE_F30 7
0524 #define DEFMODE_STE 2
0525 #define DEFMODE_EXT 6
0526
0527
0528 static int get_video_mode(char *vname)
0529 {
0530 char ***name_list;
0531 char **name;
0532 int i;
0533
0534 name_list = fb_var_names;
0535 for (i = 0; i < num_atafb_predefined; i++) {
0536 name = *name_list++;
0537 if (!name || !*name)
0538 break;
0539 while (*name) {
0540 if (!strcmp(vname, *name))
0541 return i + 1;
0542 name++;
0543 }
0544 }
0545 return 0;
0546 }
0547
0548
0549
0550
0551
0552 #ifdef ATAFB_TT
0553
0554 static int tt_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par)
0555 {
0556 int mode;
0557
0558 strcpy(fix->id, "Atari Builtin");
0559 fix->smem_start = phys_screen_base;
0560 fix->smem_len = screen_len;
0561 fix->type = FB_TYPE_INTERLEAVED_PLANES;
0562 fix->type_aux = 2;
0563 fix->visual = FB_VISUAL_PSEUDOCOLOR;
0564 mode = par->hw.tt.mode & TT_SHIFTER_MODEMASK;
0565 if (mode == TT_SHIFTER_TTHIGH || mode == TT_SHIFTER_STHIGH) {
0566 fix->type = FB_TYPE_PACKED_PIXELS;
0567 fix->type_aux = 0;
0568 if (mode == TT_SHIFTER_TTHIGH)
0569 fix->visual = FB_VISUAL_MONO01;
0570 }
0571 fix->xpanstep = 0;
0572 fix->ypanstep = 1;
0573 fix->ywrapstep = 0;
0574 fix->line_length = par->next_line;
0575 fix->accel = FB_ACCEL_ATARIBLITT;
0576 return 0;
0577 }
0578
0579 static int tt_decode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
0580 {
0581 int xres = var->xres;
0582 int yres = var->yres;
0583 int bpp = var->bits_per_pixel;
0584 int linelen;
0585 int yres_virtual = var->yres_virtual;
0586
0587 if (mono_moni) {
0588 if (bpp > 1 || xres > sttt_xres * 2 || yres > tt_yres * 2)
0589 return -EINVAL;
0590 par->hw.tt.mode = TT_SHIFTER_TTHIGH;
0591 xres = sttt_xres * 2;
0592 yres = tt_yres * 2;
0593 bpp = 1;
0594 } else {
0595 if (bpp > 8 || xres > sttt_xres || yres > tt_yres)
0596 return -EINVAL;
0597 if (bpp > 4) {
0598 if (xres > sttt_xres / 2 || yres > tt_yres)
0599 return -EINVAL;
0600 par->hw.tt.mode = TT_SHIFTER_TTLOW;
0601 xres = sttt_xres / 2;
0602 yres = tt_yres;
0603 bpp = 8;
0604 } else if (bpp > 2) {
0605 if (xres > sttt_xres || yres > tt_yres)
0606 return -EINVAL;
0607 if (xres > sttt_xres / 2 || yres > st_yres / 2) {
0608 par->hw.tt.mode = TT_SHIFTER_TTMID;
0609 xres = sttt_xres;
0610 yres = tt_yres;
0611 bpp = 4;
0612 } else {
0613 par->hw.tt.mode = TT_SHIFTER_STLOW;
0614 xres = sttt_xres / 2;
0615 yres = st_yres / 2;
0616 bpp = 4;
0617 }
0618 } else if (bpp > 1) {
0619 if (xres > sttt_xres || yres > st_yres / 2)
0620 return -EINVAL;
0621 par->hw.tt.mode = TT_SHIFTER_STMID;
0622 xres = sttt_xres;
0623 yres = st_yres / 2;
0624 bpp = 2;
0625 } else if (var->xres > sttt_xres || var->yres > st_yres) {
0626 return -EINVAL;
0627 } else {
0628 par->hw.tt.mode = TT_SHIFTER_STHIGH;
0629 xres = sttt_xres;
0630 yres = st_yres;
0631 bpp = 1;
0632 }
0633 }
0634 if (yres_virtual <= 0)
0635 yres_virtual = 0;
0636 else if (yres_virtual < yres)
0637 yres_virtual = yres;
0638 if (var->sync & FB_SYNC_EXT)
0639 par->hw.tt.sync = 0;
0640 else
0641 par->hw.tt.sync = 1;
0642 linelen = xres * bpp / 8;
0643 if (yres_virtual * linelen > screen_len && screen_len)
0644 return -EINVAL;
0645 if (yres * linelen > screen_len && screen_len)
0646 return -EINVAL;
0647 if (var->yoffset + yres > yres_virtual && yres_virtual)
0648 return -EINVAL;
0649 par->yres_virtual = yres_virtual;
0650 par->screen_base = screen_base + var->yoffset * linelen;
0651 par->next_line = linelen;
0652 return 0;
0653 }
0654
0655 static int tt_encode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
0656 {
0657 int linelen;
0658 memset(var, 0, sizeof(struct fb_var_screeninfo));
0659 var->red.offset = 0;
0660 var->red.length = 4;
0661 var->red.msb_right = 0;
0662 var->grayscale = 0;
0663
0664 var->pixclock = 31041;
0665 var->left_margin = 120;
0666 var->right_margin = 100;
0667 var->upper_margin = 8;
0668 var->lower_margin = 16;
0669 var->hsync_len = 140;
0670 var->vsync_len = 30;
0671
0672 var->height = -1;
0673 var->width = -1;
0674
0675 if (par->hw.tt.sync & 1)
0676 var->sync = 0;
0677 else
0678 var->sync = FB_SYNC_EXT;
0679
0680 switch (par->hw.tt.mode & TT_SHIFTER_MODEMASK) {
0681 case TT_SHIFTER_STLOW:
0682 var->xres = sttt_xres / 2;
0683 var->xres_virtual = sttt_xres_virtual / 2;
0684 var->yres = st_yres / 2;
0685 var->bits_per_pixel = 4;
0686 break;
0687 case TT_SHIFTER_STMID:
0688 var->xres = sttt_xres;
0689 var->xres_virtual = sttt_xres_virtual;
0690 var->yres = st_yres / 2;
0691 var->bits_per_pixel = 2;
0692 break;
0693 case TT_SHIFTER_STHIGH:
0694 var->xres = sttt_xres;
0695 var->xres_virtual = sttt_xres_virtual;
0696 var->yres = st_yres;
0697 var->bits_per_pixel = 1;
0698 break;
0699 case TT_SHIFTER_TTLOW:
0700 var->xres = sttt_xres / 2;
0701 var->xres_virtual = sttt_xres_virtual / 2;
0702 var->yres = tt_yres;
0703 var->bits_per_pixel = 8;
0704 break;
0705 case TT_SHIFTER_TTMID:
0706 var->xres = sttt_xres;
0707 var->xres_virtual = sttt_xres_virtual;
0708 var->yres = tt_yres;
0709 var->bits_per_pixel = 4;
0710 break;
0711 case TT_SHIFTER_TTHIGH:
0712 var->red.length = 0;
0713 var->xres = sttt_xres * 2;
0714 var->xres_virtual = sttt_xres_virtual * 2;
0715 var->yres = tt_yres * 2;
0716 var->bits_per_pixel = 1;
0717 break;
0718 }
0719 var->blue = var->green = var->red;
0720 var->transp.offset = 0;
0721 var->transp.length = 0;
0722 var->transp.msb_right = 0;
0723 linelen = var->xres_virtual * var->bits_per_pixel / 8;
0724 if (!use_hwscroll)
0725 var->yres_virtual = var->yres;
0726 else if (screen_len) {
0727 if (par->yres_virtual)
0728 var->yres_virtual = par->yres_virtual;
0729 else
0730
0731 var->yres_virtual = screen_len / linelen;
0732 } else {
0733 if (hwscroll < 0)
0734 var->yres_virtual = 2 * var->yres;
0735 else
0736 var->yres_virtual = var->yres + hwscroll * 16;
0737 }
0738 var->xoffset = 0;
0739 if (screen_base)
0740 var->yoffset = (par->screen_base - screen_base) / linelen;
0741 else
0742 var->yoffset = 0;
0743 var->nonstd = 0;
0744 var->activate = 0;
0745 var->vmode = FB_VMODE_NONINTERLACED;
0746 return 0;
0747 }
0748
0749 static void tt_get_par(struct atafb_par *par)
0750 {
0751 unsigned long addr;
0752 par->hw.tt.mode = shifter_tt.tt_shiftmode;
0753 par->hw.tt.sync = shifter_st.syncmode;
0754 addr = ((shifter_st.bas_hi & 0xff) << 16) |
0755 ((shifter_st.bas_md & 0xff) << 8) |
0756 ((shifter_st.bas_lo & 0xff));
0757 par->screen_base = atari_stram_to_virt(addr);
0758 }
0759
0760 static void tt_set_par(struct atafb_par *par)
0761 {
0762 shifter_tt.tt_shiftmode = par->hw.tt.mode;
0763 shifter_st.syncmode = par->hw.tt.sync;
0764
0765 if (current_par.screen_base != par->screen_base)
0766 fbhw->set_screen_base(par->screen_base);
0767 }
0768
0769 static int tt_setcolreg(unsigned int regno, unsigned int red,
0770 unsigned int green, unsigned int blue,
0771 unsigned int transp, struct fb_info *info)
0772 {
0773 if ((shifter_tt.tt_shiftmode & TT_SHIFTER_MODEMASK) == TT_SHIFTER_STHIGH)
0774 regno += 254;
0775 if (regno > 255)
0776 return 1;
0777 tt_palette[regno] = (((red >> 12) << 8) | ((green >> 12) << 4) |
0778 (blue >> 12));
0779 if ((shifter_tt.tt_shiftmode & TT_SHIFTER_MODEMASK) ==
0780 TT_SHIFTER_STHIGH && regno == 254)
0781 tt_palette[0] = 0;
0782 return 0;
0783 }
0784
0785 static int tt_detect(void)
0786 {
0787 struct atafb_par par;
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797 if (ATARIHW_PRESENT(PCM_8BIT)) {
0798 tt_dmasnd.ctrl = DMASND_CTRL_OFF;
0799 udelay(20);
0800 }
0801 mono_moni = (st_mfp.par_dt_reg & 0x80) == 0;
0802
0803 tt_get_par(&par);
0804 tt_encode_var(&atafb_predefined[0], &par);
0805
0806 return 1;
0807 }
0808
0809 #endif
0810
0811
0812
0813 #ifdef ATAFB_FALCON
0814
0815 static int mon_type;
0816 static int f030_bus_width;
0817 #define F_MON_SM 0
0818 #define F_MON_SC 1
0819 #define F_MON_VGA 2
0820 #define F_MON_TV 3
0821
0822 static struct pixel_clock {
0823 unsigned long f;
0824 unsigned long t;
0825 int right, hsync, left;
0826
0827 int sync_mask;
0828 int control_mask;
0829 } f25 = {
0830 25175000, 39721, 18, 0, 42, 0x0, VCO_CLOCK25
0831 }, f32 = {
0832 32000000, 31250, 18, 0, 42, 0x0, 0
0833 }, fext = {
0834 0, 0, 18, 0, 42, 0x1, 0
0835 };
0836
0837
0838 static int vdl_prescale[4][3] = {
0839 { 4,2,1 }, { 4,2,1 }, { 4,2,2 }, { 4,2,1 }
0840 };
0841
0842
0843 static long h_syncs[4] = { 3000000, 4875000, 4000000, 4875000 };
0844
0845 static inline int hxx_prescale(struct falcon_hw *hw)
0846 {
0847 return hw->ste_mode ? 16
0848 : vdl_prescale[mon_type][hw->vid_mode >> 2 & 0x3];
0849 }
0850
0851 static int falcon_encode_fix(struct fb_fix_screeninfo *fix,
0852 struct atafb_par *par)
0853 {
0854 strcpy(fix->id, "Atari Builtin");
0855 fix->smem_start = phys_screen_base;
0856 fix->smem_len = screen_len;
0857 fix->type = FB_TYPE_INTERLEAVED_PLANES;
0858 fix->type_aux = 2;
0859 fix->visual = FB_VISUAL_PSEUDOCOLOR;
0860 fix->xpanstep = 1;
0861 fix->ypanstep = 1;
0862 fix->ywrapstep = 0;
0863 if (par->hw.falcon.mono) {
0864 fix->type = FB_TYPE_PACKED_PIXELS;
0865 fix->type_aux = 0;
0866
0867 fix->xpanstep = 32;
0868 } else if (par->hw.falcon.f_shift & 0x100) {
0869 fix->type = FB_TYPE_PACKED_PIXELS;
0870 fix->type_aux = 0;
0871
0872 fix->visual = FB_VISUAL_TRUECOLOR;
0873 fix->xpanstep = 2;
0874 }
0875 fix->line_length = par->next_line;
0876 fix->accel = FB_ACCEL_ATARIBLITT;
0877 return 0;
0878 }
0879
0880 static int falcon_decode_var(struct fb_var_screeninfo *var,
0881 struct atafb_par *par)
0882 {
0883 int bpp = var->bits_per_pixel;
0884 int xres = var->xres;
0885 int yres = var->yres;
0886 int xres_virtual = var->xres_virtual;
0887 int yres_virtual = var->yres_virtual;
0888 int left_margin, right_margin, hsync_len;
0889 int upper_margin, lower_margin, vsync_len;
0890 int linelen;
0891 int interlace = 0, doubleline = 0;
0892 struct pixel_clock *pclock;
0893 int plen;
0894 int xstretch;
0895 int prescale;
0896 int longoffset = 0;
0897 int hfreq, vfreq;
0898 int hdb_off, hde_off, base_off;
0899 int gstart, gend1, gend2, align;
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914
0915
0916
0917
0918
0919
0920
0921
0922
0923
0924 if (!xres || !yres || !bpp)
0925 return -EINVAL;
0926
0927 if (mon_type == F_MON_SM && bpp != 1)
0928 return -EINVAL;
0929
0930 if (bpp <= 1) {
0931 bpp = 1;
0932 par->hw.falcon.f_shift = 0x400;
0933 par->hw.falcon.st_shift = 0x200;
0934 } else if (bpp <= 2) {
0935 bpp = 2;
0936 par->hw.falcon.f_shift = 0x000;
0937 par->hw.falcon.st_shift = 0x100;
0938 } else if (bpp <= 4) {
0939 bpp = 4;
0940 par->hw.falcon.f_shift = 0x000;
0941 par->hw.falcon.st_shift = 0x000;
0942 } else if (bpp <= 8) {
0943 bpp = 8;
0944 par->hw.falcon.f_shift = 0x010;
0945 } else if (bpp <= 16) {
0946 bpp = 16;
0947 par->hw.falcon.f_shift = 0x100;
0948 } else
0949 return -EINVAL;
0950 par->hw.falcon.bpp = bpp;
0951
0952 if (mon_type == F_MON_SM || DontCalcRes) {
0953
0954 struct fb_var_screeninfo *myvar = &atafb_predefined[0];
0955
0956 if (bpp > myvar->bits_per_pixel ||
0957 var->xres > myvar->xres ||
0958 var->yres > myvar->yres)
0959 return -EINVAL;
0960 fbhw->get_par(par);
0961 goto set_screen_base;
0962 }
0963
0964
0965 if (xres <= 320)
0966 xres = 320;
0967 else if (xres <= 640 && bpp != 16)
0968 xres = 640;
0969 if (yres <= 200)
0970 yres = 200;
0971 else if (yres <= 240)
0972 yres = 240;
0973 else if (yres <= 400)
0974 yres = 400;
0975
0976
0977 par->hw.falcon.ste_mode = bpp == 2;
0978 par->hw.falcon.mono = bpp == 1;
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988 if (par->hw.falcon.ste_mode)
0989 xres = (xres + 63) & ~63;
0990 else if (bpp == 1)
0991 xres = (xres + 31) & ~31;
0992 else
0993 xres = (xres + 15) & ~15;
0994 if (yres >= 400)
0995 yres = (yres + 15) & ~15;
0996 else
0997 yres = (yres + 7) & ~7;
0998
0999 if (xres_virtual < xres)
1000 xres_virtual = xres;
1001 else if (bpp == 1)
1002 xres_virtual = (xres_virtual + 31) & ~31;
1003 else
1004 xres_virtual = (xres_virtual + 15) & ~15;
1005
1006 if (yres_virtual <= 0)
1007 yres_virtual = 0;
1008 else if (yres_virtual < yres)
1009 yres_virtual = yres;
1010
1011 par->hw.falcon.line_width = bpp * xres / 16;
1012 par->hw.falcon.line_offset = bpp * (xres_virtual - xres) / 16;
1013
1014
1015 xstretch = (xres < 640) ? 2 : 1;
1016
1017 #if 0
1018 if (mon_type == F_MON_SM) {
1019 if (xres != 640 && yres != 400)
1020 return -EINVAL;
1021 plen = 1;
1022 pclock = &f32;
1023
1024 par->hw.falcon.ste_mode = 1;
1025 par->hw.falcon.f_shift = 0x000;
1026 par->hw.falcon.st_shift = 0x200;
1027 left_margin = hsync_len = 128 / plen;
1028 right_margin = 0;
1029
1030 } else
1031 #endif
1032 if (mon_type == F_MON_SC || mon_type == F_MON_TV) {
1033 plen = 2 * xstretch;
1034 if (var->pixclock > f32.t * plen)
1035 return -EINVAL;
1036 pclock = &f32;
1037 if (yres > 240)
1038 interlace = 1;
1039 if (var->pixclock == 0) {
1040
1041 left_margin = 32;
1042 right_margin = 18;
1043 hsync_len = pclock->hsync / plen;
1044 upper_margin = 31;
1045 lower_margin = 14;
1046 vsync_len = interlace ? 3 : 4;
1047 } else {
1048 left_margin = var->left_margin;
1049 right_margin = var->right_margin;
1050 hsync_len = var->hsync_len;
1051 upper_margin = var->upper_margin;
1052 lower_margin = var->lower_margin;
1053 vsync_len = var->vsync_len;
1054 if (var->vmode & FB_VMODE_INTERLACED) {
1055 upper_margin = (upper_margin + 1) / 2;
1056 lower_margin = (lower_margin + 1) / 2;
1057 vsync_len = (vsync_len + 1) / 2;
1058 } else if (var->vmode & FB_VMODE_DOUBLE) {
1059 upper_margin *= 2;
1060 lower_margin *= 2;
1061 vsync_len *= 2;
1062 }
1063 }
1064 } else {
1065 if (bpp == 16)
1066 xstretch = 2;
1067
1068 if (var->pixclock == 0) {
1069
1070 plen = 1 * xstretch;
1071 if ((plen * xres + f25.right + f25.hsync + f25.left) *
1072 fb_info.monspecs.hfmin < f25.f)
1073 pclock = &f25;
1074 else if ((plen * xres + f32.right + f32.hsync +
1075 f32.left) * fb_info.monspecs.hfmin < f32.f)
1076 pclock = &f32;
1077 else if ((plen * xres + fext.right + fext.hsync +
1078 fext.left) * fb_info.monspecs.hfmin < fext.f &&
1079 fext.f)
1080 pclock = &fext;
1081 else
1082 return -EINVAL;
1083
1084 left_margin = pclock->left / plen;
1085 right_margin = pclock->right / plen;
1086 hsync_len = pclock->hsync / plen;
1087 upper_margin = 31;
1088 lower_margin = 11;
1089 vsync_len = 3;
1090 } else {
1091
1092 int i;
1093 unsigned long pcl = ULONG_MAX;
1094 pclock = 0;
1095 for (i = 1; i <= 4; i *= 2) {
1096 if (f25.t * i >= var->pixclock &&
1097 f25.t * i < pcl) {
1098 pcl = f25.t * i;
1099 pclock = &f25;
1100 }
1101 if (f32.t * i >= var->pixclock &&
1102 f32.t * i < pcl) {
1103 pcl = f32.t * i;
1104 pclock = &f32;
1105 }
1106 if (fext.t && fext.t * i >= var->pixclock &&
1107 fext.t * i < pcl) {
1108 pcl = fext.t * i;
1109 pclock = &fext;
1110 }
1111 }
1112 if (!pclock)
1113 return -EINVAL;
1114 plen = pcl / pclock->t;
1115
1116 left_margin = var->left_margin;
1117 right_margin = var->right_margin;
1118 hsync_len = var->hsync_len;
1119 upper_margin = var->upper_margin;
1120 lower_margin = var->lower_margin;
1121 vsync_len = var->vsync_len;
1122
1123 if (var->vmode & FB_VMODE_INTERLACED) {
1124
1125
1126 upper_margin = (upper_margin + 1) / 2;
1127 lower_margin = (lower_margin + 1) / 2;
1128 vsync_len = (vsync_len + 1) / 2;
1129 } else if (var->vmode & FB_VMODE_DOUBLE) {
1130
1131 upper_margin *= 2;
1132 lower_margin *= 2;
1133 vsync_len *= 2;
1134 }
1135 }
1136 if (pclock == &fext)
1137 longoffset = 1;
1138 }
1139
1140
1141 if (pclock->f / plen / 8 * bpp > 32000000L)
1142 return -EINVAL;
1143
1144 if (vsync_len < 1)
1145 vsync_len = 1;
1146
1147
1148 right_margin += hsync_len;
1149 lower_margin += vsync_len;
1150
1151
1152
1153
1154
1155
1156 again:
1157
1158 par->hw.falcon.vid_control = mon_type | f030_bus_width;
1159 if (!longoffset)
1160 par->hw.falcon.vid_control |= VCO_SHORTOFFS;
1161 if (var->sync & FB_SYNC_HOR_HIGH_ACT)
1162 par->hw.falcon.vid_control |= VCO_HSYPOS;
1163 if (var->sync & FB_SYNC_VERT_HIGH_ACT)
1164 par->hw.falcon.vid_control |= VCO_VSYPOS;
1165
1166 par->hw.falcon.vid_control |= pclock->control_mask;
1167
1168 par->hw.falcon.sync = pclock->sync_mask | 0x2;
1169
1170 par->hw.falcon.vid_mode = (2 / plen) << 2;
1171 if (doubleline)
1172 par->hw.falcon.vid_mode |= VMO_DOUBLE;
1173 if (interlace)
1174 par->hw.falcon.vid_mode |= VMO_INTER;
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197 {
1198 prescale = hxx_prescale(&par->hw.falcon);
1199 base_off = par->hw.falcon.vid_control & VCO_SHORTOFFS ? 64 : 128;
1200
1201
1202
1203
1204
1205 if (par->hw.falcon.f_shift & 0x100) {
1206 align = 1;
1207 hde_off = 0;
1208 hdb_off = (base_off + 16 * plen) + prescale;
1209 } else {
1210 align = 128 / bpp;
1211 hde_off = ((128 / bpp + 2) * plen);
1212 if (par->hw.falcon.ste_mode)
1213 hdb_off = (64 + base_off + (128 / bpp + 2) * plen) + prescale;
1214 else
1215 hdb_off = (base_off + (128 / bpp + 18) * plen) + prescale;
1216 }
1217
1218 gstart = (prescale / 2 + plen * left_margin) / prescale;
1219
1220 gend1 = gstart + roundup(xres, align) * plen / prescale;
1221
1222 gend2 = gstart + xres * plen / prescale;
1223 par->HHT = plen * (left_margin + xres + right_margin) /
1224 (2 * prescale) - 2;
1225
1226
1227 par->HDB = gstart - hdb_off / prescale;
1228 par->HBE = gstart;
1229 if (par->HDB < 0)
1230 par->HDB += par->HHT + 2 + 0x200;
1231 par->HDE = gend1 - par->HHT - 2 - hde_off / prescale;
1232 par->HBB = gend2 - par->HHT - 2;
1233 #if 0
1234
1235 if ((par->HDB & 0x200) && (par->HDB & ~0x200) - par->HDE <= 5) {
1236
1237 }
1238 #endif
1239 if (hde_off % prescale)
1240 par->HBB++;
1241 par->HSS = par->HHT + 2 - plen * hsync_len / prescale;
1242 if (par->HSS < par->HBB)
1243 par->HSS = par->HBB;
1244 }
1245
1246
1247 hfreq = pclock->f / ((par->HHT + 2) * prescale * 2);
1248 if (hfreq > fb_info.monspecs.hfmax && mon_type != F_MON_VGA) {
1249
1250
1251 left_margin += 1;
1252 right_margin += 1;
1253 goto again;
1254 }
1255 if (hfreq > fb_info.monspecs.hfmax || hfreq < fb_info.monspecs.hfmin)
1256 return -EINVAL;
1257
1258
1259
1260
1261
1262
1263
1264
1265 par->VBE = (upper_margin * 2 + 1);
1266 par->VDB = par->VBE;
1267 par->VDE = yres;
1268 if (!interlace)
1269 par->VDE <<= 1;
1270 if (doubleline)
1271 par->VDE <<= 1;
1272 par->VDE += par->VDB;
1273 par->VBB = par->VDE;
1274 par->VFT = par->VBB + (lower_margin * 2 - 1) - 1;
1275 par->VSS = par->VFT + 1 - (vsync_len * 2 - 1);
1276
1277 if (interlace) {
1278 par->VBB++;
1279 par->VSS++;
1280 par->VFT++;
1281 }
1282
1283
1284
1285 vfreq = (hfreq * 2) / (par->VFT + 1);
1286 if (vfreq > fb_info.monspecs.vfmax && !doubleline && !interlace) {
1287
1288 doubleline = 1;
1289 goto again;
1290 } else if (vfreq < fb_info.monspecs.vfmin && !interlace && !doubleline) {
1291
1292 interlace = 1;
1293 goto again;
1294 } else if (vfreq < fb_info.monspecs.vfmin && doubleline) {
1295
1296 int lines;
1297 doubleline = 0;
1298 for (lines = 0;
1299 (hfreq * 2) / (par->VFT + 1 + 4 * lines - 2 * yres) >
1300 fb_info.monspecs.vfmax;
1301 lines++)
1302 ;
1303 upper_margin += lines;
1304 lower_margin += lines;
1305 goto again;
1306 } else if (vfreq > fb_info.monspecs.vfmax && doubleline) {
1307
1308 int lines;
1309 for (lines = 0;
1310 (hfreq * 2) / (par->VFT + 1 + 4 * lines) >
1311 fb_info.monspecs.vfmax;
1312 lines += 2)
1313 ;
1314 upper_margin += lines;
1315 lower_margin += lines;
1316 goto again;
1317 } else if (vfreq > fb_info.monspecs.vfmax && interlace) {
1318
1319 int lines;
1320 for (lines = 0;
1321 (hfreq * 2) / (par->VFT + 1 + 4 * lines) >
1322 fb_info.monspecs.vfmax;
1323 lines++)
1324 ;
1325 upper_margin += lines;
1326 lower_margin += lines;
1327 goto again;
1328 } else if (vfreq < fb_info.monspecs.vfmin ||
1329 vfreq > fb_info.monspecs.vfmax)
1330 return -EINVAL;
1331
1332 set_screen_base:
1333 linelen = xres_virtual * bpp / 8;
1334 if (yres_virtual * linelen > screen_len && screen_len)
1335 return -EINVAL;
1336 if (yres * linelen > screen_len && screen_len)
1337 return -EINVAL;
1338 if (var->yoffset + yres > yres_virtual && yres_virtual)
1339 return -EINVAL;
1340 par->yres_virtual = yres_virtual;
1341 par->screen_base = screen_base + var->yoffset * linelen;
1342 par->hw.falcon.xoffset = 0;
1343
1344 par->next_line = linelen;
1345
1346 return 0;
1347 }
1348
1349 static int falcon_encode_var(struct fb_var_screeninfo *var,
1350 struct atafb_par *par)
1351 {
1352
1353 int linelen;
1354 int prescale, plen;
1355 int hdb_off, hde_off, base_off;
1356 struct falcon_hw *hw = &par->hw.falcon;
1357
1358 memset(var, 0, sizeof(struct fb_var_screeninfo));
1359
1360 var->pixclock = hw->sync & 0x1 ? fext.t :
1361 hw->vid_control & VCO_CLOCK25 ? f25.t : f32.t;
1362
1363 var->height = -1;
1364 var->width = -1;
1365
1366 var->sync = 0;
1367 if (hw->vid_control & VCO_HSYPOS)
1368 var->sync |= FB_SYNC_HOR_HIGH_ACT;
1369 if (hw->vid_control & VCO_VSYPOS)
1370 var->sync |= FB_SYNC_VERT_HIGH_ACT;
1371
1372 var->vmode = FB_VMODE_NONINTERLACED;
1373 if (hw->vid_mode & VMO_INTER)
1374 var->vmode |= FB_VMODE_INTERLACED;
1375 if (hw->vid_mode & VMO_DOUBLE)
1376 var->vmode |= FB_VMODE_DOUBLE;
1377
1378
1379
1380
1381
1382
1383 var->yres = hw->vde - hw->vdb;
1384 if (!(var->vmode & FB_VMODE_INTERLACED))
1385 var->yres >>= 1;
1386 if (var->vmode & FB_VMODE_DOUBLE)
1387 var->yres >>= 1;
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397 if (hw->f_shift & 0x400)
1398 var->bits_per_pixel = 1;
1399 else if (hw->f_shift & 0x100)
1400 var->bits_per_pixel = 16;
1401 else if (hw->f_shift & 0x010)
1402 var->bits_per_pixel = 8;
1403 else if (hw->st_shift == 0)
1404 var->bits_per_pixel = 4;
1405 else if (hw->st_shift == 0x100)
1406 var->bits_per_pixel = 2;
1407 else
1408 var->bits_per_pixel = 1;
1409
1410 var->xres = hw->line_width * 16 / var->bits_per_pixel;
1411 var->xres_virtual = var->xres + hw->line_offset * 16 / var->bits_per_pixel;
1412 if (hw->xoffset)
1413 var->xres_virtual += 16;
1414
1415 if (var->bits_per_pixel == 16) {
1416 var->red.offset = 11;
1417 var->red.length = 5;
1418 var->red.msb_right = 0;
1419 var->green.offset = 5;
1420 var->green.length = 6;
1421 var->green.msb_right = 0;
1422 var->blue.offset = 0;
1423 var->blue.length = 5;
1424 var->blue.msb_right = 0;
1425 } else {
1426 var->red.offset = 0;
1427 var->red.length = hw->ste_mode ? 4 : 6;
1428 if (var->red.length > var->bits_per_pixel)
1429 var->red.length = var->bits_per_pixel;
1430 var->red.msb_right = 0;
1431 var->grayscale = 0;
1432 var->blue = var->green = var->red;
1433 }
1434 var->transp.offset = 0;
1435 var->transp.length = 0;
1436 var->transp.msb_right = 0;
1437
1438 linelen = var->xres_virtual * var->bits_per_pixel / 8;
1439 if (screen_len) {
1440 if (par->yres_virtual)
1441 var->yres_virtual = par->yres_virtual;
1442 else
1443
1444 var->yres_virtual = screen_len / linelen;
1445 } else {
1446 if (hwscroll < 0)
1447 var->yres_virtual = 2 * var->yres;
1448 else
1449 var->yres_virtual = var->yres + hwscroll * 16;
1450 }
1451 var->xoffset = 0;
1452
1453
1454 prescale = hxx_prescale(hw);
1455 plen = 4 >> (hw->vid_mode >> 2 & 0x3);
1456 base_off = hw->vid_control & VCO_SHORTOFFS ? 64 : 128;
1457 if (hw->f_shift & 0x100) {
1458 hde_off = 0;
1459 hdb_off = (base_off + 16 * plen) + prescale;
1460 } else {
1461 hde_off = ((128 / var->bits_per_pixel + 2) * plen);
1462 if (hw->ste_mode)
1463 hdb_off = (64 + base_off + (128 / var->bits_per_pixel + 2) * plen)
1464 + prescale;
1465 else
1466 hdb_off = (base_off + (128 / var->bits_per_pixel + 18) * plen)
1467 + prescale;
1468 }
1469
1470
1471 var->left_margin = hdb_off + prescale * ((hw->hdb & 0x1ff) -
1472 (hw->hdb & 0x200 ? 2 + hw->hht : 0));
1473 if (hw->ste_mode || mon_type != F_MON_VGA)
1474 var->right_margin = prescale * (hw->hht + 2 - hw->hde) - hde_off;
1475 else
1476
1477 var->right_margin = prescale * (hw->hht + 2 - hw->hbb);
1478 var->hsync_len = prescale * (hw->hht + 2 - hw->hss);
1479
1480
1481 var->upper_margin = hw->vdb / 2;
1482 var->lower_margin = (hw->vft + 1 - hw->vde + 1) / 2;
1483 var->vsync_len = (hw->vft + 1 - hw->vss + 1) / 2;
1484 if (var->vmode & FB_VMODE_INTERLACED) {
1485 var->upper_margin *= 2;
1486 var->lower_margin *= 2;
1487 var->vsync_len *= 2;
1488 } else if (var->vmode & FB_VMODE_DOUBLE) {
1489 var->upper_margin = (var->upper_margin + 1) / 2;
1490 var->lower_margin = (var->lower_margin + 1) / 2;
1491 var->vsync_len = (var->vsync_len + 1) / 2;
1492 }
1493
1494 var->pixclock *= plen;
1495 var->left_margin /= plen;
1496 var->right_margin /= plen;
1497 var->hsync_len /= plen;
1498
1499 var->right_margin -= var->hsync_len;
1500 var->lower_margin -= var->vsync_len;
1501
1502 if (screen_base)
1503 var->yoffset = (par->screen_base - screen_base) / linelen;
1504 else
1505 var->yoffset = 0;
1506 var->nonstd = 0;
1507 var->activate = 0;
1508 return 0;
1509 }
1510
1511 static int f_change_mode;
1512 static struct falcon_hw f_new_mode;
1513 static int f_pan_display;
1514
1515 static void falcon_get_par(struct atafb_par *par)
1516 {
1517 unsigned long addr;
1518 struct falcon_hw *hw = &par->hw.falcon;
1519
1520 hw->line_width = shifter_f030.scn_width;
1521 hw->line_offset = shifter_f030.off_next;
1522 hw->st_shift = videl.st_shift & 0x300;
1523 hw->f_shift = videl.f_shift;
1524 hw->vid_control = videl.control;
1525 hw->vid_mode = videl.mode;
1526 hw->sync = shifter_st.syncmode & 0x1;
1527 hw->xoffset = videl.xoffset & 0xf;
1528 hw->hht = videl.hht;
1529 hw->hbb = videl.hbb;
1530 hw->hbe = videl.hbe;
1531 hw->hdb = videl.hdb;
1532 hw->hde = videl.hde;
1533 hw->hss = videl.hss;
1534 hw->vft = videl.vft;
1535 hw->vbb = videl.vbb;
1536 hw->vbe = videl.vbe;
1537 hw->vdb = videl.vdb;
1538 hw->vde = videl.vde;
1539 hw->vss = videl.vss;
1540
1541 addr = (shifter_st.bas_hi & 0xff) << 16 |
1542 (shifter_st.bas_md & 0xff) << 8 |
1543 (shifter_st.bas_lo & 0xff);
1544 par->screen_base = atari_stram_to_virt(addr);
1545
1546
1547 hw->ste_mode = (hw->f_shift & 0x510) == 0 && hw->st_shift == 0x100;
1548 hw->mono = (hw->f_shift & 0x400) ||
1549 ((hw->f_shift & 0x510) == 0 && hw->st_shift == 0x200);
1550 }
1551
1552 static void falcon_set_par(struct atafb_par *par)
1553 {
1554 f_change_mode = 0;
1555
1556
1557 if (current_par.screen_base != par->screen_base)
1558 fbhw->set_screen_base(par->screen_base);
1559
1560
1561 if (DontCalcRes)
1562 return;
1563
1564
1565
1566
1567
1568
1569
1570 f_new_mode = par->hw.falcon;
1571 f_change_mode = 1;
1572 }
1573
1574 static irqreturn_t falcon_vbl_switcher(int irq, void *dummy)
1575 {
1576 struct falcon_hw *hw = &f_new_mode;
1577
1578 if (f_change_mode) {
1579 f_change_mode = 0;
1580
1581 if (hw->sync & 0x1) {
1582
1583 *(volatile unsigned short *)0xffff9202 = 0xffbf;
1584 } else {
1585
1586 *(volatile unsigned short *)0xffff9202;
1587 }
1588 shifter_st.syncmode = hw->sync;
1589
1590 videl.hht = hw->hht;
1591 videl.hbb = hw->hbb;
1592 videl.hbe = hw->hbe;
1593 videl.hdb = hw->hdb;
1594 videl.hde = hw->hde;
1595 videl.hss = hw->hss;
1596 videl.vft = hw->vft;
1597 videl.vbb = hw->vbb;
1598 videl.vbe = hw->vbe;
1599 videl.vdb = hw->vdb;
1600 videl.vde = hw->vde;
1601 videl.vss = hw->vss;
1602
1603 videl.f_shift = 0;
1604 if (hw->ste_mode) {
1605 videl.st_shift = hw->st_shift;
1606 } else {
1607
1608
1609
1610
1611
1612
1613 videl.st_shift = 0;
1614
1615 videl.f_shift = hw->f_shift;
1616 }
1617
1618 videl.xoffset = hw->xoffset;
1619 shifter_f030.scn_width = hw->line_width;
1620 shifter_f030.off_next = hw->line_offset;
1621 videl.control = hw->vid_control;
1622 videl.mode = hw->vid_mode;
1623 }
1624 if (f_pan_display) {
1625 f_pan_display = 0;
1626 videl.xoffset = current_par.hw.falcon.xoffset;
1627 shifter_f030.off_next = current_par.hw.falcon.line_offset;
1628 }
1629 return IRQ_HANDLED;
1630 }
1631
1632 static int falcon_pan_display(struct fb_var_screeninfo *var,
1633 struct fb_info *info)
1634 {
1635 struct atafb_par *par = info->par;
1636
1637 int xoffset;
1638 int bpp = info->var.bits_per_pixel;
1639
1640 if (bpp == 1)
1641 var->xoffset = round_up(var->xoffset, 32);
1642 if (bpp != 16)
1643 par->hw.falcon.xoffset = var->xoffset & 15;
1644 else {
1645 par->hw.falcon.xoffset = 0;
1646 var->xoffset = round_up(var->xoffset, 2);
1647 }
1648 par->hw.falcon.line_offset = bpp *
1649 (info->var.xres_virtual - info->var.xres) / 16;
1650 if (par->hw.falcon.xoffset)
1651 par->hw.falcon.line_offset -= bpp;
1652 xoffset = var->xoffset - par->hw.falcon.xoffset;
1653
1654 par->screen_base = screen_base +
1655 (var->yoffset * info->var.xres_virtual + xoffset) * bpp / 8;
1656 if (fbhw->set_screen_base)
1657 fbhw->set_screen_base(par->screen_base);
1658 else
1659 return -EINVAL;
1660 f_pan_display = 1;
1661 return 0;
1662 }
1663
1664 static int falcon_setcolreg(unsigned int regno, unsigned int red,
1665 unsigned int green, unsigned int blue,
1666 unsigned int transp, struct fb_info *info)
1667 {
1668 if (regno > 255)
1669 return 1;
1670 f030_col[regno] = (((red & 0xfc00) << 16) |
1671 ((green & 0xfc00) << 8) |
1672 ((blue & 0xfc00) >> 8));
1673 if (regno < 16) {
1674 shifter_tt.color_reg[regno] =
1675 ((((red & 0xe000) >> 13) | ((red & 0x1000) >> 12)) << 8) |
1676 ((((green & 0xe000) >> 13) | ((green & 0x1000) >> 12)) << 4) |
1677 ((blue & 0xe000) >> 13) | ((blue & 0x1000) >> 12);
1678 ((u32 *)info->pseudo_palette)[regno] = ((red & 0xf800) |
1679 ((green & 0xfc00) >> 5) |
1680 ((blue & 0xf800) >> 11));
1681 }
1682 return 0;
1683 }
1684
1685 static int falcon_blank(int blank_mode)
1686 {
1687
1688
1689
1690
1691 int vdb, vss, hbe, hss;
1692
1693 if (mon_type == F_MON_SM)
1694 return 1;
1695
1696 vdb = current_par.VDB;
1697 vss = current_par.VSS;
1698 hbe = current_par.HBE;
1699 hss = current_par.HSS;
1700
1701 if (blank_mode >= 1) {
1702
1703 vdb = current_par.VFT + 1;
1704
1705 hbe = current_par.HHT + 2;
1706 }
1707
1708 if (mon_type == F_MON_VGA) {
1709 if (blank_mode == 2 || blank_mode == 4)
1710 vss = current_par.VFT + 1;
1711 if (blank_mode == 3 || blank_mode == 4)
1712 hss = current_par.HHT + 2;
1713 }
1714
1715 videl.vdb = vdb;
1716 videl.vss = vss;
1717 videl.hbe = hbe;
1718 videl.hss = hss;
1719
1720 return 0;
1721 }
1722
1723 static int falcon_detect(void)
1724 {
1725 struct atafb_par par;
1726 unsigned char fhw;
1727
1728
1729 fhw = *(unsigned char *)0xffff8006;
1730 mon_type = fhw >> 6 & 0x3;
1731
1732 f030_bus_width = fhw << 6 & 0x80;
1733 switch (mon_type) {
1734 case F_MON_SM:
1735 fb_info.monspecs.vfmin = 70;
1736 fb_info.monspecs.vfmax = 72;
1737 fb_info.monspecs.hfmin = 35713;
1738 fb_info.monspecs.hfmax = 35715;
1739 break;
1740 case F_MON_SC:
1741 case F_MON_TV:
1742
1743 fb_info.monspecs.vfmin = 49;
1744 fb_info.monspecs.vfmax = 60;
1745 fb_info.monspecs.hfmin = 15620;
1746 fb_info.monspecs.hfmax = 15755;
1747 break;
1748 }
1749
1750 f25.hsync = h_syncs[mon_type] / f25.t;
1751 f32.hsync = h_syncs[mon_type] / f32.t;
1752 if (fext.t)
1753 fext.hsync = h_syncs[mon_type] / fext.t;
1754
1755 falcon_get_par(&par);
1756 falcon_encode_var(&atafb_predefined[0], &par);
1757
1758
1759 return 1;
1760 }
1761
1762 #endif
1763
1764
1765
1766 #ifdef ATAFB_STE
1767
1768 static int stste_encode_fix(struct fb_fix_screeninfo *fix,
1769 struct atafb_par *par)
1770 {
1771 int mode;
1772
1773 strcpy(fix->id, "Atari Builtin");
1774 fix->smem_start = phys_screen_base;
1775 fix->smem_len = screen_len;
1776 fix->type = FB_TYPE_INTERLEAVED_PLANES;
1777 fix->type_aux = 2;
1778 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1779 mode = par->hw.st.mode & 3;
1780 if (mode == ST_HIGH) {
1781 fix->type = FB_TYPE_PACKED_PIXELS;
1782 fix->type_aux = 0;
1783 fix->visual = FB_VISUAL_MONO10;
1784 }
1785 if (ATARIHW_PRESENT(EXTD_SHIFTER)) {
1786 fix->xpanstep = 16;
1787 fix->ypanstep = 1;
1788 } else {
1789 fix->xpanstep = 0;
1790 fix->ypanstep = 0;
1791 }
1792 fix->ywrapstep = 0;
1793 fix->line_length = par->next_line;
1794 fix->accel = FB_ACCEL_ATARIBLITT;
1795 return 0;
1796 }
1797
1798 static int stste_decode_var(struct fb_var_screeninfo *var,
1799 struct atafb_par *par)
1800 {
1801 int xres = var->xres;
1802 int yres = var->yres;
1803 int bpp = var->bits_per_pixel;
1804 int linelen;
1805 int yres_virtual = var->yres_virtual;
1806
1807 if (mono_moni) {
1808 if (bpp > 1 || xres > sttt_xres || yres > st_yres)
1809 return -EINVAL;
1810 par->hw.st.mode = ST_HIGH;
1811 xres = sttt_xres;
1812 yres = st_yres;
1813 bpp = 1;
1814 } else {
1815 if (bpp > 4 || xres > sttt_xres || yres > st_yres)
1816 return -EINVAL;
1817 if (bpp > 2) {
1818 if (xres > sttt_xres / 2 || yres > st_yres / 2)
1819 return -EINVAL;
1820 par->hw.st.mode = ST_LOW;
1821 xres = sttt_xres / 2;
1822 yres = st_yres / 2;
1823 bpp = 4;
1824 } else if (bpp > 1) {
1825 if (xres > sttt_xres || yres > st_yres / 2)
1826 return -EINVAL;
1827 par->hw.st.mode = ST_MID;
1828 xres = sttt_xres;
1829 yres = st_yres / 2;
1830 bpp = 2;
1831 } else
1832 return -EINVAL;
1833 }
1834 if (yres_virtual <= 0)
1835 yres_virtual = 0;
1836 else if (yres_virtual < yres)
1837 yres_virtual = yres;
1838 if (var->sync & FB_SYNC_EXT)
1839 par->hw.st.sync = (par->hw.st.sync & ~1) | 1;
1840 else
1841 par->hw.st.sync = (par->hw.st.sync & ~1);
1842 linelen = xres * bpp / 8;
1843 if (yres_virtual * linelen > screen_len && screen_len)
1844 return -EINVAL;
1845 if (yres * linelen > screen_len && screen_len)
1846 return -EINVAL;
1847 if (var->yoffset + yres > yres_virtual && yres_virtual)
1848 return -EINVAL;
1849 par->yres_virtual = yres_virtual;
1850 par->screen_base = screen_base + var->yoffset * linelen;
1851 par->next_line = linelen;
1852 return 0;
1853 }
1854
1855 static int stste_encode_var(struct fb_var_screeninfo *var,
1856 struct atafb_par *par)
1857 {
1858 int linelen;
1859 memset(var, 0, sizeof(struct fb_var_screeninfo));
1860 var->red.offset = 0;
1861 var->red.length = ATARIHW_PRESENT(EXTD_SHIFTER) ? 4 : 3;
1862 var->red.msb_right = 0;
1863 var->grayscale = 0;
1864
1865 var->pixclock = 31041;
1866 var->left_margin = 120;
1867 var->right_margin = 100;
1868 var->upper_margin = 8;
1869 var->lower_margin = 16;
1870 var->hsync_len = 140;
1871 var->vsync_len = 30;
1872
1873 var->height = -1;
1874 var->width = -1;
1875
1876 if (!(par->hw.st.sync & 1))
1877 var->sync = 0;
1878 else
1879 var->sync = FB_SYNC_EXT;
1880
1881 switch (par->hw.st.mode & 3) {
1882 case ST_LOW:
1883 var->xres = sttt_xres / 2;
1884 var->yres = st_yres / 2;
1885 var->bits_per_pixel = 4;
1886 break;
1887 case ST_MID:
1888 var->xres = sttt_xres;
1889 var->yres = st_yres / 2;
1890 var->bits_per_pixel = 2;
1891 break;
1892 case ST_HIGH:
1893 var->xres = sttt_xres;
1894 var->yres = st_yres;
1895 var->bits_per_pixel = 1;
1896 break;
1897 }
1898 var->blue = var->green = var->red;
1899 var->transp.offset = 0;
1900 var->transp.length = 0;
1901 var->transp.msb_right = 0;
1902 var->xres_virtual = sttt_xres_virtual;
1903 linelen = var->xres_virtual * var->bits_per_pixel / 8;
1904 ovsc_addlen = linelen * (sttt_yres_virtual - st_yres);
1905
1906 if (!use_hwscroll)
1907 var->yres_virtual = var->yres;
1908 else if (screen_len) {
1909 if (par->yres_virtual)
1910 var->yres_virtual = par->yres_virtual;
1911 else
1912
1913 var->yres_virtual = screen_len / linelen;
1914 } else {
1915 if (hwscroll < 0)
1916 var->yres_virtual = 2 * var->yres;
1917 else
1918 var->yres_virtual = var->yres + hwscroll * 16;
1919 }
1920 var->xoffset = 0;
1921 if (screen_base)
1922 var->yoffset = (par->screen_base - screen_base) / linelen;
1923 else
1924 var->yoffset = 0;
1925 var->nonstd = 0;
1926 var->activate = 0;
1927 var->vmode = FB_VMODE_NONINTERLACED;
1928 return 0;
1929 }
1930
1931 static void stste_get_par(struct atafb_par *par)
1932 {
1933 unsigned long addr;
1934 par->hw.st.mode = shifter_tt.st_shiftmode;
1935 par->hw.st.sync = shifter_st.syncmode;
1936 addr = ((shifter_st.bas_hi & 0xff) << 16) |
1937 ((shifter_st.bas_md & 0xff) << 8);
1938 if (ATARIHW_PRESENT(EXTD_SHIFTER))
1939 addr |= (shifter_st.bas_lo & 0xff);
1940 par->screen_base = atari_stram_to_virt(addr);
1941 }
1942
1943 static void stste_set_par(struct atafb_par *par)
1944 {
1945 shifter_tt.st_shiftmode = par->hw.st.mode;
1946 shifter_st.syncmode = par->hw.st.sync;
1947
1948 if (current_par.screen_base != par->screen_base)
1949 fbhw->set_screen_base(par->screen_base);
1950 }
1951
1952 static int stste_setcolreg(unsigned int regno, unsigned int red,
1953 unsigned int green, unsigned int blue,
1954 unsigned int transp, struct fb_info *info)
1955 {
1956 if (regno > 15)
1957 return 1;
1958 red >>= 12;
1959 blue >>= 12;
1960 green >>= 12;
1961 if (ATARIHW_PRESENT(EXTD_SHIFTER))
1962 shifter_tt.color_reg[regno] =
1963 ((((red & 0xe) >> 1) | ((red & 1) << 3)) << 8) |
1964 ((((green & 0xe) >> 1) | ((green & 1) << 3)) << 4) |
1965 ((blue & 0xe) >> 1) | ((blue & 1) << 3);
1966 else
1967 shifter_tt.color_reg[regno] =
1968 ((red & 0xe) << 7) |
1969 ((green & 0xe) << 3) |
1970 ((blue & 0xe) >> 1);
1971 return 0;
1972 }
1973
1974 static int stste_detect(void)
1975 {
1976 struct atafb_par par;
1977
1978
1979
1980
1981
1982 if (ATARIHW_PRESENT(PCM_8BIT)) {
1983 tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1984 udelay(20);
1985 }
1986 mono_moni = (st_mfp.par_dt_reg & 0x80) == 0;
1987
1988 stste_get_par(&par);
1989 stste_encode_var(&atafb_predefined[0], &par);
1990
1991 if (!ATARIHW_PRESENT(EXTD_SHIFTER))
1992 use_hwscroll = 0;
1993 return 1;
1994 }
1995
1996 static void stste_set_screen_base(void *s_base)
1997 {
1998 unsigned long addr;
1999 addr = atari_stram_to_phys(s_base);
2000
2001 shifter_st.bas_hi = (unsigned char)((addr & 0xff0000) >> 16);
2002 shifter_st.bas_md = (unsigned char)((addr & 0x00ff00) >> 8);
2003 if (ATARIHW_PRESENT(EXTD_SHIFTER))
2004 shifter_st.bas_lo = (unsigned char)(addr & 0x0000ff);
2005 }
2006
2007 #endif
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024 #define LINE_DELAY (mono_moni ? 30 : 70)
2025 #define SYNC_DELAY (mono_moni ? 1500 : 2000)
2026
2027
2028 static void st_ovsc_switch(void)
2029 {
2030 unsigned long flags;
2031 register unsigned char old, new;
2032
2033 if (!(atari_switches & ATARI_SWITCH_OVSC_MASK))
2034 return;
2035 local_irq_save(flags);
2036
2037 st_mfp.tim_ct_b = 0x10;
2038 st_mfp.active_edge |= 8;
2039 st_mfp.tim_ct_b = 0;
2040 st_mfp.tim_dt_b = 0xf0;
2041 st_mfp.tim_ct_b = 8;
2042 while (st_mfp.tim_dt_b > 1)
2043 ;
2044 new = st_mfp.tim_dt_b;
2045 do {
2046 udelay(LINE_DELAY);
2047 old = new;
2048 new = st_mfp.tim_dt_b;
2049 } while (old != new);
2050 st_mfp.tim_ct_b = 0x10;
2051 udelay(SYNC_DELAY);
2052
2053 if (atari_switches & ATARI_SWITCH_OVSC_IKBD)
2054 acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID | ACIA_RIE;
2055 if (atari_switches & ATARI_SWITCH_OVSC_MIDI)
2056 acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID;
2057 if (atari_switches & (ATARI_SWITCH_OVSC_SND6|ATARI_SWITCH_OVSC_SND7)) {
2058 sound_ym.rd_data_reg_sel = 14;
2059 sound_ym.wd_data = sound_ym.rd_data_reg_sel |
2060 ((atari_switches & ATARI_SWITCH_OVSC_SND6) ? 0x40:0) |
2061 ((atari_switches & ATARI_SWITCH_OVSC_SND7) ? 0x80:0);
2062 }
2063 local_irq_restore(flags);
2064 }
2065
2066
2067
2068 #ifdef ATAFB_EXT
2069
2070 static int ext_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par)
2071 {
2072 strcpy(fix->id, "Unknown Extern");
2073 fix->smem_start = external_addr;
2074 fix->smem_len = PAGE_ALIGN(external_len);
2075 if (external_depth == 1) {
2076 fix->type = FB_TYPE_PACKED_PIXELS;
2077
2078
2079 fix->visual =
2080 (external_pmode == FB_TYPE_INTERLEAVED_PLANES ||
2081 external_pmode == FB_TYPE_PACKED_PIXELS) ?
2082 FB_VISUAL_MONO10 : FB_VISUAL_MONO01;
2083 } else {
2084
2085 int visual = external_vgaiobase ?
2086 FB_VISUAL_PSEUDOCOLOR :
2087 FB_VISUAL_STATIC_PSEUDOCOLOR;
2088 switch (external_pmode) {
2089 case -1:
2090 fix->type = FB_TYPE_PACKED_PIXELS;
2091 fix->visual = FB_VISUAL_TRUECOLOR;
2092 break;
2093 case FB_TYPE_PACKED_PIXELS:
2094 fix->type = FB_TYPE_PACKED_PIXELS;
2095 fix->visual = visual;
2096 break;
2097 case FB_TYPE_PLANES:
2098 fix->type = FB_TYPE_PLANES;
2099 fix->visual = visual;
2100 break;
2101 case FB_TYPE_INTERLEAVED_PLANES:
2102 fix->type = FB_TYPE_INTERLEAVED_PLANES;
2103 fix->type_aux = 2;
2104 fix->visual = visual;
2105 break;
2106 }
2107 }
2108 fix->xpanstep = 0;
2109 fix->ypanstep = 0;
2110 fix->ywrapstep = 0;
2111 fix->line_length = par->next_line;
2112 return 0;
2113 }
2114
2115 static int ext_decode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
2116 {
2117 struct fb_var_screeninfo *myvar = &atafb_predefined[0];
2118
2119 if (var->bits_per_pixel > myvar->bits_per_pixel ||
2120 var->xres > myvar->xres ||
2121 var->xres_virtual > myvar->xres_virtual ||
2122 var->yres > myvar->yres ||
2123 var->xoffset > 0 ||
2124 var->yoffset > 0)
2125 return -EINVAL;
2126
2127 par->next_line = external_xres_virtual * external_depth / 8;
2128 return 0;
2129 }
2130
2131 static int ext_encode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
2132 {
2133 memset(var, 0, sizeof(struct fb_var_screeninfo));
2134 var->red.offset = 0;
2135 var->red.length = (external_pmode == -1) ? external_depth / 3 :
2136 (external_vgaiobase ? external_bitspercol : 0);
2137 var->red.msb_right = 0;
2138 var->grayscale = 0;
2139
2140 var->pixclock = 31041;
2141 var->left_margin = 120;
2142 var->right_margin = 100;
2143 var->upper_margin = 8;
2144 var->lower_margin = 16;
2145 var->hsync_len = 140;
2146 var->vsync_len = 30;
2147
2148 var->height = -1;
2149 var->width = -1;
2150
2151 var->sync = 0;
2152
2153 var->xres = external_xres;
2154 var->yres = external_yres;
2155 var->xres_virtual = external_xres_virtual;
2156 var->bits_per_pixel = external_depth;
2157
2158 var->blue = var->green = var->red;
2159 var->transp.offset = 0;
2160 var->transp.length = 0;
2161 var->transp.msb_right = 0;
2162 var->yres_virtual = var->yres;
2163 var->xoffset = 0;
2164 var->yoffset = 0;
2165 var->nonstd = 0;
2166 var->activate = 0;
2167 var->vmode = FB_VMODE_NONINTERLACED;
2168 return 0;
2169 }
2170
2171 static void ext_get_par(struct atafb_par *par)
2172 {
2173 par->screen_base = external_screen_base;
2174 }
2175
2176 static void ext_set_par(struct atafb_par *par)
2177 {
2178 }
2179
2180 #define OUTB(port,val) \
2181 *((unsigned volatile char *) ((port)+external_vgaiobase)) = (val)
2182 #define INB(port) \
2183 (*((unsigned volatile char *) ((port)+external_vgaiobase)))
2184 #define DACDelay \
2185 do { \
2186 unsigned char tmp = INB(0x3da); \
2187 tmp = INB(0x3da); \
2188 } while (0)
2189
2190 static int ext_setcolreg(unsigned int regno, unsigned int red,
2191 unsigned int green, unsigned int blue,
2192 unsigned int transp, struct fb_info *info)
2193 {
2194 unsigned char colmask = (1 << external_bitspercol) - 1;
2195
2196 if (!external_vgaiobase)
2197 return 1;
2198
2199 if (regno > 255)
2200 return 1;
2201
2202 red >>= 8;
2203 green >>= 8;
2204 blue >>= 8;
2205
2206 switch (external_card_type) {
2207 case IS_VGA:
2208 OUTB(0x3c8, regno);
2209 DACDelay;
2210 OUTB(0x3c9, red & colmask);
2211 DACDelay;
2212 OUTB(0x3c9, green & colmask);
2213 DACDelay;
2214 OUTB(0x3c9, blue & colmask);
2215 DACDelay;
2216 return 0;
2217
2218 case IS_MV300:
2219 OUTB((MV300_reg[regno] << 2) + 1, red);
2220 OUTB((MV300_reg[regno] << 2) + 1, green);
2221 OUTB((MV300_reg[regno] << 2) + 1, blue);
2222 return 0;
2223
2224 default:
2225 return 1;
2226 }
2227 }
2228
2229 static int ext_detect(void)
2230 {
2231 struct fb_var_screeninfo *myvar = &atafb_predefined[0];
2232 struct atafb_par dummy_par;
2233
2234 myvar->xres = external_xres;
2235 myvar->xres_virtual = external_xres_virtual;
2236 myvar->yres = external_yres;
2237 myvar->bits_per_pixel = external_depth;
2238 ext_encode_var(myvar, &dummy_par);
2239 return 1;
2240 }
2241
2242 #endif
2243
2244
2245
2246 static void set_screen_base(void *s_base)
2247 {
2248 unsigned long addr;
2249
2250 addr = atari_stram_to_phys(s_base);
2251
2252 shifter_st.bas_hi = (unsigned char)((addr & 0xff0000) >> 16);
2253 shifter_st.bas_md = (unsigned char)((addr & 0x00ff00) >> 8);
2254 shifter_st.bas_lo = (unsigned char)(addr & 0x0000ff);
2255 }
2256
2257 static int pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
2258 {
2259 struct atafb_par *par = info->par;
2260
2261 if (!fbhw->set_screen_base ||
2262 (!ATARIHW_PRESENT(EXTD_SHIFTER) && var->xoffset))
2263 return -EINVAL;
2264 var->xoffset = round_up(var->xoffset, 16);
2265 par->screen_base = screen_base +
2266 (var->yoffset * info->var.xres_virtual + var->xoffset)
2267 * info->var.bits_per_pixel / 8;
2268 fbhw->set_screen_base(par->screen_base);
2269 return 0;
2270 }
2271
2272
2273
2274 #ifdef ATAFB_TT
2275 static struct fb_hwswitch tt_switch = {
2276 .detect = tt_detect,
2277 .encode_fix = tt_encode_fix,
2278 .decode_var = tt_decode_var,
2279 .encode_var = tt_encode_var,
2280 .get_par = tt_get_par,
2281 .set_par = tt_set_par,
2282 .set_screen_base = set_screen_base,
2283 .pan_display = pan_display,
2284 };
2285 #endif
2286
2287 #ifdef ATAFB_FALCON
2288 static struct fb_hwswitch falcon_switch = {
2289 .detect = falcon_detect,
2290 .encode_fix = falcon_encode_fix,
2291 .decode_var = falcon_decode_var,
2292 .encode_var = falcon_encode_var,
2293 .get_par = falcon_get_par,
2294 .set_par = falcon_set_par,
2295 .set_screen_base = set_screen_base,
2296 .blank = falcon_blank,
2297 .pan_display = falcon_pan_display,
2298 };
2299 #endif
2300
2301 #ifdef ATAFB_STE
2302 static struct fb_hwswitch st_switch = {
2303 .detect = stste_detect,
2304 .encode_fix = stste_encode_fix,
2305 .decode_var = stste_decode_var,
2306 .encode_var = stste_encode_var,
2307 .get_par = stste_get_par,
2308 .set_par = stste_set_par,
2309 .set_screen_base = stste_set_screen_base,
2310 .pan_display = pan_display
2311 };
2312 #endif
2313
2314 #ifdef ATAFB_EXT
2315 static struct fb_hwswitch ext_switch = {
2316 .detect = ext_detect,
2317 .encode_fix = ext_encode_fix,
2318 .decode_var = ext_decode_var,
2319 .encode_var = ext_encode_var,
2320 .get_par = ext_get_par,
2321 .set_par = ext_set_par,
2322 };
2323 #endif
2324
2325 static void ata_get_par(struct atafb_par *par)
2326 {
2327 if (current_par_valid)
2328 *par = current_par;
2329 else
2330 fbhw->get_par(par);
2331 }
2332
2333 static void ata_set_par(struct atafb_par *par)
2334 {
2335 fbhw->set_par(par);
2336 current_par = *par;
2337 current_par_valid = 1;
2338 }
2339
2340
2341
2342
2343
2344
2345
2346
2347 static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
2348 {
2349 int err, activate;
2350 struct atafb_par par;
2351
2352 err = fbhw->decode_var(var, &par);
2353 if (err)
2354 return err;
2355 activate = var->activate;
2356 if (((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive)
2357 ata_set_par(&par);
2358 fbhw->encode_var(var, &par);
2359 var->activate = activate;
2360 return 0;
2361 }
2362
2363
2364
2365
2366 static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
2367 {
2368 struct atafb_par par;
2369 int err;
2370
2371 err = fbhw->decode_var(&info->var, &par);
2372 if (err)
2373 return err;
2374 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
2375 err = fbhw->encode_fix(fix, &par);
2376 return err;
2377 }
2378
2379 static int atafb_get_var(struct fb_var_screeninfo *var, struct fb_info *info)
2380 {
2381 struct atafb_par par;
2382
2383 ata_get_par(&par);
2384 fbhw->encode_var(var, &par);
2385
2386 return 0;
2387 }
2388
2389
2390
2391
2392 static void atafb_set_disp(struct fb_info *info)
2393 {
2394 atafb_get_var(&info->var, info);
2395 atafb_get_fix(&info->fix, info);
2396
2397
2398 info->screen_base = (external_addr ? external_screen_base :
2399 atari_stram_to_virt(info->fix.smem_start));
2400 }
2401
2402 static int
2403 atafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
2404 {
2405 if (!fbhw->pan_display)
2406 return -EINVAL;
2407
2408 return fbhw->pan_display(var, info);
2409 }
2410
2411
2412
2413
2414
2415 static void atafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
2416 {
2417 struct atafb_par *par = info->par;
2418 int x2, y2;
2419 u32 width, height;
2420
2421 if (!rect->width || !rect->height)
2422 return;
2423
2424 #ifdef ATAFB_FALCON
2425 if (info->var.bits_per_pixel == 16) {
2426 cfb_fillrect(info, rect);
2427 return;
2428 }
2429 #endif
2430
2431
2432
2433
2434
2435 x2 = rect->dx + rect->width;
2436 y2 = rect->dy + rect->height;
2437 x2 = x2 < info->var.xres_virtual ? x2 : info->var.xres_virtual;
2438 y2 = y2 < info->var.yres_virtual ? y2 : info->var.yres_virtual;
2439 width = x2 - rect->dx;
2440 height = y2 - rect->dy;
2441
2442 if (info->var.bits_per_pixel == 1)
2443 atafb_mfb_fillrect(info, par->next_line, rect->color,
2444 rect->dy, rect->dx, height, width);
2445 else if (info->var.bits_per_pixel == 2)
2446 atafb_iplan2p2_fillrect(info, par->next_line, rect->color,
2447 rect->dy, rect->dx, height, width);
2448 else if (info->var.bits_per_pixel == 4)
2449 atafb_iplan2p4_fillrect(info, par->next_line, rect->color,
2450 rect->dy, rect->dx, height, width);
2451 else
2452 atafb_iplan2p8_fillrect(info, par->next_line, rect->color,
2453 rect->dy, rect->dx, height, width);
2454
2455 return;
2456 }
2457
2458 static void atafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
2459 {
2460 struct atafb_par *par = info->par;
2461 int x2, y2;
2462 u32 dx, dy, sx, sy, width, height;
2463 int rev_copy = 0;
2464
2465 #ifdef ATAFB_FALCON
2466 if (info->var.bits_per_pixel == 16) {
2467 cfb_copyarea(info, area);
2468 return;
2469 }
2470 #endif
2471
2472
2473 x2 = area->dx + area->width;
2474 y2 = area->dy + area->height;
2475 dx = area->dx > 0 ? area->dx : 0;
2476 dy = area->dy > 0 ? area->dy : 0;
2477 x2 = x2 < info->var.xres_virtual ? x2 : info->var.xres_virtual;
2478 y2 = y2 < info->var.yres_virtual ? y2 : info->var.yres_virtual;
2479 width = x2 - dx;
2480 height = y2 - dy;
2481
2482 if (area->sx + dx < area->dx || area->sy + dy < area->dy)
2483 return;
2484
2485
2486 sx = area->sx + (dx - area->dx);
2487 sy = area->sy + (dy - area->dy);
2488
2489
2490 if (sx + width > info->var.xres_virtual ||
2491 sy + height > info->var.yres_virtual)
2492 return;
2493
2494 if (dy > sy || (dy == sy && dx > sx)) {
2495 dy += height;
2496 sy += height;
2497 rev_copy = 1;
2498 }
2499
2500 if (info->var.bits_per_pixel == 1)
2501 atafb_mfb_copyarea(info, par->next_line, sy, sx, dy, dx, height, width);
2502 else if (info->var.bits_per_pixel == 2)
2503 atafb_iplan2p2_copyarea(info, par->next_line, sy, sx, dy, dx, height, width);
2504 else if (info->var.bits_per_pixel == 4)
2505 atafb_iplan2p4_copyarea(info, par->next_line, sy, sx, dy, dx, height, width);
2506 else
2507 atafb_iplan2p8_copyarea(info, par->next_line, sy, sx, dy, dx, height, width);
2508
2509 return;
2510 }
2511
2512 static void atafb_imageblit(struct fb_info *info, const struct fb_image *image)
2513 {
2514 struct atafb_par *par = info->par;
2515 int x2, y2;
2516 const char *src;
2517 u32 dx, dy, width, height, pitch;
2518
2519 #ifdef ATAFB_FALCON
2520 if (info->var.bits_per_pixel == 16) {
2521 cfb_imageblit(info, image);
2522 return;
2523 }
2524 #endif
2525
2526
2527
2528
2529
2530
2531 x2 = image->dx + image->width;
2532 y2 = image->dy + image->height;
2533 dx = image->dx;
2534 dy = image->dy;
2535 x2 = x2 < info->var.xres_virtual ? x2 : info->var.xres_virtual;
2536 y2 = y2 < info->var.yres_virtual ? y2 : info->var.yres_virtual;
2537 width = x2 - dx;
2538 height = y2 - dy;
2539
2540 if (image->depth == 1) {
2541
2542 src = image->data;
2543 pitch = (image->width + 7) / 8;
2544 while (height--) {
2545
2546 if (info->var.bits_per_pixel == 1)
2547 atafb_mfb_linefill(info, par->next_line,
2548 dy, dx, width, src,
2549 image->bg_color, image->fg_color);
2550 else if (info->var.bits_per_pixel == 2)
2551 atafb_iplan2p2_linefill(info, par->next_line,
2552 dy, dx, width, src,
2553 image->bg_color, image->fg_color);
2554 else if (info->var.bits_per_pixel == 4)
2555 atafb_iplan2p4_linefill(info, par->next_line,
2556 dy, dx, width, src,
2557 image->bg_color, image->fg_color);
2558 else
2559 atafb_iplan2p8_linefill(info, par->next_line,
2560 dy, dx, width, src,
2561 image->bg_color, image->fg_color);
2562 dy++;
2563 src += pitch;
2564 }
2565 } else {
2566 c2p_iplan2(info->screen_base, image->data, dx, dy, width,
2567 height, par->next_line, image->width,
2568 info->var.bits_per_pixel);
2569 }
2570 }
2571
2572 static int
2573 atafb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
2574 {
2575 switch (cmd) {
2576 #ifdef FBCMD_GET_CURRENTPAR
2577 case FBCMD_GET_CURRENTPAR:
2578 if (copy_to_user((void *)arg, ¤t_par,
2579 sizeof(struct atafb_par)))
2580 return -EFAULT;
2581 return 0;
2582 #endif
2583 #ifdef FBCMD_SET_CURRENTPAR
2584 case FBCMD_SET_CURRENTPAR:
2585 if (copy_from_user(¤t_par, (void *)arg,
2586 sizeof(struct atafb_par)))
2587 return -EFAULT;
2588 ata_set_par(¤t_par);
2589 return 0;
2590 #endif
2591 }
2592 return -EINVAL;
2593 }
2594
2595
2596
2597
2598
2599
2600
2601
2602 static int atafb_blank(int blank, struct fb_info *info)
2603 {
2604 unsigned short black[16];
2605 struct fb_cmap cmap;
2606 if (fbhw->blank && !fbhw->blank(blank))
2607 return 1;
2608 if (blank) {
2609 memset(black, 0, 16 * sizeof(unsigned short));
2610 cmap.red = black;
2611 cmap.green = black;
2612 cmap.blue = black;
2613 cmap.transp = NULL;
2614 cmap.start = 0;
2615 cmap.len = 16;
2616 fb_set_cmap(&cmap, info);
2617 }
2618 #if 0
2619 else
2620 do_install_cmap(info);
2621 #endif
2622 return 0;
2623 }
2624
2625
2626
2627
2628
2629
2630
2631 static int atafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
2632 {
2633 int err;
2634 struct atafb_par par;
2635
2636
2637
2638 err = fbhw->decode_var(var, &par);
2639 if (err)
2640 return err;
2641
2642
2643 fbhw->encode_var(var, &par);
2644 return 0;
2645 }
2646
2647
2648
2649 static int atafb_set_par(struct fb_info *info)
2650 {
2651 struct atafb_par *par = info->par;
2652
2653
2654 fbhw->decode_var(&info->var, par);
2655 mutex_lock(&info->mm_lock);
2656 fbhw->encode_fix(&info->fix, par);
2657 mutex_unlock(&info->mm_lock);
2658
2659
2660 ata_set_par(par);
2661
2662 return 0;
2663 }
2664
2665
2666 static struct fb_ops atafb_ops = {
2667 .owner = THIS_MODULE,
2668 .fb_check_var = atafb_check_var,
2669 .fb_set_par = atafb_set_par,
2670 .fb_blank = atafb_blank,
2671 .fb_pan_display = atafb_pan_display,
2672 .fb_fillrect = atafb_fillrect,
2673 .fb_copyarea = atafb_copyarea,
2674 .fb_imageblit = atafb_imageblit,
2675 .fb_ioctl = atafb_ioctl,
2676 };
2677
2678 static void check_default_par(int detected_mode)
2679 {
2680 char default_name[10];
2681 int i;
2682 struct fb_var_screeninfo var;
2683 unsigned long min_mem;
2684
2685
2686 if (default_par) {
2687 var = atafb_predefined[default_par - 1];
2688 var.activate = FB_ACTIVATE_TEST;
2689 if (do_fb_set_var(&var, 1))
2690 default_par = 0;
2691 }
2692
2693 if (!default_par) {
2694 var = atafb_predefined[detected_mode - 1];
2695 var.activate = FB_ACTIVATE_TEST;
2696 if (!do_fb_set_var(&var, 1))
2697 default_par = detected_mode;
2698 }
2699
2700 if (!default_par) {
2701
2702 for (i = 1; i < 10; i++) {
2703 sprintf(default_name,"default%d", i);
2704 default_par = get_video_mode(default_name);
2705 if (!default_par)
2706 panic("can't set default video mode");
2707 var = atafb_predefined[default_par - 1];
2708 var.activate = FB_ACTIVATE_TEST;
2709 if (!do_fb_set_var(&var,1))
2710 break;
2711 }
2712 }
2713 min_mem = var.xres_virtual * var.yres_virtual * var.bits_per_pixel / 8;
2714 if (default_mem_req < min_mem)
2715 default_mem_req = min_mem;
2716 }
2717
2718 #ifdef ATAFB_EXT
2719 static void __init atafb_setup_ext(char *spec)
2720 {
2721 int xres, xres_virtual, yres, depth, planes;
2722 unsigned long addr, len;
2723 char *p;
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735 p = strsep(&spec, ";");
2736 if (!p || !*p)
2737 return;
2738 xres_virtual = xres = simple_strtoul(p, NULL, 10);
2739 if (xres <= 0)
2740 return;
2741
2742 p = strsep(&spec, ";");
2743 if (!p || !*p)
2744 return;
2745 yres = simple_strtoul(p, NULL, 10);
2746 if (yres <= 0)
2747 return;
2748
2749 p = strsep(&spec, ";");
2750 if (!p || !*p)
2751 return;
2752 depth = simple_strtoul(p, NULL, 10);
2753 if (depth != 1 && depth != 2 && depth != 4 && depth != 8 &&
2754 depth != 16 && depth != 24)
2755 return;
2756
2757 p = strsep(&spec, ";");
2758 if (!p || !*p)
2759 return;
2760 if (*p == 'i')
2761 planes = FB_TYPE_INTERLEAVED_PLANES;
2762 else if (*p == 'p')
2763 planes = FB_TYPE_PACKED_PIXELS;
2764 else if (*p == 'n')
2765 planes = FB_TYPE_PLANES;
2766 else if (*p == 't')
2767 planes = -1;
2768 else
2769 return;
2770
2771 p = strsep(&spec, ";");
2772 if (!p || !*p)
2773 return;
2774 addr = simple_strtoul(p, NULL, 0);
2775
2776 p = strsep(&spec, ";");
2777 if (!p || !*p)
2778 len = xres * yres * depth / 8;
2779 else
2780 len = simple_strtoul(p, NULL, 0);
2781
2782 p = strsep(&spec, ";");
2783 if (p && *p)
2784 external_vgaiobase = simple_strtoul(p, NULL, 0);
2785
2786 p = strsep(&spec, ";");
2787 if (p && *p) {
2788 external_bitspercol = simple_strtoul(p, NULL, 0);
2789 if (external_bitspercol > 8)
2790 external_bitspercol = 8;
2791 else if (external_bitspercol < 1)
2792 external_bitspercol = 1;
2793 }
2794
2795 p = strsep(&spec, ";");
2796 if (p && *p) {
2797 if (!strcmp(p, "vga"))
2798 external_card_type = IS_VGA;
2799 if (!strcmp(p, "mv300"))
2800 external_card_type = IS_MV300;
2801 }
2802
2803 p = strsep(&spec, ";");
2804 if (p && *p) {
2805 xres_virtual = simple_strtoul(p, NULL, 10);
2806 if (xres_virtual < xres)
2807 xres_virtual = xres;
2808 if (xres_virtual * yres * depth / 8 > len)
2809 len = xres_virtual * yres * depth / 8;
2810 }
2811
2812 external_xres = xres;
2813 external_xres_virtual = xres_virtual;
2814 external_yres = yres;
2815 external_depth = depth;
2816 external_pmode = planes;
2817 external_addr = addr;
2818 external_len = len;
2819
2820 if (external_card_type == IS_MV300) {
2821 switch (external_depth) {
2822 case 1:
2823 MV300_reg = MV300_reg_1bit;
2824 break;
2825 case 4:
2826 MV300_reg = MV300_reg_4bit;
2827 break;
2828 case 8:
2829 MV300_reg = MV300_reg_8bit;
2830 break;
2831 }
2832 }
2833 }
2834 #endif
2835
2836 static void __init atafb_setup_int(char *spec)
2837 {
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850 int xres;
2851 char *p;
2852
2853 if (!(p = strsep(&spec, ";")) || !*p)
2854 return;
2855 xres = simple_strtoul(p, NULL, 10);
2856 if (!(p = strsep(&spec, ";")) || !*p)
2857 return;
2858 sttt_xres = xres;
2859 tt_yres = st_yres = simple_strtoul(p, NULL, 10);
2860 if ((p = strsep(&spec, ";")) && *p)
2861 sttt_xres_virtual = simple_strtoul(p, NULL, 10);
2862 if ((p = strsep(&spec, ";")) && *p)
2863 sttt_yres_virtual = simple_strtoul(p, NULL, 0);
2864 if ((p = strsep(&spec, ";")) && *p)
2865 ovsc_offset = simple_strtoul(p, NULL, 0);
2866
2867 if (ovsc_offset || (sttt_yres_virtual != st_yres))
2868 use_hwscroll = 0;
2869 }
2870
2871 #ifdef ATAFB_FALCON
2872 static void __init atafb_setup_mcap(char *spec)
2873 {
2874 char *p;
2875 int vmin, vmax, hmin, hmax;
2876
2877
2878
2879
2880
2881 if (!(p = strsep(&spec, ";")) || !*p)
2882 return;
2883 vmin = simple_strtoul(p, NULL, 10);
2884 if (vmin <= 0)
2885 return;
2886 if (!(p = strsep(&spec, ";")) || !*p)
2887 return;
2888 vmax = simple_strtoul(p, NULL, 10);
2889 if (vmax <= 0 || vmax <= vmin)
2890 return;
2891 if (!(p = strsep(&spec, ";")) || !*p)
2892 return;
2893 hmin = 1000 * simple_strtoul(p, NULL, 10);
2894 if (hmin <= 0)
2895 return;
2896 if (!(p = strsep(&spec, "")) || !*p)
2897 return;
2898 hmax = 1000 * simple_strtoul(p, NULL, 10);
2899 if (hmax <= 0 || hmax <= hmin)
2900 return;
2901
2902 fb_info.monspecs.vfmin = vmin;
2903 fb_info.monspecs.vfmax = vmax;
2904 fb_info.monspecs.hfmin = hmin;
2905 fb_info.monspecs.hfmax = hmax;
2906 }
2907 #endif
2908
2909 static void __init atafb_setup_user(char *spec)
2910 {
2911
2912
2913 char *p;
2914 int xres, yres, depth, temp;
2915
2916 p = strsep(&spec, ";");
2917 if (!p || !*p)
2918 return;
2919 xres = simple_strtoul(p, NULL, 10);
2920 p = strsep(&spec, ";");
2921 if (!p || !*p)
2922 return;
2923 yres = simple_strtoul(p, NULL, 10);
2924 p = strsep(&spec, "");
2925 if (!p || !*p)
2926 return;
2927 depth = simple_strtoul(p, NULL, 10);
2928 temp = get_video_mode("user0");
2929 if (temp) {
2930 default_par = temp;
2931 atafb_predefined[default_par - 1].xres = xres;
2932 atafb_predefined[default_par - 1].yres = yres;
2933 atafb_predefined[default_par - 1].bits_per_pixel = depth;
2934 }
2935 }
2936
2937 static int __init atafb_setup(char *options)
2938 {
2939 char *this_opt;
2940 int temp;
2941
2942 if (!options || !*options)
2943 return 0;
2944
2945 while ((this_opt = strsep(&options, ",")) != NULL) {
2946 if (!*this_opt)
2947 continue;
2948 if ((temp = get_video_mode(this_opt))) {
2949 default_par = temp;
2950 mode_option = this_opt;
2951 } else if (!strcmp(this_opt, "inverse"))
2952 fb_invert_cmaps();
2953 else if (!strncmp(this_opt, "hwscroll_", 9)) {
2954 hwscroll = simple_strtoul(this_opt + 9, NULL, 10);
2955 if (hwscroll < 0)
2956 hwscroll = 0;
2957 if (hwscroll > 200)
2958 hwscroll = 200;
2959 }
2960 #ifdef ATAFB_EXT
2961 else if (!strcmp(this_opt, "mv300")) {
2962 external_bitspercol = 8;
2963 external_card_type = IS_MV300;
2964 } else if (!strncmp(this_opt, "external:", 9))
2965 atafb_setup_ext(this_opt + 9);
2966 #endif
2967 else if (!strncmp(this_opt, "internal:", 9))
2968 atafb_setup_int(this_opt + 9);
2969 #ifdef ATAFB_FALCON
2970 else if (!strncmp(this_opt, "eclock:", 7)) {
2971 fext.f = simple_strtoul(this_opt + 7, NULL, 10);
2972
2973 fext.t = 1000000000 / fext.f;
2974 fext.f *= 1000;
2975 } else if (!strncmp(this_opt, "monitorcap:", 11))
2976 atafb_setup_mcap(this_opt + 11);
2977 #endif
2978 else if (!strcmp(this_opt, "keep"))
2979 DontCalcRes = 1;
2980 else if (!strncmp(this_opt, "R", 1))
2981 atafb_setup_user(this_opt + 1);
2982 }
2983 return 0;
2984 }
2985
2986 static int __init atafb_probe(struct platform_device *pdev)
2987 {
2988 int pad, detected_mode, error;
2989 unsigned int defmode = 0;
2990 unsigned long mem_req;
2991 char *option = NULL;
2992
2993 if (fb_get_options("atafb", &option))
2994 return -ENODEV;
2995 atafb_setup(option);
2996 dev_dbg(&pdev->dev, "%s: start\n", __func__);
2997
2998 do {
2999 #ifdef ATAFB_EXT
3000 if (external_addr) {
3001 dev_dbg(&pdev->dev, "initializing external hw\n");
3002 fbhw = &ext_switch;
3003 atafb_ops.fb_setcolreg = &ext_setcolreg;
3004 defmode = DEFMODE_EXT;
3005 break;
3006 }
3007 #endif
3008 #ifdef ATAFB_TT
3009 if (ATARIHW_PRESENT(TT_SHIFTER)) {
3010 dev_dbg(&pdev->dev, "initializing TT hw\n");
3011 fbhw = &tt_switch;
3012 atafb_ops.fb_setcolreg = &tt_setcolreg;
3013 defmode = DEFMODE_TT;
3014 break;
3015 }
3016 #endif
3017 #ifdef ATAFB_FALCON
3018 if (ATARIHW_PRESENT(VIDEL_SHIFTER)) {
3019 dev_dbg(&pdev->dev, "initializing Falcon hw\n");
3020 fbhw = &falcon_switch;
3021 atafb_ops.fb_setcolreg = &falcon_setcolreg;
3022 error = request_irq(IRQ_AUTO_4, falcon_vbl_switcher, 0,
3023 "framebuffer:modeswitch",
3024 falcon_vbl_switcher);
3025 if (error)
3026 return error;
3027 defmode = DEFMODE_F30;
3028 break;
3029 }
3030 #endif
3031 #ifdef ATAFB_STE
3032 if (ATARIHW_PRESENT(STND_SHIFTER) ||
3033 ATARIHW_PRESENT(EXTD_SHIFTER)) {
3034 dev_dbg(&pdev->dev, "initializing ST/E hw\n");
3035 fbhw = &st_switch;
3036 atafb_ops.fb_setcolreg = &stste_setcolreg;
3037 defmode = DEFMODE_STE;
3038 break;
3039 }
3040 fbhw = &st_switch;
3041 atafb_ops.fb_setcolreg = &stste_setcolreg;
3042 dev_warn(&pdev->dev,
3043 "Cannot determine video hardware; defaulting to ST(e)\n");
3044 #else
3045
3046
3047 panic("Cannot initialize video hardware");
3048 #endif
3049 } while (0);
3050
3051
3052
3053 if (fb_info.monspecs.hfmin == 0) {
3054 fb_info.monspecs.hfmin = 31000;
3055 fb_info.monspecs.hfmax = 32000;
3056 fb_info.monspecs.vfmin = 58;
3057 fb_info.monspecs.vfmax = 62;
3058 }
3059
3060 detected_mode = fbhw->detect();
3061 check_default_par(detected_mode);
3062 #ifdef ATAFB_EXT
3063 if (!external_addr) {
3064 #endif
3065 mem_req = default_mem_req + ovsc_offset + ovsc_addlen;
3066 mem_req = PAGE_ALIGN(mem_req) + PAGE_SIZE;
3067 screen_base = atari_stram_alloc(mem_req, "atafb");
3068 if (!screen_base)
3069 panic("Cannot allocate screen memory");
3070 memset(screen_base, 0, mem_req);
3071 pad = -(unsigned long)screen_base & (PAGE_SIZE - 1);
3072 screen_base += pad;
3073 phys_screen_base = atari_stram_to_phys(screen_base + ovsc_offset);
3074 screen_len = (mem_req - pad - ovsc_offset) & PAGE_MASK;
3075 st_ovsc_switch();
3076 if (CPU_IS_040_OR_060) {
3077
3078
3079 cache_push(atari_stram_to_phys(screen_base), screen_len);
3080 kernel_set_cachemode(screen_base, screen_len,
3081 IOMAP_WRITETHROUGH);
3082 }
3083 dev_info(&pdev->dev, "phys_screen_base %lx screen_len %d\n",
3084 phys_screen_base, screen_len);
3085 #ifdef ATAFB_EXT
3086 } else {
3087
3088
3089
3090 external_screen_base = ioremap_wt(external_addr, external_len);
3091 if (external_vgaiobase)
3092 external_vgaiobase =
3093 (unsigned long)ioremap(external_vgaiobase, 0x10000);
3094 screen_base = external_screen_base;
3095 phys_screen_base = external_addr;
3096 screen_len = external_len & PAGE_MASK;
3097 memset (screen_base, 0, external_len);
3098 }
3099 #endif
3100
3101
3102 fb_info.fbops = &atafb_ops;
3103
3104 do_fb_set_var(&atafb_predefined[default_par - 1], 1);
3105
3106 ata_get_par(¤t_par);
3107 fb_info.par = ¤t_par;
3108
3109
3110 atafb_get_var(&fb_info.var, &fb_info);
3111
3112 #ifdef ATAFB_FALCON
3113 fb_info.pseudo_palette = current_par.hw.falcon.pseudo_palette;
3114 #endif
3115 fb_info.flags = FBINFO_FLAG_DEFAULT;
3116
3117 if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, atafb_modedb,
3118 NUM_TOTAL_MODES, &atafb_modedb[defmode],
3119 fb_info.var.bits_per_pixel)) {
3120 return -EINVAL;
3121 }
3122
3123 fb_videomode_to_modelist(atafb_modedb, NUM_TOTAL_MODES,
3124 &fb_info.modelist);
3125
3126 atafb_set_disp(&fb_info);
3127
3128 fb_alloc_cmap(&(fb_info.cmap), 1 << fb_info.var.bits_per_pixel, 0);
3129
3130
3131 dev_info(&pdev->dev, "Determined %dx%d, depth %d\n", fb_info.var.xres,
3132 fb_info.var.yres, fb_info.var.bits_per_pixel);
3133 if ((fb_info.var.xres != fb_info.var.xres_virtual) ||
3134 (fb_info.var.yres != fb_info.var.yres_virtual))
3135 dev_info(&pdev->dev, " virtual %dx%d\n",
3136 fb_info.var.xres_virtual, fb_info.var.yres_virtual);
3137
3138 if (register_framebuffer(&fb_info) < 0) {
3139 #ifdef ATAFB_EXT
3140 if (external_addr) {
3141 iounmap(external_screen_base);
3142 external_addr = 0;
3143 }
3144 if (external_vgaiobase) {
3145 iounmap((void*)external_vgaiobase);
3146 external_vgaiobase = 0;
3147 }
3148 #endif
3149 return -EINVAL;
3150 }
3151
3152 fb_info(&fb_info, "frame buffer device, using %dK of video memory\n",
3153 screen_len >> 10);
3154
3155
3156 return 0;
3157 }
3158
3159 static void atafb_shutdown(struct platform_device *pdev)
3160 {
3161
3162 if (fbhw->blank)
3163 fbhw->blank(0);
3164 }
3165
3166 static struct platform_driver atafb_driver = {
3167 .shutdown = atafb_shutdown,
3168 .driver = {
3169 .name = "atafb",
3170 },
3171 };
3172
3173 static int __init atafb_init(void)
3174 {
3175 struct platform_device *pdev;
3176
3177 if (!MACH_IS_ATARI)
3178 return -ENODEV;
3179
3180 pdev = platform_device_register_simple("atafb", -1, NULL, 0);
3181 if (IS_ERR(pdev))
3182 return PTR_ERR(pdev);
3183
3184 return platform_driver_probe(&atafb_driver, atafb_probe);
3185 }
3186
3187 device_initcall(atafb_init);