📄 atafb.c
字号:
640, 400, 640, 0, 0, 0, 1, 0, {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 }, { /* tt low */ 320, 480, 320, 0, 0, 0, 8, 0, {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 }, { /* tt mid */ 640, 480, 640, 0, 0, 0, 4, 0, {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 }, { /* tt high */ 1280, 960, 1280, 0, 0, 0, 1, 0, {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 }, { /* vga2 */ 640, 480, 640, 0, 0, 0, 1, 0, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 }, { /* vga4 */ 640, 480, 640, 0, 0, 0, 2, 0, {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 }, { /* vga16 */ 640, 480, 640, 0, 0, 0, 4, 0, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 }, { /* vga256 */ 640, 480, 640, 0, 0, 0, 8, 0, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 }, { /* falh2 */ 896, 608, 896, 0, 0, 0, 1, 0, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 }, { /* falh16 */ 896, 608, 896, 0, 0, 0, 4, 0, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },};static int num_atafb_predefined = ARRAY_SIZE(atafb_predefined);static struct fb_videomode atafb_modedb[] __initdata = { /* * Atari Video Modes * * If you change these, make sure to update DEFMODE_* as well! */ /* * ST/TT Video Modes */ { /* 320x200, 15 kHz, 60 Hz (ST low) */ "st-low", 60, 320, 200, 32000, 32, 16, 31, 14, 96, 4, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 640x200, 15 kHz, 60 Hz (ST medium) */ "st-mid", 60, 640, 200, 32000, 32, 16, 31, 14, 96, 4, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 640x400, 30.25 kHz, 63.5 Hz (ST high) */ "st-high", 63, 640, 400, 32000, 128, 0, 40, 14, 128, 4, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 320x480, 15 kHz, 60 Hz (TT low) */ "tt-low", 60, 320, 480, 31041, 120, 100, 8, 16, 140, 30, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 640x480, 29 kHz, 57 Hz (TT medium) */ "tt-mid", 60, 640, 480, 31041, 120, 100, 8, 16, 140, 30, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 1280x960, 29 kHz, 60 Hz (TT high) */ "tt-high", 57, 640, 960, 31041, 120, 100, 8, 16, 140, 30, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, /* * VGA Video Modes */ { /* 640x480, 31 kHz, 60 Hz (VGA) */ "vga", 63.5, 640, 480, 32000, 18, 42, 31, 11, 96, 3, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 640x400, 31 kHz, 70 Hz (VGA) */ "vga70", 70, 640, 400, 32000, 18, 42, 31, 11, 96, 3, FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, /* * Falcon HiRes Video Modes */ { /* 896x608, 31 kHz, 60 Hz (Falcon High) */ "falh", 60, 896, 608, 32000, 18, 42, 31, 1, 96,3, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP },};#define NUM_TOTAL_MODES ARRAY_SIZE(atafb_modedb)static char *mode_option __initdata = NULL; /* default modes */#define DEFMODE_TT 5 /* "tt-high" for TT */#define DEFMODE_F30 7 /* "vga70" for Falcon */#define DEFMODE_STE 2 /* "st-high" for ST/E */#define DEFMODE_EXT 6 /* "vga" for external */static int get_video_mode(char *vname){ char ***name_list; char **name; int i; name_list = fb_var_names; for (i = 0; i < num_atafb_predefined; i++) { name = *name_list++; if (!name || !*name) break; while (*name) { if (!strcmp(vname, *name)) return i + 1; name++; } } return 0;}/* ------------------- TT specific functions ---------------------- */#ifdef ATAFB_TTstatic int tt_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par){ int mode; strcpy(fix->id, "Atari Builtin"); fix->smem_start = (unsigned long)real_screen_base; fix->smem_len = screen_len; fix->type = FB_TYPE_INTERLEAVED_PLANES; fix->type_aux = 2; fix->visual = FB_VISUAL_PSEUDOCOLOR; mode = par->hw.tt.mode & TT_SHIFTER_MODEMASK; if (mode == TT_SHIFTER_TTHIGH || mode == TT_SHIFTER_STHIGH) { fix->type = FB_TYPE_PACKED_PIXELS; fix->type_aux = 0; if (mode == TT_SHIFTER_TTHIGH) fix->visual = FB_VISUAL_MONO01; } fix->xpanstep = 0; fix->ypanstep = 1; fix->ywrapstep = 0; fix->line_length = par->next_line; fix->accel = FB_ACCEL_ATARIBLITT; return 0;}static int tt_decode_var(struct fb_var_screeninfo *var, struct atafb_par *par){ int xres = var->xres; int yres = var->yres; int bpp = var->bits_per_pixel; int linelen; int yres_virtual = var->yres_virtual; if (mono_moni) { if (bpp > 1 || xres > sttt_xres * 2 || yres > tt_yres * 2) return -EINVAL; par->hw.tt.mode = TT_SHIFTER_TTHIGH; xres = sttt_xres * 2; yres = tt_yres * 2; bpp = 1; } else { if (bpp > 8 || xres > sttt_xres || yres > tt_yres) return -EINVAL; if (bpp > 4) { if (xres > sttt_xres / 2 || yres > tt_yres) return -EINVAL; par->hw.tt.mode = TT_SHIFTER_TTLOW; xres = sttt_xres / 2; yres = tt_yres; bpp = 8; } else if (bpp > 2) { if (xres > sttt_xres || yres > tt_yres) return -EINVAL; if (xres > sttt_xres / 2 || yres > st_yres / 2) { par->hw.tt.mode = TT_SHIFTER_TTMID; xres = sttt_xres; yres = tt_yres; bpp = 4; } else { par->hw.tt.mode = TT_SHIFTER_STLOW; xres = sttt_xres / 2; yres = st_yres / 2; bpp = 4; } } else if (bpp > 1) { if (xres > sttt_xres || yres > st_yres / 2) return -EINVAL; par->hw.tt.mode = TT_SHIFTER_STMID; xres = sttt_xres; yres = st_yres / 2; bpp = 2; } else if (var->xres > sttt_xres || var->yres > st_yres) { return -EINVAL; } else { par->hw.tt.mode = TT_SHIFTER_STHIGH; xres = sttt_xres; yres = st_yres; bpp = 1; } } if (yres_virtual <= 0) yres_virtual = 0; else if (yres_virtual < yres) yres_virtual = yres; if (var->sync & FB_SYNC_EXT) par->hw.tt.sync = 0; else par->hw.tt.sync = 1; linelen = xres * bpp / 8; if (yres_virtual * linelen > screen_len && screen_len) return -EINVAL; if (yres * linelen > screen_len && screen_len) return -EINVAL; if (var->yoffset + yres > yres_virtual && yres_virtual) return -EINVAL; par->yres_virtual = yres_virtual; par->screen_base = screen_base + var->yoffset * linelen; par->next_line = linelen; return 0;}static int tt_encode_var(struct fb_var_screeninfo *var, struct atafb_par *par){ int linelen; memset(var, 0, sizeof(struct fb_var_screeninfo)); var->red.offset = 0; var->red.length = 4; var->red.msb_right = 0; var->grayscale = 0; var->pixclock = 31041; var->left_margin = 120; /* these may be incorrect */ var->right_margin = 100; var->upper_margin = 8; var->lower_margin = 16; var->hsync_len = 140; var->vsync_len = 30; var->height = -1; var->width = -1; if (par->hw.tt.sync & 1) var->sync = 0; else var->sync = FB_SYNC_EXT; switch (par->hw.tt.mode & TT_SHIFTER_MODEMASK) { case TT_SHIFTER_STLOW: var->xres = sttt_xres / 2; var->xres_virtual = sttt_xres_virtual / 2; var->yres = st_yres / 2; var->bits_per_pixel = 4; break; case TT_SHIFTER_STMID: var->xres = sttt_xres; var->xres_virtual = sttt_xres_virtual; var->yres = st_yres / 2; var->bits_per_pixel = 2; break; case TT_SHIFTER_STHIGH: var->xres = sttt_xres; var->xres_virtual = sttt_xres_virtual; var->yres = st_yres; var->bits_per_pixel = 1; break; case TT_SHIFTER_TTLOW: var->xres = sttt_xres / 2; var->xres_virtual = sttt_xres_virtual / 2; var->yres = tt_yres; var->bits_per_pixel = 8; break; case TT_SHIFTER_TTMID: var->xres = sttt_xres; var->xres_virtual = sttt_xres_virtual; var->yres = tt_yres; var->bits_per_pixel = 4; break; case TT_SHIFTER_TTHIGH: var->red.length = 0; var->xres = sttt_xres * 2; var->xres_virtual = sttt_xres_virtual * 2; var->yres = tt_yres * 2; var->bits_per_pixel = 1; break; } var->blue = var->green = var->red; var->transp.offset = 0; var->transp.length = 0; var->transp.msb_right = 0; linelen = var->xres_virtual * var->bits_per_pixel / 8; if (!use_hwscroll) var->yres_virtual = var->yres; else if (screen_len) { if (par->yres_virtual) var->yres_virtual = par->yres_virtual; else /* yres_virtual == 0 means use maximum */ var->yres_virtual = screen_len / linelen; } else { if (hwscroll < 0) var->yres_virtual = 2 * var->yres; else var->yres_virtual = var->yres + hwscroll * 16; } var->xoffset = 0; if (screen_base) var->yoffset = (par->screen_base - screen_base) / linelen; else var->yoffset = 0; var->nonstd = 0; var->activate = 0; var->vmode = FB_VMODE_NONINTERLACED; return 0;}static void tt_get_par(struct atafb_par *par){ unsigned long addr; par->hw.tt.mode = shifter_tt.tt_shiftmode; par->hw.tt.sync = shifter.syncmode; addr = ((shifter.bas_hi & 0xff) << 16) | ((shifter.bas_md & 0xff) << 8) | ((shifter.bas_lo & 0xff)); par->screen_base = phys_to_virt(addr);}static void tt_set_par(struct atafb_par *par){ shifter_tt.tt_shiftmode = par->hw.tt.mode; shifter.syncmode = par->hw.tt.sync; /* only set screen_base if really necessary */ if (current_par.screen_base != par->screen_base) fbhw->set_screen_base(par->screen_base);}static int tt_setcolreg(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, unsigned int transp, struct fb_info *info){ if ((shifter_tt.tt_shiftmode & TT_SHIFTER_MODEMASK) == TT_SHIFTER_STHIGH) regno += 254; if (regno > 255) return 1; tt_palette[regno] = (((red >> 12) << 8) | ((green >> 12) << 4) | (blue >> 12)); if ((shifter_tt.tt_shiftmode & TT_SHIFTER_MODEMASK) == TT_SHIFTER_STHIGH && regno == 254) tt_palette[0] = 0; return 0;}static int tt_detect(void){ struct atafb_par par; /* Determine the connected monitor: The DMA sound must be * disabled before reading the MFP GPIP, because the Sound * Done Signal and the Monochrome Detect are XORed together! * * Even on a TT, we should look if there is a DMA sound. It was * announced that the Eagle is TT compatible, but only the PCM is * missing... */ if (ATARIHW_PRESENT(PCM_8BIT)) { tt_dmasnd.ctrl = DMASND_CTRL_OFF; udelay(20); /* wait a while for things to settle down */ } mono_moni = (st_mfp.par_dt_reg & 0x80) == 0; tt_get_par(&par); tt_encode_var(&atafb_predefined[0], &par); return 1;}#endif /* ATAFB_TT *//* ------------------- Falcon specific functions ---------------------- */#ifdef ATAFB_FALCONstatic int mon_type; /* Falcon connected monitor */static int f030_bus_width; /* Falcon ram bus width (for vid_control) */#define F_MON_SM 0#define F_MON_SC 1#define F_MON_VGA 2#define F_MON_TV 3static struct pixel_clock { unsigned long f; /* f/[Hz] */ unsigned long t; /* t/[ps] (=1/f) */ int right, hsync, left; /* standard timing in clock cycles, not pixel */ /* hsync initialized in falcon_detect() */ int sync_mask; /* or-mask for hw.falcon.sync to set this clock */ int control_mask; /* ditto, for hw.falcon.vid_control */} f25 = { 25175000, 39721, 18, 0, 42, 0x0, VCO_CLOCK25}, f32 = { 32000000, 31250, 18, 0, 42, 0x0, 0}, fext = { 0, 0, 18, 0, 42, 0x1, 0};/* VIDEL-prescale values [mon_type][pixel_length from VCO] */static int vdl_prescale[4][3] = { { 4,2,1 }, { 4,2,1 }, { 4,2,2 }, { 4,2,1 }};/* Default hsync timing [mon_type] in picoseconds */static long h_syncs[4] = { 3000000, 4875000, 4000000, 4875000 };static inline int hxx_prescale(struct falcon_hw *hw){ return hw->ste_mode ? 16 : vdl_prescale[mon_type][hw->vid_mode >> 2 & 0x3];}static int falcon_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par){ strcpy(fix->id, "Atari Builtin"); fix->smem_start = (unsigned long)real_screen_base; fix->smem_len = screen_len; fix->type = FB_TYPE_INTERLEAVED_PLANES; fix->type_aux = 2; fix->visual = FB_VISUAL_PSEUDOCOLOR; fix->xpanstep = 1; fix->ypanstep = 1; fix->ywrapstep = 0; if (par->hw.falcon.mono) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -