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

📄 sstfb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* 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);}/* * Interface to the world */int  __init sstfb_setup(char *options){	char *this_opt;	f_dprintk("sstfb_setup\n");	if (!options || !*options)		return 0;	for(this_opt = strtok(options, ","); this_opt;		this_opt = strtok(NULL, ",")) { //XXX//XXX	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 __devinit sstfb_init(void){	f_dprintk("sstfb_init\n");	dprintk("Compile date: "__DATE__" "__TIME__"\n");	return pci_module_init(&sstfb_driver);}void __devexit sstfb_exit(void){	f_dprintk("sstfb_exit\n");	pci_unregister_driver(&sstfb_driver);}#ifdef MODULEmodule_init(sstfb_init);module_exit(sstfb_exit);#endifstatic int __devinit sstfb_probe(struct pci_dev *pdev, const struct pci_device_id *id){	struct fb_var_screeninfo var;	struct sstfb_info * sst_info;	struct sst_spec * spec;	int tmp,err;	f_dprintk("sstfb_probe\n");	/* dev >  0  the device is not the one asked for.   skip */	/* dev == 0  this is the device the user asked.     init */	/* dev == -1 we already inited the asked device.    skip */	/* dev < -1  init all devices. including this one.  init */	if ((dev == -1 ) || (dev-- > 0))		return -1;	if ((err=pci_enable_device(pdev))) {		eprintk("cannot enable device\n");		return err;	}	sst_info = (struct sstfb_info*)kmalloc(sizeof(*sst_info), GFP_KERNEL);	if (!sst_info)		goto fail_kmalloc;	pci_set_drvdata(pdev, sst_info);	sst_info->type = id->driver_data;	spec = &voodoo_spec[sst_info->type];	f_ddprintk("found device : %s\n", spec->name);	sst_info->dev = pdev;	pci_read_config_byte(pdev, PCI_REVISION_ID, &sst_info->revision);	sst_info->mmio.base = pci_resource_start(pdev,0);	sst_info->video.base = sst_info->mmio.base+0x400000;	if (!request_mem_region(sst_info->mmio.base,0x400000,"sstfb MMIO")) {		eprintk ("cannot reserve mmio memory\n");		goto fail_mmio_mem;	}	if (!request_mem_region(sst_info->video.base,0x400000,"sstfb FB")) {		eprintk ("cannot reserve fb memory\n");		goto fail_fb_mem;	}	sst_info->mmio.vbase = (u_long) ioremap_nocache(sst_info->mmio.base, 0x400000);	if (!sst_info->mmio.vbase) {		eprintk("cannot remap register area %#lx\n",		        sst_info->mmio.base);		goto fail_mmio_remap;	}	sst_info->video.vbase = (u_long) ioremap_nocache(sst_info->video.base, 0x400000);	if (!sst_info->video.vbase) {		eprintk("cannot remap framebuffer %#lx\n",		        sst_info->video.base);		goto fail_fb_remap;	}	if(!sst_init(sst_info)) {		eprintk("Init failed\n");		goto fail;	}	sst_get_memsize(sst_info, &sst_info->video.len);	strncpy(sst_info->info.modename, spec->name, 16);	iprintk("%s with %s dac\n", sst_info->info.modename, sst_info->dac_sw.name);	iprintk("framebuffer at %#lx, mapped to %#lx,"	        " size %ldMb\n",	        sst_info->video.base, sst_info->video.vbase,	        sst_info->video.len >> 20);	f_ddprintk("revision: %d\n", sst_info->revision);	f_ddprintk("regbase_virt: %#lx\n", sst_info->mmio.vbase);	f_ddprintk("membase_phys: %#lx\n", sst_info->video.base);	f_ddprintk("fbbase_virt: %#lx\n", sst_info->video.vbase);	sst_info->info.node       = -1 ;	sst_info->info.flags      = FBINFO_FLAG_DEFAULT;	sst_info->info.fbops      = &sstfb_ops;	sst_info->info.disp       = &sst_info->disp;	sst_info->info.changevar  = NULL;	sst_info->info.switch_con = &sstfbcon_switch;	sst_info->info.updatevar  = &sstfbcon_updatevar;	sst_info->info.blank      = &sstfbcon_blank;	tmp=0;	var = sstfb_default;	if ( mode_option  &&	     fb_find_mode(&var, &sst_info->info, mode_option,	                   NULL, 0, NULL, 16)) {		if (sstfb_set_var(&var, -1, &sst_info->info)) {			eprintk("can't set supplied video mode. Using default\n");			var = sstfb_default;		} else {			/* set the new default */			sstfb_default = var;			tmp=1;  /* no need to set the mode. */		}	}	if (!tmp && sstfb_set_var(&var, -1, &sst_info->info)) {		eprintk("can't set default video mode.\n");		goto fail;	}	/*clear fb */	memset_io(sst_info->video.vbase, 0, sst_info->video.len);	/* print some squares ... */	sstfb_test16(sst_info); /* FIXME this is only for 16bpp */	/* register fb */	if (register_framebuffer(&sst_info->info) < 0) {		eprintk("can't register framebuffer.\n");		goto fail;	}	printk(KERN_INFO "fb%d: %s frame buffer device\n",	       GET_FB_IDX(sst_info->info.node),sst_info->info.modename);	return 0;fail:	iounmap((void *)sst_info->video.base);fail_fb_remap:	iounmap((void *)sst_info->mmio.base);fail_mmio_remap:	release_mem_region(sst_info->video.base,0x400000);fail_fb_mem:	release_mem_region(sst_info->mmio.base,0x400000);fail_mmio_mem:	kfree(sst_info);fail_kmalloc:	return -ENXIO; 	/* no voodoo detected */}static void __devexit sstfb_remove(struct pci_dev *pdev){	struct sstfb_info * sst_info;	f_dprintk("sstfb_remove\n");	sst_info=pci_get_drvdata(pdev);	sst_shutdown(sst_info);	unregister_framebuffer(&sst_info->info);	iounmap((void*)sst_info->video.vbase);	iounmap((void*)sst_info->mmio.vbase);	release_mem_region(sst_info->video.base,0x400000);	release_mem_region(sst_info->mmio.base,0x400000);	kfree(sst_info);}/* * 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", sst_info->currcon);	v_dprintk("currcon: %d\n", sst_info->currcon);	if (sst_info->currcon >=  0) {		if (fb_display[sst_info->currcon].cmap.len)			fb_get_cmap(&fb_display[sst_info->currcon].cmap, 1,			            sstfb_getcolreg, info);	}	sst_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");	/* white rectangle 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;	  }	}	/* blue rectangle 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;	  }	}	/* green rectangle 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;	  }	}	/* red rectangle 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;	u_long 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 */MODULE_AUTHOR("(c) 2000,2002 Ghozlane Toumi <gtoumi@laposte.net>");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)");/* * Overrides for Emacs so that we follow Linus's tabbing style. * --------------------------------------------------------------------------- * Local variables: * c-basic-offset: 8 * End: */#if 0void __Dump_regs (struct sstfb_info * sst_info){	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"},	};	int pci_s = sizeof(pci_regs)/sizeof(*pci_regs);	int sst_s = sizeof(sst_regs)/sizeof(*sst_regs);	u32 pci_res[pci_s];	u32 sst_res[sst_s];	struct pci_dev * dev = sst_info->dev;	int i;	for (i=0; i < pci_s ; i++ ) {		pci_read_config_dword ( dev, pci_regs[i].reg , &pci_res[i]) ;	}	for (i=0; i < sst_s ; i++ ) {		sst_res[i]=sst_read(sst_regs[i].reg);	}	dprintk ("Dump regs\n");	for (i=0; i < pci_s ; i++ ) {		dprintk("%s = %0#10x\n", pci_regs[i].reg_name , pci_res[i]) ;	}	for (i=0; i < sst_s ; 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 + -