50 #include <linux/module.h>
51 #include <linux/kernel.h>
52 #include <linux/errno.h>
53 #include <linux/string.h>
59 #include <asm/setup.h>
61 #include <asm/pgtable.h>
75 #define SWITCH_ACIA 0x01
76 #define SWITCH_SND6 0x40
77 #define SWITCH_SND7 0x80
78 #define SWITCH_NONE 0x00
81 #define up(x, r) (((x) + (r) - 1) & ~((r)-1))
89 static int atafb_setcolreg(
unsigned int regno,
unsigned int red,
unsigned int green,
92 static int atafb_blank(
int blank,
struct fb_info *
info);
106 static unsigned long default_mem_req;
108 static int hwscroll = -1;
110 static int use_hwscroll = 1;
112 static int sttt_xres = 640, st_yres = 400, tt_yres = 480;
113 static int sttt_xres_virtual = 640, sttt_yres_virtual = 400;
114 static int ovsc_offset, ovsc_addlen;
120 static struct atafb_par {
124 #if defined ATAFB_TT || defined ATAFB_STE
144 short hht, hbb, hbe, hdb, hde, hss;
145 short vft, vbb, vbe, vdb, vde, vss;
150 u32 pseudo_palette[16];
160 static int DontCalcRes = 0;
163 #define HHT hw.falcon.hht
164 #define HBB hw.falcon.hbb
165 #define HBE hw.falcon.hbe
166 #define HDB hw.falcon.hdb
167 #define HDE hw.falcon.hde
168 #define HSS hw.falcon.hss
169 #define VFT hw.falcon.vft
170 #define VBB hw.falcon.vbb
171 #define VBE hw.falcon.vbe
172 #define VDB hw.falcon.vdb
173 #define VDE hw.falcon.vde
174 #define VSS hw.falcon.vss
175 #define VCO_CLOCK25 0x04
176 #define VCO_CSYPOS 0x10
177 #define VCO_VSYPOS 0x20
178 #define VCO_HSYPOS 0x40
179 #define VCO_SHORTOFFS 0x100
180 #define VMO_DOUBLE 0x01
181 #define VMO_INTER 0x02
182 #define VMO_PREMASK 0x0c
194 static void *real_screen_base;
196 static int screen_len;
198 static int current_par_valid;
200 static int mono_moni;
206 static unsigned int external_xres;
207 static unsigned int external_xres_virtual;
208 static unsigned int external_yres;
214 static unsigned int external_depth;
215 static int external_pmode;
216 static void *external_addr;
217 static unsigned long external_len;
218 static unsigned long external_vgaiobase;
219 static unsigned int external_bitspercol = 6;
233 static int MV300_reg_1bit[2] = {
236 static int MV300_reg_4bit[16] = {
237 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
239 static int MV300_reg_8bit[256] = {
240 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240,
241 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248,
242 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,
243 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252,
244 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
245 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250,
246 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246,
247 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254,
248 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241,
249 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
250 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245,
251 13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
252 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
253 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
254 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
255 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255
258 static int *MV300_reg = MV300_reg_8bit;
383 static struct fb_hwswitch {
386 struct atafb_par *par);
388 struct atafb_par *par);
390 struct atafb_par *par);
391 void (*get_par)(
struct atafb_par *par);
392 void (*set_par)(
struct atafb_par *par);
393 void (*set_screen_base)(
void *s_base);
394 int (*blank)(
int blank_mode);
396 struct fb_info *
info);
399 static char *autodetect_names[] = {
"autodetect",
NULL };
400 static char *stlow_names[] = {
"stlow",
NULL };
401 static char *stmid_names[] = {
"stmid",
"default5",
NULL };
402 static char *sthigh_names[] = {
"sthigh",
"default4",
NULL };
403 static char *ttlow_names[] = {
"ttlow",
NULL };
404 static char *ttmid_names[] = {
"ttmid",
"default1",
NULL };
405 static char *tthigh_names[] = {
"tthigh",
"default2",
NULL };
406 static char *vga2_names[] = {
"vga2",
NULL };
407 static char *vga4_names[] = {
"vga4",
NULL };
408 static char *vga16_names[] = {
"vga16",
"default3",
NULL };
409 static char *vga256_names[] = {
"vga256",
NULL };
410 static char *falh2_names[] = {
"falh2",
NULL };
411 static char *falh16_names[] = {
"falh16",
NULL };
413 static char **fb_var_names[] = {
435 0, 0, 0, 0, 0, 0, 0, 0,
436 {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
437 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
439 320, 200, 320, 0, 0, 0, 4, 0,
440 {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
441 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
443 640, 200, 640, 0, 0, 0, 2, 0,
444 {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
445 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
447 640, 400, 640, 0, 0, 0, 1, 0,
448 {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
449 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
451 320, 480, 320, 0, 0, 0, 8, 0,
452 {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
453 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
455 640, 480, 640, 0, 0, 0, 4, 0,
456 {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
457 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
459 1280, 960, 1280, 0, 0, 0, 1, 0,
460 {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
461 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
463 640, 480, 640, 0, 0, 0, 1, 0,
464 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
465 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
467 640, 480, 640, 0, 0, 0, 2, 0,
468 {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
469 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
471 640, 480, 640, 0, 0, 0, 4, 0,
472 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
473 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
475 640, 480, 640, 0, 0, 0, 8, 0,
476 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
477 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
479 896, 608, 896, 0, 0, 0, 1, 0,
480 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
481 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
483 896, 608, 896, 0, 0, 0, 4, 0,
484 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
485 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
488 static int num_atafb_predefined =
ARRAY_SIZE(atafb_predefined);
503 "st-low", 60, 320, 200, 32000, 32, 16, 31, 14, 96, 4,
507 "st-mid", 60, 640, 200, 32000, 32, 16, 31, 14, 96, 4,
511 "st-high", 63, 640, 400, 32000, 128, 0, 40, 14, 128, 4,
515 "tt-low", 60, 320, 480, 31041, 120, 100, 8, 16, 140, 30,
519 "tt-mid", 60, 640, 480, 31041, 120, 100, 8, 16, 140, 30,
523 "tt-high", 57, 640, 960, 31041, 120, 100, 8, 16, 140, 30,
533 "vga", 63.5, 640, 480, 32000, 18, 42, 31, 11, 96, 3,
537 "vga70", 70, 640, 400, 32000, 18, 42, 31, 11, 96, 3,
547 "falh", 60, 896, 608, 32000, 18, 42, 31, 1, 96,3,
552 #define NUM_TOTAL_MODES ARRAY_SIZE(atafb_modedb)
554 static char *mode_option __initdata =
NULL;
559 #define DEFMODE_F30 7
560 #define DEFMODE_STE 2
561 #define DEFMODE_EXT 6
564 static int get_video_mode(
char *vname)
570 name_list = fb_var_names;
571 for (i = 0; i < num_atafb_predefined; i++) {
576 if (!
strcmp(vname, *name))
624 if (bpp > 1 || xres > sttt_xres * 2 || yres > tt_yres * 2)
627 xres = sttt_xres * 2;
631 if (bpp > 8 || xres > sttt_xres || yres > tt_yres)
634 if (xres > sttt_xres / 2 || yres > tt_yres)
637 xres = sttt_xres / 2;
640 }
else if (bpp > 2) {
641 if (xres > sttt_xres || yres > tt_yres)
643 if (xres > sttt_xres / 2 || yres > st_yres / 2) {
650 xres = sttt_xres / 2;
654 }
else if (bpp > 1) {
655 if (xres > sttt_xres || yres > st_yres / 2)
661 }
else if (var->
xres > sttt_xres || var->
yres > st_yres) {
670 if (yres_virtual <= 0)
672 else if (yres_virtual < yres)
678 linelen = xres * bpp / 8;
679 if (yres_virtual * linelen > screen_len && screen_len)
681 if (yres * linelen > screen_len && screen_len)
683 if (var->
yoffset + yres > yres_virtual && yres_virtual)
685 par->yres_virtual = yres_virtual;
686 par->screen_base = screen_base + var->
yoffset * linelen;
687 par->next_line = linelen;
697 var->
red.msb_right = 0;
711 if (par->hw.tt.sync & 1)
718 var->
xres = sttt_xres / 2;
720 var->
yres = st_yres / 2;
724 var->
xres = sttt_xres;
726 var->
yres = st_yres / 2;
730 var->
xres = sttt_xres;
736 var->
xres = sttt_xres / 2;
742 var->
xres = sttt_xres;
749 var->
xres = sttt_xres * 2;
751 var->
yres = tt_yres * 2;
758 var->
transp.msb_right = 0;
762 else if (screen_len) {
763 if (par->yres_virtual)
776 var->
yoffset = (par->screen_base - screen_base) / linelen;
785 static void tt_get_par(
struct atafb_par *par)
789 par->hw.tt.sync =
shifter.syncmode;
790 addr = ((
shifter.bas_hi & 0xff) << 16) |
791 ((
shifter.bas_md & 0xff) << 8) |
796 static void tt_set_par(
struct atafb_par *par)
799 shifter.syncmode = par->hw.tt.sync;
801 if (current_par.screen_base != par->screen_base)
802 fbhw->set_screen_base(par->screen_base);
805 static int tt_setcolreg(
unsigned int regno,
unsigned int red,
813 tt_palette[regno] = (((red >> 12) << 8) | ((green >> 12) << 4) |
821 static int tt_detect(
void)
823 struct atafb_par par;
837 mono_moni = (
st_mfp.par_dt_reg & 0x80) == 0;
840 tt_encode_var(&atafb_predefined[0], &par);
852 static int f030_bus_width;
868 32000000, 31250, 18, 0, 42, 0x0, 0
870 0, 0, 18, 0, 42, 0x1, 0
874 static int vdl_prescale[4][3] = {
875 { 4,2,1 }, { 4,2,1 }, { 4,2,2 }, { 4,2,1 }
879 static long h_syncs[4] = { 3000000, 4875000, 4000000, 4875000 };
881 static inline int hxx_prescale(
struct falcon_hw *
hw)
883 return hw->ste_mode ? 16
884 : vdl_prescale[mon_type][hw->vid_mode >> 2 & 0x3];
888 struct atafb_par *par)
899 if (par->hw.falcon.mono) {
904 }
else if (par->hw.falcon.f_shift & 0x100) {
917 struct atafb_par *par)
920 int xres = var->
xres;
921 int yres = var->
yres;
924 int left_margin, right_margin, hsync_len;
925 int upper_margin, lower_margin, vsync_len;
934 int hdb_off, hde_off, base_off;
935 int gstart, gend1, gend2,
align;
960 if (!xres || !yres || !bpp)
963 if (mon_type ==
F_MON_SM && bpp != 1)
968 par->hw.falcon.f_shift = 0x400;
969 par->hw.falcon.st_shift = 0x200;
970 }
else if (bpp <= 2) {
972 par->hw.falcon.f_shift = 0x000;
973 par->hw.falcon.st_shift = 0x100;
974 }
else if (bpp <= 4) {
976 par->hw.falcon.f_shift = 0x000;
977 par->hw.falcon.st_shift = 0x000;
978 }
else if (bpp <= 8) {
980 par->hw.falcon.f_shift = 0x010;
981 }
else if (bpp <= 16) {
983 par->hw.falcon.f_shift = 0x100;
986 par->hw.falcon.bpp =
bpp;
988 if (mon_type ==
F_MON_SM || DontCalcRes) {
997 goto set_screen_base;
1003 else if (xres <= 640 && bpp != 16)
1007 else if (yres <= 240)
1009 else if (yres <= 400)
1013 par->hw.falcon.ste_mode = bpp == 2;
1014 par->hw.falcon.mono = bpp == 1;
1024 if (par->hw.falcon.ste_mode)
1025 xres = (xres + 63) & ~63;
1027 xres = (xres + 31) & ~31;
1029 xres = (xres + 15) & ~15;
1031 yres = (yres + 15) & ~15;
1033 yres = (yres + 7) & ~7;
1035 if (xres_virtual < xres)
1036 xres_virtual =
xres;
1038 xres_virtual = (xres_virtual + 31) & ~31;
1040 xres_virtual = (xres_virtual + 15) & ~15;
1042 if (yres_virtual <= 0)
1044 else if (yres_virtual < yres)
1045 yres_virtual =
yres;
1051 par->hw.falcon.line_width = bpp * xres / 16;
1052 par->hw.falcon.line_offset = bpp * (xres_virtual -
xres) / 16;
1055 xstretch = (xres < 640) ? 2 : 1;
1059 if (xres != 640 && yres != 400)
1064 par->hw.falcon.ste_mode = 1;
1065 par->hw.falcon.f_shift = 0x000;
1066 par->hw.falcon.st_shift = 0x200;
1067 left_margin = hsync_len = 128 /
plen;
1073 plen = 2 * xstretch;
1083 hsync_len = pclock->hsync /
plen;
1086 vsync_len = interlace ? 3 : 4;
1095 upper_margin = (upper_margin + 1) / 2;
1096 lower_margin = (lower_margin + 1) / 2;
1097 vsync_len = (vsync_len + 1) / 2;
1112 plen = 1 * xstretch;
1113 if ((plen * xres + f25.right + f25.hsync + f25.left) *
1116 else if ((plen * xres + f32.right + f32.hsync +
1117 f32.left) * fb_info.
monspecs.hfmin < f32.f)
1119 else if ((plen * xres + fext.right + fext.hsync +
1120 fext.left) * fb_info.
monspecs.hfmin < fext.f &&
1126 left_margin = pclock->left /
plen;
1127 right_margin = pclock->right /
plen;
1128 hsync_len = pclock->hsync /
plen;
1129 linesize = left_margin + xres + right_margin +
hsync_len;
1138 for (i = 1; i <= 4; i *= 2) {
1149 if (fext.t && fext.t * i >= var->
pixclock &&
1157 plen = pcl / pclock->t;
1169 upper_margin = (upper_margin + 1) / 2;
1170 lower_margin = (lower_margin + 1) / 2;
1171 vsync_len = (vsync_len + 1) / 2;
1179 if (pclock == &fext)
1184 if (pclock->f / plen / 8 * bpp > 32000000L)
1201 par->hw.falcon.vid_control = mon_type | f030_bus_width;
1209 par->hw.falcon.vid_control |= pclock->control_mask;
1211 par->hw.falcon.sync = pclock->sync_mask | 0x2;
1213 par->hw.falcon.vid_mode = (2 /
plen) << 2;
1241 prescale = hxx_prescale(&par->hw.falcon);
1242 base_off = par->hw.falcon.vid_control &
VCO_SHORTOFFS ? 64 : 128;
1248 if (par->hw.falcon.f_shift & 0x100) {
1251 hdb_off = (base_off + 16 *
plen) + prescale;
1254 hde_off = ((128 / bpp + 2) * plen);
1255 if (par->hw.falcon.ste_mode)
1256 hdb_off = (64 + base_off + (128 / bpp + 2) * plen) +
prescale;
1258 hdb_off = (base_off + (128 / bpp + 18) * plen) +
prescale;
1261 gstart = (prescale / 2 + plen *
left_margin) / prescale;
1265 gend2 = gstart + xres * plen /
prescale;
1266 par->HHT = plen * (left_margin + xres +
right_margin) /
1270 par->HDB = gstart - hdb_off /
prescale;
1273 par->HDB += par->HHT + 2 + 0x200;
1274 par->HDE = gend1 - par->HHT - 2 - hde_off /
prescale;
1275 par->HBB = gend2 - par->HHT - 2;
1278 if ((par->HDB & 0x200) && (par->HDB & ~0x200) - par->HDE <= 5) {
1282 if (hde_off % prescale)
1284 par->HSS = par->HHT + 2 - plen * hsync_len /
prescale;
1285 if (par->HSS < par->HBB)
1286 par->HSS = par->HBB;
1290 hfreq = pclock->f / ((par->HHT + 2) * prescale * 2);
1308 par->VBE = (upper_margin * 2 + 1);
1309 par->VDB = par->VBE;
1315 par->VDE += par->VDB;
1316 par->VBB = par->VDE;
1317 par->VFT = par->VBB + (lower_margin * 2 - 1) - 1;
1318 par->VSS = par->VFT + 1 - (vsync_len * 2 - 1);
1328 vfreq = (hfreq * 2) / (par->VFT + 1);
1329 if (vfreq > fb_info.
monspecs.vfmax && !doubleline && !interlace) {
1333 }
else if (vfreq < fb_info.
monspecs.vfmin && !interlace && !doubleline) {
1337 }
else if (vfreq < fb_info.
monspecs.vfmin && doubleline) {
1342 (hfreq * 2) / (par->VFT + 1 + 4 * lines - 2 * yres) >
1346 upper_margin += lines;
1347 lower_margin += lines;
1349 }
else if (vfreq > fb_info.
monspecs.vfmax && doubleline) {
1353 (hfreq * 2) / (par->VFT + 1 + 4 * lines) >
1357 upper_margin += lines;
1358 lower_margin += lines;
1360 }
else if (vfreq > fb_info.
monspecs.vfmax && interlace) {
1364 (hfreq * 2) / (par->VFT + 1 + 4 * lines) >
1368 upper_margin += lines;
1369 lower_margin += lines;
1371 }
else if (vfreq < fb_info.
monspecs.vfmin ||
1376 linelen = xres_virtual * bpp / 8;
1377 if (yres_virtual * linelen > screen_len && screen_len)
1379 if (yres * linelen > screen_len && screen_len)
1381 if (var->
yoffset + yres > yres_virtual && yres_virtual)
1384 par->screen_base = screen_base + var->
yoffset * linelen;
1385 par->hw.falcon.xoffset = 0;
1387 par->next_line = linelen;
1393 struct atafb_par *par)
1398 int hdb_off, hde_off, base_off;
1399 struct falcon_hw *
hw = &par->hw.falcon;
1403 var->
pixclock = hw->sync & 0x1 ? fext.t :
1426 var->
yres = hw->vde - hw->vdb;
1440 if (hw->f_shift & 0x400)
1442 else if (hw->f_shift & 0x100)
1444 else if (hw->f_shift & 0x010)
1446 else if (hw->st_shift == 0)
1448 else if (hw->st_shift == 0x100)
1459 var->
red.offset = 11;
1460 var->
red.length = 5;
1461 var->
red.msb_right = 0;
1462 var->
green.offset = 5;
1463 var->
green.length = 6;
1464 var->
green.msb_right = 0;
1465 var->
blue.offset = 0;
1466 var->
blue.length = 5;
1467 var->
blue.msb_right = 0;
1469 var->
red.offset = 0;
1470 var->
red.length = hw->ste_mode ? 4 : 6;
1473 var->
red.msb_right = 0;
1479 var->
transp.msb_right = 0;
1483 if (par->yres_virtual)
1497 prescale = hxx_prescale(hw);
1498 plen = 4 >> (hw->vid_mode >> 2 & 0x3);
1500 if (hw->f_shift & 0x100) {
1502 hdb_off = (base_off + 16 *
plen) + prescale;
1506 hdb_off = (64 + base_off + (128 / var->
bits_per_pixel + 2) * plen)
1514 var->
left_margin = hdb_off + prescale * ((hw->hdb & 0x1ff) -
1515 (hw->hdb & 0x200 ? 2 + hw->hht : 0));
1516 if (hw->ste_mode || mon_type !=
F_MON_VGA)
1517 var->
right_margin = prescale * (hw->hht + 2 - hw->hde) - hde_off;
1520 var->
right_margin = prescale * (hw->hht + 2 - hw->hbb);
1521 var->
hsync_len = prescale * (hw->hht + 2 - hw->hss);
1526 var->
vsync_len = (hw->vft + 1 - hw->vss + 1) / 2;
1546 var->
yoffset = (par->screen_base - screen_base) / linelen;
1554 static int f_change_mode;
1555 static struct falcon_hw f_new_mode;
1556 static int f_pan_display;
1558 static void falcon_get_par(
struct atafb_par *par)
1561 struct falcon_hw *hw = &par->hw.falcon;
1565 hw->st_shift =
videl.st_shift & 0x300;
1566 hw->f_shift =
videl.f_shift;
1567 hw->vid_control =
videl.control;
1568 hw->vid_mode =
videl.mode;
1569 hw->sync =
shifter.syncmode & 0x1;
1570 hw->xoffset =
videl.xoffset & 0xf;
1571 hw->hht =
videl.hht;
1572 hw->hbb =
videl.hbb;
1573 hw->hbe =
videl.hbe;
1574 hw->hdb =
videl.hdb;
1575 hw->hde =
videl.hde;
1576 hw->hss =
videl.hss;
1577 hw->vft =
videl.vft;
1578 hw->vbb =
videl.vbb;
1579 hw->vbe =
videl.vbe;
1580 hw->vdb =
videl.vdb;
1581 hw->vde =
videl.vde;
1582 hw->vss =
videl.vss;
1584 addr = (
shifter.bas_hi & 0xff) << 16 |
1585 (
shifter.bas_md & 0xff) << 8 |
1590 hw->ste_mode = (hw->f_shift & 0x510) == 0 && hw->st_shift == 0x100;
1591 hw->mono = (hw->f_shift & 0x400) ||
1592 ((hw->f_shift & 0x510) == 0 && hw->st_shift == 0x200);
1595 static void falcon_set_par(
struct atafb_par *par)
1600 if (current_par.screen_base != par->screen_base)
1601 fbhw->set_screen_base(par->screen_base);
1613 f_new_mode = par->hw.falcon;
1619 struct falcon_hw *hw = &f_new_mode;
1621 if (f_change_mode) {
1624 if (hw->sync & 0x1) {
1626 *(
volatile unsigned short *)0xffff9202 = 0xffbf;
1629 *(
volatile unsigned short *)0xffff9202;
1633 videl.hht = hw->hht;
1634 videl.hbb = hw->hbb;
1635 videl.hbe = hw->hbe;
1636 videl.hdb = hw->hdb;
1637 videl.hde = hw->hde;
1638 videl.hss = hw->hss;
1639 videl.vft = hw->vft;
1640 videl.vbb = hw->vbb;
1641 videl.vbe = hw->vbe;
1642 videl.vdb = hw->vdb;
1643 videl.vde = hw->vde;
1644 videl.vss = hw->vss;
1648 videl.st_shift = hw->st_shift;
1658 videl.f_shift = hw->f_shift;
1661 videl.xoffset = hw->xoffset;
1664 videl.control = hw->vid_control;
1665 videl.mode = hw->vid_mode;
1667 if (f_pan_display) {
1669 videl.xoffset = current_par.hw.falcon.xoffset;
1670 shifter_f030.off_next = current_par.hw.falcon.line_offset;
1676 struct fb_info *info)
1678 struct atafb_par *par = (
struct atafb_par *)info->
par;
1681 int bpp = info->
var.bits_per_pixel;
1686 par->hw.falcon.xoffset = var->
xoffset & 15;
1688 par->hw.falcon.xoffset = 0;
1691 par->hw.falcon.line_offset = bpp *
1692 (info->
var.xres_virtual - info->
var.xres) / 16;
1693 if (par->hw.falcon.xoffset)
1694 par->hw.falcon.line_offset -=
bpp;
1695 xoffset = var->
xoffset - par->hw.falcon.xoffset;
1697 par->screen_base = screen_base +
1698 (var->
yoffset * info->
var.xres_virtual + xoffset) * bpp / 8;
1699 if (fbhw->set_screen_base)
1700 fbhw->set_screen_base(par->screen_base);
1707 static int falcon_setcolreg(
unsigned int regno,
unsigned int red,
1708 unsigned int green,
unsigned int blue,
1709 unsigned int transp,
struct fb_info *info)
1713 f030_col[regno] = (((red & 0xfc00) << 16) |
1714 ((green & 0xfc00) << 8) |
1715 ((blue & 0xfc00) >> 8));
1718 (((red & 0xe000) >> 13) | ((red & 0x1000) >> 12) << 8) |
1719 (((green & 0xe000) >> 13) | ((green & 0x1000) >> 12) << 4) |
1720 ((blue & 0xe000) >> 13) | ((blue & 0x1000) >> 12);
1722 ((green & 0xfc00) >> 5) |
1723 ((blue & 0xf800) >> 11));
1728 static int falcon_blank(
int blank_mode)
1734 int vdb, vss, hbe, hss;
1739 vdb = current_par.VDB;
1740 vss = current_par.VSS;
1741 hbe = current_par.HBE;
1742 hss = current_par.HSS;
1744 if (blank_mode >= 1) {
1746 vdb = current_par.VFT + 1;
1748 hbe = current_par.HHT + 2;
1752 if (blank_mode == 2 || blank_mode == 4)
1753 vss = current_par.VFT + 1;
1754 if (blank_mode == 3 || blank_mode == 4)
1755 hss = current_par.HHT + 2;
1766 static int falcon_detect(
void)
1768 struct atafb_par par;
1772 fhw = *(
unsigned char *)0xffff8006;
1773 mon_type = fhw >> 6 & 0x3;
1775 f030_bus_width = fhw << 6 & 0x80;
1793 f25.hsync = h_syncs[mon_type] / f25.t;
1794 f32.hsync = h_syncs[mon_type] / f32.t;
1796 fext.hsync = h_syncs[mon_type] / fext.t;
1798 falcon_get_par(&par);
1799 falcon_encode_var(&atafb_predefined[0], &par);
1812 struct atafb_par *par)
1822 mode = par->hw.st.mode & 3;
1842 struct atafb_par *par)
1844 int xres = var->
xres;
1845 int yres = var->
yres;
1851 if (bpp > 1 || xres > sttt_xres || yres > st_yres)
1858 if (bpp > 4 || xres > sttt_xres || yres > st_yres)
1861 if (xres > sttt_xres / 2 || yres > st_yres / 2)
1863 par->hw.st.mode =
ST_LOW;
1864 xres = sttt_xres / 2;
1867 }
else if (bpp > 1) {
1868 if (xres > sttt_xres || yres > st_yres / 2)
1870 par->hw.st.mode =
ST_MID;
1877 if (yres_virtual <= 0)
1879 else if (yres_virtual < yres)
1880 yres_virtual = yres;
1882 par->hw.st.sync = (par->hw.st.sync & ~1) | 1;
1884 par->hw.st.sync = (par->hw.st.sync & ~1);
1885 linelen = xres * bpp / 8;
1886 if (yres_virtual * linelen > screen_len && screen_len)
1888 if (yres * linelen > screen_len && screen_len)
1890 if (var->
yoffset + yres > yres_virtual && yres_virtual)
1892 par->yres_virtual = yres_virtual;
1893 par->screen_base = screen_base + var->
yoffset * linelen;
1894 par->next_line = linelen;
1899 struct atafb_par *par)
1903 var->
red.offset = 0;
1905 var->
red.msb_right = 0;
1919 if (!(par->hw.st.sync & 1))
1924 switch (par->hw.st.mode & 3) {
1926 var->
xres = sttt_xres / 2;
1927 var->
yres = st_yres / 2;
1931 var->
xres = sttt_xres;
1932 var->
yres = st_yres / 2;
1936 var->
xres = sttt_xres;
1937 var->
yres = st_yres;
1944 var->
transp.msb_right = 0;
1947 ovsc_addlen = linelen * (sttt_yres_virtual - st_yres);
1951 else if (screen_len) {
1952 if (par->yres_virtual)
1965 var->
yoffset = (par->screen_base - screen_base) / linelen;
1974 static void stste_get_par(
struct atafb_par *par)
1978 par->hw.st.sync =
shifter.syncmode;
1979 addr = ((
shifter.bas_hi & 0xff) << 16) |
1980 ((
shifter.bas_md & 0xff) << 8);
1982 addr |= (
shifter.bas_lo & 0xff);
1986 static void stste_set_par(
struct atafb_par *par)
1989 shifter.syncmode = par->hw.st.sync;
1991 if (current_par.screen_base != par->screen_base)
1992 fbhw->set_screen_base(par->screen_base);
1995 static int stste_setcolreg(
unsigned int regno,
unsigned int red,
1996 unsigned int green,
unsigned int blue,
1997 unsigned int transp,
struct fb_info *info)
2006 (((red & 0xe) >> 1) | ((red & 1) << 3) << 8) |
2007 (((green & 0
xe) >> 1) | ((green & 1) << 3) << 4) |
2008 ((blue & 0xe) >> 1) | ((blue & 1) << 3);
2011 ((red & 0xe) << 7) |
2012 ((green & 0xe) << 3) |
2013 ((blue & 0xe) >> 1);
2017 static int stste_detect(
void)
2019 struct atafb_par par;
2029 mono_moni = (
st_mfp.par_dt_reg & 0x80) == 0;
2031 stste_get_par(&par);
2032 stste_encode_var(&atafb_predefined[0], &par);
2039 static void stste_set_screen_base(
void *s_base)
2044 shifter.bas_hi = (
unsigned char)((addr & 0xff0000) >> 16);
2045 shifter.bas_md = (
unsigned char)((addr & 0x00ff00) >> 8);
2047 shifter.bas_lo = (
unsigned char)(addr & 0x0000ff);
2067 #define LINE_DELAY (mono_moni ? 30 : 70)
2068 #define SYNC_DELAY (mono_moni ? 1500 : 2000)
2071 static void st_ovsc_switch(
void)
2073 unsigned long flags;
2074 register unsigned char old,
new;
2085 while (
st_mfp.tim_dt_b > 1)
2092 }
while (old !=
new);
2118 if (external_depth == 1) {
2128 int visual = external_vgaiobase ?
2131 switch (external_pmode) {
2170 par->next_line = external_xres_virtual * external_depth / 8;
2177 var->
red.offset = 0;
2178 var->
red.length = (external_pmode == -1) ? external_depth / 3 :
2179 (external_vgaiobase ? external_bitspercol : 0);
2180 var->
red.msb_right = 0;
2196 var->
xres = external_xres;
2197 var->
yres = external_yres;
2204 var->
transp.msb_right = 0;
2214 static void ext_get_par(
struct atafb_par *par)
2216 par->screen_base = external_addr;
2219 static void ext_set_par(
struct atafb_par *par)
2223 #define OUTB(port,val) \
2224 *((unsigned volatile char *) ((port)+external_vgaiobase)) = (val)
2226 (*((unsigned volatile char *) ((port)+external_vgaiobase)))
2229 unsigned char tmp = INB(0x3da); \
2233 static int ext_setcolreg(
unsigned int regno,
unsigned int red,
2234 unsigned int green,
unsigned int blue,
2235 unsigned int transp,
struct fb_info *info)
2237 unsigned char colmask = (1 << external_bitspercol) - 1;
2239 if (!external_vgaiobase)
2245 switch (external_card_type) {
2249 OUTB(0x3c9, red & colmask);
2251 OUTB(0x3c9, green & colmask);
2253 OUTB(0x3c9, blue & colmask);
2258 OUTB((MV300_reg[regno] << 2) + 1, red);
2259 OUTB((MV300_reg[regno] << 2) + 1, green);
2260 OUTB((MV300_reg[regno] << 2) + 1, blue);
2268 static int ext_detect(
void)
2271 struct atafb_par dummy_par;
2273 myvar->
xres = external_xres;
2275 myvar->
yres = external_yres;
2277 ext_encode_var(myvar, &dummy_par);
2285 static void set_screen_base(
void *s_base)
2291 shifter.bas_hi = (
unsigned char)((addr & 0xff0000) >> 16);
2292 shifter.bas_md = (
unsigned char)((addr & 0x00ff00) >> 8);
2293 shifter.bas_lo = (
unsigned char)(addr & 0x0000ff);
2298 struct atafb_par *par = (
struct atafb_par *)info->
par;
2300 if (!fbhw->set_screen_base ||
2304 par->screen_base = screen_base +
2306 * info->
var.bits_per_pixel / 8;
2307 fbhw->set_screen_base(par->screen_base);
2314 static struct fb_hwswitch tt_switch = {
2315 .detect = tt_detect,
2316 .encode_fix = tt_encode_fix,
2317 .decode_var = tt_decode_var,
2318 .encode_var = tt_encode_var,
2319 .get_par = tt_get_par,
2320 .set_par = tt_set_par,
2321 .set_screen_base = set_screen_base,
2322 .pan_display = pan_display,
2327 static struct fb_hwswitch falcon_switch = {
2328 .detect = falcon_detect,
2329 .encode_fix = falcon_encode_fix,
2330 .decode_var = falcon_decode_var,
2331 .encode_var = falcon_encode_var,
2332 .get_par = falcon_get_par,
2333 .set_par = falcon_set_par,
2334 .set_screen_base = set_screen_base,
2335 .blank = falcon_blank,
2336 .pan_display = falcon_pan_display,
2341 static struct fb_hwswitch st_switch = {
2342 .detect = stste_detect,
2343 .encode_fix = stste_encode_fix,
2344 .decode_var = stste_decode_var,
2345 .encode_var = stste_encode_var,
2346 .get_par = stste_get_par,
2347 .set_par = stste_set_par,
2348 .set_screen_base = stste_set_screen_base,
2349 .pan_display = pan_display
2354 static struct fb_hwswitch ext_switch = {
2355 .detect = ext_detect,
2356 .encode_fix = ext_encode_fix,
2357 .decode_var = ext_decode_var,
2358 .encode_var = ext_encode_var,
2359 .get_par = ext_get_par,
2360 .set_par = ext_set_par,
2364 static void ata_get_par(
struct atafb_par *par)
2366 if (current_par_valid)
2372 static void ata_set_par(
struct atafb_par *par)
2376 current_par_valid = 1;
2389 struct atafb_par par;
2391 err = fbhw->decode_var(var, &par);
2397 fbhw->encode_var(var, &par);
2407 struct atafb_par par;
2410 err = fbhw->decode_var(&info->
var, &par);
2414 err = fbhw->encode_fix(fix, &par);
2420 struct atafb_par par;
2423 fbhw->encode_var(var, &par);
2431 static void atafb_set_disp(
struct fb_info *info)
2433 atafb_get_var(&info->
var, info);
2434 atafb_get_fix(&info->
fix, info);
2440 u_int transp,
struct fb_info *info)
2446 return info->
fbops->fb_setcolreg(regno, red, green, blue, transp, info);
2457 if (yoffset < 0 || yoffset >= info->
var.yres_virtual || xoffset)
2460 if (xoffset + info->
var.xres > info->
var.xres_virtual ||
2461 yoffset + info->
var.yres > info->
var.yres_virtual)
2465 if (fbhw->pan_display) {
2466 err = fbhw->pan_display(var, info);
2472 info->
var.xoffset = xoffset;
2473 info->
var.yoffset = yoffset;
2487 #if BITS_PER_LONG == 32
2488 #define BYTES_PER_LONG 4
2489 #define SHIFT_PER_LONG 5
2490 #elif BITS_PER_LONG == 64
2491 #define BYTES_PER_LONG 8
2492 #define SHIFT_PER_LONG 6
2494 #define Please update me
2498 static void atafb_fillrect(
struct fb_info *info,
const struct fb_fillrect *rect)
2500 struct atafb_par *par = (
struct atafb_par *)info->
par;
2508 if (info->
var.bits_per_pixel == 16) {
2520 x2 = x2 < info->
var.xres_virtual ? x2 : info->
var.xres_virtual;
2521 y2 = y2 < info->
var.yres_virtual ? y2 : info->
var.yres_virtual;
2522 width = x2 - rect->
dx;
2525 if (info->
var.bits_per_pixel == 1)
2528 else if (info->
var.bits_per_pixel == 2)
2531 else if (info->
var.bits_per_pixel == 4)
2541 static void atafb_copyarea(
struct fb_info *info,
const struct fb_copyarea *area)
2543 struct atafb_par *par = (
struct atafb_par *)info->
par;
2549 if (info->
var.bits_per_pixel == 16) {
2558 dx = area->
dx > 0 ? area->
dx : 0;
2559 dy = area->
dy > 0 ? area->
dy : 0;
2560 x2 = x2 < info->
var.xres_virtual ? x2 : info->
var.xres_virtual;
2561 y2 = y2 < info->
var.yres_virtual ? y2 : info->
var.yres_virtual;
2565 if (area->
sx + dx < area->dx || area->
sy + dy < area->dy)
2569 sx = area->
sx + (dx - area->
dx);
2570 sy = area->
sy + (dy - area->
dy);
2577 if (dy > sy || (dy == sy && dx >
sx)) {
2583 if (info->
var.bits_per_pixel == 1)
2585 else if (info->
var.bits_per_pixel == 2)
2587 else if (info->
var.bits_per_pixel == 4)
2595 static void atafb_imageblit(
struct fb_info *info,
const struct fb_image *
image)
2597 struct atafb_par *par = (
struct atafb_par *)info->
par;
2605 if (info->
var.bits_per_pixel == 16) {
2616 x2 = image->
dx + image->
width;
2620 x2 = x2 < info->
var.xres_virtual ? x2 : info->
var.xres_virtual;
2621 y2 = y2 < info->
var.yres_virtual ? y2 : info->
var.yres_virtual;
2625 if (image->
depth == 1) {
2627 dst = (
unsigned long *)
2629 dst_idx = ((
unsigned long)info->
screen_base & (BYTES_PER_LONG - 1)) * 8;
2630 dst_idx += dy * par->next_line * 8 + dx;
2632 pitch = (image->
width + 7) / 8;
2635 if (info->
var.bits_per_pixel == 1)
2639 else if (info->
var.bits_per_pixel == 2)
2643 else if (info->
var.bits_per_pixel == 4)
2657 info->
var.bits_per_pixel);
2662 atafb_ioctl(
struct fb_info *info,
unsigned int cmd,
unsigned long arg)
2665 #ifdef FBCMD_GET_CURRENTPAR
2666 case FBCMD_GET_CURRENTPAR:
2668 sizeof(
struct atafb_par)))
2672 #ifdef FBCMD_SET_CURRENTPAR
2673 case FBCMD_SET_CURRENTPAR:
2675 sizeof(
struct atafb_par)))
2677 ata_set_par(¤t_par);
2691 static int atafb_blank(
int blank,
struct fb_info *info)
2693 unsigned short black[16];
2695 if (fbhw->blank && !fbhw->blank(blank))
2698 memset(black, 0, 16 *
sizeof(
unsigned short));
2709 do_install_cmap(info);
2723 struct atafb_par par;
2727 err = fbhw->decode_var(var, &par);
2732 fbhw->encode_var(var, &par);
2738 static int atafb_set_par(
struct fb_info *info)
2740 struct atafb_par *par = (
struct atafb_par *)info->
par;
2743 fbhw->decode_var(&info->
var, par);
2745 fbhw->encode_fix(&info->
fix, par);
2755 static struct fb_ops atafb_ops = {
2757 .fb_check_var = atafb_check_var,
2758 .fb_set_par = atafb_set_par,
2759 .fb_setcolreg = atafb_setcolreg,
2760 .fb_blank = atafb_blank,
2761 .fb_pan_display = atafb_pan_display,
2762 .fb_fillrect = atafb_fillrect,
2763 .fb_copyarea = atafb_copyarea,
2764 .fb_imageblit = atafb_imageblit,
2765 .fb_ioctl = atafb_ioctl,
2768 static void check_default_par(
int detected_mode)
2770 char default_name[10];
2773 unsigned long min_mem;
2779 if (do_fb_set_var(&var, 1))
2784 var = atafb_predefined[detected_mode - 1];
2786 if (!do_fb_set_var(&var, 1))
2792 for (i = 1; i < 10; i++) {
2793 sprintf(default_name,
"default%d", i);
2796 panic(
"can't set default video mode");
2799 if (!do_fb_set_var(&var,1))
2804 if (default_mem_req < min_mem)
2805 default_mem_req = min_mem;
2809 static void __init atafb_setup_ext(
char *spec)
2843 if (depth != 1 && depth != 2 && depth != 4 && depth != 8 &&
2844 depth != 16 && depth != 24)
2868 len = xres * yres * depth / 8;
2879 if (external_bitspercol > 8)
2880 external_bitspercol = 8;
2881 else if (external_bitspercol < 1)
2882 external_bitspercol = 1;
2888 external_card_type =
IS_VGA;
2896 if (xres_virtual < xres)
2897 xres_virtual =
xres;
2898 if (xres_virtual * yres * depth / 8 > len)
2899 len = xres_virtual * yres * depth / 8;
2902 external_xres =
xres;
2904 external_yres =
yres;
2905 external_depth =
depth;
2906 external_pmode = planes;
2907 external_addr = (
void *)addr;
2910 if (external_card_type ==
IS_MV300) {
2911 switch (external_depth) {
2913 MV300_reg = MV300_reg_1bit;
2916 MV300_reg = MV300_reg_4bit;
2919 MV300_reg = MV300_reg_8bit;
2926 static void __init atafb_setup_int(
char *spec)
2943 if (!(p =
strsep(&spec,
";")) || !*p)
2946 if (!(p =
strsep(&spec,
";")) || !*p)
2950 if ((p =
strsep(&spec,
";")) && *p)
2952 if ((p =
strsep(&spec,
";")) && *p)
2954 if ((p =
strsep(&spec,
";")) && *p)
2957 if (ovsc_offset || (sttt_yres_virtual != st_yres))
2962 static void __init atafb_setup_mcap(
char *spec)
2965 int vmin, vmax, hmin, hmax;
2971 if (!(p =
strsep(&spec,
";")) || !*p)
2976 if (!(p =
strsep(&spec,
";")) || !*p)
2979 if (vmax <= 0 || vmax <= vmin)
2981 if (!(p =
strsep(&spec,
";")) || !*p)
2986 if (!(p =
strsep(&spec,
"")) || !*p)
2989 if (hmax <= 0 || hmax <= hmin)
2999 static void __init atafb_setup_user(
char *spec)
3018 temp = get_video_mode(
"user0");
3032 if (!options || !*options)
3035 while ((this_opt =
strsep(&options,
",")) !=
NULL) {
3038 if ((temp = get_video_mode(this_opt))) {
3040 mode_option = this_opt;
3041 }
else if (!
strcmp(this_opt,
"inverse"))
3043 else if (!
strncmp(this_opt,
"hwscroll_", 9)) {
3051 else if (!
strcmp(this_opt,
"mv300")) {
3052 external_bitspercol = 8;
3054 }
else if (!
strncmp(this_opt,
"external:", 9))
3055 atafb_setup_ext(this_opt + 9);
3057 else if (!
strncmp(this_opt,
"internal:", 9))
3058 atafb_setup_int(this_opt + 9);
3060 else if (!
strncmp(this_opt,
"eclock:", 7)) {
3063 fext.t = 1000000000 / fext.f;
3065 }
else if (!
strncmp(this_opt,
"monitorcap:", 11))
3066 atafb_setup_mcap(this_opt + 11);
3068 else if (!
strcmp(this_opt,
"keep"))
3070 else if (!
strncmp(this_opt,
"R", 1))
3071 atafb_setup_user(this_opt + 1);
3079 unsigned int defmode = 0;
3080 unsigned long mem_req;
3089 printk(
"atafb_init: start\n");
3096 if (external_addr) {
3097 printk(
"atafb_init: initializing external hw\n");
3106 printk(
"atafb_init: initializing TT hw\n");
3115 printk(
"atafb_init: initializing Falcon hw\n");
3116 fbhw = &falcon_switch;
3118 error =
request_irq(IRQ_AUTO_4, falcon_vbl_switcher,
3120 "framebuffer:modeswitch",
3121 falcon_vbl_switcher);
3131 printk(
"atafb_init: initializing ST/E hw\n");
3139 printk(
"Cannot determine video hardware; defaulting to ST(e)\n");
3143 panic(
"Cannot initialize video hardware");
3156 detected_mode = fbhw->detect();
3157 check_default_par(detected_mode);
3159 if (!external_addr) {
3161 mem_req = default_mem_req + ovsc_offset + ovsc_addlen;
3165 panic(
"Cannot allocate screen memory");
3166 memset(screen_base, 0, mem_req);
3169 real_screen_base = screen_base + ovsc_offset;
3170 screen_len = (mem_req - pad - ovsc_offset) &
PAGE_MASK;
3177 IOMAP_WRITETHROUGH);
3179 printk(
"atafb: screen_base %p real_screen_base %p screen_len %d\n",
3180 screen_base, real_screen_base, screen_len);
3188 if (external_vgaiobase)
3189 external_vgaiobase =
3190 (
unsigned long)
ioremap(external_vgaiobase, 0x10000);
3192 real_screen_base = external_addr;
3194 memset (screen_base, 0, external_len);
3199 fb_info.
fbops = &atafb_ops;
3201 do_fb_set_var(&atafb_predefined[
default_par - 1], 1);
3203 ata_get_par(¤t_par);
3204 fb_info.
par = ¤t_par;
3207 atafb_get_var(&fb_info.
var, &fb_info);
3216 fb_info.
var.bits_per_pixel)) {
3223 atafb_set_disp(&fb_info);
3228 printk(
"Determined %dx%d, depth %d\n",
3229 fb_info.
var.xres, fb_info.
var.yres, fb_info.
var.bits_per_pixel);
3230 if ((fb_info.
var.xres != fb_info.
var.xres_virtual) ||
3231 (fb_info.
var.yres != fb_info.
var.yres_virtual))
3232 printk(
" virtual %dx%d\n", fb_info.
var.xres_virtual,
3233 fb_info.
var.yres_virtual);
3237 if (external_addr) {
3239 external_addr =
NULL;
3241 if (external_vgaiobase) {
3242 iounmap((
void*)external_vgaiobase);
3243 external_vgaiobase = 0;
3252 printk(
"fb%d: frame buffer device, using %dK of video memory\n",
3253 fb_info.
node, screen_len >> 10);
3267 return atafb_deinit();