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

📄 viafbdev.c

📁 via framebuffer driver
💻 C
📖 第 1 页 / 共 5 页
字号:
		rop = 0x5A;		break;	case ROP_COPY:	default:		rop = 0xF0;		break;	}	switch (info->var.bits_per_pixel) {	case 8:		col = rect->color;		break;	case 16:		col = ((u32 *) (info->pseudo_palette))[rect->color];		break;	case 32:		col = ((u32 *) (info->pseudo_palette))[rect->color];		break;	}	/* BitBlt Source Address */	MMIO_OUT32(VIA_REG_SRCPOS, 0x0);	/* Source Base Address */	MMIO_OUT32(VIA_REG_SRCBASE, 0x0);	/* Destination Base Address */	/*MMIO_OUT32(VIA_REG_DSTBASE, 0x0); */	MMIO_OUT32(VIA_REG_DSTBASE,		   ((u32) (info->screen_base) - (u32) viafb_FB_MM) >> 3);	/* Pitch */	pitch = (info->var.xres_virtual + 7) & ~7;	MMIO_OUT32(VIA_REG_PITCH,		   VIA_PITCH_ENABLE |		   (((pitch *		      info->var.bits_per_pixel >> 3) >> 3) |		      (((pitch * info->		      var.bits_per_pixel >> 3) >> 3) << 16)));	/* BitBlt Destination Address */	MMIO_OUT32(VIA_REG_DSTPOS, ((rect->dy << 16) | rect->dx));	/* Dimension: width & height */	MMIO_OUT32(VIA_REG_DIMENSION,		   (((rect->height - 1) << 16) | (rect->width - 1)));	/* Forground color or Destination color */	MMIO_OUT32(VIA_REG_FGCOLOR, col);	/* GE Command */	MMIO_OUT32(VIA_REG_GECMD, (0x01 | 0x2000 | (rop << 24)));}static void viafb_copyarea(struct fb_info *info,	const struct fb_copyarea *area){	u32 dy = area->dy, sy = area->sy, direction = 0x0;	u32 sx = area->sx, dx = area->dx, width = area->width;	int pitch;	DEBUG_MSG(KERN_INFO "viafb_copyarea!!\n");	if (!via_fb_accel)		return cfb_copyarea(info, area);	if (!area->width || !area->height)		return;	if (sy < dy) {		dy += area->height - 1;		sy += area->height - 1;		direction |= 0x4000;	}	if (sx < dx) {		dx += width - 1;		sx += width - 1;		direction |= 0x8000;	}	/* Source Base Address */	/*MMIO_OUT32(VIA_REG_SRCBASE, 0x0); */	MMIO_OUT32(VIA_REG_SRCBASE,		   ((u32) (info->screen_base) - (u32) viafb_FB_MM) >> 3);	/* Destination Base Address */	/*MMIO_OUT32(VIA_REG_DSTBASE, 0x0); */	MMIO_OUT32(VIA_REG_DSTBASE,		   ((u32) (info->screen_base) - (u32) viafb_FB_MM) >> 3);	/* Pitch */	pitch = (info->var.xres_virtual + 7) & ~7;	/* VIA_PITCH_ENABLE can be omitted now. */	MMIO_OUT32(VIA_REG_PITCH,		   VIA_PITCH_ENABLE |		   (((pitch *		      info->var.bits_per_pixel >> 3) >> 3) | (((pitch *								info->var.								bits_per_pixel								>> 3) >> 3)							      << 16)));	/* BitBlt Source Address */	MMIO_OUT32(VIA_REG_SRCPOS, ((sy << 16) | sx));	/* BitBlt Destination Address */	MMIO_OUT32(VIA_REG_DSTPOS, ((dy << 16) | dx));	/* Dimension: width & height */	MMIO_OUT32(VIA_REG_DIMENSION,		   (((area->height - 1) << 16) | (area->width - 1)));	/* GE Command */	MMIO_OUT32(VIA_REG_GECMD, (0x01 | direction | (0xCC << 24)));}static void viafb_imageblit(struct fb_info *info,	const struct fb_image *image){	u32 size, bg_col = 0, fg_col = 0, *udata;	int i;	int pitch;	if (!via_fb_accel)		return cfb_imageblit(info, image);	udata = (u32 *) image->data;	switch (info->var.bits_per_pixel) {	case 8:		bg_col = image->bg_color;		fg_col = image->fg_color;		break;	case 16:		bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color];		fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color];		break;	case 32:		bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color];		fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color];		break;	}	size = image->width * image->height;	/* Source Base Address */	MMIO_OUT32(VIA_REG_SRCBASE, 0x0);	/* Destination Base Address */	/*MMIO_OUT32(VIA_REG_DSTBASE, 0x0); */	MMIO_OUT32(VIA_REG_DSTBASE,		   ((u32) (info->screen_base) - (u32) viafb_FB_MM) >> 3);	/* Pitch */	pitch = (info->var.xres_virtual + 7) & ~7;	MMIO_OUT32(VIA_REG_PITCH,		   VIA_PITCH_ENABLE |		   (((pitch *		      info->var.bits_per_pixel >> 3) >> 3) | (((pitch *								info->var.								bits_per_pixel								>> 3) >> 3)							      << 16)));	/* BitBlt Source Address */	MMIO_OUT32(VIA_REG_SRCPOS, 0x0);	/* BitBlt Destination Address */	MMIO_OUT32(VIA_REG_DSTPOS, ((image->dy << 16) | image->dx));	/* Dimension: width & height */	MMIO_OUT32(VIA_REG_DIMENSION,		   (((image->height - 1) << 16) | (image->width - 1)));	/* fb color */	MMIO_OUT32(VIA_REG_FGCOLOR, fg_col);	/* bg color */	MMIO_OUT32(VIA_REG_BGCOLOR, bg_col);	/* GE Command */	MMIO_OUT32(VIA_REG_GECMD, 0xCC020142);	for (i = 0; i < size / 4; i++) {		MMIO_OUT32(VIA_MMIO_BLTBASE, *udata);		udata++;	}}static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor){	u8 data[CURSOR_SIZE / 8];	u32 data_bak[CURSOR_SIZE / 32];	u32 temp, xx, yy, bg_col = 0, fg_col = 0;	int size, i, j = 0;	static int hw_cursor;	struct viafb_par *p_viafb_par;	if (via_fb_accel)		hw_cursor = 1;	if (!via_fb_accel) {		if (hw_cursor) {			viafb_show_hw_cursor(info, HW_Cursor_OFF);			hw_cursor = 0;		}		return soft_cursor(info, cursor);	}	if ((((struct viafb_par *)(info->par))->iga_path == IGA2)	    && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266))		return soft_cursor(info, cursor);	/*When duoview and using lcd , use soft cursor */	if (viafb_LCD_ON || ((struct viafb_par *)(info->par))->duoview)		return soft_cursor(info, cursor);	viafb_show_hw_cursor(info, HW_Cursor_OFF);	viacursor = *cursor;	if (cursor->set & FB_CUR_SETHOT) {		viacursor.hot = cursor->hot;		temp = ((viacursor.hot.x) << 16) + viacursor.hot.y;		MMIO_OUT32(VIA_REG_CURSOR_ORG, temp);	}	if (cursor->set & FB_CUR_SETPOS) {		viacursor.image.dx = cursor->image.dx;		viacursor.image.dy = cursor->image.dy;		yy = cursor->image.dy - info->var.yoffset;		xx = cursor->image.dx - info->var.xoffset;		temp = yy & 0xFFFF;		temp |= (xx << 16);		MMIO_OUT32(VIA_REG_CURSOR_POS, temp);	}	if (cursor->set & FB_CUR_SETSIZE) {		temp = MMIO_IN32(VIA_REG_CURSOR_MODE);		if ((cursor->image.width <= 32)		    && (cursor->image.height <= 32)) {			MAX_CURS = 32;			temp |= 0x2;		} else if ((cursor->image.width <= 64)			   && (cursor->image.height <= 64)) {			MAX_CURS = 64;			temp &= 0xFFFFFFFD;		} else {			DEBUG_MSG(KERN_INFO			"The cursor image is biger than 64x64 bits...\n");			return -ENXIO;		}		MMIO_OUT32(VIA_REG_CURSOR_MODE, temp);		viacursor.image.height = cursor->image.height;		viacursor.image.width = cursor->image.width;	}	if (cursor->set & FB_CUR_SETCMAP) {		viacursor.image.fg_color = cursor->image.fg_color;		viacursor.image.bg_color = cursor->image.bg_color;		switch (info->var.bits_per_pixel) {		case 8:		case 16:		case 32:			bg_col =			    (0xFF << 24) |			    (((info->cmap.red)[viacursor.image.bg_color] &			    0xFF00) << 8) |			    ((info->cmap.green)[viacursor.image.bg_color] &			    0xFF00) |			    (((info->cmap.blue)[viacursor.image.bg_color] &			    0xFF00) >> 8);			fg_col =			    (0xFF << 24) |			    (((info->cmap.red)[viacursor.image.fg_color] &			    0xFF00) << 8) |			    ((info->cmap.green)[viacursor.image.fg_color] &			    0xFF00) |			    (((info->cmap.blue)[viacursor.image.fg_color] &			    0xFF00) >> 8);			break;		default:			return 0;		}		/* This is indeed a patch for VT3324/VT3353 */		if (!info->par)			return 0;		p_viafb_par = (struct viafb_par *)info->par;		if ((p_viafb_par->chip_info->gfx_chip_name ==			UNICHROME_CX700) ||			((p_viafb_par->chip_info->gfx_chip_name ==			UNICHROME_VX800))) {			bg_col =			    (((info->cmap.red)[viacursor.image.bg_color] &			    0xFFC0) << 14) |			    (((info->cmap.green)[viacursor.image.bg_color] &			    0xFFC0) << 4) |			    (((info->cmap.blue)[viacursor.image.bg_color] &			    0xFFC0) >> 6);			fg_col =			    (((info->cmap.red)[viacursor.image.fg_color] &			    0xFFC0) << 14) |			    (((info->cmap.green)[viacursor.image.fg_color] &			    0xFFC0) << 4) |			    (((info->cmap.blue)[viacursor.image.fg_color] &			    0xFFC0) >> 6);		}		MMIO_OUT32(VIA_REG_CURSOR_BG, bg_col);		MMIO_OUT32(VIA_REG_CURSOR_FG, fg_col);	}	if (cursor->set & FB_CUR_SETSHAPE) {		size =		    ((viacursor.image.width + 7) >> 3) *		    viacursor.image.height;		if (MAX_CURS == 32) {			for (i = 0; i < (CURSOR_SIZE / 32); i++) {				data_bak[i] = 0x0;				data_bak[i + 1] = 0xFFFFFFFF;				i += 1;			}		} else if (MAX_CURS == 64) {			for (i = 0; i < (CURSOR_SIZE / 32); i++) {				data_bak[i] = 0x0;				data_bak[i + 1] = 0x0;				data_bak[i + 2] = 0xFFFFFFFF;				data_bak[i + 3] = 0xFFFFFFFF;				i += 3;			}		}		switch (viacursor.rop) {		case ROP_XOR:			for (i = 0; i < size; i++)				data[i] = viacursor.mask[i];			break;		case ROP_COPY:			for (i = 0; i < size; i++)				data[i] = viacursor.mask[i];			break;		default:			break;		}		if (MAX_CURS == 32) {			for (i = 0; i < size; i++) {				data_bak[j] = (u32) data[i];				data_bak[j + 1] = ~data_bak[j];				j += 2;			}		} else if (MAX_CURS == 64) {			for (i = 0; i < size; i++) {				data_bak[j] = (u32) data[i];				data_bak[j + 1] = 0x0;				data_bak[j + 2] = ~data_bak[j];				data_bak[j + 3] = ~data_bak[j + 1];				j += 4;			}		}		memcpy(((struct viafb_par *)(info->par))->fbmem_virt +		       ((struct viafb_par *)(info->par))->cursor_start,		       data_bak, CURSOR_SIZE);	}	if (viacursor.enable)		viafb_show_hw_cursor(info, HW_Cursor_ON);	return 0;}static int viafb_sync(struct fb_info *info){	if (via_fb_accel)		viafb_wait_engine_idle();	return 0;}int viafb_get_mode_index(int hres, int vres, int flag){	u32 i;	DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n");	for (i = 0; viafb_modentry[i].mode_index != VIA_RES_INVALID; i++)		if (viafb_modentry[i].xres == hres &&			viafb_modentry[i].yres == vres)			break;	viafb_resMode = viafb_modentry[i].mode_index;	if (flag)		viafb_mode1 = viafb_modentry[i].mode_res;	else		viafb_mode = viafb_modentry[i].mode_res;	return viafb_resMode;}static void check_available_device_to_enable(int device_id){	int device_num = 0;	/* Initialize: */	viafb_CRT_ON = STATE_OFF;	viafb_DVI_ON = STATE_OFF;	viafb_LCD_ON = STATE_OFF;	viafb_LCD2_ON = STATE_OFF;	viafb_DeviceStatus = None_Device;	if ((device_id & CRT_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {		viafb_CRT_ON = STATE_ON;		device_num++;		viafb_DeviceStatus |= CRT_Device;	}	if ((device_id & DVI_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {		viafb_DVI_ON = STATE_ON;		device_num++;		viafb_DeviceStatus |= DVI_Device;	}	if ((device_id & LCD_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {		viafb_LCD_ON = STATE_ON;		device_num++;		viafb_DeviceStatus |= LCD_Device;	}	if ((device_id & LCD2_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {		viafb_LCD2_ON = STATE_ON;		device_num++;		viafb_DeviceStatus |= LCD2_Device;	}	if (viafb_DeviceStatus == None_Device) {		/* Use CRT as default active device: */		viafb_CRT_ON = STATE_ON;		viafb_DeviceStatus = CRT_Device;	}	DEBUG_MSG(KERN_INFO "Device Status:%x", viafb_DeviceStatus);}static void viafb_set_device(struct device_t active_dev){	/* Check available device to enable: */	int device_id = None_Device;	if (active_dev.crt)		device_id |= CRT_Device;	if (active_dev.dvi)		device_id |= DVI_Device;	if (active_dev.lcd)		device_id |= LCD_Device;	check_available_device_to_enable(device_id);	/* Check property of LCD: */	if (viafb_LCD_ON) {		if (active_dev.lcd_dsp_cent) {			viaparinfo->lvds_setting_info->display_method =				viafb_lcd_dsp_method = LCD_CENTERING;		} else {			viaparinfo->lvds_setting_info->display_method =				viafb_lcd_dsp_method = LCD_EXPANDSION;		}		if (active_dev.lcd_mode == LCD_SPWG) {			viaparinfo->lvds_setting_info->lcd_mode =				viafb_lcd_mode = LCD_SPWG;		} else {			viaparinfo->lvds_setting_info->lcd_mode =				viafb_lcd_mode = LCD_OPENLDI;		}		if (active_dev.lcd_panel_id <= LCD_PANEL_ID_MAXIMUM) {			viafb_lcd_panel_id = active_dev.lcd_panel_id;			viafb_init_lcd_size();		}	}	/* Check property of mode: */	if (!active_dev.xres1) {		viafb_second_xres = 640;	} else {		viafb_second_xres = active_dev.xres1;	}

⌨️ 快捷键说明

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