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

📄 tgafb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (f >= TGA_PLL_MAX_FREQ / 2)		shift = 0;	else if (f >= TGA_PLL_MAX_FREQ / 4)		shift = 1;	else		shift = 2;	TGA_WRITE_REG(par, shift & 1, TGA_CLOCK_REG);	TGA_WRITE_REG(par, shift >> 1, TGA_CLOCK_REG);	for (r = 0 ; r < 10 ; r++)		TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);	if (f <= 120000) {		TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);		TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);	}	else if (f <= 200000) {		TGA_WRITE_REG(par, 1, TGA_CLOCK_REG);		TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);	}	else {		TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);		TGA_WRITE_REG(par, 1, TGA_CLOCK_REG);	}	TGA_WRITE_REG(par, 1, TGA_CLOCK_REG);	TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);	TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);	TGA_WRITE_REG(par, 1, TGA_CLOCK_REG);	TGA_WRITE_REG(par, 0, TGA_CLOCK_REG);	TGA_WRITE_REG(par, 1, TGA_CLOCK_REG);	target = (f << shift) / TGA_PLL_BASE_FREQ;	min_diff = TGA_PLL_MAX_FREQ;	r = 7 / target;	if (!r) r = 1;	base = target * r;	while (base < 449) {		for (n = base < 7 ? 7 : base; n < base + target && n < 449; n++) {			m = ((n + 3) / 7) - 1;			a = 0;			DIFFCHECK((m + 1) * 7);			m++;			DIFFCHECK((m + 1) * 7);			m = (n / 6) - 1;			if ((a = n % 6))				DIFFCHECK(n);		}		r++;		base += target;	}	vr--;	for (r = 0; r < 8; r++)		TGA_WRITE_REG(par, (vm >> r) & 1, TGA_CLOCK_REG);	for (r = 0; r < 8 ; r++)		TGA_WRITE_REG(par, (va >> r) & 1, TGA_CLOCK_REG);	for (r = 0; r < 7 ; r++)		TGA_WRITE_REG(par, (vr >> r) & 1, TGA_CLOCK_REG);	TGA_WRITE_REG(par, ((vr >> 7) & 1)|2, TGA_CLOCK_REG);}/** *      tgafb_setcolreg - Optional function. Sets a color register. *      @regno: boolean, 0 copy local, 1 get_user() function *      @red: frame buffer colormap structure *      @green: The green value which can be up to 16 bits wide *      @blue:  The blue value which can be up to 16 bits wide. *      @transp: If supported the alpha value which can be up to 16 bits wide. *      @info: frame buffer info structure */static inttgafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,		unsigned transp, struct fb_info *info){	struct tga_par *par = (struct tga_par *) info->par;	int tga_bus_pci = TGA_BUS_PCI(par->dev);	int tga_bus_tc = TGA_BUS_TC(par->dev);	if (regno > 255)		return 1;	red >>= 8;	green >>= 8;	blue >>= 8;	if (par->tga_type == TGA_TYPE_8PLANE && tga_bus_pci) {		BT485_WRITE(par, regno, BT485_ADDR_PAL_WRITE);		TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);		TGA_WRITE_REG(par, red|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);		TGA_WRITE_REG(par, green|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);		TGA_WRITE_REG(par, blue|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);	} else if (par->tga_type == TGA_TYPE_8PLANE && tga_bus_tc) {		BT459_LOAD_ADDR(par, regno);		TGA_WRITE_REG(par, BT459_PALETTE << 2, TGA_RAMDAC_SETUP_REG);		TGA_WRITE_REG(par, red, TGA_RAMDAC_REG);		TGA_WRITE_REG(par, green, TGA_RAMDAC_REG);		TGA_WRITE_REG(par, blue, TGA_RAMDAC_REG);	} else {		if (regno < 16) {			u32 value = (regno << 16) | (regno << 8) | regno;			((u32 *)info->pseudo_palette)[regno] = value;		}		BT463_LOAD_ADDR(par, regno);		TGA_WRITE_REG(par, BT463_PALETTE << 2, TGA_RAMDAC_SETUP_REG);		TGA_WRITE_REG(par, red, TGA_RAMDAC_REG);		TGA_WRITE_REG(par, green, TGA_RAMDAC_REG);		TGA_WRITE_REG(par, blue, TGA_RAMDAC_REG);	}	return 0;}/** *      tgafb_blank - Optional function.  Blanks the display. *      @blank_mode: the blank mode we want. *      @info: frame buffer structure that represents a single frame buffer */static inttgafb_blank(int blank, struct fb_info *info){	struct tga_par *par = (struct tga_par *) info->par;	u32 vhcr, vvcr, vvvr;	unsigned long flags;	local_irq_save(flags);	vhcr = TGA_READ_REG(par, TGA_HORIZ_REG);	vvcr = TGA_READ_REG(par, TGA_VERT_REG);	vvvr = TGA_READ_REG(par, TGA_VALID_REG);	vvvr &= ~(TGA_VALID_VIDEO | TGA_VALID_BLANK);	switch (blank) {	case FB_BLANK_UNBLANK: /* Unblanking */		if (par->vesa_blanked) {			TGA_WRITE_REG(par, vhcr & 0xbfffffff, TGA_HORIZ_REG);			TGA_WRITE_REG(par, vvcr & 0xbfffffff, TGA_VERT_REG);			par->vesa_blanked = 0;		}		TGA_WRITE_REG(par, vvvr | TGA_VALID_VIDEO, TGA_VALID_REG);		break;	case FB_BLANK_NORMAL: /* Normal blanking */		TGA_WRITE_REG(par, vvvr | TGA_VALID_VIDEO | TGA_VALID_BLANK,			      TGA_VALID_REG);		break;	case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */		TGA_WRITE_REG(par, vvcr | 0x40000000, TGA_VERT_REG);		TGA_WRITE_REG(par, vvvr | TGA_VALID_BLANK, TGA_VALID_REG);		par->vesa_blanked = 1;		break;	case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */		TGA_WRITE_REG(par, vhcr | 0x40000000, TGA_HORIZ_REG);		TGA_WRITE_REG(par, vvvr | TGA_VALID_BLANK, TGA_VALID_REG);		par->vesa_blanked = 1;		break;	case FB_BLANK_POWERDOWN: /* Poweroff */		TGA_WRITE_REG(par, vhcr | 0x40000000, TGA_HORIZ_REG);		TGA_WRITE_REG(par, vvcr | 0x40000000, TGA_VERT_REG);		TGA_WRITE_REG(par, vvvr | TGA_VALID_BLANK, TGA_VALID_REG);		par->vesa_blanked = 1;		break;	}	local_irq_restore(flags);	return 0;}/* *  Acceleration. */static voidtgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image){	struct tga_par *par = (struct tga_par *) info->par;	u32 fgcolor, bgcolor, dx, dy, width, height, vxres, vyres, pixelmask;	unsigned long rincr, line_length, shift, pos, is8bpp;	unsigned long i, j;	const unsigned char *data;	void __iomem *regs_base;	void __iomem *fb_base;	is8bpp = info->var.bits_per_pixel == 8;	dx = image->dx;	dy = image->dy;	width = image->width;	height = image->height;	vxres = info->var.xres_virtual;	vyres = info->var.yres_virtual;	line_length = info->fix.line_length;	rincr = (width + 7) / 8;	/* A shift below cannot cope with.  */	if (unlikely(width == 0))		return;	/* Crop the image to the screen.  */	if (dx > vxres || dy > vyres)		return;	if (dx + width > vxres)		width = vxres - dx;	if (dy + height > vyres)		height = vyres - dy;	regs_base = par->tga_regs_base;	fb_base = par->tga_fb_base;	/* Expand the color values to fill 32-bits.  */	/* ??? Would be nice to notice colour changes elsewhere, so	   that we can do this only when necessary.  */	fgcolor = image->fg_color;	bgcolor = image->bg_color;	if (is8bpp) {		fgcolor |= fgcolor << 8;		fgcolor |= fgcolor << 16;		bgcolor |= bgcolor << 8;		bgcolor |= bgcolor << 16;	} else {		if (fgcolor < 16)			fgcolor = ((u32 *)info->pseudo_palette)[fgcolor];		if (bgcolor < 16)			bgcolor = ((u32 *)info->pseudo_palette)[bgcolor];	}	__raw_writel(fgcolor, regs_base + TGA_FOREGROUND_REG);	__raw_writel(bgcolor, regs_base + TGA_BACKGROUND_REG);	/* Acquire proper alignment; set up the PIXELMASK register	   so that we only write the proper character cell.  */	pos = dy * line_length;	if (is8bpp) {		pos += dx;		shift = pos & 3;		pos &= -4;	} else {		pos += dx * 4;		shift = (pos & 7) >> 2;		pos &= -8;	}	data = (const unsigned char *) image->data;	/* Enable opaque stipple mode.  */	__raw_writel((is8bpp		      ? TGA_MODE_SBM_8BPP | TGA_MODE_OPAQUE_STIPPLE		      : TGA_MODE_SBM_24BPP | TGA_MODE_OPAQUE_STIPPLE),		     regs_base + TGA_MODE_REG);	if (width + shift <= 32) {		unsigned long bwidth;		/* Handle common case of imaging a single character, in		   a font less than or 32 pixels wide.  */		/* Avoid a shift by 32; width > 0 implied.  */		pixelmask = (2ul << (width - 1)) - 1;		pixelmask <<= shift;		__raw_writel(pixelmask, regs_base + TGA_PIXELMASK_REG);		wmb();		bwidth = (width + 7) / 8;		for (i = 0; i < height; ++i) {			u32 mask = 0;			/* The image data is bit big endian; we need			   little endian.  */			for (j = 0; j < bwidth; ++j)				mask |= bitrev8(data[j]) << (j * 8);			__raw_writel(mask << shift, fb_base + pos);			pos += line_length;			data += rincr;		}		wmb();		__raw_writel(0xffffffff, regs_base + TGA_PIXELMASK_REG);	} else if (shift == 0) {		unsigned long pos0 = pos;		const unsigned char *data0 = data;		unsigned long bincr = (is8bpp ? 8 : 8*4);		unsigned long bwidth;		/* Handle another common case in which accel_putcs		   generates a large bitmap, which happens to be aligned.		   Allow the tail to be misaligned.  This case is 		   interesting because we've not got to hold partial		   bytes across the words being written.  */		wmb();		bwidth = (width / 8) & -4;		for (i = 0; i < height; ++i) {			for (j = 0; j < bwidth; j += 4) {				u32 mask = 0;				mask |= bitrev8(data[j+0]) << (0 * 8);				mask |= bitrev8(data[j+1]) << (1 * 8);				mask |= bitrev8(data[j+2]) << (2 * 8);				mask |= bitrev8(data[j+3]) << (3 * 8);				__raw_writel(mask, fb_base + pos + j*bincr);			}			pos += line_length;			data += rincr;		}		wmb();		pixelmask = (1ul << (width & 31)) - 1;		if (pixelmask) {			__raw_writel(pixelmask, regs_base + TGA_PIXELMASK_REG);			wmb();			pos = pos0 + bwidth*bincr;			data = data0 + bwidth;			bwidth = ((width & 31) + 7) / 8;			for (i = 0; i < height; ++i) {				u32 mask = 0;				for (j = 0; j < bwidth; ++j)					mask |= bitrev8(data[j]) << (j * 8);				__raw_writel(mask, fb_base + pos);				pos += line_length;				data += rincr;			}			wmb();			__raw_writel(0xffffffff, regs_base + TGA_PIXELMASK_REG);		}	} else {		unsigned long pos0 = pos;		const unsigned char *data0 = data;		unsigned long bincr = (is8bpp ? 8 : 8*4);		unsigned long bwidth;		/* Finally, handle the generic case of misaligned start.		   Here we split the write into 16-bit spans.  This allows		   us to use only one pixel mask, instead of four as would		   be required by writing 24-bit spans.  */		pixelmask = 0xffff << shift;		__raw_writel(pixelmask, regs_base + TGA_PIXELMASK_REG);		wmb();		bwidth = (width / 8) & -2;		for (i = 0; i < height; ++i) {			for (j = 0; j < bwidth; j += 2) {				u32 mask = 0;				mask |= bitrev8(data[j+0]) << (0 * 8);				mask |= bitrev8(data[j+1]) << (1 * 8);				mask <<= shift;				__raw_writel(mask, fb_base + pos + j*bincr);			}			pos += line_length;			data += rincr;		}		wmb();		pixelmask = ((1ul << (width & 15)) - 1) << shift;		if (pixelmask) {			__raw_writel(pixelmask, regs_base + TGA_PIXELMASK_REG);			wmb();			pos = pos0 + bwidth*bincr;			data = data0 + bwidth;			bwidth = (width & 15) > 8;			for (i = 0; i < height; ++i) {				u32 mask = bitrev8(data[0]);				if (bwidth)					mask |= bitrev8(data[1]) << 8;				mask <<= shift;				__raw_writel(mask, fb_base + pos);				pos += line_length;				data += rincr;			}			wmb();		}		__raw_writel(0xffffffff, regs_base + TGA_PIXELMASK_REG);	}	/* Disable opaque stipple mode.  */	__raw_writel((is8bpp		      ? TGA_MODE_SBM_8BPP | TGA_MODE_SIMPLE		      : TGA_MODE_SBM_24BPP | TGA_MODE_SIMPLE),		     regs_base + TGA_MODE_REG);}static voidtgafb_clut_imageblit(struct fb_info *info, const struct fb_image *image){	struct tga_par *par = (struct tga_par *) info->par;	u32 color, dx, dy, width, height, vxres, vyres;	u32 *palette = ((u32 *)info->pseudo_palette);	unsigned long pos, line_length, i, j;	const unsigned char *data;	void __iomem *regs_base, *fb_base;	dx = image->dx;	dy = image->dy;	width = image->width;	height = image->height;	vxres = info->var.xres_virtual;	vyres = info->var.yres_virtual;	line_length = info->fix.line_length;	/* Crop the image to the screen.  */	if (dx > vxres || dy > vyres)		return;	if (dx + width > vxres)		width = vxres - dx;	if (dy + height > vyres)		height = vyres - dy;	regs_base = par->tga_regs_base;	fb_base = par->tga_fb_base;	pos = dy * line_length + (dx * 4);	data = image->data;	/* Now copy the image, color_expanding via the palette. */	for (i = 0; i < height; i++) {		for (j = 0; j < width; j++) {			color = palette[*data++];			__raw_writel(color, fb_base + pos + j*4);		}		pos += line_length;	}}/** *      tgafb_imageblit - REQUIRED function. Can use generic routines if *                        non acclerated hardware and packed pixel based. *                        Copies a image from system memory to the screen. * *      @info: frame buffer structure that represents a single frame buffer *      @image: structure defining the image. */static void

⌨️ 快捷键说明

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