📄 cirrusfb.c
字号:
break; case BT_PICASSO: DPRINTK("(for Picasso)\n"); /* ##vorher 22 MCLK select */ vga_wseq(regbase, CL_SEQR1F, 0x22); /* ## vorher d0 avoid FIFO underruns..? */ vga_wseq(regbase, CL_SEQRF, 0xd0); break; case BT_PICASSO4: case BT_ALPINE: case BT_GD5480: case BT_LAGUNA: DPRINTK(" (for GD54xx)\n"); /* do nothing */ break; default: printk(KERN_WARNING "cirrusfb: unknown Board\n"); break; } /* pixel mask: pass-through for first plane */ WGen(cinfo, VGA_PEL_MSK, 0x01); if (regs.multiplexing) /* hidden dac reg: 1280x1024 */ WHDR(cinfo, 0x4a); else /* hidden dac: nothing */ WHDR(cinfo, 0); /* memory mode: odd/even, ext. memory */ vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06); /* plane mask: only write to first plane */ vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01); offset = var->xres_virtual / 16; } /****************************************************** * * 8 bpp * */ else if (var->bits_per_pixel == 8) { DPRINTK("cirrusfb: preparing for 8 bit deep display\n"); switch (cinfo->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(regbase, CL_SEQR7, regs.multiplexing ? bi->sr07_8bpp_mux : bi->sr07_8bpp); break; case BT_LAGUNA: DPRINTK(" (for GD546x)\n"); vga_wseq(regbase, CL_SEQR7, vga_rseq(regbase, CL_SEQR7) | 0x01); break; default: printk(KERN_WARNING "cirrusfb: unknown Board\n"); break; } switch (cinfo->btype) { case BT_SD64: /* MCLK select */ vga_wseq(regbase, CL_SEQR1F, 0x1d); break; case BT_PICCOLO: case BT_PICASSO: case BT_SPECTRUM: /* ### vorher 1c MCLK select */ vga_wseq(regbase, CL_SEQR1F, 0x22); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); break; case BT_PICASSO4:#ifdef CONFIG_ZORRO /* ### INCOMPLETE!! */ vga_wseq(regbase, CL_SEQRF, 0xb8);#endif/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */ break; case BT_ALPINE: DPRINTK(" (for GD543x)\n"); /* We already set SRF and SR1F */ break; case BT_GD5480: case BT_LAGUNA: DPRINTK(" (for GD54xx)\n"); /* do nothing */ break; default: printk(KERN_WARNING "cirrusfb: unknown Board\n"); break; } /* mode register: 256 color mode */ vga_wgfx(regbase, VGA_GFX_MODE, 64); /* pixel mask: pass-through all planes */ WGen(cinfo, VGA_PEL_MSK, 0xff); if (regs.multiplexing) /* hidden dac reg: 1280x1024 */ WHDR(cinfo, 0x4a); else /* hidden dac: nothing */ WHDR(cinfo, 0); /* memory mode: chain4, ext. memory */ vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a); /* plane mask: enable writing to all 4 planes */ vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff); offset = var->xres_virtual / 8; } /****************************************************** * * 16 bpp * */ else if (var->bits_per_pixel == 16) { DPRINTK("cirrusfb: preparing for 16 bit deep display\n"); switch (cinfo->btype) { case BT_SD64: /* Extended Sequencer Mode: 256c col. mode */ vga_wseq(regbase, CL_SEQR7, 0xf7); /* MCLK select */ vga_wseq(regbase, CL_SEQR1F, 0x1e); break; case BT_PICCOLO: case BT_SPECTRUM: vga_wseq(regbase, CL_SEQR7, 0x87); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); /* MCLK select */ vga_wseq(regbase, CL_SEQR1F, 0x22); break; case BT_PICASSO: vga_wseq(regbase, CL_SEQR7, 0x27); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); /* MCLK select */ vga_wseq(regbase, CL_SEQR1F, 0x22); break; case BT_PICASSO4: vga_wseq(regbase, CL_SEQR7, 0x27);/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */ break; case BT_ALPINE: DPRINTK(" (for GD543x)\n"); vga_wseq(regbase, CL_SEQR7, 0xa7); break; case BT_GD5480: DPRINTK(" (for GD5480)\n"); vga_wseq(regbase, CL_SEQR7, 0x17); /* We already set SRF and SR1F */ break; case BT_LAGUNA: DPRINTK(" (for GD546x)\n"); vga_wseq(regbase, CL_SEQR7, vga_rseq(regbase, CL_SEQR7) & ~0x01); break; default: printk(KERN_WARNING "CIRRUSFB: unknown Board\n"); break; } /* mode register: 256 color mode */ vga_wgfx(regbase, VGA_GFX_MODE, 64); /* pixel mask: pass-through all planes */ WGen(cinfo, VGA_PEL_MSK, 0xff);#ifdef CONFIG_PCI WHDR(cinfo, 0xc0); /* Copy Xbh */#elif defined(CONFIG_ZORRO) /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */ WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */#endif /* memory mode: chain4, ext. memory */ vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a); /* plane mask: enable writing to all 4 planes */ vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff); offset = var->xres_virtual / 4; } /****************************************************** * * 32 bpp * */ else if (var->bits_per_pixel == 32) { DPRINTK("cirrusfb: preparing for 32 bit deep display\n"); switch (cinfo->btype) { case BT_SD64: /* Extended Sequencer Mode: 256c col. mode */ vga_wseq(regbase, CL_SEQR7, 0xf9); /* MCLK select */ vga_wseq(regbase, CL_SEQR1F, 0x1e); break; case BT_PICCOLO: case BT_SPECTRUM: vga_wseq(regbase, CL_SEQR7, 0x85); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); /* MCLK select */ vga_wseq(regbase, CL_SEQR1F, 0x22); break; case BT_PICASSO: vga_wseq(regbase, CL_SEQR7, 0x25); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); /* MCLK select */ vga_wseq(regbase, CL_SEQR1F, 0x22); break; case BT_PICASSO4: vga_wseq(regbase, CL_SEQR7, 0x25);/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */ break; case BT_ALPINE: DPRINTK(" (for GD543x)\n"); vga_wseq(regbase, CL_SEQR7, 0xa9); break; case BT_GD5480: DPRINTK(" (for GD5480)\n"); vga_wseq(regbase, CL_SEQR7, 0x19); /* We already set SRF and SR1F */ break; case BT_LAGUNA: DPRINTK(" (for GD546x)\n"); vga_wseq(regbase, CL_SEQR7, vga_rseq(regbase, CL_SEQR7) & ~0x01); break; default: printk(KERN_WARNING "cirrusfb: unknown Board\n"); break; } /* mode register: 256 color mode */ vga_wgfx(regbase, VGA_GFX_MODE, 64); /* pixel mask: pass-through all planes */ WGen(cinfo, VGA_PEL_MSK, 0xff); /* hidden dac reg: 8-8-8 mode (24 or 32) */ WHDR(cinfo, 0xc5); /* memory mode: chain4, ext. memory */ vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a); /* plane mask: enable writing to all 4 planes */ vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff); offset = var->xres_virtual / 4; } /****************************************************** * * unknown/unsupported bpp * */ else printk(KERN_ERR "cirrusfb: What's this?? " " requested color depth == %d.\n", var->bits_per_pixel); vga_wcrt(regbase, VGA_CRTC_OFFSET, offset & 0xff); tmp = 0x22; if (offset & 0x100) tmp |= 0x10; /* offset overflow bit */ /* screen start addr #16-18, fastpagemode cycles */ vga_wcrt(regbase, CL_CRT1B, tmp); if (cinfo->btype == BT_SD64 || cinfo->btype == BT_PICASSO4 || cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) /* screen start address bit 19 */ vga_wcrt(regbase, CL_CRT1D, 0x00); /* text cursor location high */ vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0); /* text cursor location low */ vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0); /* underline row scanline = at very bottom */ vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0); /* controller mode */ vga_wattr(regbase, VGA_ATC_MODE, 1); /* overscan (border) color */ vga_wattr(regbase, VGA_ATC_OVERSCAN, 0); /* color plane enable */ vga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 15); /* pixel panning */ vga_wattr(regbase, CL_AR33, 0); /* color select */ vga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0); /* [ EGS: SetOffset(); ] */ /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */ AttrOn(cinfo); /* set/reset register */ vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0); /* set/reset enable */ vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0); /* color compare */ vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0); /* data rotate */ vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0); /* read map select */ vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0); /* miscellaneous register */ vga_wgfx(regbase, VGA_GFX_MISC, 1); /* color don't care */ vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 15); /* bit mask */ vga_wgfx(regbase, VGA_GFX_BIT_MASK, 255); /* graphics cursor attributes: nothing special */ vga_wseq(regbase, CL_SEQR12, 0x0); /* finally, turn on everything - turn off "FullBandwidth" bit */ /* also, set "DotClock%2" bit where requested */ tmp = 0x01;/*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ? if (var->vmode & FB_VMODE_CLOCK_HALVE) tmp |= 0x08;*/ vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp); DPRINTK("CL_SEQR1: %d\n", tmp); cinfo->currentmode = regs; /* pan to requested offset */ cirrusfb_pan_display(var, info);#ifdef CIRRUSFB_DEBUG cirrusfb_dump();#endif DPRINTK("EXIT\n"); return 0;}/* for some reason incomprehensible to me, cirrusfb requires that you write * the registers twice for the settings to take..grr. -dte */static int cirrusfb_set_par(struct fb_info *info){ cirrusfb_set_par_foo(info); return cirrusfb_set_par_foo(info);}static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info){ struct cirrusfb_info *cinfo = info->par; if (regno > 255) return -EINVAL; if (info->fix.visual == FB_VISUAL_TRUECOLOR) { u32 v; red >>= (16 - info->var.red.length); green >>= (16 - info->var.green.length); blue >>= (16 - info->var.blue.length); if (regno >= 16) return 1; v = (red << info->var.red.offset) | (green << info->var.green.offset) | (blue << info->var.blue.offset); cinfo->pseudo_palette[regno] = v; return 0; } if (info->var.bits_per_pixel == 8) WClut(cinfo, regno, red >> 10, green >> 10, blue >> 10); return 0;}/************************************************************************* cirrusfb_pan_display() performs display panning - provided hardware permits this**************************************************************************/static int cirrusfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info){ int xoffset = 0; int yoffset = 0; unsigned long base; unsigned char tmp = 0, tmp2 = 0, xpix; struct cirrusfb_info *cinfo = info->par; DPRINTK("ENTER\n"); DPRINTK("virtual offset: (%d,%d)\n", var->xoffset, var->yoffset); /* no range checks for xoffset and yoffset, */ /* as fb_pan_display has already done this */ if (var->vmode & FB_VMODE_YWRAP) return -EINVAL; info->var.xoffset = var->xoffset; info->var.yoffset = var->yoffset; xoffset = var->xoffset * info->var.bits_per_pixel / 8; yoffset = var->yoffset; base = yoffset * info->fix.line_length + xoffset; if (info->var.bits_per_pixel == 1) { /* base is already correct */ xpix = (unsigned char) (var->xoffset % 8); } else { base /= 4; xpix = (unsigned char) ((xoffset % 4) * 2); } cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */ /* lower 8 + 8 bits of screen start address */ vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, (unsigned char) (base & 0xff)); vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, (unsigned char) (base >> 8)); /* construct bits 16, 17 and 18 of screen start address */ if (base & 0x10000) tmp |= 0x01; if (base & 0x20000) tmp |= 0x04; if (base & 0x40000) tmp |= 0x08; /* 0xf2 is %11110010, exclude tmp bits */ tmp2 = (vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2) | tmp; vga_wcrt(cinfo->regbase, CL_CRT1B, tmp2); /* construct bit 19 of screen start address */ if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80); /* write pixel panning value to AR33; this does not quite work in 8bpp * * ### Piccolo..? Will this work? */ if (info->var.bits_per_pixel == 1) vga_wattr(cinfo->regbase, CL_AR33, xpix); cirrusfb_WaitBLT(cinfo->regbase); DPRINTK("EXIT\n"); return 0;}static int cirrusfb_blank(int blank_mode, struct fb_info *info){ /* * Blank the screen if blank_mode != 0, else unblank. If blank == NULL * then the caller blanks by setting the CLUT (Color Look Up Table) * to all black. Return 0 if blanking succeeded, != 0 if un-/blanking * failed due to e.g. a video mode which doesn't support it. * Implements VESA suspend and powerdown modes on hardware that * supports disabling hsync/vsync: * blank_mode == 2: suspend vsync * blank_mode == 3: suspend hsync * blank_mode == 4: powerdown */ unsigned char val; struct cirrusfb_info *cinfo = info->par; int current_mode = cinfo->blank_mode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -