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

📄 sstfb.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
		dprintk("bug line %d: bad depth '%u'\n", __LINE__, bpp);		break;	}}static int __init sst_init(void){	struct pll_timing gfx_timings;	int Fout;	int dac_ok;	u32 fbiinit0, fbiinit1, fbiinit4;	struct pci_dev * sst_dev = fb_info.dev; /* or define a macro ?*/	f_dprintk("sst_init\n");	f_ddprintk(" fbiinit0   fbiinit1   fbiinit2   fbiinit3   fbiinit4  "	           " fbiinit6\n");	f_ddprintk("%0#10x %0#10x %0#10x %0#10x %0#10x %0#10x\n",	            sst_read(FBIINIT0), sst_read(FBIINIT1), sst_read(FBIINIT2),	            sst_read(FBIINIT3), sst_read(FBIINIT4), sst_read(FBIINIT6));	/* disable video clock */	pci_write_config_dword(sst_dev, PCI_VCLK_DISABLE,0);	/* enable writing to init registers ,disable pci fifo*/	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);	/* reset video */	sst_set_bits(FBIINIT1, VIDEO_RESET);	sst_wait_idle();	/* reset gfx + pci fifo */	sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);	sst_wait_idle();	/* unreset fifo */	/*sst_unset_bits(FBIINIT0, FIFO_RESET);	sst_wait_idle();*/	/* unreset FBI */	/*sst_unset_bits(FBIINIT0, FBI_RESET);	sst_wait_idle();*/	/* disable dram refresh */	sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH);	sst_wait_idle();	/* remap fbinit2/3 to dac */	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,	                               PCI_EN_INIT_WR | PCI_REMAP_DAC );	/* detect dac type */	dac_ok = sst_detect_dactype();	if (!dac_ok) {		eprintk("Unknown dac type\n");		return 0;	}	/* set graphic clock */	if (dac_ok) {		fb_info.gfx_clock = fb_info.spec->default_gfx_clock;		if ((gfxclk >10 ) && (gfxclk < fb_info.spec->max_gfxclk)) {			iprintk ("Using supplied graphic freq : %dMHz\n", gfxclk);			 fb_info.gfx_clock = gfxclk *1000;		} else if (gfxclk) {			wprintk ("You fool, %dMhz is way out of spec! Using default\n", gfxclk);		}		sst_calc_pll(fb_info.gfx_clock, &Fout, &gfx_timings);		fb_info.dac_sw->set_pll(&gfx_timings, GFX_CLOCK);	}	/* disable fbiinit remap */	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,	                       PCI_EN_INIT_WR| PCI_EN_FIFO_WR );	/* defaults init registers */	/* FbiInit0: unreset gfx, unreset fifo */	fbiinit0 = FBIINIT0_DEFAULT;	fbiinit1 = FBIINIT1_DEFAULT;	fbiinit4 = FBIINIT4_DEFAULT;	if (vgapass)		fbiinit0 &= ~EN_VGA_PASSTHROUGH;	else		fbiinit0 |= EN_VGA_PASSTHROUGH;	if (slowpci) {		fbiinit1 |= SLOW_PCI_WRITES;		fbiinit4 |= SLOW_PCI_READS;	} else {		fbiinit1 &= ~SLOW_PCI_WRITES;		fbiinit4 &= ~SLOW_PCI_READS;	}	sst_write(FBIINIT0, fbiinit0);	sst_wait_idle();	sst_write(FBIINIT1, fbiinit1);	sst_wait_idle();	sst_write(FBIINIT2, FBIINIT2_DEFAULT);	sst_wait_idle();	sst_write(FBIINIT3, FBIINIT3_DEFAULT);	sst_wait_idle();	sst_write(FBIINIT4, fbiinit4);	sst_wait_idle();	if (fb_info.is_voodoo2) {		sst_write(FBIINIT6, FBIINIT6_DEFAULT);		sst_wait_idle();	}	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR );	pci_write_config_dword(sst_dev, PCI_VCLK_ENABLE, 0);	return dac_ok;}#ifdef MODULEstatic void  __exit sst_shutdown(void){	struct pll_timing gfx_timings;	int Fout;	struct pci_dev * sst_dev = fb_info.dev;	f_dprintk("sst_shutdown\n");	/* reset video, gfx, fifo, disable dram + remap fbiinit2/3 */	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);	sst_set_bits(FBIINIT1, VIDEO_RESET | EN_BLANKING);	sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH);	sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);	sst_wait_idle();	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,	                       PCI_EN_INIT_WR | PCI_REMAP_DAC );	/*set 20Mhz gfx clock */	sst_calc_pll(20000, &Fout, &gfx_timings);	fb_info.dac_sw->set_pll(&gfx_timings, GFX_CLOCK);	/* TODO maybe shutdown the dac, vrefresh and so on... */	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,	                       PCI_EN_INIT_WR);	sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET | EN_VGA_PASSTHROUGH);	pci_write_config_dword(sst_dev, PCI_VCLK_DISABLE,0);/* maybe keep fbiinit* and PCI_INIT_enable in the fb_info struct at the beginining ? */	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, 0);}#endif /* MODULE *//* * Interface to the world */int  __init sstfb_setup(char *options){	char *this_opt;	f_dprintk("sstfb_setup\n");	if (!options || !*options)		return 0;	while ((this_opt = strsep(&options, ",")) != NULL) {		if (!*this_opt) continue;		f_ddprintk("option %s\n", this_opt);		if (!strcmp(this_opt, "inverse")) {			inverse = 1;			fb_invert_cmaps();		}		else if (!strcmp(this_opt, "vganopass"))			vgapass = 0;		else if (!strcmp(this_opt, "vgapass"))			vgapass = 1;		else if (!strcmp(this_opt, "clipping"))		        clipping = 1;		else if (!strcmp(this_opt, "noclipping"))		        clipping = 0;		else if (!strcmp(this_opt, "fastpci"))		        slowpci = 0;		else if (!strcmp(this_opt, "slowpci"))		        slowpci = 1;		else if (!strncmp(this_opt, "mem:",4))			mem=simple_strtoul (this_opt+4, NULL, 0);		else if (!strncmp(this_opt, "gfxclk:",7))			gfxclk=simple_strtoul (this_opt+7, NULL, 0);		else if (!strncmp(this_opt, "dev:",4))			dev=simple_strtoul (this_opt+4, NULL, 0);		else			mode_option=this_opt;	}	return 0;}int __init sstfb_init(void){	struct pci_dev * pdev;	struct fb_var_screeninfo var;#define sst_dev	(fb_info.dev)	f_dprintk("sstfb_init\n");	dprintk("Compile date: "__DATE__" "__TIME__"\n");	memset (&fb_info, 0, sizeof(fb_info));	pci_for_each_dev(pdev) {		if (pdev->vendor != PCI_VENDOR_ID_3DFX) continue;		if (pdev->device == PCI_DEVICE_ID_3DFX_VOODOO) {			fb_info.is_voodoo2=0;			fb_info.spec=&voodoo1_spec;		}		else if (pdev->device == PCI_DEVICE_ID_3DFX_VOODOO2) {			fb_info.is_voodoo2=1;			fb_info.spec=&voodoo2_spec;		}		else			continue;		if (dev > 0) {			dev--;			continue;		}		f_ddprintk("found device : %s\n", fb_info.spec->name);		fb_info.dev = pdev;		fb_info.mmio.base = sst_dev->resource[0].start;		pci_read_config_byte(sst_dev,		                     PCI_REVISION_ID, &fb_info.revision);		fb_info.mmio.vbase = (u32) ioremap_nocache(fb_info.mmio.base, 0x400000);		if (!fb_info.mmio.vbase) {			eprintk("cannot remap register area %#lx\n",			        fb_info.mmio.base);			return -ENXIO;		}		fb_info.video.base = fb_info.mmio.base+0x400000;		fb_info.video.vbase = (u32) ioremap_nocache(fb_info.video.base,					            0x400000);		if (!fb_info.video.vbase) {			eprintk("cannot remap framebuffer %#lx\n",			        fb_info.video.base);			iounmap((void*) fb_info.mmio.vbase);			return -ENXIO;		}		if(!sst_init()) {			eprintk("Init failed\n");			iounmap((void*)fb_info.mmio.vbase);			iounmap((void*)fb_info.video.vbase);			return -ENXIO;		}		sst_get_memsize(&fb_info.video.len);		fb_info.configured = 1;		strncpy(fb_info.info.modename, fb_info.spec->name, 16);		iprintk("%s with %s dac\n", fb_info.info.modename, fb_info.dac_sw->name);		iprintk("framebuffer at %#lx, mapped to %#lx,"		        " size %ldMb\n",		        fb_info.video.base, fb_info.video.vbase,		        fb_info.video.len >> 20);		f_ddprintk("revision: %d\n", fb_info.revision);		f_ddprintk("regbase_virt: %#lx\n", fb_info.mmio.vbase);		f_ddprintk("membase_phys: %#lx\n", fb_info.video.base);		f_ddprintk("fbbase_virt: %#lx\n", fb_info.video.vbase);		fb_info.info.node       = -1 ;		fb_info.info.flags      = FBINFO_FLAG_DEFAULT;		fb_info.info.fbops      = &sstfb_ops;		fb_info.info.disp       = &disp;		fb_info.info.changevar  = NULL;		fb_info.info.switch_con = &sstfbcon_switch;		fb_info.info.updatevar  = &sstfbcon_updatevar;		fb_info.info.blank      = &sstfbcon_blank;		if ( !mode_option &&	             !fb_find_mode(&var, &fb_info.info, mode_option,		                   NULL, 0, NULL, 16)) {			var = sstfb_default;		}		if (sstfb_set_var(&var, -1, &fb_info.info)) {			eprintk("can't set supplied video mode. Using default\n");			var = sstfb_default;			if (sstfb_set_var(&var, -1, &fb_info.info)) {				eprintk("can't set default video mode.\n");				return -ENXIO;			}		}		/*clear fb */		memset_io(fb_info.video.vbase, 0, fb_info.video.len);		/* print some squares ... */		sstfb_test16(&fb_info); /* FIXME this is only for 16bpp */		/* register fb */		if (register_framebuffer(&fb_info.info) < 0) {			eprintk("can't register framebuffer.\n");			return -ENXIO;		}		printk(KERN_INFO "fb%d: %s frame buffer device\n",		       GET_FB_IDX(fb_info.info.node),fb_info.info.modename);		num_sst++;		if (dev <= 0)	/* we use the first card only for now (==0) */			return 0;	}	return -ENXIO; 	/* no voodoo detected */#undef sst_dev}/* * console driver */static int sstfbcon_switch(int con, struct fb_info *info){#define sst_info	 ((struct sstfb_info *) info)	struct sstfb_par par;	f_dprintk("sstfbcon_switch(con: %d)\n",con);	f_ddprintk("currcon: %d\n", currcon);	v_dprintk("currcon: %d\n", currcon);	if (currcon >=  0) {		if (fb_display[currcon].cmap.len)			fb_get_cmap(&fb_display[currcon].cmap, 1,			            sstfb_getcolreg, info);	}	currcon = con;	fb_display[con].var.activate = FB_ACTIVATE_NOW;	print_var(&fb_display[con].var, "&fb_display[con: %d].var",con);	sstfb_decode_var(&fb_display[con].var, &par, sst_info);	if (memcmp(&par,&(sst_info->current_par),sizeof(par))) {		sstfb_set_par(&par, sst_info);	}	sstfb_install_cmap(con, info);	return 0;#undef sst_info}static int sstfbcon_updatevar(int con, struct fb_info *info){	f_dprintk("sstfbcon_updatevar\n");	return -EINVAL;}static void sstfbcon_blank(int blank, struct fb_info *info){	f_dprintk("sstfbcon_blank(level %d)\n", blank);}/* print some squares on the fb (presuming 16bpp)  */static void sstfb_test16(struct sstfb_info *sst_info){	int i,j;	u_long p;	u_long fbbase_virt = sst_info->video.vbase;	f_dprintk("sstfb_test16\n");	/* rect blanc 20x100+200+0 */	for (i=0 ; i< 100; i++) {	  p = fbbase_virt + 2048 *i+400;	  for (j=0 ; j < 10 ; j++) {	    writel( 0xffffffff, p);	    p+=4;	  }	}	/* rect bleu 180x200+0+0 */	for (i=0 ; i< 200; i++) {	  p = fbbase_virt + 2048 *i;	  for (j=0 ; j < 90 ; j++) {	    writel(0x001f001f,p);	    p+=4;	  }	}	/* carre vert 40x40+100+0 */	for (i=0 ; i< 40 ; i++) {	  p = fbbase_virt + 2048 *i + 200;	  for (j=0; j <20;j++) {	    writel(0x07e007e0, p);	    p+=4;	  }	}	/*carre rouge 40x40+100+40 */	for (i=0; i<40; i++) {	  p = fbbase_virt + 2048 * (i+40) + 200;	  for (j=0; j <20;j++) {	    writel( 0xf800f800, p);	    p+=4;	  }	}}/* print some squares on the fb (24/32bpp)  */#ifdef EN_24_32_BPPstatic void sstfb_test32(struct sstfb_info *sst_info){	int i,j;	u_long p;	u32 fbbase_virt = sst_info->video.vbase;	f_dprintk("sstfb_test32\n");	/* rect blanc 20x100+200+0 */	for (i=0 ; i< 100; i++) {	  p = fbbase_virt + 4096*i + 800;	  for (j=0 ; j < 20 ; j++) {	    writel( 0x00ffffff, p);	    p+=4;	  }	}	/* rect bleu 180x200+0+0 */	for (i=0 ; i< 200; i++) {	  p = fbbase_virt + 4096 * i;	  for (j=0 ; j < 180 ; j++) {	    writel(0x000000ff,p);	    p+=4;	  }	}	/* carre vert 40x40+100+0 */	for (i=0 ; i< 40 ; i++) {	  p = fbbase_virt + 4096 *i + 400;	  for (j=0; j <40;j++) {	    writel(0x0000ff00, p);	    p+=4;	  }	}	/*carre rouge 40x40+100+10 */	for (i=0; i<40; i++) {	  p = fbbase_virt + 4096 * (i+40) + 400;	  for (j=0; j <40;j++) {	    writel( 0x00ff0000, p);	    p+=4;	  }	}}#endif /* EN_24_32_BPP */#ifdef MODULEint init_module(void){	f_dprintk("init_module\n");	sstfb_init();	if (num_sst == 0 )		return -ENXIO;	return 0;}void cleanup_module(void){	f_dprintk("cleanup_module\n");	f_ddprintk("conf %d\n",fb_info.configured);	if (fb_info.configured) {		sst_shutdown();		iounmap((void*)fb_info.mmio.vbase);		iounmap((void*)fb_info.video.vbase);		unregister_framebuffer(&fb_info.info);	}}MODULE_AUTHOR("(c) 2000,2001 Ghozlane Toumi <gtoumi@messel.emse.fr>");MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards");MODULE_LICENSE("GPL");MODULE_PARM(mem, "i");MODULE_PARM_DESC(mem, "Size of frame buffer memory in MiB (1, 2, 4 Mb, default=autodetect)");MODULE_PARM(vgapass, "i");MODULE_PARM_DESC(vgapass, "Enable VGA PassThrough cable (0 or 1) (default=0)");MODULE_PARM(inverse, "i");MODULE_PARM_DESC(inverse, "Inverse colormap (0 or 1) (default=0)");MODULE_PARM(clipping , "i");MODULE_PARM_DESC(clipping, "Enable clipping (slower, safer) (0 or 1) (default=1)");MODULE_PARM(gfxclk , "i");MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in Mhz. DANGEROUS. (default=auto)");MODULE_PARM(slowpci, "i");MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");MODULE_PARM(dev,"i");MODULE_PARM_DESC(dev , "Attach to device ID (0..n) (default=1st device)");#endif	/* MODULE *//* * Overrides for Emacs so that we follow Linus's tabbing style. * --------------------------------------------------------------------------- * Local variables: * c-basic-offset: 8 * End: */#if 0void Dump_regs ( void){	struct { u32 reg ; char * reg_name;}  pci_regs [] =  {		{ PCI_INIT_ENABLE, "initenable"},		{ PCI_VCLK_ENABLE, "enable vclk"}, 		{ PCI_VCLK_DISABLE, "disable vclk"}, 	};	struct { u32 reg ; char * reg_name;}  sst_regs [] =  {		{FBIINIT0,"fbiinit0"},		{FBIINIT1,"fbiinit1"},		{FBIINIT2,"fbiinit2"},		{FBIINIT3,"fbiinit3"},		{FBIINIT4,"fbiinit4"},		{FBIINIT5,"fbiinit5"},		{FBIINIT6,"fbiinit6"},		{FBIINIT7,"fbiinit7"},		{LFBMODE,"lfbmode"},		{FBZMODE,"fbzmode"},	};	u32 pci_res[sizeof(pci_regs)/sizeof(pci_regs[0])];	u32 sst_res[sizeof(sst_regs)/sizeof(sst_regs[0])];	struct pci_dev * dev = fb_info.dev;	int i;	for (i=0; i<(sizeof(pci_regs)/sizeof(pci_regs[0])) ; i++ ) {		pci_read_config_dword ( dev, pci_regs[i].reg , &pci_res[i]) ;	}	for (i=0; i<(sizeof(sst_regs)/sizeof(sst_regs[0])) ; i++ ) {		sst_res[i]=sst_read(sst_regs[i].reg);	}	dprintk ("Dump regs\n");	for (i=0; i<(sizeof(pci_regs)/sizeof(pci_regs[0])) ; i++ ) {		dprintk("%s = %0#10x\n", pci_regs[i].reg_name , pci_res[i]) ;	}	for (i=0; i<(sizeof(sst_regs)/sizeof(sst_regs[0])) ; i++ ) {		dprintk("%s = %0#10x\n", sst_regs[i].reg_name , sst_res[i]) ;	}}#endif

⌨️ 快捷键说明

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