⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cirrusfb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	DPRINTK("ENTER, blank mode = %d\n", blank_mode);	if (info->state != FBINFO_STATE_RUNNING ||	    current_mode == blank_mode) {		DPRINTK("EXIT, returning 0\n");		return 0;	}	/* Undo current */	if (current_mode == FB_BLANK_NORMAL ||	    current_mode == FB_BLANK_UNBLANK) {		/* unblank the screen */		val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);		/* clear "FullBandwidth" bit */		vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf);		/* and undo VESA suspend trickery */		vga_wgfx(cinfo->regbase, CL_GRE, 0x00);	}	/* set new */	if (blank_mode > FB_BLANK_NORMAL) {		/* blank the screen */		val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);		/* set "FullBandwidth" bit */		vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20);	}	switch (blank_mode) {	case FB_BLANK_UNBLANK:	case FB_BLANK_NORMAL:		break;	case FB_BLANK_VSYNC_SUSPEND:		vga_wgfx(cinfo->regbase, CL_GRE, 0x04);		break;	case FB_BLANK_HSYNC_SUSPEND:		vga_wgfx(cinfo->regbase, CL_GRE, 0x02);		break;	case FB_BLANK_POWERDOWN:		vga_wgfx(cinfo->regbase, CL_GRE, 0x06);		break;	default:		DPRINTK("EXIT, returning 1\n");		return 1;	}	cinfo->blank_mode = blank_mode;	DPRINTK("EXIT, returning 0\n");	/* Let fbcon do a soft blank for us */	return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;}/**** END   Hardware specific Routines **************************************//****************************************************************************//**** BEGIN Internal Routines ***********************************************/static void init_vgachip(struct fb_info *info){	struct cirrusfb_info *cinfo = info->par;	const struct cirrusfb_board_info_rec *bi;	DPRINTK("ENTER\n");	assert(cinfo != NULL);	bi = &cirrusfb_board_info[cinfo->btype];	/* reset board globally */	switch (cinfo->btype) {	case BT_PICCOLO:		WSFR(cinfo, 0x01);		udelay(500);		WSFR(cinfo, 0x51);		udelay(500);		break;	case BT_PICASSO:		WSFR2(cinfo, 0xff);		udelay(500);		break;	case BT_SD64:	case BT_SPECTRUM:		WSFR(cinfo, 0x1f);		udelay(500);		WSFR(cinfo, 0x4f);		udelay(500);		break;	case BT_PICASSO4:		/* disable flickerfixer */		vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);		mdelay(100);		/* from Klaus' NetBSD driver: */		vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);		/* put blitter into 542x compat */		vga_wgfx(cinfo->regbase, CL_GR33, 0x00);		/* mode */		vga_wgfx(cinfo->regbase, CL_GR31, 0x00);		break;	case BT_GD5480:		/* from Klaus' NetBSD driver: */		vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);		break;	case BT_ALPINE:		/* Nothing to do to reset the board. */		break;	default:		printk(KERN_ERR "cirrusfb: Warning: Unknown board type\n");		break;	}	/* make sure RAM size set by this point */	assert(info->screen_size > 0);	/* the P4 is not fully initialized here; I rely on it having been */	/* inited under AmigaOS already, which seems to work just fine    */	/* (Klaus advised to do it this way)			      */	if (cinfo->btype != BT_PICASSO4) {		WGen(cinfo, CL_VSSM, 0x10);	/* EGS: 0x16 */		WGen(cinfo, CL_POS102, 0x01);		WGen(cinfo, CL_VSSM, 0x08);	/* EGS: 0x0e */		if (cinfo->btype != BT_SD64)			WGen(cinfo, CL_VSSM2, 0x01);		/* reset sequencer logic */		vga_wseq(cinfo->regbase, CL_SEQR0, 0x03);		/* FullBandwidth (video off) and 8/9 dot clock */		vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);		/* polarity (-/-), disable access to display memory,		 * VGA_CRTC_START_HI base address: color		 */		WGen(cinfo, VGA_MIS_W, 0xc1);		/* "magic cookie" - doesn't make any sense to me.. *//*      vga_wgfx(cinfo->regbase, CL_GRA, 0xce);   */		/* unlock all extension registers */		vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);		/* reset blitter */		vga_wgfx(cinfo->regbase, CL_GR31, 0x04);		switch (cinfo->btype) {		case BT_GD5480:			vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);			break;		case BT_ALPINE:			break;		case BT_SD64:			vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);			break;		default:			vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);			vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);			break;		}	}	/* plane mask: nothing */	vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);	/* character map select: doesn't even matter in gx mode */	vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);	/* memory mode: chain-4, no odd/even, ext. memory */	vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e);	/* controller-internal base address of video memory */	if (bi->init_sr07)		vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);	/*  vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */	/* EEPROM control: shouldn't be necessary to write to this at all.. */	/* graphics cursor X position (incomplete; position gives rem. 3 bits */	vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);	/* graphics cursor Y position (..."... ) */	vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);	/* graphics cursor attributes */	vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);	/* graphics cursor pattern address */	vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);	/* writing these on a P4 might give problems..  */	if (cinfo->btype != BT_PICASSO4) {		/* configuration readback and ext. color */		vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);		/* signature generator */		vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);	}	/* MCLK select etc. */	if (bi->init_sr1f)		vga_wseq(cinfo->regbase, CL_SEQR1F, bi->sr1f);	/* Screen A preset row scan: none */	vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);	/* Text cursor start: disable text cursor */	vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);	/* Text cursor end: - */	vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);	/* Screen start address high: 0 */	vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, 0x00);	/* Screen start address low: 0 */	vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 0x00);	/* text cursor location high: 0 */	vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);	/* text cursor location low: 0 */	vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);	/* Underline Row scanline: - */	vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);	/* mode control: timing enable, byte mode, no compat modes */	vga_wcrt(cinfo->regbase, VGA_CRTC_MODE, 0xc3);	/* Line Compare: not needed */	vga_wcrt(cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00);	/* ### add 0x40 for text modes with > 30 MHz pixclock */	/* ext. display controls: ext.adr. wrap */	vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);	/* Set/Reset registes: - */	vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);	/* Set/Reset enable: - */	vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);	/* Color Compare: - */	vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);	/* Data Rotate: - */	vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);	/* Read Map Select: - */	vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);	/* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */	vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);	/* Miscellaneous: memory map base address, graphics mode */	vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);	/* Color Don't care: involve all planes */	vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);	/* Bit Mask: no mask at all */	vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);	if (cinfo->btype == BT_ALPINE)		/* (5434 can't have bit 3 set for bitblt) */		vga_wgfx(cinfo->regbase, CL_GRB, 0x20);	else	/* Graphics controller mode extensions: finer granularity,	 * 8byte data latches	 */		vga_wgfx(cinfo->regbase, CL_GRB, 0x28);	vga_wgfx(cinfo->regbase, CL_GRC, 0xff);	/* Color Key compare: - */	vga_wgfx(cinfo->regbase, CL_GRD, 0x00);	/* Color Key compare mask: - */	vga_wgfx(cinfo->regbase, CL_GRE, 0x00);	/* Miscellaneous control: - */	/* Background color byte 1: - */	/*  vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */	/*  vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */	/* Attribute Controller palette registers: "identity mapping" */	vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);	vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);	/* Attribute Controller mode: graphics mode */	vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);	/* Overscan color reg.: reg. 0 */	vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);	/* Color Plane enable: Enable all 4 planes */	vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);/* ###  vga_wattr(cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */	/* Color Select: - */	vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);	WGen(cinfo, VGA_PEL_MSK, 0xff);	/* Pixel mask: no mask */	if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480)	/* polarity (-/-), enable display mem,	 * VGA_CRTC_START_HI i/o base = color	 */		WGen(cinfo, VGA_MIS_W, 0xc3);	/* BLT Start/status: Blitter reset */	vga_wgfx(cinfo->regbase, CL_GR31, 0x04);	/* - " -	   : "end-of-reset" */	vga_wgfx(cinfo->regbase, CL_GR31, 0x00);	/* misc... */	WHDR(cinfo, 0);	/* Hidden DAC register: - */	DPRINTK("EXIT\n");	return;}static void switch_monitor(struct cirrusfb_info *cinfo, int on){#ifdef CONFIG_ZORRO /* only works on Zorro boards */	static int IsOn = 0;	/* XXX not ok for multiple boards */	DPRINTK("ENTER\n");	if (cinfo->btype == BT_PICASSO4)		return;		/* nothing to switch */	if (cinfo->btype == BT_ALPINE)		return;		/* nothing to switch */	if (cinfo->btype == BT_GD5480)		return;		/* nothing to switch */	if (cinfo->btype == BT_PICASSO) {		if ((on && !IsOn) || (!on && IsOn))			WSFR(cinfo, 0xff);		DPRINTK("EXIT\n");		return;	}	if (on) {		switch (cinfo->btype) {		case BT_SD64:			WSFR(cinfo, cinfo->SFR | 0x21);			break;		case BT_PICCOLO:			WSFR(cinfo, cinfo->SFR | 0x28);			break;		case BT_SPECTRUM:			WSFR(cinfo, 0x6f);			break;		default: /* do nothing */ break;		}	} else {		switch (cinfo->btype) {		case BT_SD64:			WSFR(cinfo, cinfo->SFR & 0xde);			break;		case BT_PICCOLO:			WSFR(cinfo, cinfo->SFR & 0xd7);			break;		case BT_SPECTRUM:			WSFR(cinfo, 0x4f);			break;		default: /* do nothing */ break;		}	}	DPRINTK("EXIT\n");#endif /* CONFIG_ZORRO */}/******************************************//* Linux 2.6-style  accelerated functions *//******************************************/static void cirrusfb_fillrect(struct fb_info *info,			      const struct fb_fillrect *region){	struct fb_fillrect modded;	int vxres, vyres;	struct cirrusfb_info *cinfo = info->par;	int m = info->var.bits_per_pixel;	u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?		cinfo->pseudo_palette[region->color] : region->color;	if (info->state != FBINFO_STATE_RUNNING)		return;	if (info->flags & FBINFO_HWACCEL_DISABLED) {		cfb_fillrect(info, region);		return;	}	vxres = info->var.xres_virtual;	vyres = info->var.yres_virtual;	memcpy(&modded, region, sizeof(struct fb_fillrect));	if (!modded.width || !modded.height ||	   modded.dx >= vxres || modded.dy >= vyres)		return;	if (modded.dx + modded.width  > vxres)		modded.width  = vxres - modded.dx;	if (modded.dy + modded.height > vyres)		modded.height = vyres - modded.dy;	cirrusfb_RectFill(cinfo->regbase,			  info->var.bits_per_pixel,			  (region->dx * m) / 8, region->dy,			  (region->width * m) / 8, region->height,			  color,			  info->fix.line_length);}static void cirrusfb_copyarea(struct fb_info *info,			      const struct fb_copyarea *area){	struct fb_copyarea modded;	u32 vxres, vyres;	struct cirrusfb_info *cinfo = info->par;	int m = info->var.bits_per_pixel;	if (info->state != FBINFO_STATE_RUNNING)		return;	if (info->flags & FBINFO_HWACCEL_DISABLED) {		cfb_copyarea(info, area);		return;	}	vxres = info->var.xres_virtual;	vyres = info->var.yres_virtual;	memcpy(&modded, area, sizeof(struct fb_copyarea));	if (!modded.width || !modded.height ||	   modded.sx >= vxres || modded.sy >= vyres ||	   modded.dx >= vxres || modded.dy >= vyres)		return;	if (modded.sx + modded.width > vxres)		modded.width = vxres - modded.sx;	if (modded.dx + modded.width > vxres)		modded.width = vxres - modded.dx;	if (modded.sy + modded.height > vyres)		modded.height = vyres - modded.sy;	if (modded.dy + modded.height > vyres)		modded.height = vyres - modded.dy;	cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,			(area->sx * m) / 8, area->sy,			(area->dx * m) / 8, area->dy,			(area->width * m) / 8, area->height,			info->fix.line_length);}static void cirrusfb_imageblit(struct fb_info *info,			       const struct fb_image *image){	struct cirrusfb_info *cinfo = info->par;	cirrusfb_WaitBLT(cinfo->regbase);	cfb_imageblit(info, image);}#ifdef CONFIG_PPC_PREP#define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)#define PREP_IO_BASE    ((volatile unsigned char *) 0x80000000)static void get_prep_addrs(unsigned long *display, unsigned long *registers){	DPRINTK("ENTER\n");	*display = PREP_VIDEO_BASE;	*registers = (unsigned long) PREP_IO_BASE;	DPRINTK("EXIT\n");}#endif				/* CONFIG_PPC_PREP */#ifdef CONFIG_PCIstatic int release_io_ports;/* Pulled the logic from XFree86 Cirrus driver to get the memory size, * based on the DRAM bandwidth bit and DRAM bank switching bit.  This * works with 1MB, 2MB and 4MB configurations (which the Motorola boards * seem to have. */static unsigned int __devinit cirrusfb_get_memsize(u8 __iomem *regbase){	unsigned long mem;	unsigned char SRF;	DPRINTK("ENTER\n");	SRF = vga_rseq(regbase, CL_SEQRF);	switch ((SRF & 0x18)) {	case 0x08:		mem = 512 * 1024;		break;	case 0x10:		mem = 1024 * 1024;		break;	/* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory	 * on the 5430.	 */	case 0x18:		mem = 2048 * 1024;		break;	default:		printk(KERN_WARNING "CLgenfb: Unknown memory size!\n");		mem = 1024 * 1024;	}	if (SRF & 0x80)	/* If DRAM bank switching is enabled, there must be twice as much	 * memory installed. (4MB on the 5434)	 */		mem *= 2;	/* TODO: Handling of GD5446/5480 (see XF86 sources ...) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -