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

📄 sis_main.c

📁 该文件是rt_linux
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef SISFB_PAN        fb_pan_display:	sisfb_pan_display,#endif	fb_ioctl:	sisfb_ioctl,	fb_mmap:	sisfb_mmap,};#endif/* ------------ Interface to the low level console driver -------------*/#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)	/* --------- for 2.4 series --------- */static int sisfb_update_var(int con, struct fb_info *info){#ifdef SISFB_PAN        sisfb_pan_var(&fb_display[con].var);#endif	return 0;}static int sisfb_switch(int con, struct fb_info *info){	int cols, rows;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)#define currcon info->currcon#endif        if(fb_display[currcon].cmap.len)		fb_get_cmap(&fb_display[currcon].cmap, 1, sis_getcolreg, info);	fb_display[con].var.activate = FB_ACTIVATE_NOW;	if(!memcmp(&fb_display[con].var, &fb_display[currcon].var,	                           sizeof(struct fb_var_screeninfo))) {		currcon = con;		return 1;	}	currcon = con;	sisfb_do_set_var(&fb_display[con].var, 1, info);	sisfb_set_disp(con, &fb_display[con].var, info);	sisfb_do_install_cmap(con, info);	cols = sisbios_mode[sisfb_mode_idx].cols;	rows = sisbios_mode[sisfb_mode_idx].rows;	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);	sisfb_update_var(con, info);	return 1;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)#undef currcon#endif}static void sisfb_blank(int blank, struct fb_info *info){	u8 reg;	inSISIDXREG(SISCR, 0x17, reg);	if(blank > 0)		reg &= 0x7f;	else		reg |= 0x80;	outSISIDXREG(SISCR, 0x17, reg);}#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)	/* ---------- for 2.5 series -------- */static int sisfb_blank(int blank, struct fb_info *info){	u8 reg;	inSISIDXREG(SISCR, 0x17, reg);	if(blank > 0)		reg &= 0x7f;	else		reg |= 0x80;	outSISIDXREG(SISCR, 0x17, reg);        return(0);}#endif/* --------------- Chip-dependent Routines --------------------------- */#ifdef CONFIG_FB_SIS_300 /* for SiS 300/630/540/730 */static int sisfb_get_dram_size_300(void){	struct pci_dev *pdev = NULL;	int pdev_valid = 0;	u8  pci_data, reg;	u16 nbridge_id;	switch (ivideo.chip) {	   case SIS_540:		nbridge_id = PCI_DEVICE_ID_SI_540;		break;	   case SIS_630:		nbridge_id = PCI_DEVICE_ID_SI_630;		break;	   case SIS_730:		nbridge_id = PCI_DEVICE_ID_SI_730;		break;	   default:		nbridge_id = 0;		break;	}	if (nbridge_id == 0) {  /* 300 */	        inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE,reg);		ivideo.video_size =		        ((unsigned int) ((reg & SIS_DRAM_SIZE_MASK) + 1) << 20);	} else {		/* 540, 630, 730 */		pci_for_each_dev(pdev) {			if ((pdev->vendor == PCI_VENDOR_ID_SI) 				       && (pdev->device == nbridge_id)) {				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS, &pci_data);				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;				ivideo.video_size = (unsigned int)(1 << (pci_data+21));				pdev_valid = 1;					reg = SIS_DATA_BUS_64 << 6;				switch (pci_data) {				   case BRI_DRAM_SIZE_2MB:					reg |= SIS_DRAM_SIZE_2MB;					break;				   case BRI_DRAM_SIZE_4MB:					reg |= SIS_DRAM_SIZE_4MB;					break;				   case BRI_DRAM_SIZE_8MB:					reg |= SIS_DRAM_SIZE_8MB;					break;				   case BRI_DRAM_SIZE_16MB:					reg |= SIS_DRAM_SIZE_16MB;					break;				   case BRI_DRAM_SIZE_32MB:					reg |= SIS_DRAM_SIZE_32MB;					break;				   case BRI_DRAM_SIZE_64MB:					reg |= SIS_DRAM_SIZE_64MB;					break;				}				outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);				break;			}  		}   			if (!pdev_valid)  return -1;	}	return 0;}static void sisfb_detect_VB_connect_300(){	u8 sr16, sr17, cr32, temp;	ivideo.TV_plug = ivideo.TV_type = 0;        switch(ivideo.hasVB) {	  case HASVB_LVDS_CHRONTEL:	  case HASVB_CHRONTEL:	     SiS_SenseCh();	     break;	  case HASVB_301:	  case HASVB_302:	     SiS_Sense30x();	     break;	}	inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17);        inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR32, cr32);	if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {		if ((sr17 & 0x01) && !sisfb_crt1off)			sisfb_crt1off = 0;		else {			if (sr17 & 0x0E)				sisfb_crt1off = 1;			else				sisfb_crt1off = 0;		}		if (sisfb_crt2type != -1)			/* TW: override detected CRT2 type */			ivideo.disp_state = sisfb_crt2type;		else if (sr17 & 0x08 )			ivideo.disp_state = DISPTYPE_CRT2;		else if (sr17 & 0x02)			ivideo.disp_state = DISPTYPE_LCD;		else if (sr17 & 0x04)			ivideo.disp_state = DISPTYPE_TV;		else			ivideo.disp_state = 0;		if(sisfb_tvplug != -1)			/* PR/TW: override detected TV type */			ivideo.TV_plug = sisfb_tvplug;		else if (sr17 & 0x20)			ivideo.TV_plug = TVPLUG_SVIDEO;		else if (sr17 & 0x10)			ivideo.TV_plug = TVPLUG_COMPOSITE;		inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_16, sr16);		if (sr16 & 0x20)			ivideo.TV_type = TVMODE_PAL;		else			ivideo.TV_type = TVMODE_NTSC;	} else {		if ((cr32 & SIS_CRT1) && !sisfb_crt1off)			sisfb_crt1off = 0;		else {			if (cr32 & 0x5F)				sisfb_crt1off = 1;			else				sisfb_crt1off = 0;		}		if (sisfb_crt2type != -1)			/* TW: override detected CRT2 type */			ivideo.disp_state = sisfb_crt2type;		else if (cr32 & SIS_VB_CRT2)			ivideo.disp_state = DISPTYPE_CRT2;		else if (cr32 & SIS_VB_LCD)			ivideo.disp_state = DISPTYPE_LCD;		else if (cr32 & SIS_VB_TV)			ivideo.disp_state = DISPTYPE_TV;		else			ivideo.disp_state = 0;		/* TW: Detect TV plug & type */		if(sisfb_tvplug != -1)			/* PR/TW: override with option */		        ivideo.TV_plug = sisfb_tvplug;#ifdef oldHV		else if (cr32 & SIS_VB_HIVISION) {			ivideo.TV_type = TVMODE_HIVISION;			ivideo.TV_plug = TVPLUG_SVIDEO;		}#endif		else if (cr32 & SIS_VB_SVIDEO)			ivideo.TV_plug = TVPLUG_SVIDEO;		else if (cr32 & SIS_VB_COMPOSITE)			ivideo.TV_plug = TVPLUG_COMPOSITE;		else if (cr32 & SIS_VB_SCART)			ivideo.TV_plug = TVPLUG_SCART;		if (ivideo.TV_type == 0) {		        inSISIDXREG(SISSR, IND_SIS_POWER_ON_TRAP, temp);			if (temp & 0x01)				ivideo.TV_type = TVMODE_PAL;			else				ivideo.TV_type = TVMODE_NTSC;		}	}	/* TW: Copy forceCRT1 option to CRT1off if option is given */    	if (sisfb_forcecrt1 != -1) {    		if(sisfb_forcecrt1) sisfb_crt1off = 0;		else                sisfb_crt1off = 1;    	}}static void sisfb_get_VB_type_300(void){	u8 reg;	if(ivideo.chip != SIS_300) {		if(!sisfb_has_VB_300()) {		        inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);			switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {			   case SIS_EXTERNAL_CHIP_SIS301:				ivideo.hasVB = HASVB_301;				break;			   case SIS_EXTERNAL_CHIP_LVDS:				ivideo.hasVB = HASVB_LVDS;				break;			   case SIS_EXTERNAL_CHIP_TRUMPION:				ivideo.hasVB = HASVB_TRUMPION;				break;			   case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:				ivideo.hasVB = HASVB_LVDS_CHRONTEL;				break;			   case SIS_EXTERNAL_CHIP_CHRONTEL:				ivideo.hasVB = HASVB_CHRONTEL;				break;			   default:				break;			}		}	} else {		sisfb_has_VB_300();	}}static int sisfb_has_VB_300(void){	u8 vb_chipid;	inSISIDXREG(SISPART4, 0x00, vb_chipid);	switch (vb_chipid) {	   case 0x01:		ivideo.hasVB = HASVB_301;		break;	   case 0x02:		ivideo.hasVB = HASVB_302;		break;	   case 0x03:		ivideo.hasVB = HASVB_303;		break;	   default:		ivideo.hasVB = HASVB_NONE;		return FALSE;	}	return TRUE;}#endif  /* CONFIG_FB_SIS_300 */#ifdef CONFIG_FB_SIS_315    /* for SiS 315/550/650/740 */static int sisfb_get_dram_size_315(void){	struct pci_dev *pdev = NULL;	int pdev_valid = 0;	u8  pci_data;	u8  reg = 0;	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650) {#ifdef LINUXBIOS		pci_for_each_dev(pdev) {			if ( (pdev->vendor == PCI_VENDOR_ID_SI)				&& ( (pdev->device == PCI_DEVICE_ID_SI_550) ||				     (pdev->device == PCI_DEVICE_ID_SI_650))) {				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,				                     &pci_data);				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;				ivideo.video_size = (unsigned int)(1 << (pci_data + 21));				pdev_valid = 1;				/* TW: Initialize SR14 "by hand" */				inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);				reg &= 0xC0;				switch (pci_data) {				   case BRI_DRAM_SIZE_4MB:					reg |= SIS550_DRAM_SIZE_4MB;					break;				   case BRI_DRAM_SIZE_8MB:					reg |= SIS550_DRAM_SIZE_8MB;					break;				   case BRI_DRAM_SIZE_16MB:					reg |= SIS550_DRAM_SIZE_16MB;					break;				   case BRI_DRAM_SIZE_32MB:					reg |= SIS550_DRAM_SIZE_32MB;					break;				   case BRI_DRAM_SIZE_64MB:					reg |= SIS550_DRAM_SIZE_64MB;					break;				}			        /* TODO: set Dual channel and bus width bits here */				outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);				break;			}  		}			if (!pdev_valid)  return -1;#else                inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);		switch (reg & SIS550_DRAM_SIZE_MASK) {		   case SIS550_DRAM_SIZE_4MB:			ivideo.video_size = 0x400000;   break;		   case SIS550_DRAM_SIZE_8MB:			ivideo.video_size = 0x800000;   break;		   case SIS550_DRAM_SIZE_16MB:			ivideo.video_size = 0x1000000;  break;		   case SIS550_DRAM_SIZE_24MB:			ivideo.video_size = 0x1800000;  break;		   case SIS550_DRAM_SIZE_32MB:			ivideo.video_size = 0x2000000;	break;		   case SIS550_DRAM_SIZE_64MB:			ivideo.video_size = 0x4000000;	break;		   case SIS550_DRAM_SIZE_96MB:			ivideo.video_size = 0x6000000;	break;		   case SIS550_DRAM_SIZE_128MB:			ivideo.video_size = 0x8000000;	break;		   case SIS550_DRAM_SIZE_256MB:			ivideo.video_size = 0x10000000;	break;		   default:		        /* TW: Some 550 BIOSes don't seem to initialize SR14 correctly (if at all),			 *     do it the hard way ourselves in this case. Unfortunately, we don't			 *     support 24, 48, 96 and other "odd" amounts here.			 */		        printk(KERN_INFO			       "sisfb: Warning: Could not determine memory size, "			       "now reading from PCI config\n");			pdev_valid = 0;			pci_for_each_dev(pdev) {			   if ( (pdev->vendor == PCI_VENDOR_ID_SI)			         && (pdev->device == PCI_DEVICE_ID_SI_550) ) {				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,				                     &pci_data);				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;				ivideo.video_size = (unsigned int)(1 << (pci_data+21));				pdev_valid = 1;				/* TW: Initialize SR14=IND_SIS_DRAM_SIZE */				inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);				reg &= 0xC0;				switch (pci_data) {				   case BRI_DRAM_SIZE_4MB:					reg |= SIS550_DRAM_SIZE_4MB;  break;				   case BRI_DRAM_SIZE_8MB:					reg |= SIS550_DRAM_SIZE_8MB;  break;				   case BRI_DRAM_SIZE_16MB:					reg |= SIS550_DRAM_SIZE_16MB; break;				   case BRI_DRAM_SIZE_32MB:					reg |= SIS550_DRAM_SIZE_32MB; break;				   case BRI_DRAM_SIZE_64MB:					reg |= SIS550_DRAM_SIZE_64MB; break;				   default:				   	printk(KERN_INFO "sisfb: Unable to determine memory size, giving up.\n");					return -1;				}				outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);			   }			}			if (!pdev_valid) {				printk(KERN_INFO "sisfb: Total confusion - No SiS PCI VGA device found?!\n");				return -1;			}			return 0;		}#endif		return 0;	} else {	/* 315 */	        inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);		switch ((reg & SIS315_DRAM_SIZE_MASK) >> 4) {		   case SIS315_DRAM_SIZE_2MB:			ivideo.video_size = 0x200000;			break;		   case SIS315_DRAM_SIZE_4MB:			ivideo.video_size = 0x400000;			break;		   case SIS315_DRAM_SIZE_8MB:			ivideo.video_size = 0x800000;			break;		   case SIS315_DRAM_SIZE_16MB:			ivideo.video_size = 0x1000000;			break;		   case SIS315_DRAM_SIZE_32MB:			ivideo.video_size = 0x2000000;			break;		   case SIS315_DRAM_SIZE_64MB:			ivideo.video_size = 0x4000000;			break;		   case SIS315_DRAM_SIZE_128MB:			ivideo.video_size = 0x8000000;			break;		   default:			return -1;		}	}	reg &= SIS315_DUAL_CHANNEL_MASK;	reg >>= 2;	switch (reg) {	   case SIS315_SINGLE_CHANNEL_2_RANK:		ivideo.video_size <<= 1;		break;	   case SIS315_DUAL_CHANNEL_1_RANK:		ivideo.video_size <<= 1;		break;	   case SIS315_ASYM_DDR:		/* TW: DDR asymentric */		ivideo.video_size += (ivideo.video_size/2);		break;	}	return 0;}static void sisfb_detect_VB_connect_315(void){

⌨️ 快捷键说明

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