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

📄 sis_main.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 5 页
字号:
		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;}#endif  /* CONFIG_FB_SIS_300 */#ifdef CONFIG_FB_SIS_315    /* for SiS 315/550/650/740/330 */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 || ivideo.chip == SIS_740) {#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) ||				     (pdev->device == PCI_DEVICE_ID_SI_740))) {				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, 330 */	        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;				if(ivideo.chip == SIS_330) {				   if(reg) ivideo.video_size <<= 1;				} else {		   		   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 asymetric */			   ivideo.video_size += (ivideo.video_size/2);			   break;		   }		}		return 0;	}		return -1;	}#endif   /* CONFIG_FB_SIS_315 *//* -------------- video bridge detection --------------- */static void sisfb_detect_VB_connect(){	u8 sr16, sr17, cr32, temp;	if(sisvga_engine == SIS_300_VGA) {			inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17); 	      		if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {				/* Old BIOSes store the detected CRT2 type in SR17		 	 * instead of CR32. However, since our detection			 * routines store their results to CR32, we now copy			 * the remaining bits (for LCD and VGA) to CR32 for			 * unified usage.			 * SR17[0] CRT1    [1] LCD     [2] TV    [3] VGA2			 *     [4] AVIDEO  [5] SVIDEO			 */			if (sr17 & 0x01) orSISIDXREG(SISCR, 0x32, SIS_CRT1);			else		 andSISIDXREG(SISCR, 0x32, ~SIS_CRT1);					if (sr17 & 0x02) orSISIDXREG(SISCR, 0x32, SIS_VB_LCD);			else		 andSISIDXREG(SISCR, 0x32, ~SIS_VB_LCD);					/* no HiVision and no DVI connector here */			andSISIDXREG(SISCR, 0x32, ~0xc0);					/* PAL/NTSC is stored on SR16 on such machines */			if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {		   		inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_16, sr16);				if (sr16 & 0x20)					ivideo.vbflags |= TV_PAL;				else					ivideo.vbflags |= TV_NTSC;			}		} 			}		inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR32, cr32);	if (cr32 & SIS_CRT1)		sisfb_crt1off = 0;	else {		if (cr32 & 0x5F)			sisfb_crt1off = 1;		else			sisfb_crt1off = 0;	}	ivideo.vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);	if (cr32 & SIS_VB_TV)		ivideo.vbflags |= CRT2_TV;	if (cr32 & SIS_VB_LCD)		ivideo.vbflags |= CRT2_LCD;	if (cr32 & SIS_VB_CRT2)		ivideo.vbflags |= CRT2_VGA;			/* TW: Detect/set TV plug & type */	if(sisfb_tvplug != -1)	        ivideo.vbflags |= sisfb_tvplug;	if (cr32 & SIS_VB_HIVISION) 		ivideo.vbflags |= (TV_HIVISION | TV_SVIDEO);	else if (cr32 & SIS_VB_SVIDEO)		ivideo.vbflags |= TV_SVIDEO;	else if (cr32 & SIS_VB_COMPOSITE)		ivideo.vbflags |= TV_AVIDEO;	else if (cr32 & SIS_VB_SCART)		ivideo.vbflags |= TV_SCART;			if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {		if(sisvga_engine == SIS_300_VGA) {	        	inSISIDXREG(SISSR, IND_SIS_POWER_ON_TRAP, temp);			if (temp & 0x01)				ivideo.vbflags |= TV_PAL;			else				ivideo.vbflags |= TV_NTSC;		} else if((ivideo.chip <= SIS_315PRO) || (ivideo.chip >= SIS_330)) {                	inSISIDXREG(SISCR, 0x38, temp);			if(temp & 0x10)				ivideo.vbflags |= TV_PAL;			else				ivideo.vbflags |= TV_NTSC;			    	} else {	        	inSISIDXREG(SISCR, 0x79, temp);			if(temp & 0x20)				ivideo.vbflags |= TV_PAL;			else				ivideo.vbflags |= TV_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;    	}	if(enable_dstn) {		ivideo.vbflags &= ~(CRT2_TV | CRT2_VGA);		ivideo.vbflags |= CRT2_LCD;	}}static void sisfb_get_VB_type(void){	u8 vb_chipid;	u8 reg;		ivideo.hasVB = HASVB_NONE;	sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;	sishw_ext.Is301BDH = FALSE;	sishw_ext.usExternalChip = 0;	if(enable_dstn) {		ivideo.hasVB = HASVB_LVDS;		ivideo.vbflags |= VB_LVDS;		sishw_ext.usExternalChip = 0x01;		return;	}	inSISIDXREG(SISPART4, 0x00, vb_chipid);	switch (vb_chipid) {	   case 0x01:		ivideo.hasVB = HASVB_301;		inSISIDXREG(SISPART4, 0x01, reg);		if(reg < 0xb0) { 			ivideo.vbflags |= VB_301;			sishw_ext.ujVBChipID = VB_CHIP_301;			printk(KERN_INFO "sisfb: Detected SiS301 video bridge\n");		} else if(reg < 0xd0) {		 	ivideo.vbflags |= VB_301B;			sishw_ext.ujVBChipID = VB_CHIP_301B;			printk(KERN_INFO "sisfb: Detected SiS301B video bridge\n");		} else if(reg < 0xe0) {			ivideo.vbflags |= VB_301LV;			sishw_ext.ujVBChipID = VB_CHIP_301LV;			printk(KERN_INFO "sisfb: Detected SiS301LV video bridge\n");		} else if(reg <= 0xe1) {			ivideo.vbflags |= VB_302LV;			sishw_ext.ujVBChipID = VB_CHIP_302LV;			printk(KERN_INFO "sisfb: Detected SiS302LV video bridge\n");		}		break;	   case 0x02:		ivideo.hasVB = HASVB_302;		inSISIDXREG(SISPART4, 0x01, reg);		if(reg < 0xd0) {			ivideo.vbflags |= VB_302B;			sishw_ext.ujVBChipID = VB_CHIP_302B;			printk(KERN_INFO "sisfb: Detected SiS302B video bridge\n");		} else if(reg < 0xe0) {		 	ivideo.vbflags |= VB_301LV;			sishw_ext.ujVBChipID = VB_CHIP_301LV;			printk(KERN_INFO "sisfb: Detected SiS301LV video bridge\n");		} else if(reg <= 0xe1) {			ivideo.vbflags |= VB_302LV;			sishw_ext.ujVBChipID = VB_CHIP_302LV;			printk(KERN_INFO "sisfb: Detected SiS302LV video bridge\n");		}		break;	}		if(ivideo.vbflags & (VB_301B | VB_302B)) {		inSISIDXREG(SISPART4,0x23,reg);		if(!(reg & 0x02)) {			sishw_ext.Is301BDH = TRUE;			ivideo.vbflags |= VB_30xBDH;		}	}		if((!(ivideo.vbflags & VB_VIDEOBRIDGE)) && (ivideo.chip != SIS_300)) {		inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);		reg &= SIS_EXTERNAL_CHIP_MASK;		reg >>= 1;		if(sisvga_engine == SIS_300_VGA) {			switch (reg) {			   case SIS_EXTERNAL_CHIP_LVDS:				ivideo.hasVB = HASVB_LVDS;				ivideo.vbflags |= VB_LVDS;				sishw_ext.usExternalChip = 0x01;				printk(KERN_INFO "sisfb: Detected LVDS transmitter\n");				break;			   case SIS_EXTERNAL_CHIP_TRUMPION:				ivideo.hasVB = HASVB_TRUMPION;				ivideo.vbflags |= VB_TRUMPION;				sishw_ext.usExternalChip = 0x02;				printk(KERN_INFO "sisfb: Detected Trumpion LCD scaler\n");				break;	   			   case SIS_EXTERNAL_CHIP_CHRONTEL:				ivideo.hasVB = HASVB_CHRONTEL;				ivideo.vbflags |= VB_CHRONTEL;				sishw_ext.usExternalChip = 0x04;				printk(KERN_INFO "sisfb: Detected Chrontel TV encoder\n");				break;			   case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:				ivideo.hasVB = HASVB_LVDS_CHRONTEL;				ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);				sishw_ext.usExternalChip = 0x05;				printk(KERN_INFO "sisfb: Detected LVDS transmitter and Chrontel TV encoder\n");				break;			}		} else {			switch (reg) {	 	   	   case SIS310_EXTERNAL_CHIP_LVDS:				ivideo.hasVB = HASVB_LVDS;				ivideo.vbflags |= VB_LVDS;				sishw_ext.usExternalChip = 0x01;				printk(KERN_INFO "sisfb: Detected LVDS transmitter\n");				break;		   	   case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:				ivideo.hasVB = HASVB_LVDS_CHRONTEL;				ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);				sishw_ext.usExternalChip = 0x05;				printk(KERN_INFO "sisfb: Detected Chrontel LVDS transmitter and TV encoder\n");				break;				}		}		}		if(ivideo.vbflags & VB_SISBRIDGE) {		SiS_Sense30x();	} else if(ivideo.vbflags & VB_CHRONTEL) {		SiS_SenseCh();	}	}/* ------------------ Sensing routines ------------------ *//* TW: Determine and detect attached devices on SiS30x */intSISDoSense(int tempbl, int tempbh, int tempcl, int tempch){    int temp,i;    outSISIDXREG(SISPART4,0x11,tempbl);    temp = tempbh | tempcl;    setSISIDXREG(SISPART4,0x10,0xe0,temp);    for(i=0; i<10; i++) SiS_LongWait(&SiS_Pr);    tempch &= 0x7f;    inSISIDXREG(SISPART4,0x03,temp);    temp ^= 0x0e;    temp &= tempch;    return(temp);}voidSiS_Sense30x(void){  u8 backupP4_0d;  u8 testsvhs_tempbl, testsvhs_tempbh;  u8 testsvhs_tempcl, testsvhs_tempch;  u8 testcvbs_tempbl, testcvbs_tempbh;  u8 testcvbs_tempcl, testcvbs_tempch;  u8 testvga2_tempbl, testvga2_tempbh;  u8 testvga2_tempcl, testvga2_tempch;  int myflag, result;  inSISIDXREG(SISPART4,0x0d,backupP4_0d);  outSISIDXREG(SISPART4,0x0d,(backupP4_0d | 0x04));  if(sisvga_engine == SIS_300_VGA) {	if(ivideo.vbflags & (VB_301B|VB_302B|VB_301LV|VB_302LV)) {	   	testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;	   	testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;	   	testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;	} else {		testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;        	testsvhs_tempbh = 0x00; 

⌨️ 快捷键说明

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