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

📄 aty128fb.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
static void __devexit aty128_remove(struct pci_dev *pdev){	struct fb_info *info = pci_get_drvdata(pdev);	struct aty128fb_par *par;	if (!info)		return;	par = info->par;	unregister_framebuffer(info);#ifdef CONFIG_MTRR	if (par->mtrr.vram_valid)		mtrr_del(par->mtrr.vram, info->fix.smem_start,			 par->vram_size);#endif /* CONFIG_MTRR */	iounmap(par->regbase);	iounmap(info->screen_base);	release_mem_region(pci_resource_start(pdev, 0),			   pci_resource_len(pdev, 0));	release_mem_region(pci_resource_start(pdev, 2),			   pci_resource_len(pdev, 2));	framebuffer_release(info);}#endif /* CONFIG_PCI */    /*     *  Blank the display.     */static int aty128fb_blank(int blank, struct fb_info *fb){	struct aty128fb_par *par = fb->par;	u8 state = 0;	if (par->lock_blank || par->asleep)		return 0;#ifdef CONFIG_PMAC_BACKLIGHT	if ((_machine == _MACH_Pmac) && blank)		set_backlight_enable(0);#endif /* CONFIG_PMAC_BACKLIGHT */	if (blank & FB_BLANK_VSYNC_SUSPEND)		state |= 2;	if (blank & FB_BLANK_HSYNC_SUSPEND)		state |= 1;	if (blank & FB_BLANK_POWERDOWN)		state |= 4;	aty_st_8(CRTC_EXT_CNTL+1, state);	if (par->chip_gen == rage_M3) {		aty128_set_crt_enable(par, par->crt_on && !blank);		aty128_set_lcd_enable(par, par->lcd_on && !blank);	}#ifdef CONFIG_PMAC_BACKLIGHT	if ((_machine == _MACH_Pmac) && !blank)		set_backlight_enable(1);#endif /* CONFIG_PMAC_BACKLIGHT */	return 0;}/* *  Set a single color register. The values supplied are already *  rounded down to the hardware's capabilities (according to the *  entries in the var structure). Return != 0 for invalid regno. */static int aty128fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,			      u_int transp, struct fb_info *info){	struct aty128fb_par *par = info->par;	if (regno > 255	    || (par->crtc.depth == 16 && regno > 63)	    || (par->crtc.depth == 15 && regno > 31))		return 1;	red >>= 8;	green >>= 8;	blue >>= 8;	if (regno < 16) {		int i;		u32 *pal = info->pseudo_palette;		switch (par->crtc.depth) {		case 15:			pal[regno] = (regno << 10) | (regno << 5) | regno;			break;		case 16:			pal[regno] = (regno << 11) | (regno << 6) | regno;			break;		case 24:			pal[regno] = (regno << 16) | (regno << 8) | regno;			break;		case 32:			i = (regno << 8) | regno;			pal[regno] = (i << 16) | i;			break;		}	}	if (par->crtc.depth == 16 && regno > 0) {		/*		 * With the 5-6-5 split of bits for RGB at 16 bits/pixel, we		 * have 32 slots for R and B values but 64 slots for G values.		 * Thus the R and B values go in one slot but the G value		 * goes in a different slot, and we have to avoid disturbing		 * the other fields in the slots we touch.		 */		par->green[regno] = green;		if (regno < 32) {			par->red[regno] = red;			par->blue[regno] = blue;			aty128_st_pal(regno * 8, red, par->green[regno*2],				      blue, par);		}		red = par->red[regno/2];		blue = par->blue[regno/2];		regno <<= 2;	} else if (par->crtc.bpp == 16)		regno <<= 3;	aty128_st_pal(regno, red, green, blue, par);	return 0;}#define ATY_MIRROR_LCD_ON	0x00000001#define ATY_MIRROR_CRT_ON	0x00000002/* out param: u32*	backlight value: 0 to 15 */#define FBIO_ATY128_GET_MIRROR	_IOR('@', 1, __u32)/* in param: u32*	backlight value: 0 to 15 */#define FBIO_ATY128_SET_MIRROR	_IOW('@', 2, __u32)static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,			  u_long arg, struct fb_info *info){	struct aty128fb_par *par = info->par;	u32 value;	int rc;    	switch (cmd) {	case FBIO_ATY128_SET_MIRROR:		if (par->chip_gen != rage_M3)			return -EINVAL;		rc = get_user(value, (__u32 __user *)arg);		if (rc)			return rc;		par->lcd_on = (value & 0x01) != 0;		par->crt_on = (value & 0x02) != 0;		if (!par->crt_on && !par->lcd_on)			par->lcd_on = 1;		aty128_set_crt_enable(par, par->crt_on);			aty128_set_lcd_enable(par, par->lcd_on);			return 0;	case FBIO_ATY128_GET_MIRROR:		if (par->chip_gen != rage_M3)			return -EINVAL;		value = (par->crt_on << 1) | par->lcd_on;		return put_user(value, (__u32 __user *)arg);	}	return -EINVAL;}#ifdef CONFIG_PMAC_BACKLIGHTstatic int backlight_conv[] = {	0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,	0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24};/* We turn off the LCD completely instead of just dimming the backlight. * This provides greater power saving and the display is useless without * backlight anyway */#define BACKLIGHT_LVDS_OFF/* That one prevents proper CRT output with LCD off */#undef BACKLIGHT_DAC_OFFstatic int aty128_set_backlight_enable(int on, int level, void *data){	struct aty128fb_par *par = data;	unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);	if (!par->lcd_on)		on = 0;	reg |= LVDS_BL_MOD_EN | LVDS_BLON;	if (on && level > BACKLIGHT_OFF) {		reg |= LVDS_DIGION;		if (!(reg & LVDS_ON)) {			reg &= ~LVDS_BLON;			aty_st_le32(LVDS_GEN_CNTL, reg);			(void)aty_ld_le32(LVDS_GEN_CNTL);			mdelay(10);			reg |= LVDS_BLON;			aty_st_le32(LVDS_GEN_CNTL, reg);		}		reg &= ~LVDS_BL_MOD_LEVEL_MASK;		reg |= (backlight_conv[level] << LVDS_BL_MOD_LEVEL_SHIFT);#ifdef BACKLIGHT_LVDS_OFF		reg |= LVDS_ON | LVDS_EN;		reg &= ~LVDS_DISPLAY_DIS;#endif		aty_st_le32(LVDS_GEN_CNTL, reg);#ifdef BACKLIGHT_DAC_OFF		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & (~DAC_PDWN));#endif			} else {		reg &= ~LVDS_BL_MOD_LEVEL_MASK;		reg |= (backlight_conv[0] << LVDS_BL_MOD_LEVEL_SHIFT);#ifdef BACKLIGHT_LVDS_OFF		reg |= LVDS_DISPLAY_DIS;		aty_st_le32(LVDS_GEN_CNTL, reg);		(void)aty_ld_le32(LVDS_GEN_CNTL);		udelay(10);		reg &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION);#endif				aty_st_le32(LVDS_GEN_CNTL, reg);#ifdef BACKLIGHT_DAC_OFF		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PDWN);#endif			}	return 0;}static int aty128_set_backlight_level(int level, void* data){	return aty128_set_backlight_enable(1, level, data);}#endif /* CONFIG_PMAC_BACKLIGHT */#if 0    /*     *  Accelerated functions     */static inline void aty128_rectcopy(int srcx, int srcy, int dstx, int dsty,				   u_int width, u_int height,				   struct fb_info_aty128 *par){    u32 save_dp_datatype, save_dp_cntl, dstval;    if (!width || !height)        return;    dstval = depth_to_dst(par->current_par.crtc.depth);    if (dstval == DST_24BPP) {        srcx *= 3;        dstx *= 3;        width *= 3;    } else if (dstval == -EINVAL) {        printk("aty128fb: invalid depth or RGBA\n");        return;    }    wait_for_fifo(2, par);    save_dp_datatype = aty_ld_le32(DP_DATATYPE);    save_dp_cntl     = aty_ld_le32(DP_CNTL);    wait_for_fifo(6, par);    aty_st_le32(SRC_Y_X, (srcy << 16) | srcx);    aty_st_le32(DP_MIX, ROP3_SRCCOPY | DP_SRC_RECT);    aty_st_le32(DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);    aty_st_le32(DP_DATATYPE, save_dp_datatype | dstval | SRC_DSTCOLOR);    aty_st_le32(DST_Y_X, (dsty << 16) | dstx);    aty_st_le32(DST_HEIGHT_WIDTH, (height << 16) | width);    par->blitter_may_be_busy = 1;    wait_for_fifo(2, par);    aty_st_le32(DP_DATATYPE, save_dp_datatype);    aty_st_le32(DP_CNTL, save_dp_cntl); }    /*     * Text mode accelerated functions     */static void fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, int dx,			int height, int width){    sx     *= fontwidth(p);    sy     *= fontheight(p);    dx     *= fontwidth(p);    dy     *= fontheight(p);    width  *= fontwidth(p);    height *= fontheight(p);    aty128_rectcopy(sx, sy, dx, dy, width, height,			(struct fb_info_aty128 *)p->fb_info);}#endif /* 0 */static void aty128_set_suspend(struct aty128fb_par *par, int suspend){	u32	pmgt;	u16	pwr_command;	struct pci_dev *pdev = par->pdev;	if (!par->pm_reg)		return;			/* Set the chip into the appropriate suspend mode (we use D2,	 * D3 would require a complete re-initialisation of the chip,	 * including PCI config registers, clocks, AGP configuration, ...)	 */	if (suspend) {		/* Make sure CRTC2 is reset. Remove that the day we decide to		 * actually use CRTC2 and replace it with real code for disabling		 * the CRTC2 output during sleep		 */		aty_st_le32(CRTC2_GEN_CNTL, aty_ld_le32(CRTC2_GEN_CNTL) &			~(CRTC2_EN));		/* Set the power management mode to be PCI based */		/* Use this magic value for now */		pmgt = 0x0c005407;		aty_st_pll(POWER_MANAGEMENT, pmgt);		(void)aty_ld_pll(POWER_MANAGEMENT);		aty_st_le32(BUS_CNTL1, 0x00000010);		aty_st_le32(MEM_POWER_MISC, 0x0c830000);		mdelay(100);		pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);		/* Switch PCI power management to D2 */		pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL,			(pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2);		pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);	} else {		/* Switch back PCI power management to D0 */		mdelay(100);		pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 0);		pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);		mdelay(100);	}}static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state){	struct fb_info *info = pci_get_drvdata(pdev);	struct aty128fb_par *par = info->par;	/* We don't do anything but D2, for now we return 0, but	 * we may want to change that. How do we know if the BIOS	 * can properly take care of D3 ? Also, with swsusp, we	 * know we'll be rebooted, ...	 */#ifndef CONFIG_PPC_PMAC	/* HACK ALERT ! Once I find a proper way to say to each driver	 * individually what will happen with it's PCI slot, I'll change	 * that. On laptops, the AGP slot is just unclocked, so D2 is	 * expected, while on desktops, the card is powered off	 */	return 0;#endif /* CONFIG_PPC_PMAC */	 	if (state.event == pdev->dev.power.power_state.event)		return 0;	printk(KERN_DEBUG "aty128fb: suspending...\n");		acquire_console_sem();	fb_set_suspend(info, 1);	/* Make sure engine is reset */	wait_for_idle(par);	aty128_reset_engine(par);	wait_for_idle(par);	/* Blank display and LCD */	aty128fb_blank(VESA_POWERDOWN, info);	/* Sleep */	par->asleep = 1;	par->lock_blank = 1;#ifdef CONFIG_PPC_PMAC	/* On powermac, we have hooks to properly suspend/resume AGP now,	 * use them here. We'll ultimately need some generic support here,	 * but the generic code isn't quite ready for that yet	 */	pmac_suspend_agp_for_card(pdev);#endif /* CONFIG_PPC_PMAC */	/* We need a way to make sure the fbdev layer will _not_ touch the	 * framebuffer before we put the chip to suspend state. On 2.4, I	 * used dummy fb ops, 2.5 need proper support for this at the	 * fbdev level	 */	if (state.event != PM_EVENT_ON)		aty128_set_suspend(par, 1);	release_console_sem();	pdev->dev.power.power_state = state;	return 0;}static int aty128_do_resume(struct pci_dev *pdev){	struct fb_info *info = pci_get_drvdata(pdev);	struct aty128fb_par *par = info->par;	if (pdev->dev.power.power_state.event == PM_EVENT_ON)		return 0;	/* Wakeup chip */	aty128_set_suspend(par, 0);	par->asleep = 0;	/* Restore display & engine */	aty128_reset_engine(par);	wait_for_idle(par);	aty128fb_set_par(info);	fb_pan_display(info, &info->var);	fb_set_cmap(&info->cmap, info);	/* Refresh */	fb_set_suspend(info, 0);	/* Unblank */	par->lock_blank = 0;	aty128fb_blank(0, info);#ifdef CONFIG_PPC_PMAC	/* On powermac, we have hooks to properly suspend/resume AGP now,	 * use them here. We'll ultimately need some generic support here,	 * but the generic code isn't quite ready for that yet	 */	pmac_resume_agp_for_card(pdev);#endif /* CONFIG_PPC_PMAC */	pdev->dev.power.power_state = PMSG_ON;	printk(KERN_DEBUG "aty128fb: resumed !\n");	return 0;}static int aty128_pci_resume(struct pci_dev *pdev){	int rc;	acquire_console_sem();	rc = aty128_do_resume(pdev);	release_console_sem();	return rc;}static int __init aty128fb_init(void){#ifndef MODULE	char *option = NULL;	if (fb_get_options("aty128fb", &option))		return -ENODEV;	aty128fb_setup(option);#endif	return pci_register_driver(&aty128fb_driver);}static void __exit aty128fb_exit(void){	pci_unregister_driver(&aty128fb_driver);}module_init(aty128fb_init);module_exit(aty128fb_exit);MODULE_AUTHOR("(c)1999-2003 Brad Douglas <brad@neruo.com>");MODULE_DESCRIPTION("FBDev driver for ATI Rage128 / Pro cards");MODULE_LICENSE("GPL");module_param(mode_option, charp, 0);MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");#ifdef CONFIG_MTRRmodule_param_named(nomtrr, mtrr, invbool, 0);MODULE_PARM_DESC(nomtrr, "bool: Disable MTRR support (0 or 1=disabled) (default=0)");#endif

⌨️ 快捷键说明

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