📄 fbdev.c
字号:
/* Do we have to save the colormap? */ cmap = &(rivainfo->currcon_display->cmap); DPRINTK ("switch1: con = %d, cmap.len = %d\n", rivainfo->currcon, cmap->len); if (cmap->len) { DPRINTK ("switch1a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp); fb_get_cmap (cmap, 1, riva_getcolreg, info);#ifdef DEBUG if (cmap->red) { DPRINTK ("switch1r: %X\n", cmap->red[0]); }#endif } } rivainfo->currcon = con; rivainfo->currcon_display = dsp; dsp->var.activate = FB_ACTIVATE_NOW;#ifdef riva_DEBUG cmap = &dsp->cmap; DPRINTK ("switch2: con = %d, cmap.len = %d\n", con, cmap->len); DPRINTK ("switch2a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp); if (dsp->cmap.red) { DPRINTK ("switch2r: %X\n", cmap->red[0]); }#endif rivafb_set_var (&dsp->var, con, info);#ifdef riva_DEBUG DPRINTK ("switch3: con = %d, cmap.len = %d\n", con, cmap->len); DPRINTK ("switch3a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp); if (dsp->cmap.red) { DPRINTK ("switch3r: %X\n", cmap->red[0]); }#endif DPRINTK ("EXIT, returning 0\n"); return 0;}static int rivafb_updatevar (int con, struct fb_info *info){ int rc; DPRINTK ("ENTER\n"); rc = (con < 0) ? -EINVAL : rivafb_pan_display (&fb_display[con].var, con, info); DPRINTK ("EXIT, returning %d\n", rc); return rc;}static void rivafb_blank (int blank, struct fb_info *info){ unsigned char tmp; struct rivafb_info *rivainfo = (struct rivafb_info *) info; DPRINTK ("ENTER\n"); assert (rivainfo != NULL); tmp = vga_io_rseq (VGA_SEQ_CLOCK_MODE) & ~VGA_SR01_SCREEN_OFF; if (blank) tmp |= VGA_SR01_SCREEN_OFF; vga_io_wseq (VGA_SEQ_CLOCK_MODE, tmp); DPRINTK ("EXIT\n");}/* ------------------------------------------------------------------------- * * internal fb_ops helper functions * * ------------------------------------------------------------------------- *//** * riva_get_cmap_len * @var: * * DESCRIPTION: */static int riva_get_cmap_len (const struct fb_var_screeninfo *var){ int rc = 16; /* reasonable default */ assert (var != NULL); switch (var->bits_per_pixel) {#ifdef FBCON_HAS_CFB4 case 4: rc = 16; /* pseudocolor... 16 entries HW palette */ break;#endif#ifdef FBCON_HAS_CFB8 case 8: rc = 256; /* pseudocolor... 256 entries HW palette */ break;#endif#ifdef FBCON_HAS_CFB16 case 16: rc = 16; /* directcolor... 16 entries SW palette */ break; /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */#endif#ifdef FBCON_HAS_CFB32 case 32: rc = 16; /* directcolor... 16 entries SW palette */ break; /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */#endif default: assert (0); /* should not occur */ break; } return rc;}/** * riva_getcolreg * @regno: * @red: * @green: * @blue: * @transp: * @info: pointer to rivafb_info object containing info for current riva board * * DESCRIPTION: * Read a single color register and split it into colors/transparent. * The return values must have a 16 bit magnitude. * Return != 0 for invalid regno. * * CALLED FROM: * fbcmap.c:fb_get_cmap() * fbgen.c:fbgen_get_cmap() * fbgen.c:fbgen_switch() */static int riva_getcolreg (unsigned regno, unsigned *red, unsigned *green, unsigned *blue, unsigned *transp, struct fb_info *info){ struct rivafb_info *rivainfo = (struct rivafb_info *) info; if (regno >= riva_get_cmap_len(&rivainfo->currcon_display->var)) return 1; *red = rivainfo->palette[regno].red; *green = rivainfo->palette[regno].green; *blue = rivainfo->palette[regno].blue; *transp = 0; return 0;}/** * riva_setcolreg * @regno: * @red: * @green: * @blue: * @transp: * @info: pointer to rivafb_info object containing info for current riva board * * DESCRIPTION: * Set a single color register. The values supplied have a 16 bit * magnitude. * Return != 0 for invalid regno. * * CALLED FROM: * fbcmap.c:fb_set_cmap() * fbgen.c:fbgen_get_cmap() * fbgen.c:fbgen_install_cmap() * fbgen.c:fbgen_set_var() * fbgen.c:fbgen_switch() * fbgen.c:fbgen_blank() * fbgen.c:fbgen_blank() */static int riva_setcolreg (unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info){ struct rivafb_info *rivainfo = (struct rivafb_info *) info; struct display *p; unsigned shift = 8; DPRINTK ("ENTER\n"); assert (rivainfo != NULL); assert (rivainfo->currcon_display != NULL); p = rivainfo->currcon_display; if (regno >= riva_get_cmap_len(&p->var)) return -EINVAL; rivainfo->palette[regno].red = red; rivainfo->palette[regno].green = green; rivainfo->palette[regno].blue = blue; if (p->var.grayscale) { /* gray = 0.30*R + 0.59*G + 0.11*B */ red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; } switch (rivainfo->riva.Architecture) { case 3: shift = 10; break; case 4: case 5: shift = 8; break; } switch (p->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8 case 8: /* "transparent" stuff is completely ignored. */ riva_wclut (regno, red >> shift, green >> shift, blue >> shift); break;#endif /* FBCON_HAS_CFB8 */#ifdef FBCON_HAS_CFB16 case 16: assert (regno < 16);#ifdef CONFIG_PREP rivainfo->con_cmap.cfb16[regno] = ((red & 0xf800) >> 9) | ((green & 0xf800) >> 14) | ((green & 0xf800) << 2) | ((blue & 0xf800) >> 3);#else rivainfo->con_cmap.cfb16[regno] = ((red & 0xf800) >> 1) | ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11);#endif break;#endif /* FBCON_HAS_CFB16 */#ifdef FBCON_HAS_CFB32 case 32: assert (regno < 16);#ifdef CONFIG_PREP rivainfo->con_cmap.cfb32[regno] = ((red & 0xff00)) | ((green & 0xff00) << 8) | ((blue & 0xff00) << 16);#else rivainfo->con_cmap.cfb32[regno] = ((red & 0xff00) << 8) | ((green & 0xff00)) | ((blue & 0xff00) >> 8);#endif break;#endif /* FBCON_HAS_CFB32 */ default: /* do nothing */ break; } return 0;}/* * riva_load_video_mode() * * calculate some timings and then send em off to riva_load_state() */static void riva_load_video_mode (struct rivafb_info *rinfo, struct fb_var_screeninfo *video_mode){ struct riva_regs newmode; int bpp, width, hDisplaySize, hDisplay, hStart, hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock; /* time to calculate */ bpp = video_mode->bits_per_pixel; width = hDisplaySize = video_mode->xres; hDisplay = (hDisplaySize / 8) - 1; hStart = (hDisplaySize + video_mode->right_margin) / 8 + 2; hEnd = (hDisplaySize + video_mode->right_margin + video_mode->hsync_len) / 8 - 1; hTotal = (hDisplaySize + video_mode->right_margin + video_mode->hsync_len + video_mode->left_margin) / 8 - 1; height = video_mode->yres; vDisplay = video_mode->yres - 1; vStart = video_mode->yres + video_mode->lower_margin - 1; vEnd = video_mode->yres + video_mode->lower_margin + video_mode->vsync_len - 1; vTotal = video_mode->yres + video_mode->lower_margin + video_mode->vsync_len + video_mode->upper_margin + 2; dotClock = 1000000000 / video_mode->pixclock; memcpy (&newmode, ®_template, sizeof (struct riva_regs)); newmode.crtc[0x0] = Set8Bits (hTotal - 4); newmode.crtc[0x1] = Set8Bits (hDisplay); newmode.crtc[0x2] = Set8Bits (hDisplay); newmode.crtc[0x3] = SetBitField (hTotal, 4: 0, 4:0) | SetBit (7); newmode.crtc[0x4] = Set8Bits (hStart); newmode.crtc[0x5] = SetBitField (hTotal, 5: 5, 7:7) | SetBitField (hEnd, 4: 0, 4:0); newmode.crtc[0x6] = SetBitField (vTotal, 7: 0, 7:0); newmode.crtc[0x7] = SetBitField (vTotal, 8: 8, 0:0) | SetBitField (vDisplay, 8: 8, 1:1) | SetBitField (vStart, 8: 8, 2:2) | SetBitField (vDisplay, 8: 8, 3:3) | SetBit (4) | SetBitField (vTotal, 9: 9, 5:5) | SetBitField (vDisplay, 9: 9, 6:6) | SetBitField (vStart, 9: 9, 7:7); newmode.crtc[0x9] = SetBitField (vDisplay, 9: 9, 5:5) | SetBit (6); newmode.crtc[0x10] = Set8Bits (vStart); newmode.crtc[0x11] = SetBitField (vEnd, 3: 0, 3:0) | SetBit (5); newmode.crtc[0x12] = Set8Bits (vDisplay); newmode.crtc[0x13] = ((width / 8) * (bpp / 8)) & 0xFF; newmode.crtc[0x15] = Set8Bits (vDisplay); newmode.crtc[0x16] = Set8Bits (vTotal + 1); newmode.ext.bpp = bpp; newmode.ext.width = width; newmode.ext.height = height; rinfo->riva.CalcStateExt (&rinfo->riva, &newmode.ext, bpp, width, hDisplaySize, hDisplay, hStart, hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock); rinfo->initial_state = newmode; riva_load_state (rinfo, &newmode);}/* ------------------------------------------------------------------------- */ /* * Modularization */static struct pci_driver rivafb_driver = { name: "rivafb", id_table: rivafb_pci_tbl, probe: rivafb_init_one, remove: rivafb_remove_one,};int __init rivafb_init (void){ return pci_module_init (&rivafb_driver);}static void __exit rivafb_exit (void){ pci_unregister_driver (&rivafb_driver);}#ifdef MODULEmodule_init(rivafb_init);#endif /* MODULE */module_exit(rivafb_exit);MODULE_AUTHOR("Ani Joshi, maintainer");MODULE_DESCRIPTION("Framebuffer driver for nVidia Riva 128, TNT, TNT2");/* from GGI */static void riva_save_state (struct rivafb_info *rinfo, struct riva_regs *regs){ int i; outb (rinfo->riva.LockUnlockIndex, rinfo->riva.LockUnlockIO); outb (0x57, rinfo->riva.LockUnlockIO + 1); rinfo->riva.UnloadStateExt (&rinfo->riva, ®s->ext); regs->misc_output = io_in8 (0x3CC); for (i = 0; i < NUM_CRT_REGS; i++) { io_out8 (i, 0x3D4); regs->crtc[i] = io_in8 (0x3D5); } for (i = 0; i < NUM_ATC_REGS; i++) { io_out8 (i, 0x3C0); regs->attr[i] = io_in8 (0x3C1); } for (i = 0; i < NUM_GRC_REGS; i++) { io_out8 (i, 0x3CE); regs->gra[i] = io_in8 (0x3CF); } for (i = 0; i < NUM_SEQ_REGS; i++) { io_out8 (i, 0x3C4); regs->seq[i] = io_in8 (0x3C5); }}/* from GGI */staticvoid riva_load_state (struct rivafb_info *rinfo, struct riva_regs *regs){ int i; RIVA_HW_STATE *state = ®s->ext; io_out8 (0x11, 0x3D4); io_out8 (0x00, 0x3D5); outb (rinfo->riva.LockUnlockIndex, rinfo->riva.LockUnlockIO); outb (0x57, rinfo->riva.LockUnlockIO + 1); rinfo->riva.LoadStateExt (&rinfo->riva, state); io_out8 (regs->misc_output, 0x3C2); for (i = 0; i < NUM_CRT_REGS; i++) { if (i < 0x19) { io_out8 (i, 0x3D4); io_out8 (regs->crtc[i], 0x3D5); } else { switch (i) { case 0x19: case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: case 0x40: break; default: io_out8 (i, 0x3D4); io_out8 (regs->crtc[i], 0x3D5); } } } for (i = 0; i < NUM_ATC_REGS; i++) { io_out8 (i, 0x3C0); io_out8 (regs->attr[i], 0x3C0); } for (i = 0; i < NUM_GRC_REGS; i++) { io_out8 (i, 0x3CE); io_out8 (regs->gra[i], 0x3CF); } for (i = 0; i < NUM_SEQ_REGS; i++) { io_out8 (i, 0x3C4); io_out8 (regs->seq[i], 0x3C5); }}/** * riva_board_list_add * @board_list: Root node of list of boards * @new_node: New node to be added * * DESCRIPTION: * Adds @new_node to the list referenced by @board_list * * RETURNS: * New root node */staticstruct rivafb_info *riva_board_list_add (struct rivafb_info *board_list, struct rivafb_info *new_node){ struct rivafb_info *i_p = board_list; new_node->next = NULL; if (board_list == NULL) return new_node; while (i_p->next != NULL) i_p = i_p->next; i_p->next = new_node; return board_list;}/** * riva_board_list_del * @board_list: Root node of list of boards * @del_node: Node to be removed * * DESCRIPTION: * Removes @del_node from the list referenced by @board_list * * RETURNS: * New root node */staticstruct rivafb_info *riva_board_list_del (struct rivafb_info *board_list, struct rivafb_info *del_node){ struct rivafb_info *i_p = board_list; if (board_list == del_node) return del_node->next; while (i_p->next != del_node) i_p = i_p->next; i_p->next = del_node->next; return board_list;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -