📄 clgenfb.c
字号:
_par->var.blue.offset = 0; } _par->var.red.length = 5; _par->var.green.length = 5; _par->var.blue.length = 5; break; case 24: _par->line_length = _par->var.xres_virtual * 3; _par->visual = FB_VISUAL_DIRECTCOLOR; if(isPReP) { _par->var.red.offset = 8; _par->var.green.offset = 16; _par->var.blue.offset = 24; } else { _par->var.red.offset = 16; _par->var.green.offset = 8; _par->var.blue.offset = 0; } _par->var.red.length = 8; _par->var.green.length = 8; _par->var.blue.length = 8; break; case 32: _par->line_length = _par->var.xres_virtual * 4; _par->visual = FB_VISUAL_DIRECTCOLOR; if(isPReP) { _par->var.red.offset = 8; _par->var.green.offset = 16; _par->var.blue.offset = 24; } else { _par->var.red.offset = 16; _par->var.green.offset = 8; _par->var.blue.offset = 0; } _par->var.red.length = 8; _par->var.green.length = 8; _par->var.blue.length = 8; break; default: DPRINTK("Unsupported bpp size: %d\n", _par->var.bits_per_pixel); assert (FALSE); /* should never occur */ break; } _par->var.red.msb_right = _par->var.green.msb_right = _par->var.blue.msb_right = _par->var.transp.offset = _par->var.transp.length = _par->var.transp.msb_right = 0; _par->type = FB_TYPE_PACKED_PIXELS; /* convert from ps to kHz */ freq = 1000000000 / var->pixclock; DPRINTK ("desired pixclock: %ld kHz\n", freq); if (IS_7548(fb_info)) maxclock = 80100; else maxclock = clgen_board_info[fb_info->btype].maxclock; _par->multiplexing = 0; /* If the frequency is greater than we can support, we might be able * to use multiplexing for the video mode */ if (freq > maxclock) { switch (fb_info->btype) { case BT_ALPINE: case BT_GD5480: _par->multiplexing = 1; break; default: printk (KERN_WARNING "clgen: ERROR: Frequency greater than maxclock (%ld kHz)\n", maxclock); DPRINTK ("EXIT - return -EINVAL\n"); return -EINVAL; } }#if 0 /* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where * the VCLK is double the pixel clock. */ switch (var->bits_per_pixel) { case 16: case 32: if (_par->HorizRes <= 800) freq /= 2; /* Xbh has this type of clock for 32-bit */ break; }#endif bestclock (freq, &_par->freq, &_par->nom, &_par->den, &_par->div, maxclock); _par->mclk = clgen_get_mclk (freq, _par->var.bits_per_pixel, &_par->divMCLK); xres = _par->var.xres; hfront = _par->var.right_margin; hsync = _par->var.hsync_len; hback = _par->var.left_margin; yres = _par->var.yres; vfront = _par->var.lower_margin; vsync = _par->var.vsync_len; vback = _par->var.upper_margin; if (_par->var.vmode & FB_VMODE_DOUBLE) { yres *= 2; vfront *= 2; vsync *= 2; vback *= 2; } else if (_par->var.vmode & FB_VMODE_INTERLACED) { yres = (yres + 1) / 2; vfront = (vfront + 1) / 2; vsync = (vsync + 1) / 2; vback = (vback + 1) / 2; } _par->HorizRes = xres; _par->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5; _par->HorizDispEnd = xres / 8 - 1; _par->HorizBlankStart = xres / 8; _par->HorizBlankEnd = _par->HorizTotal + 5; /* does not count with "-5" */ _par->HorizSyncStart = (xres + hfront) / 8 + 1; _par->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1; _par->VertRes = yres; _par->VertTotal = yres + vfront + vsync + vback - 2; _par->VertDispEnd = yres - 1; _par->VertBlankStart = yres; _par->VertBlankEnd = _par->VertTotal; _par->VertSyncStart = yres + vfront - 1; _par->VertSyncEnd = yres + vfront + vsync - 1; if (_par->VertRes >= 1024) { _par->VertTotal /= 2; _par->VertSyncStart /= 2; _par->VertSyncEnd /= 2; _par->VertDispEnd /= 2; } if (_par->multiplexing) { _par->HorizTotal /= 2; _par->HorizSyncStart /= 2; _par->HorizSyncEnd /= 2; _par->HorizDispEnd /= 2; } if (_par->VertRes >= 1280) { printk (KERN_WARNING "clgen: ERROR: VerticalTotal >= 1280; special treatment required! (TODO)\n"); DPRINTK ("EXIT - EINVAL error\n"); return -EINVAL; } DPRINTK ("EXIT\n"); return 0;}static int clgen_encode_var (struct fb_var_screeninfo *var, const void *par, struct fb_info_gen *info){ DPRINTK ("ENTER\n"); *var = ((struct clgenfb_par *) par)->var; DPRINTK ("EXIT\n"); return 0;}/* get current video mode */static void clgen_get_par (void *par, struct fb_info_gen *info){ struct clgenfb_par *_par = (struct clgenfb_par *) par; struct clgenfb_info *_info = (struct clgenfb_info *) info; DPRINTK ("ENTER\n"); *_par = _info->currentmode; DPRINTK ("EXIT\n");}static void clgen_set_mclk (const struct clgenfb_info *fb_info, int val, int div){ assert (fb_info != NULL); if (div == 2) { /* VCLK = MCLK/2 */ unsigned char old = vga_rseq (fb_info->regs, CL_SEQR1E); vga_wseq (fb_info->regs, CL_SEQR1E, old | 0x1); vga_wseq (fb_info->regs, CL_SEQR1F, 0x40 | (val & 0x3f)); } else if (div == 1) { /* VCLK = MCLK */ unsigned char old = vga_rseq (fb_info->regs, CL_SEQR1E); vga_wseq (fb_info->regs, CL_SEQR1E, old & ~0x1); vga_wseq (fb_info->regs, CL_SEQR1F, 0x40 | (val & 0x3f)); } else { vga_wseq (fb_info->regs, CL_SEQR1F, val & 0x3f); }}/************************************************************************* clgen_set_par() actually writes the values for a new video mode into the hardware,**************************************************************************/static void clgen_set_par (const void *par, struct fb_info_gen *info){ unsigned char tmp; int offset = 0; struct clgenfb_par *_par = (struct clgenfb_par *) par; struct clgenfb_info *fb_info = (struct clgenfb_info *) info; const struct clgen_board_info_rec *bi; DPRINTK ("ENTER\n"); DPRINTK ("Requested mode: %dx%dx%d\n", _par->var.xres, _par->var.yres, _par->var.bits_per_pixel); DPRINTK ("pixclock: %d\n", _par->var.pixclock); bi = &clgen_board_info[fb_info->btype]; /* unlock register VGA_CRTC_H_TOTAL..CRT7 */ vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */ /* if debugging is enabled, all parameters get output before writing */ DPRINTK ("CRT0: %ld\n", _par->HorizTotal); vga_wcrt (fb_info->regs, VGA_CRTC_H_TOTAL, _par->HorizTotal); DPRINTK ("CRT1: %ld\n", _par->HorizDispEnd); vga_wcrt (fb_info->regs, VGA_CRTC_H_DISP, _par->HorizDispEnd); DPRINTK ("CRT2: %ld\n", _par->HorizBlankStart); vga_wcrt (fb_info->regs, VGA_CRTC_H_BLANK_START, _par->HorizBlankStart); DPRINTK ("CRT3: 128+%ld\n", _par->HorizBlankEnd % 32); /* + 128: Compatible read */ vga_wcrt (fb_info->regs, VGA_CRTC_H_BLANK_END, 128 + (_par->HorizBlankEnd % 32)); DPRINTK ("CRT4: %ld\n", _par->HorizSyncStart); vga_wcrt (fb_info->regs, VGA_CRTC_H_SYNC_START, _par->HorizSyncStart); tmp = _par->HorizSyncEnd % 32; if (_par->HorizBlankEnd & 32) tmp += 128; DPRINTK ("CRT5: %d\n", tmp); vga_wcrt (fb_info->regs, VGA_CRTC_H_SYNC_END, tmp); DPRINTK ("CRT6: %ld\n", _par->VertTotal & 0xff); vga_wcrt (fb_info->regs, VGA_CRTC_V_TOTAL, (_par->VertTotal & 0xff)); tmp = 16; /* LineCompare bit #9 */ if (_par->VertTotal & 256) tmp |= 1; if (_par->VertDispEnd & 256) tmp |= 2; if (_par->VertSyncStart & 256) tmp |= 4; if (_par->VertBlankStart & 256) tmp |= 8; if (_par->VertTotal & 512) tmp |= 32; if (_par->VertDispEnd & 512) tmp |= 64; if (_par->VertSyncStart & 512) tmp |= 128; DPRINTK ("CRT7: %d\n", tmp); vga_wcrt (fb_info->regs, VGA_CRTC_OVERFLOW, tmp); tmp = 0x40; /* LineCompare bit #8 */ if (_par->VertBlankStart & 512) tmp |= 0x20; if (_par->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80; DPRINTK ("CRT9: %d\n", tmp); vga_wcrt (fb_info->regs, VGA_CRTC_MAX_SCAN, tmp); DPRINTK ("CRT10: %ld\n", _par->VertSyncStart & 0xff); vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_START, (_par->VertSyncStart & 0xff)); DPRINTK ("CRT11: 64+32+%ld\n", _par->VertSyncEnd % 16); vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, (_par->VertSyncEnd % 16 + 64 + 32)); DPRINTK ("CRT12: %ld\n", _par->VertDispEnd & 0xff); vga_wcrt (fb_info->regs, VGA_CRTC_V_DISP_END, (_par->VertDispEnd & 0xff)); DPRINTK ("CRT15: %ld\n", _par->VertBlankStart & 0xff); vga_wcrt (fb_info->regs, VGA_CRTC_V_BLANK_START, (_par->VertBlankStart & 0xff)); DPRINTK ("CRT16: %ld\n", _par->VertBlankEnd & 0xff); vga_wcrt (fb_info->regs, VGA_CRTC_V_BLANK_END, (_par->VertBlankEnd & 0xff)); DPRINTK ("CRT18: 0xff\n"); vga_wcrt (fb_info->regs, VGA_CRTC_LINE_COMPARE, 0xff); tmp = 0; if (_par->var.vmode & FB_VMODE_INTERLACED) tmp |= 1; if (_par->HorizBlankEnd & 64) tmp |= 16; if (_par->HorizBlankEnd & 128) tmp |= 32; if (_par->VertBlankEnd & 256) tmp |= 64; if (_par->VertBlankEnd & 512) tmp |= 128; DPRINTK ("CRT1a: %d\n", tmp); vga_wcrt (fb_info->regs, CL_CRT1A, tmp); /* set VCLK0 */ /* hardware RefClock: 14.31818 MHz */ /* formula: VClk = (OSC * N) / (D * (1+P)) */ /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */ vga_wseq (fb_info->regs, CL_SEQRB, _par->nom); tmp = _par->den << 1; if (_par->div != 0) tmp |= 1; if ((fb_info->btype == BT_SD64) || (fb_info->btype == BT_ALPINE) || (fb_info->btype == BT_GD5480)) tmp |= 0x80; /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */ DPRINTK ("CL_SEQR1B: %ld\n", (long) tmp); vga_wseq (fb_info->regs, CL_SEQR1B, tmp); if (_par->VertRes >= 1024) /* 1280x1024 */ vga_wcrt (fb_info->regs, VGA_CRTC_MODE, 0xc7); else /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit * address wrap, no compat. */ vga_wcrt (fb_info->regs, VGA_CRTC_MODE, 0xc3);/* HAEH? vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, 0x20); * previously: 0x00 unlock VGA_CRTC_H_TOTAL..CRT7 */ /* don't know if it would hurt to also program this if no interlaced */ /* mode is used, but I feel better this way.. :-) */ if (_par->var.vmode & FB_VMODE_INTERLACED) vga_wcrt (fb_info->regs, VGA_CRTC_REGS, _par->HorizTotal / 2); else vga_wcrt (fb_info->regs, VGA_CRTC_REGS, 0x00); /* interlace control */ vga_wseq (fb_info->regs, VGA_SEQ_CHARACTER_MAP, 0); /* adjust horizontal/vertical sync type (low/high) */ tmp = 0x03; /* enable display memory & CRTC I/O address for color mode */ if (_par->var.sync & FB_SYNC_HOR_HIGH_ACT) tmp |= 0x40; if (_par->var.sync & FB_SYNC_VERT_HIGH_ACT) tmp |= 0x80; WGen (fb_info, VGA_MIS_W, tmp); vga_wcrt (fb_info->regs, VGA_CRTC_PRESET_ROW, 0); /* Screen A Preset Row-Scan register */ vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_START, 0); /* text cursor on and start line */ vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_END, 31); /* text cursor end line */ /****************************************************** * * 1 bpp * */ /* programming for different color depths */ if (_par->var.bits_per_pixel == 1) { DPRINTK ("clgen: preparing for 1 bit deep display\n"); vga_wgfx (fb_info->regs, VGA_GFX_MODE, 0); /* mode register */ /* SR07 */ switch (fb_info->btype) { case BT_SD64: case BT_PICCOLO: case BT_PICASSO: case BT_SPECTRUM: case BT_PICASSO4: case BT_ALPINE: case BT_GD5480: DPRINTK (" (for GD54xx)\n"); vga_wseq (fb_info->regs, CL_SEQR7, _par->multiplexing ? bi->sr07_1bpp_mux : bi->sr07_1bpp); break; case BT_LAGUNA: DPRINTK (" (for GD546x)\n"); vga_wseq (fb_info->regs, CL_SEQR7, vga_rseq (fb_info->regs, CL_SEQR7) & ~0x01); break; default: printk (KERN_WARNING "clgen: unknown Board\n"); break; } /* Extended Sequencer Mode */ switch (fb_info->btype) { case BT_SD64: /* setting the SEQRF on SD64 is not necessary (only during init) */ DPRINTK ("(for SD64)\n"); vga_wseq (fb_info->regs, CL_SEQR1F, 0x1a); /* MCLK select */ break; case BT_PICCOLO: DPRINTK ("(for Piccolo)\n");/* ### ueberall 0x22? */ vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* ##vorher 1c MCLK select */ vga_wseq (fb_info->regs, CL_SEQRF, 0xb0); /* evtl d0 bei 1 bit? avoid FIFO underruns..? */ break; case BT_PICASSO: DPRINTK ("(for Picasso)\n"); vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* ##vorher 22 MCLK select */ vga_wseq (fb_info->regs, CL_SEQRF, 0xd0); /* ## vorher d0 avoid FIFO underruns..? */ break; case BT_SPECTRUM: DPRINTK ("(for Spectrum)\n");/* ### ueberall 0x22? */ vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* ##vorher 1c MCLK select */ vga_wseq (fb_info->regs, CL_SEQRF, 0xb0); /* evtl d0? avoid FIFO underruns..? */ break; case BT_PICASSO4: case BT_ALPINE: case BT_GD5480: case BT_LAGUNA: DPRINTK (" (for GD54xx)\n"); /* do nothing */ break; default: printk (KERN_WARNING "clgen: unknown Board\n"); break; } WGen (fb_info, VGA_PEL_MSK, 0x01); /* pixel mask: pass-through for first plane */ if (_par->multiplexing) WHDR (fb_info, 0x4a); /* hidden dac reg: 1280x1024 */ else WHDR (fb_info, 0); /* hidden dac: nothing */ vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x06); /* memory mode: odd/even, ext. memory */ vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0x01); /* plane mask: only write to first plane */ offset = _par->var.xres_virtual / 16; } /****************************************************** * * 8 bpp * */ else if (_par->var.bits_per_pixel == 8) { DPRINTK ("clgen: preparing for 8 bit deep display\n"); switch (fb_info->btype) { case BT_SD64: case BT_PICCOLO: case BT_PICASSO:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -