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

📄 i810_main.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
static void i810_restore_vga_state(struct i810fb_par *par){	u8 __iomem *mmio = par->mmio_start_virtual;	i810_screen_off(mmio, OFF);	i810_protect_regs(mmio, OFF);	i810_dram_off(mmio, OFF);	i810_restore_pll(par);	i810_restore_dac(par);	i810_restore_vga(par);	i810_restore_vgax(par);	i810_restore_addr_map(par);	i810_dram_off(mmio, ON);	i810_restore_2d(par);	i810_screen_off(mmio, ON);	i810_protect_regs(mmio, ON);}/*********************************************************************** *                         VGA State Save                              * ***********************************************************************/static void i810_save_vgax(struct i810fb_par *par){	u8 i;	u8 __iomem *mmio = par->mmio_start_virtual;	for (i = 0; i < 4; i++) {		i810_writeb(CR_INDEX_CGA, mmio, CR30 + i);		*(&(par->hw_state.cr30) + i) = i810_readb(CR_DATA_CGA, mmio);	}	i810_writeb(CR_INDEX_CGA, mmio, CR35);	par->hw_state.cr35 = i810_readb(CR_DATA_CGA, mmio);	i810_writeb(CR_INDEX_CGA, mmio, CR39);	par->hw_state.cr39 = i810_readb(CR_DATA_CGA, mmio);	i810_writeb(CR_INDEX_CGA, mmio, CR41);	par->hw_state.cr41 = i810_readb(CR_DATA_CGA, mmio);	i810_writeb(CR_INDEX_CGA, mmio, CR70);	par->hw_state.cr70 = i810_readb(CR_DATA_CGA, mmio);		par->hw_state.msr = i810_readb(MSR_READ, mmio);	i810_writeb(CR_INDEX_CGA, mmio, CR80);	par->hw_state.cr80 = i810_readb(CR_DATA_CGA, mmio);	i810_writeb(SR_INDEX, mmio, SR01);	par->hw_state.sr01 = i810_readb(SR_DATA, mmio);}static void i810_save_vga(struct i810fb_par *par){	u8 i;	u8 __iomem *mmio = par->mmio_start_virtual;	for (i = 0; i < 10; i++) {		i810_writeb(CR_INDEX_CGA, mmio, CR00 + i);		*((&par->hw_state.cr00) + i) = i810_readb(CR_DATA_CGA, mmio);	}	for (i = 0; i < 8; i++) {		i810_writeb(CR_INDEX_CGA, mmio, CR10 + i);		*((&par->hw_state.cr10) + i) = i810_readb(CR_DATA_CGA, mmio);	}}static void i810_save_2d(struct i810fb_par *par){	u8 __iomem *mmio = par->mmio_start_virtual;	par->hw_state.dclk_2d = i810_readl(DCLK_2D, mmio);	par->hw_state.dclk_1d = i810_readl(DCLK_1D, mmio);	par->hw_state.dclk_0ds = i810_readl(DCLK_0DS, mmio);	par->hw_state.pixconf = i810_readl(PIXCONF, mmio);	par->hw_state.fw_blc = i810_readl(FW_BLC, mmio);	par->hw_state.bltcntl = i810_readw(BLTCNTL, mmio);	par->hw_state.hwstam = i810_readw(HWSTAM, mmio); 	par->hw_state.hws_pga = i810_readl(HWS_PGA, mmio); 	par->hw_state.ier = i810_readw(IER, mmio);	par->hw_state.imr = i810_readw(IMR, mmio);	par->hw_state.dplystas = i810_readl(DPLYSTAS, mmio);}static void i810_save_vga_state(struct i810fb_par *par){	i810_save_vga(par);	i810_save_vgax(par);	i810_save_2d(par);}/************************************************************ *                    Helpers                               *  ************************************************************//** * get_line_length - calculates buffer pitch in bytes * @par: pointer to i810fb_par structure * @xres_virtual: virtual resolution of the frame * @bpp: bits per pixel * * DESCRIPTION: * Calculates buffer pitch in bytes.   */static u32 get_line_length(struct i810fb_par *par, int xres_virtual, int bpp){   	u32 length;		length = xres_virtual*bpp;	length = (length+31)&-32;	length >>= 3;	return length;}/** * i810_calc_dclk - calculates the P, M, and N values of a pixelclock value * @freq: target pixelclock in picoseconds * @m: where to write M register * @n: where to write N register * @p: where to write P register * * DESCRIPTION: * Based on the formula Freq_actual = (4*M*Freq_ref)/(N^P) * Repeatedly computes the Freq until the actual Freq is equal to * the target Freq or until the loop count is zero.  In the latter * case, the actual frequency nearest the target will be used. */static void i810_calc_dclk(u32 freq, u32 *m, u32 *n, u32 *p){	u32 m_reg, n_reg, p_divisor, n_target_max;	u32 m_target, n_target, p_target, n_best, m_best, mod;	u32 f_out, target_freq, diff = 0, mod_min, diff_min;	diff_min = mod_min = 0xFFFFFFFF;	n_best = m_best = m_target = f_out = 0;	target_freq =  freq;	n_target_max = 30;	/*	 * find P such that target freq is 16x reference freq (Hz). 	 */	p_divisor = 1;	p_target = 0;	while(!((1000000 * p_divisor)/(16 * 24 * target_freq)) && 	      p_divisor <= 32) {		p_divisor <<= 1;		p_target++;	}	n_reg = m_reg = n_target = 3;		while (diff_min && mod_min && (n_target < n_target_max)) {		f_out = (p_divisor * n_reg * 1000000)/(4 * 24 * m_reg);		mod = (p_divisor * n_reg * 1000000) % (4 * 24 * m_reg);		m_target = m_reg;		n_target = n_reg;		if (f_out <= target_freq) {			n_reg++;			diff = target_freq - f_out;		} else {			m_reg++;			diff = f_out - target_freq;		}		if (diff_min > diff) {			diff_min = diff;			n_best = n_target;			m_best = m_target;		}		 		if (!diff && mod_min > mod) {			mod_min = mod;			n_best = n_target;			m_best = m_target;		}	} 	if (m) *m = (m_best - 2) & 0x3FF;	if (n) *n = (n_best - 2) & 0x3FF;	if (p) *p = (p_target << 4);}/************************************************************* *                Hardware Cursor Routines                   * *************************************************************//** * i810_enable_cursor - show or hide the hardware cursor * @mmio: address of register space * @mode: show (1) or hide (0) * * Description: * Shows or hides the hardware cursor */static void i810_enable_cursor(u8 __iomem *mmio, int mode){	u32 temp;		temp = i810_readl(PIXCONF, mmio);	temp = (mode == ON) ? temp | CURSOR_ENABLE_MASK :		temp & ~CURSOR_ENABLE_MASK;	i810_writel(PIXCONF, mmio, temp);}static void i810_reset_cursor_image(struct i810fb_par *par){	u8 __iomem *addr = par->cursor_heap.virtual;	int i, j;	for (i = 64; i--; ) {		for (j = 0; j < 8; j++) {             			i810_writeb(j, addr, 0xff);   			i810_writeb(j+8, addr, 0x00); 		}			addr +=16;	}}static void i810_load_cursor_image(int width, int height, u8 *data,				   struct i810fb_par *par){	u8 __iomem *addr = par->cursor_heap.virtual;	int i, j, w = width/8;	int mod = width % 8, t_mask, d_mask;		t_mask = 0xff >> mod;	d_mask = ~(0xff >> mod); 	for (i = height; i--; ) {		for (j = 0; j < w; j++) {			i810_writeb(j+0, addr, 0x00);			i810_writeb(j+8, addr, *data++);		}		if (mod) {			i810_writeb(j+0, addr, t_mask);			i810_writeb(j+8, addr, *data++ & d_mask);		}		addr += 16;	}}static void i810_load_cursor_colors(int fg, int bg, struct fb_info *info){	struct i810fb_par *par = (struct i810fb_par *) info->par;	u8 __iomem *mmio = par->mmio_start_virtual;	u8 red, green, blue, trans, temp;	i810fb_getcolreg(bg, &red, &green, &blue, &trans, info);	temp = i810_readb(PIXCONF1, mmio);	i810_writeb(PIXCONF1, mmio, temp | EXTENDED_PALETTE);	i810_write_dac(4, red, green, blue, mmio);	i810_writeb(PIXCONF1, mmio, temp);	i810fb_getcolreg(fg, &red, &green, &blue, &trans, info);	temp = i810_readb(PIXCONF1, mmio);	i810_writeb(PIXCONF1, mmio, temp | EXTENDED_PALETTE);	i810_write_dac(5, red, green, blue, mmio);	i810_writeb(PIXCONF1, mmio, temp);}/** * i810_init_cursor - initializes the cursor * @par: pointer to i810fb_par structure * * DESCRIPTION: * Initializes the cursor registers */static void i810_init_cursor(struct i810fb_par *par){	u8 __iomem *mmio = par->mmio_start_virtual;	i810_enable_cursor(mmio, OFF);	i810_writel(CURBASE, mmio, par->cursor_heap.physical);	i810_writew(CURCNTR, mmio, COORD_ACTIVE | CURSOR_MODE_64_XOR);}	/********************************************************************* *                    Framebuffer hook helpers                       * *********************************************************************//** * i810_round_off -  Round off values to capability of hardware * @var: pointer to fb_var_screeninfo structure * * DESCRIPTION: * @var contains user-defined information for the mode to be set. * This will try modify those values to ones nearest the * capability of the hardware */static void i810_round_off(struct fb_var_screeninfo *var){	u32 xres, yres, vxres, vyres;	/*	 *  Presently supports only these configurations 	 */	xres = var->xres;	yres = var->yres;	vxres = var->xres_virtual;	vyres = var->yres_virtual;	var->bits_per_pixel += 7;	var->bits_per_pixel &= ~7;		if (var->bits_per_pixel < 8)		var->bits_per_pixel = 8;	if (var->bits_per_pixel > 32) 		var->bits_per_pixel = 32;	round_off_xres(&xres);	if (xres < 40)		xres = 40;	if (xres > 2048) 		xres = 2048;	xres = (xres + 7) & ~7;	if (vxres < xres) 		vxres = xres;	round_off_yres(&xres, &yres);	if (yres < 1)		yres = 1;	if (yres >= 2048)		yres = 2048;	if (vyres < yres) 		vyres = yres;	if (var->bits_per_pixel == 32)		var->accel_flags = 0;	/* round of horizontal timings to nearest 8 pixels */	var->left_margin = (var->left_margin + 4) & ~7;	var->right_margin = (var->right_margin + 4) & ~7;	var->hsync_len = (var->hsync_len + 4) & ~7;	if (var->vmode & FB_VMODE_INTERLACED) {		if (!((yres + var->upper_margin + var->vsync_len + 		       var->lower_margin) & 1))			var->upper_margin++;	}		var->xres = xres;	var->yres = yres;	var->xres_virtual = vxres;	var->yres_virtual = vyres;}	/** * set_color_bitfields - sets rgba fields * @var: pointer to fb_var_screeninfo * * DESCRIPTION: * The length, offset and ordering  for each color field  * (red, green, blue)  will be set as specified  * by the hardware */  static void set_color_bitfields(struct fb_var_screeninfo *var){	switch (var->bits_per_pixel) {	case 8:       		var->red.offset = 0;		var->red.length = 8;		var->green.offset = 0;		var->green.length = 8;		var->blue.offset = 0;		var->blue.length = 8;		var->transp.offset = 0;		var->transp.length = 0;		break;	case 16:		var->green.length = (var->green.length == 5) ? 5 : 6;		var->red.length = 5;		var->blue.length = 5;		var->transp.length = 6 - var->green.length;		var->blue.offset = 0;		var->green.offset = 5;		var->red.offset = 5 + var->green.length;		var->transp.offset =  (5 + var->red.offset) & 15;		break;	case 24:	/* RGB 888   */	case 32:	/* RGBA 8888 */		var->red.offset = 16;		var->red.length = 8;		var->green.offset = 8;		var->green.length = 8;		var->blue.offset = 0;		var->blue.length = 8;		var->transp.length = var->bits_per_pixel - 24;		var->transp.offset = (var->transp.length) ? 24 : 0;		break;	}	var->red.msb_right = 0;	var->green.msb_right = 0;	var->blue.msb_right = 0;	var->transp.msb_right = 0;}/** * i810_check_params - check if contents in var are valid * @var: pointer to fb_var_screeninfo * @info: pointer to fb_info * * DESCRIPTION: * This will check if the framebuffer size is sufficient  * for the current mode and if the user's monitor has the  * required specifications to display the current mode. */static int i810_check_params(struct fb_var_screeninfo *var, 			     struct fb_info *info){	struct i810fb_par *par = (struct i810fb_par *) info->par;	int line_length, vidmem, mode_valid = 0, retval = 0;	u32 vyres = var->yres_virtual, vxres = var->xres_virtual;	/*	 *  Memory limit	 */	line_length = get_line_length(par, vxres, var->bits_per_pixel);	vidmem = line_length*vyres;	if (vidmem > par->fb.size) {		vyres = par->fb.size/line_length;		if (vyres < var->yres) {			vyres = yres;			vxres = par->fb.size/vyres;			vxres /= var->bits_per_pixel >> 3;			line_length = get_line_length(par, vxres, 						      var->bits_per_pixel);			vidmem = line_length * yres;			if (vxres < var->xres) {				printk("i810fb: required video memory, "				       "%d bytes, for %dx%d-%d (virtual) "				       "is out of range\n", 				       vidmem, vxres, vyres, 				       var->bits_per_pixel);				return -ENOMEM;			}		}	}	var->xres_virtual = vxres;	var->yres_virtual = vyres;	/*	 * Monitor limit	 */	switch (var->bits_per_pixel) {	case 8:		info->monspecs.dclkmax = 234000000;		break;	case 16:		info->monspecs.dclkmax = 229000000;		break;	case 24:	case 32:		info->monspecs.dclkmax = 204000000;		break;	}	info->monspecs.dclkmin = 15000000;	if (!fb_validate_mode(var, info))		mode_valid = 1;#ifdef CONFIG_FB_I810_I2C	if (!mode_valid && info->monspecs.gtf &&	    !fb_get_mode(FB_MAXTIMINGS, 0, var, info))		mode_valid = 1;	if (!mode_valid && info->monspecs.modedb_len) {		struct fb_videomode *mode;		mode = fb_find_best_mode(var, &info->modelist);		if (mode) {			fb_videomode_to_var(var, mode);			mode_valid = 1;		}	}#endif	if (!mode_valid && info->monspecs.modedb_len == 0) {		if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) {			int default_sync = (info->monspecs.hfmin-HFMIN)				|(info->monspecs.hfmax-HFMAX)				|(info->monspecs.vfmin-VFMIN)				|(info->monspecs.vfmax-VFMAX);			printk("i810fb: invalid video mode%s\n",			       default_sync ? "" : ". Specifying "			       "vsyncN/hsyncN parameters may help");			retval = -EINVAL;		}	}	return retval;}	/** * encode_fix - fill up fb_fix_screeninfo structure * @fix: pointer to fb_fix_screeninfo * @info: pointer to fb_info * * DESCRIPTION: * This will set up parameters that are unmodifiable by the user. */static int encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info){	struct i810fb_par *par = (struct i810fb_par *) info->par;    	memset(fix, 0, sizeof(struct fb_fix_screeninfo));    	strcpy(fix->id, "I810");    	fix->smem_start = par->fb.physical;    	fix->smem_len = par->fb.size;    	fix->type = FB_TYPE_PACKED_PIXELS;    	fix->type_aux = 0;	fix->xpanstep = 8;	fix->ypanstep = 1;    	switch (info->var.bits_per_pixel) {	case 8:	    	fix->visual = FB_VISUAL_PSEUDOCOLOR;	    	break;	case 16:	case 24:	case 32:		if (info->var.nonstd)			fix->visual = FB_VISUAL_DIRECTCOLOR;		else			fix->visual = FB_VISUAL_TRUECOLOR;	    	break;	default:		return -EINVAL;	}    	fix->ywrapstep = 0;	fix->line_length = par->pitch;	fix->mmio_start = par->mmio_start_phys;	fix->mmio_len = MMIO_SIZE;	fix->accel = FB_ACCEL_I810;	return 0;}/** * decode_var - modify par according to contents of var * @var: pointer to fb_var_screeninfo * @par: pointer to i810fb_par *

⌨️ 快捷键说明

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