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

📄 svgalib.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	vga_wcrt(NULL, 0x0E, pos >> 8);	vga_wcrt(NULL, 0x0F, pos & 0xFF);	vga_wcrt(NULL, 0x0B, ce); /* set cursor end */	vga_wcrt(NULL, 0x0A, cs); /* set cursor start and enable it */}int svga_get_tilemax(struct fb_info *info){	return 256;}/* Get capabilities of accelerator based on the mode */void svga_get_caps(struct fb_info *info, struct fb_blit_caps *caps,		   struct fb_var_screeninfo *var){	if (var->bits_per_pixel == 0) {		/* can only support 256 8x16 bitmap */		caps->x = 1 << (8 - 1);		caps->y = 1 << (16 - 1);		caps->len = 256;	} else {		caps->x = (var->bits_per_pixel == 4) ? 1 << (8 - 1) : ~(u32)0;		caps->y = ~(u32)0;		caps->len = ~(u32)0;	}}EXPORT_SYMBOL(svga_get_caps);/* ------------------------------------------------------------------------- *//* *  Compute PLL settings (M, N, R) *  F_VCO = (F_BASE * M) / N *  F_OUT = F_VCO / (2^R) */static inline u32 abs_diff(u32 a, u32 b){	return (a > b) ? (a - b) : (b - a);}int svga_compute_pll(const struct svga_pll *pll, u32 f_wanted, u16 *m, u16 *n, u16 *r, int node){	u16 am, an, ar;	u32 f_vco, f_current, delta_current, delta_best;	pr_debug("fb%d: ideal frequency: %d kHz\n", node, (unsigned int) f_wanted);	ar = pll->r_max;	f_vco = f_wanted << ar;	/* overflow check */	if ((f_vco >> ar) != f_wanted)		return -EINVAL;	/* It is usually better to have greater VCO clock	   because of better frequency stability.	   So first try r_max, then r smaller. */	while ((ar > pll->r_min) && (f_vco > pll->f_vco_max)) {		ar--;		f_vco = f_vco >> 1;	}	/* VCO bounds check */	if ((f_vco < pll->f_vco_min) || (f_vco > pll->f_vco_max))		return -EINVAL;	delta_best = 0xFFFFFFFF;	*m = 0;	*n = 0;	*r = ar;	am = pll->m_min;	an = pll->n_min;	while ((am <= pll->m_max) && (an <= pll->n_max)) {		f_current = (pll->f_base * am) / an;		delta_current = abs_diff (f_current, f_vco);		if (delta_current < delta_best) {			delta_best = delta_current;			*m = am;			*n = an;		}		if (f_current <= f_vco) {			am ++;		} else {			an ++;		}	}	f_current = (pll->f_base * *m) / *n;	pr_debug("fb%d: found frequency: %d kHz (VCO %d kHz)\n", node, (int) (f_current >> ar), (int) f_current);	pr_debug("fb%d: m = %d n = %d r = %d\n", node, (unsigned int) *m, (unsigned int) *n, (unsigned int) *r);	return 0;}/* ------------------------------------------------------------------------- *//* Check CRT timing values */int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, int node){	u32 value;	var->xres         = (var->xres+7)&~7;	var->left_margin  = (var->left_margin+7)&~7;	var->right_margin = (var->right_margin+7)&~7;	var->hsync_len    = (var->hsync_len+7)&~7;	/* Check horizontal total */	value = var->xres + var->left_margin + var->right_margin + var->hsync_len;	if (((value / 8) - 5) >= svga_regset_size (tm->h_total_regs))		return -EINVAL;	/* Check horizontal display and blank start */	value = var->xres;	if (((value / 8) - 1) >= svga_regset_size (tm->h_display_regs))		return -EINVAL;	if (((value / 8) - 1) >= svga_regset_size (tm->h_blank_start_regs))		return -EINVAL;	/* Check horizontal sync start */	value = var->xres + var->right_margin;	if (((value / 8) - 1) >= svga_regset_size (tm->h_sync_start_regs))		return -EINVAL;	/* Check horizontal blank end (or length) */	value = var->left_margin + var->right_margin + var->hsync_len;	if ((value == 0) || ((value / 8) >= svga_regset_size (tm->h_blank_end_regs)))		return -EINVAL;	/* Check horizontal sync end (or length) */	value = var->hsync_len;	if ((value == 0) || ((value / 8) >= svga_regset_size (tm->h_sync_end_regs)))		return -EINVAL;	/* Check vertical total */	value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;	if ((value - 1) >= svga_regset_size(tm->v_total_regs))		return -EINVAL;	/* Check vertical display and blank start */	value = var->yres;	if ((value - 1) >= svga_regset_size(tm->v_display_regs))		return -EINVAL;	if ((value - 1) >= svga_regset_size(tm->v_blank_start_regs))		return -EINVAL;	/* Check vertical sync start */	value = var->yres + var->lower_margin;	if ((value - 1) >= svga_regset_size(tm->v_sync_start_regs))		return -EINVAL;	/* Check vertical blank end (or length) */	value = var->upper_margin + var->lower_margin + var->vsync_len;	if ((value == 0) || (value >= svga_regset_size (tm->v_blank_end_regs)))		return -EINVAL;	/* Check vertical sync end  (or length) */	value = var->vsync_len;	if ((value == 0) || (value >= svga_regset_size (tm->v_sync_end_regs)))		return -EINVAL;	return 0;}/* Set CRT timing registers */void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var,			u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node){	u8 regval;	u32 value;	value = var->xres + var->left_margin + var->right_margin + var->hsync_len;	value = (value * hmul) / hdiv;	pr_debug("fb%d: horizontal total      : %d\n", node, value);	svga_wcrt_multi(tm->h_total_regs, (value / 8) - 5);	value = var->xres;	value = (value * hmul) / hdiv;	pr_debug("fb%d: horizontal display    : %d\n", node, value);	svga_wcrt_multi(tm->h_display_regs, (value / 8) - 1);	value = var->xres;	value = (value * hmul) / hdiv;	pr_debug("fb%d: horizontal blank start: %d\n", node, value);	svga_wcrt_multi(tm->h_blank_start_regs, (value / 8) - 1 + hborder);	value = var->xres + var->left_margin + var->right_margin + var->hsync_len;	value = (value * hmul) / hdiv;	pr_debug("fb%d: horizontal blank end  : %d\n", node, value);	svga_wcrt_multi(tm->h_blank_end_regs, (value / 8) - 1 - hborder);	value = var->xres + var->right_margin;	value = (value * hmul) / hdiv;	pr_debug("fb%d: horizontal sync start : %d\n", node, value);	svga_wcrt_multi(tm->h_sync_start_regs, (value / 8));	value = var->xres + var->right_margin + var->hsync_len;	value = (value * hmul) / hdiv;	pr_debug("fb%d: horizontal sync end   : %d\n", node, value);	svga_wcrt_multi(tm->h_sync_end_regs, (value / 8));	value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;	value = (value * vmul) / vdiv;	pr_debug("fb%d: vertical total        : %d\n", node, value);	svga_wcrt_multi(tm->v_total_regs, value - 2);	value = var->yres;	value = (value * vmul) / vdiv;	pr_debug("fb%d: vertical display      : %d\n", node, value);	svga_wcrt_multi(tm->v_display_regs, value - 1);	value = var->yres;	value = (value * vmul) / vdiv;	pr_debug("fb%d: vertical blank start  : %d\n", node, value);	svga_wcrt_multi(tm->v_blank_start_regs, value);	value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;	value = (value * vmul) / vdiv;	pr_debug("fb%d: vertical blank end    : %d\n", node, value);	svga_wcrt_multi(tm->v_blank_end_regs, value - 2);	value = var->yres + var->lower_margin;	value = (value * vmul) / vdiv;	pr_debug("fb%d: vertical sync start   : %d\n", node, value);	svga_wcrt_multi(tm->v_sync_start_regs, value);	value = var->yres + var->lower_margin + var->vsync_len;	value = (value * vmul) / vdiv;	pr_debug("fb%d: vertical sync end     : %d\n", node, value);	svga_wcrt_multi(tm->v_sync_end_regs, value);	/* Set horizontal and vertical sync pulse polarity in misc register */	regval = vga_r(NULL, VGA_MIS_R);	if (var->sync & FB_SYNC_HOR_HIGH_ACT) {		pr_debug("fb%d: positive horizontal sync\n", node);		regval = regval & ~0x80;	} else {		pr_debug("fb%d: negative horizontal sync\n", node);		regval = regval | 0x80;	}	if (var->sync & FB_SYNC_VERT_HIGH_ACT) {		pr_debug("fb%d: positive vertical sync\n", node);		regval = regval & ~0x40;	} else {		pr_debug("fb%d: negative vertical sync\n\n", node);		regval = regval | 0x40;	}	vga_w(NULL, VGA_MIS_W, regval);}/* ------------------------------------------------------------------------- */static inline int match_format(const struct svga_fb_format *frm,			       struct fb_var_screeninfo *var){	int i = 0;	int stored = -EINVAL;	while (frm->bits_per_pixel != SVGA_FORMAT_END_VAL)	{		if ((var->bits_per_pixel == frm->bits_per_pixel) &&		    (var->red.length     <= frm->red.length)     &&		    (var->green.length   <= frm->green.length)   &&		    (var->blue.length    <= frm->blue.length)    &&		    (var->transp.length  <= frm->transp.length)  &&		    (var->nonstd	 == frm->nonstd))			return i;		if (var->bits_per_pixel == frm->bits_per_pixel)			stored = i;		i++;		frm++;	}	return stored;}int svga_match_format(const struct svga_fb_format *frm,		      struct fb_var_screeninfo *var,		      struct fb_fix_screeninfo *fix){	int i = match_format(frm, var);	if (i >= 0) {		var->bits_per_pixel = frm[i].bits_per_pixel;		var->red            = frm[i].red;		var->green          = frm[i].green;		var->blue           = frm[i].blue;		var->transp         = frm[i].transp;		var->nonstd         = frm[i].nonstd;		if (fix != NULL) {			fix->type      = frm[i].type;			fix->type_aux  = frm[i].type_aux;			fix->visual    = frm[i].visual;			fix->xpanstep  = frm[i].xpanstep;		}	}	return i;}EXPORT_SYMBOL(svga_wcrt_multi);EXPORT_SYMBOL(svga_wseq_multi);EXPORT_SYMBOL(svga_set_default_gfx_regs);EXPORT_SYMBOL(svga_set_default_atc_regs);EXPORT_SYMBOL(svga_set_default_seq_regs);EXPORT_SYMBOL(svga_set_default_crt_regs);EXPORT_SYMBOL(svga_set_textmode_vga_regs);EXPORT_SYMBOL(svga_settile);EXPORT_SYMBOL(svga_tilecopy);EXPORT_SYMBOL(svga_tilefill);EXPORT_SYMBOL(svga_tileblit);EXPORT_SYMBOL(svga_tilecursor);EXPORT_SYMBOL(svga_get_tilemax);EXPORT_SYMBOL(svga_compute_pll);EXPORT_SYMBOL(svga_check_timings);EXPORT_SYMBOL(svga_set_timings);EXPORT_SYMBOL(svga_match_format);MODULE_AUTHOR("Ondrej Zajicek <santiago@crfreenet.org>");MODULE_DESCRIPTION("Common utility functions for VGA-based graphics cards");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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