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

📄 cyber2000fb.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	EXT_OVERSCAN_GREEN,	0,	EXT_OVERSCAN_BLUE,	0,	/* some of these are questionable when we have a BIOS */	EXT_MEM_CTL0,		EXT_MEM_CTL0_7CLK |				EXT_MEM_CTL0_RAS_1 |				EXT_MEM_CTL0_MULTCAS,	EXT_HIDDEN_CTL1,	0x30,	EXT_FIFO_CTL,		0x0b,	EXT_FIFO_CTL + 1,	0x17,	0x76,			0x00,	EXT_HIDDEN_CTL4,	0xc8};/* * Initialise the CyberPro hardware.  On the CyberPro5XXXX, * ensure that we're using the correct PLL (5XXX's may be * programmed to use an additional set of PLLs.) */static void cyberpro_init_hw(struct cfb_info *cfb){	int i;	for (i = 0; i < sizeof(igs_regs); i += 2)		cyber2000_grphw(igs_regs[i], igs_regs[i + 1], cfb);	if (cfb->id == ID_CYBERPRO_5000) {		unsigned char val;		cyber2000fb_writeb(0xba, 0x3ce, cfb);		val = cyber2000fb_readb(0x3cf, cfb) & 0x80;		cyber2000fb_writeb(val, 0x3cf, cfb);	}}static struct cfb_info __devinit *cyberpro_alloc_fb_info(unsigned int id,							 char *name){	struct cfb_info *cfb;	cfb = kzalloc(sizeof(struct cfb_info), GFP_KERNEL);	if (!cfb)		return NULL;	cfb->id			= id;	if (id == ID_CYBERPRO_5000)		cfb->ref_ps	= 40690; /* 24.576 MHz */	else		cfb->ref_ps	= 69842; /* 14.31818 MHz (69841?) */	cfb->divisors[0]	= 1;	cfb->divisors[1]	= 2;	cfb->divisors[2]	= 4;	if (id == ID_CYBERPRO_2000)		cfb->divisors[3] = 8;	else		cfb->divisors[3] = 6;	strcpy(cfb->fb.fix.id, name);	cfb->fb.fix.type	= FB_TYPE_PACKED_PIXELS;	cfb->fb.fix.type_aux	= 0;	cfb->fb.fix.xpanstep	= 0;	cfb->fb.fix.ypanstep	= 1;	cfb->fb.fix.ywrapstep	= 0;	switch (id) {	case ID_IGA_1682:		cfb->fb.fix.accel = 0;		break;	case ID_CYBERPRO_2000:		cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER2000;		break;	case ID_CYBERPRO_2010:		cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER2010;		break;	case ID_CYBERPRO_5000:		cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER5000;		break;	}	cfb->fb.var.nonstd	= 0;	cfb->fb.var.activate	= FB_ACTIVATE_NOW;	cfb->fb.var.height	= -1;	cfb->fb.var.width	= -1;	cfb->fb.var.accel_flags	= FB_ACCELF_TEXT;	cfb->fb.fbops		= &cyber2000fb_ops;	cfb->fb.flags		= FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;	cfb->fb.pseudo_palette	= cfb->pseudo_palette;	fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0);	return cfb;}static void cyberpro_free_fb_info(struct cfb_info *cfb){	if (cfb) {		/*		 * Free the colourmap		 */		fb_alloc_cmap(&cfb->fb.cmap, 0, 0);		kfree(cfb);	}}/* * Parse Cyber2000fb options.  Usage: *  video=cyber2000:font:fontname */#ifndef MODULEstatic int cyber2000fb_setup(char *options){	char *opt;	if (!options || !*options)		return 0;	while ((opt = strsep(&options, ",")) != NULL) {		if (!*opt)			continue;		if (strncmp(opt, "font:", 5) == 0) {			static char default_font_storage[40];			strlcpy(default_font_storage, opt + 5,				sizeof(default_font_storage));			default_font = default_font_storage;			continue;		}		printk(KERN_ERR "CyberPro20x0: unknown parameter: %s\n", opt);	}	return 0;}#endif  /*  MODULE  *//* * The CyberPro chips can be placed on many different bus types. * This probe function is common to all bus types.  The bus-specific * probe function is expected to have: *  - enabled access to the linear memory region *  - memory mapped access to the registers *  - initialised mem_ctl1 and mem_ctl2 appropriately. */static int __devinit cyberpro_common_probe(struct cfb_info *cfb){	u_long smem_size;	u_int h_sync, v_sync;	int err;	cyberpro_init_hw(cfb);	/*	 * Get the video RAM size and width from the VGA register.	 * This should have been already initialised by the BIOS,	 * but if it's garbage, claim default 1MB VRAM (woody)	 */	cfb->mem_ctl1 = cyber2000_grphr(EXT_MEM_CTL1, cfb);	cfb->mem_ctl2 = cyber2000_grphr(EXT_MEM_CTL2, cfb);	/*	 * Determine the size of the memory.	 */	switch (cfb->mem_ctl2 & MEM_CTL2_SIZE_MASK) {	case MEM_CTL2_SIZE_4MB:		smem_size = 0x00400000;		break;	case MEM_CTL2_SIZE_2MB:		smem_size = 0x00200000;		break;	case MEM_CTL2_SIZE_1MB:		smem_size = 0x00100000;		break;	default:		smem_size = 0x00100000;		break;	}	cfb->fb.fix.smem_len   = smem_size;	cfb->fb.fix.mmio_len   = MMIO_SIZE;	cfb->fb.screen_base    = cfb->region;	err = -EINVAL;	if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,			  &cyber2000fb_default_mode, 8)) {		printk(KERN_ERR "%s: no valid mode found\n", cfb->fb.fix.id);		goto failed;	}	cfb->fb.var.yres_virtual = cfb->fb.fix.smem_len * 8 /			(cfb->fb.var.bits_per_pixel * cfb->fb.var.xres_virtual);	if (cfb->fb.var.yres_virtual < cfb->fb.var.yres)		cfb->fb.var.yres_virtual = cfb->fb.var.yres;/*	fb_set_var(&cfb->fb.var, -1, &cfb->fb); */	/*	 * Calculate the hsync and vsync frequencies.  Note that	 * we split the 1e12 constant up so that we can preserve	 * the precision and fit the results into 32-bit registers.	 *  (1953125000 * 512 = 1e12)	 */	h_sync = 1953125000 / cfb->fb.var.pixclock;	h_sync = h_sync * 512 / (cfb->fb.var.xres + cfb->fb.var.left_margin +		 cfb->fb.var.right_margin + cfb->fb.var.hsync_len);	v_sync = h_sync / (cfb->fb.var.yres + cfb->fb.var.upper_margin +		 cfb->fb.var.lower_margin + cfb->fb.var.vsync_len);	printk(KERN_INFO "%s: %dKiB VRAM, using %dx%d, %d.%03dkHz, %dHz\n",		cfb->fb.fix.id, cfb->fb.fix.smem_len >> 10,		cfb->fb.var.xres, cfb->fb.var.yres,		h_sync / 1000, h_sync % 1000, v_sync);	if (cfb->dev)		cfb->fb.device = &cfb->dev->dev;	err = register_framebuffer(&cfb->fb);failed:	return err;}static void cyberpro_common_resume(struct cfb_info *cfb){	cyberpro_init_hw(cfb);	/*	 * Reprogram the MEM_CTL1 and MEM_CTL2 registers	 */	cyber2000_grphw(EXT_MEM_CTL1, cfb->mem_ctl1, cfb);	cyber2000_grphw(EXT_MEM_CTL2, cfb->mem_ctl2, cfb);	/*	 * Restore the old video mode and the palette.	 * We also need to tell fbcon to redraw the console.	 */	cyber2000fb_set_par(&cfb->fb);}#ifdef CONFIG_ARCH_SHARK#include <asm/arch/hardware.h>static int __devinit cyberpro_vl_probe(void){	struct cfb_info *cfb;	int err = -ENOMEM;	if (!request_mem_region(FB_START, FB_SIZE, "CyberPro2010"))		return err;	cfb = cyberpro_alloc_fb_info(ID_CYBERPRO_2010, "CyberPro2010");	if (!cfb)		goto failed_release;	cfb->dev = NULL;	cfb->region = ioremap(FB_START, FB_SIZE);	if (!cfb->region)		goto failed_ioremap;	cfb->regs = cfb->region + MMIO_OFFSET;	cfb->fb.fix.mmio_start = FB_START + MMIO_OFFSET;	cfb->fb.fix.smem_start = FB_START;	/*	 * Bring up the hardware.  This is expected to enable access	 * to the linear memory region, and allow access to the memory	 * mapped registers.  Also, mem_ctl1 and mem_ctl2 must be	 * initialised.	 */	cyber2000fb_writeb(0x18, 0x46e8, cfb);	cyber2000fb_writeb(0x01, 0x102, cfb);	cyber2000fb_writeb(0x08, 0x46e8, cfb);	cyber2000fb_writeb(EXT_BIU_MISC, 0x3ce, cfb);	cyber2000fb_writeb(EXT_BIU_MISC_LIN_ENABLE, 0x3cf, cfb);	cfb->mclk_mult = 0xdb;	cfb->mclk_div  = 0x54;	err = cyberpro_common_probe(cfb);	if (err)		goto failed;	if (int_cfb_info == NULL)		int_cfb_info = cfb;	return 0;failed:	iounmap(cfb->region);failed_ioremap:	cyberpro_free_fb_info(cfb);failed_release:	release_mem_region(FB_START, FB_SIZE);	return err;}#endif /* CONFIG_ARCH_SHARK *//* * PCI specific support. */#ifdef CONFIG_PCI/* * We need to wake up the CyberPro, and make sure its in linear memory * mode.  Unfortunately, this is specific to the platform and card that * we are running on. * * On x86 and ARM, should we be initialising the CyberPro first via the * IO registers, and then the MMIO registers to catch all cases?  Can we * end up in the situation where the chip is in MMIO mode, but not awake * on an x86 system? */static int cyberpro_pci_enable_mmio(struct cfb_info *cfb){	unsigned char val;#if defined(__sparc_v9__)#error "You lose, consult DaveM."#elif defined(__sparc__)	/*	 * SPARC does not have an "outb" instruction, so we generate	 * I/O cycles storing into a reserved memory space at	 * physical address 0x3000000	 */	unsigned char __iomem *iop;	iop = ioremap(0x3000000, 0x5000);	if (iop == NULL) {		prom_printf("iga5000: cannot map I/O\n");		return -ENOMEM;	}	writeb(0x18, iop + 0x46e8);	writeb(0x01, iop + 0x102);	writeb(0x08, iop + 0x46e8);	writeb(EXT_BIU_MISC, iop + 0x3ce);	writeb(EXT_BIU_MISC_LIN_ENABLE, iop + 0x3cf);	iounmap(iop);#else	/*	 * Most other machine types are "normal", so	 * we use the standard IO-based wakeup.	 */	outb(0x18, 0x46e8);	outb(0x01, 0x102);	outb(0x08, 0x46e8);	outb(EXT_BIU_MISC, 0x3ce);	outb(EXT_BIU_MISC_LIN_ENABLE, 0x3cf);#endif	/*	 * Allow the CyberPro to accept PCI burst accesses	 */	if (cfb->id == ID_CYBERPRO_2010) {		printk(KERN_INFO "%s: NOT enabling PCI bursts\n",		       cfb->fb.fix.id);	} else {		val = cyber2000_grphr(EXT_BUS_CTL, cfb);		if (!(val & EXT_BUS_CTL_PCIBURST_WRITE)) {			printk(KERN_INFO "%s: enabling PCI bursts\n",				cfb->fb.fix.id);			val |= EXT_BUS_CTL_PCIBURST_WRITE;			if (cfb->id == ID_CYBERPRO_5000)				val |= EXT_BUS_CTL_PCIBURST_READ;			cyber2000_grphw(EXT_BUS_CTL, val, cfb);		}	}	return 0;}static int __devinitcyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id){	struct cfb_info *cfb;	char name[16];	int err;	sprintf(name, "CyberPro%4X", id->device);	err = pci_enable_device(dev);	if (err)		return err;	err = pci_request_regions(dev, name);	if (err)		return err;	err = -ENOMEM;	cfb = cyberpro_alloc_fb_info(id->driver_data, name);	if (!cfb)		goto failed_release;	cfb->dev = dev;	cfb->region = ioremap(pci_resource_start(dev, 0),			      pci_resource_len(dev, 0));	if (!cfb->region)		goto failed_ioremap;	cfb->regs = cfb->region + MMIO_OFFSET;	cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET;	cfb->fb.fix.smem_start = pci_resource_start(dev, 0);	/*	 * Bring up the hardware.  This is expected to enable access	 * to the linear memory region, and allow access to the memory	 * mapped registers.  Also, mem_ctl1 and mem_ctl2 must be	 * initialised.	 */	err = cyberpro_pci_enable_mmio(cfb);	if (err)		goto failed;	/*	 * Use MCLK from BIOS. FIXME: what about hotplug?	 */	cfb->mclk_mult = cyber2000_grphr(EXT_MCLK_MULT, cfb);	cfb->mclk_div  = cyber2000_grphr(EXT_MCLK_DIV, cfb);#ifdef __arm__	/*	 * MCLK on the NetWinder and the Shark is fixed at 75MHz	 */	if (machine_is_netwinder()) {		cfb->mclk_mult = 0xdb;		cfb->mclk_div  = 0x54;	}#endif	err = cyberpro_common_probe(cfb);	if (err)		goto failed;	/*	 * Our driver data	 */	pci_set_drvdata(dev, cfb);	if (int_cfb_info == NULL)		int_cfb_info = cfb;	return 0;failed:	iounmap(cfb->region);failed_ioremap:	cyberpro_free_fb_info(cfb);failed_release:	pci_release_regions(dev);	return err;}static void __devexit cyberpro_pci_remove(struct pci_dev *dev){	struct cfb_info *cfb = pci_get_drvdata(dev);	if (cfb) {		/*		 * If unregister_framebuffer fails, then		 * we will be leaving hooks that could cause		 * oopsen laying around.		 */		if (unregister_framebuffer(&cfb->fb))			printk(KERN_WARNING "%s: danger Will Robinson, "				"danger danger!  Oopsen imminent!\n",				cfb->fb.fix.id);		iounmap(cfb->region);		cyberpro_free_fb_info(cfb);		/*		 * Ensure that the driver data is no longer		 * valid.		 */		pci_set_drvdata(dev, NULL);		if (cfb == int_cfb_info)			int_cfb_info = NULL;		pci_release_regions(dev);	}}static int cyberpro_pci_suspend(struct pci_dev *dev, pm_message_t state){	return 0;}/* * Re-initialise the CyberPro hardware */static int cyberpro_pci_resume(struct pci_dev *dev){	struct cfb_info *cfb = pci_get_drvdata(dev);	if (cfb) {		cyberpro_pci_enable_mmio(cfb);		cyberpro_common_resume(cfb);	}	return 0;}static struct pci_device_id cyberpro_pci_table[] = {/*	Not yet *	{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682, *		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 }, */	{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2000 },	{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2010 },	{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_5000 },	{ 0, }};MODULE_DEVICE_TABLE(pci, cyberpro_pci_table);static struct pci_driver cyberpro_driver = {	.name		= "CyberPro",	.probe		= cyberpro_pci_probe,	.remove		= __devexit_p(cyberpro_pci_remove),	.suspend	= cyberpro_pci_suspend,	.resume		= cyberpro_pci_resume,	.id_table	= cyberpro_pci_table};#endif/* * I don't think we can use the "module_init" stuff here because * the fbcon stuff may not be initialised yet.  Hence the #ifdef * around module_init. * * Tony: "module_init" is now required */static int __init cyber2000fb_init(void){	int ret = -1, err;#ifndef MODULE	char *option = NULL;	if (fb_get_options("cyber2000fb", &option))		return -ENODEV;	cyber2000fb_setup(option);#endif#ifdef CONFIG_ARCH_SHARK	err = cyberpro_vl_probe();	if (!err) {		ret = 0;		__module_get(THIS_MODULE);	}#endif#ifdef CONFIG_PCI	err = pci_register_driver(&cyberpro_driver);	if (!err)		ret = 0;#endif	return ret ? err : 0;}static void __exit cyberpro_exit(void){	pci_unregister_driver(&cyberpro_driver);}module_init(cyber2000fb_init);module_exit(cyberpro_exit);MODULE_AUTHOR("Russell King");MODULE_DESCRIPTION("CyberPro 2000, 2010 and 5000 framebuffer driver");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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