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

📄 viafbdev.c

📁 via framebuffer driver
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE.See the GNU General Public License * for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#ifdef MODULE#include <linux/module.h>#endif#define _MASTER_FILE#include "global.h"static int MAX_CURS = 32;static struct fb_var_screeninfo default_var;static char *viafb_name = "Via";static u32 pseudo_pal[17];/* video mode */static char *viafb_mode = "640x480";static char *viafb_mode1 = "640x480";static int viafb_resMode = VIA_RES_640X480;/* Added for specifying active devices.*/char *viafb_active_dev = "";/* Added for specifying video on devices.*/char *viafb_video_dev = "";/*Added for specify lcd output port*/char *viafb_lcd_port = "";char *viafb_dvi_port = "";static int timer_on;struct timer_list timer_for3D;static void viafb_set_device(struct device_t active_dev);static int apply_device_setting(struct viafb_ioctl_setting setting_info,			 struct fb_info *info);static void apply_second_mode_setting(struct fb_var_screeninfo	*sec_var);static void retrieve_device_setting(struct viafb_ioctl_setting	*setting_info);static void viafb_set_video_device(u32 video_dev_info);static void viafb_get_video_device(u32 *video_dev_info);/* Mode information */static const struct viafb_modeinfo viafb_modentry[] = {	{480, 640, VIA_RES_480X640, "480x640"},	{640, 480, VIA_RES_640X480, "640x480"},	{800, 480, VIA_RES_800X480, "800x480"},	{800, 600, VIA_RES_800X600, "800x600"},	{1024, 768, VIA_RES_1024X768, "1024x768"},	{1152, 864, VIA_RES_1152X864, "1152x864"},	{1280, 1024, VIA_RES_1280X1024, "1280x1024"},	{1600, 1200, VIA_RES_1600X1200, "1600x1200"},	{1440, 1050, VIA_RES_1440X1050, "1440x1050"},	{1280, 768, VIA_RES_1280X768, "1280x768"},	{1280, 800, VIA_RES_1280X800, "1280x800"},	{1280, 960, VIA_RES_1280X960, "1280x960"},	{1920, 1440, VIA_RES_1920X1440, "1920x1440"},	{848, 480, VIA_RES_848X480, "848x480"},	{1400, 1050, VIA_RES_1400X1050, "1400x1050"},	{720, 480, VIA_RES_720X480, "720x480"},	{720, 576, VIA_RES_720X576, "720x576"},	{1024, 512, VIA_RES_1024X512, "1024x512"},	{1024, 576, VIA_RES_1024X576, "1024x576"},	{1024, 600, VIA_RES_1024X600, "1024x600"},	{1280, 720, VIA_RES_1280X720, "1280x720"},	{1920, 1080, VIA_RES_1920X1080, "1920x1080"},	{1366, 768, VIA_RES_1368X768, "1368x768"},	{1680, 1050, VIA_RES_1680X1050, "1680x1050"},	{960, 600, VIA_RES_960X600, "960x600"},	{1000, 600, VIA_RES_1000X600, "1000x600"},	{1024, 576, VIA_RES_1024X576, "1024x576"},	{1024, 600, VIA_RES_1024X600, "1024x600"},	{1088, 612, VIA_RES_1088X612, "1088x612"},	{1152, 720, VIA_RES_1152X720, "1152x720"},	{1200, 720, VIA_RES_1200X720, "1200x720"},	{1280, 600, VIA_RES_1280X600, "1280x600"},	{1360, 768, VIA_RES_1360X768, "1360x768"},	{1440, 900, VIA_RES_1440X900, "1440x900"},	{1600, 900, VIA_RES_1600X900, "1600x900"},	{1600, 1024, VIA_RES_1600X1024, "1600x1024"},	{1792, 1344, VIA_RES_1792X1344, "1792x1344"},	{1856, 1392, VIA_RES_1856X1392, "1856x1392"},	{1920, 1200, VIA_RES_1920X1200, "1920x1200"},	{2048, 1536, VIA_RES_2048X1536, "2048x1536"},	{0, 0, VIA_RES_INVALID, "640x480"}};static struct fb_ops viafb_ops;static void get_panel_max_scal_size(struct _panel_size_pos_info	*p_max_size){	switch (p_max_size->device_type) {	case DVI_Device:		p_max_size->x = p_max_size->y = 0;		break;	default:		p_max_size->x = p_max_size->y = 0;	}}static void get_panel_max_scal_pos(struct _panel_size_pos_info *p_para){	switch (p_para->device_type) {	case DVI_Device:		p_para->x = p_para->y = 0;		break;	default:		p_para->x = p_para->y = 0;	}}static void get_panel_scal_pos(struct _panel_size_pos_info *p_para){	switch (p_para->device_type) {	case DVI_Device:		p_para->x = p_para->y = 0;		break;	default:		p_para->x = p_para->y = 0;	}}static void get_panel_scal_size(struct _panel_size_pos_info *p_para){	switch (p_para->device_type) {	case DVI_Device:		p_para->x = p_para->y = 0;		break;	default:		p_para->x = p_para->y = 0;	}}static void set_panel_scal_pos(struct _panel_size_pos_info *p_para){	switch (p_para->device_type) {	case DVI_Device:		break;	default:		;	}}static void set_panel_scal_size(struct _panel_size_pos_info *p_para){	switch (p_para->device_type) {	case DVI_Device:		break;	default:		;	}}static int viafb_update_fix(struct fb_fix_screeninfo *fix, struct fb_info *info){	struct viafb_par *ppar;	ppar = info->par;	DEBUG_MSG(KERN_INFO "viafb_update_fix!\n");	fix->visual =	    ppar->bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;	fix->line_length = ppar->linelength;	return 0;}static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix,	struct viafb_par *viaparinfo){	memset(fix, 0, sizeof(struct fb_fix_screeninfo));	strcpy(fix->id, viafb_name);	fix->smem_start = viaparinfo->fbmem;	fix->smem_len = viaparinfo->fbmem_free;	fix->mmio_start = viaparinfo->mmio_base;	fix->mmio_len = viaparinfo->mmio_len;	fix->type = FB_TYPE_PACKED_PIXELS;	fix->type_aux = 0;	fix->xpanstep = fix->ywrapstep = 0;	fix->ypanstep = 1;	/* Just tell the accel name */	viafbinfo->fix.accel = FB_ACCEL_VIA_UNICHROME;}static int viafb_open(struct fb_info *info, int user){	DEBUG_MSG(KERN_INFO "viafb_open!\n");	return 0;}static int viafb_release(struct fb_info *info, int user){	DEBUG_MSG(KERN_INFO "viafb_release!\n");	return 0;}static void viafb_update_viafb_par(struct fb_info *info){	struct viafb_par *ppar;	ppar = info->par;	ppar->bpp = info->var.bits_per_pixel;	ppar->linelength = ((info->var.xres_virtual + 7) & ~7) * ppar->bpp / 8;	ppar->hres = info->var.xres;	ppar->vres = info->var.yres;	ppar->xoffset = info->var.xoffset;	ppar->yoffset = info->var.yoffset;}static int viafb_check_var(struct fb_var_screeninfo *var,	struct fb_info *info){	int vmode_index, htotal, vtotal;	struct viafb_par *ppar;	u32 long_refresh;	ppar = info->par;	DEBUG_MSG(KERN_INFO "viafb_check_var!\n");	/* Sanity check */	/* HW neither support interlacte nor double-scaned mode */	if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE)		return -EINVAL;	vmode_index = viafb_get_mode_index(var->xres, var->yres, 0);	if (vmode_index == VIA_RES_INVALID) {		DEBUG_MSG(KERN_INFO			  "viafb: Mode %dx%dx%d not supported!!\n",			  var->xres, var->yres, var->bits_per_pixel);		return -EINVAL;	}	if (24 == var->bits_per_pixel)		var->bits_per_pixel = 32;	if (var->bits_per_pixel != 8 && var->bits_per_pixel != 16 &&		var->bits_per_pixel != 32)		return -EINVAL;	if ((var->xres_virtual * (var->bits_per_pixel >> 3)) & 0x1F)		/*32 pixel alignment */		var->xres_virtual = (var->xres_virtual + 31) & ~31;	if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 >		ppar->memsize)		return -EINVAL;	/* Based on var passed in to calculate the refresh,	 * because our driver use some modes special.	 */	htotal = var->xres + var->left_margin +	var->right_margin + var->hsync_len;	vtotal = var->yres + var->upper_margin +		var->lower_margin + var->vsync_len;	long_refresh = 1000000000UL / var->pixclock * 1000;	long_refresh /= (htotal * vtotal);	viafb_refresh = viafb_get_refresh(var->xres, var->yres, long_refresh);	/* Not supported by our driver, reutrn immediately */	if (!viafb_refresh)		return -EINVAL;	/* Adjust var according to our driver's own table */	viafb_fill_var_timing_info(var, viafb_refresh, vmode_index);	return 0;}static int viafb_set_par(struct fb_info *info){	int vmode_index;	int vmode_index1 = 0;	DEBUG_MSG(KERN_INFO "viafb_set_par!\n");	viafb_update_device_setting(info->var.xres, info->var.yres,			      info->var.bits_per_pixel, viafb_refresh, 0);	vmode_index = viafb_get_mode_index(info->var.xres, info->var.yres, 0);	if (viafb_SAMM_ON == 1) {		DEBUG_MSG(KERN_INFO		"viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n",			  viafb_second_xres, viafb_second_yres, via_fb_bpp1);		vmode_index1 = viafb_get_mode_index(viafb_second_xres,			viafb_second_yres, 1);		DEBUG_MSG(KERN_INFO "->viafb_SAMM_ON: index=%d\n",			vmode_index1);		viafb_update_device_setting(viafb_second_xres,			viafb_second_yres, via_fb_bpp1, viafb_refresh1, 1);	}	if (vmode_index != VIA_RES_INVALID) {		viafb_setmode(vmode_index, info->var.xres, info->var.yres,			info->var.bits_per_pixel, vmode_index1,			viafb_second_xres, viafb_second_yres, via_fb_bpp1);		/*We should set memory offset according virtual_x */		/*Fix me:put this function into viafb_setmode */		viafb_memory_pitch_patch(info);		/* Update ***fb_par information */		viafb_update_viafb_par(info);		/* Update other fixed information */		viafb_update_fix(&info->fix, info);		via_fb_bpp = info->var.bits_per_pixel;		/* Update via_fb_accel, it is necessary to our 2D accelerate */		via_fb_accel = info->var.accel_flags;		if (via_fb_accel)			viafb_set_2d_color_depth(info->var.bits_per_pixel);	}	return 0;}static int viafb_get_cmap_len(struct fb_var_screeninfo *var){	DEBUG_MSG(KERN_INFO "viafb_get_cmap_len!\n");	return (var->bits_per_pixel == 8) ? 256 : 16;}/* Set one color register */static int viafb_setcolreg(unsigned regno, unsigned red, unsigned green,unsigned blue, unsigned transp, struct fb_info *info){	u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10;	DEBUG_MSG(KERN_INFO "viafb_setcolreg!\n");	if (regno >= viafb_get_cmap_len(&info->var))		return 1;	if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) {	/* Read PCI bus 0,dev 0,function 0,index 0xF6 to get chip rev. */		outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8);		rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff;	}	switch (info->var.bits_per_pixel) {	case 8:		outb(0x1A, 0x3C4);		sr1a = inb(0x3C5);		outb(0x1B, 0x3C4);		sr1b = inb(0x3C5);		outb(0x67, 0x3D4);		cr67 = inb(0x3D5);		outb(0x6A, 0x3D4);		cr6a = inb(0x3D5);		/* Map the 3C6/7/8/9 to the IGA2 */		outb(0x1A, 0x3C4);		outb(sr1a | 0x01, 0x3C5);		/* Second Display Engine colck always on */		outb(0x1B, 0x3C4);		outb(sr1b | 0x80, 0x3C5);		/* Second Display Color Depth 8 */		outb(0x67, 0x3D4);		outb(cr67 & 0x3F, 0x3D5);		outb(0x6A, 0x3D4);		/* Second Display Channel Reset CR6A[6]) */		outb(cr6a & 0xBF, 0x3D5);		/* Second Display Channel Enable CR6A[7] */		outb(cr6a | 0x80, 0x3D5);		/* Second Display Channel stop reset) */		outb(cr6a | 0x40, 0x3D5);		/* Bit mask of palette */		outb(0xFF, 0x3c6);		/* Write one register of IGA2 */		outb(regno, 0x3C8);		if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name &&			rev >= 15) {			shift = 8;			viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5);			viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7);		} else {			shift = 10;			viafb_write_reg_mask(CR6A, VIACR, 0, BIT5);			viafb_write_reg_mask(SR15, VIASR, 0, BIT7);		}		outb(red >> shift, 0x3C9);		outb(green >> shift, 0x3C9);		outb(blue >> shift, 0x3C9);		/* Map the 3C6/7/8/9 to the IGA1 */		outb(0x1A, 0x3C4);		outb(sr1a & 0xFE, 0x3C5);		/* Bit mask of palette */		outb(0xFF, 0x3c6);		/* Write one register of IGA1 */		outb(regno, 0x3C8);		outb(red >> shift, 0x3C9);		outb(green >> shift, 0x3C9);		outb(blue >> shift, 0x3C9);		outb(0x1A, 0x3C4);		outb(sr1a, 0x3C5);		outb(0x1B, 0x3C4);		outb(sr1b, 0x3C5);		outb(0x67, 0x3D4);		outb(cr67, 0x3D5);		outb(0x6A, 0x3D4);		outb(cr6a, 0x3D5);		break;	case 16:		((u32 *) info->pseudo_palette)[regno] = (red & 0xF800) |		    ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11);		break;	case 32:		((u32 *) info->pseudo_palette)[regno] =		    ((transp & 0xFF00) << 16) |		    ((red & 0xFF00) << 8) |		    ((green & 0xFF00)) | ((blue & 0xFF00) >> 8);		break;	}	return 0;}/*CALLED BY: fb_set_cmap *//*           fb_set_var, pass 256 colors *//*CALLED BY: fb_set_cmap *//*           fbcon_set_palette, pass 16 colors */static int viafb_setcmap(struct fb_cmap *cmap, struct fb_info *info){	u32 len = cmap->len;	u32 i;	u16 *pred = cmap->red;	u16 *pgreen = cmap->green;	u16 *pblue = cmap->blue;	u16 *ptransp = cmap->transp;	u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10;	if (len > 256)		return 1;	if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) {	/* Read PCI bus 0, dev 0, function 0, index 0xF6 to get chip rev. */		outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8);		rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff;	}	switch (info->var.bits_per_pixel) {	case 8:		outb(0x1A, 0x3C4);		sr1a = inb(0x3C5);		outb(0x1B, 0x3C4);		sr1b = inb(0x3C5);		outb(0x67, 0x3D4);		cr67 = inb(0x3D5);		outb(0x6A, 0x3D4);		cr6a = inb(0x3D5);		/* Map the 3C6/7/8/9 to the IGA2 */		outb(0x1A, 0x3C4);		outb(sr1a | 0x01, 0x3C5);

⌨️ 快捷键说明

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