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

📄 radeon_base.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
						     HORZ_AUTO_RATIO_INC)));			newmode->fp_horz_stretch |= (HORZ_STRETCH_BLEND |						    HORZ_STRETCH_ENABLE);			use_rmx = 1;		}		newmode->fp_horz_stretch &= ~HORZ_AUTO_RATIO;		if (mode->yres != rinfo->panel_info.yres) {			vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX,					   rinfo->panel_info.yres);			newmode->fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) |						   (newmode->fp_vert_stretch &						   (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED)));			newmode->fp_vert_stretch |= (VERT_STRETCH_BLEND |						    VERT_STRETCH_ENABLE);			use_rmx = 1;		}		newmode->fp_vert_stretch &= ~VERT_AUTO_RATIO_EN;		newmode->fp_gen_cntl = (rinfo->init_state.fp_gen_cntl & (u32)				       ~(FP_SEL_CRTC2 |					 FP_RMX_HVSYNC_CONTROL_EN |					 FP_DFP_SYNC_SEL |					 FP_CRT_SYNC_SEL |					 FP_CRTC_LOCK_8DOT |					 FP_USE_SHADOW_EN |					 FP_CRTC_USE_SHADOW_VEND |					 FP_CRT_SYNC_ALT));		newmode->fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR |					FP_CRTC_DONT_SHADOW_HEND |					FP_PANEL_FORMAT);		if (IS_R300_VARIANT(rinfo) ||		    (rinfo->family == CHIP_FAMILY_R200)) {			newmode->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;			if (use_rmx)				newmode->fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX;			else				newmode->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1;		} else			newmode->fp_gen_cntl |= FP_SEL_CRTC1;		newmode->lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl;		newmode->lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl;		newmode->tmds_crc = rinfo->init_state.tmds_crc;		newmode->tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;		if (primary_mon == MT_LCD) {			newmode->lvds_gen_cntl |= (LVDS_ON | LVDS_BLON);			newmode->fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN);		} else {			/* DFP */			newmode->fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);			newmode->tmds_transmitter_cntl &= ~(TMDS_PLLRST);			/* TMDS_PLL_EN bit is reversed on RV (and mobility) chips */			if (IS_R300_VARIANT(rinfo) ||			    (rinfo->family == CHIP_FAMILY_R200) || !rinfo->has_CRTC2)				newmode->tmds_transmitter_cntl &= ~TMDS_PLL_EN;			else				newmode->tmds_transmitter_cntl |= TMDS_PLL_EN;			newmode->crtc_ext_cntl &= ~CRTC_CRT_ON;		}		newmode->fp_crtc_h_total_disp = (((rinfo->panel_info.hblank / 8) & 0x3ff) |				(((mode->xres / 8) - 1) << 16));		newmode->fp_crtc_v_total_disp = (rinfo->panel_info.vblank & 0xffff) |				((mode->yres - 1) << 16);		newmode->fp_h_sync_strt_wid = ((rinfo->panel_info.hOver_plus & 0x1fff) |				(hsync_wid << 16) | (h_sync_pol << 23));		newmode->fp_v_sync_strt_wid = ((rinfo->panel_info.vOver_plus & 0xfff) |				(vsync_wid << 16) | (v_sync_pol  << 23));	}	/* do it! */	if (!rinfo->asleep) {		memcpy(&rinfo->state, newmode, sizeof(*newmode));		radeon_write_mode (rinfo, newmode, 0);		/* (re)initialize the engine */		if (!(info->flags & FBINFO_HWACCEL_DISABLED))			radeonfb_engine_init (rinfo);	}	/* Update fix */	if (!(info->flags & FBINFO_HWACCEL_DISABLED))        	info->fix.line_length = rinfo->pitch*64;        else		info->fix.line_length = mode->xres_virtual			* ((mode->bits_per_pixel + 1) / 8);        info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR		: FB_VISUAL_DIRECTCOLOR;#ifdef CONFIG_BOOTX_TEXT	/* Update debug text engine */	btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres,			     rinfo->depth, info->fix.line_length);#endif	kfree(newmode);	return 0;}static struct fb_ops radeonfb_ops = {	.owner			= THIS_MODULE,	.fb_check_var		= radeonfb_check_var,	.fb_set_par		= radeonfb_set_par,	.fb_setcolreg		= radeonfb_setcolreg,	.fb_setcmap		= radeonfb_setcmap,	.fb_pan_display 	= radeonfb_pan_display,	.fb_blank		= radeonfb_blank,	.fb_ioctl		= radeonfb_ioctl,	.fb_sync		= radeonfb_sync,	.fb_fillrect		= radeonfb_fillrect,	.fb_copyarea		= radeonfb_copyarea,	.fb_imageblit		= radeonfb_imageblit,};static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo){	struct fb_info *info = rinfo->info;	info->par = rinfo;	info->pseudo_palette = rinfo->pseudo_palette;	info->flags = FBINFO_DEFAULT		    | FBINFO_HWACCEL_COPYAREA		    | FBINFO_HWACCEL_FILLRECT		    | FBINFO_HWACCEL_XPAN		    | FBINFO_HWACCEL_YPAN;	info->fbops = &radeonfb_ops;	info->screen_base = rinfo->fb_base;	info->screen_size = rinfo->mapped_vram;	/* Fill fix common fields */	strlcpy(info->fix.id, rinfo->name, sizeof(info->fix.id));        info->fix.smem_start = rinfo->fb_base_phys;        info->fix.smem_len = rinfo->video_ram;        info->fix.type = FB_TYPE_PACKED_PIXELS;        info->fix.visual = FB_VISUAL_PSEUDOCOLOR;        info->fix.xpanstep = 8;        info->fix.ypanstep = 1;        info->fix.ywrapstep = 0;        info->fix.type_aux = 0;        info->fix.mmio_start = rinfo->mmio_base_phys;        info->fix.mmio_len = RADEON_REGSIZE;	info->fix.accel = FB_ACCEL_ATI_RADEON;	fb_alloc_cmap(&info->cmap, 256, 0);	if (noaccel)		info->flags |= FBINFO_HWACCEL_DISABLED;        return 0;}/* * This reconfigure the card's internal memory map. In theory, we'd like * to setup the card's memory at the same address as it's PCI bus address, * and the AGP aperture right after that so that system RAM on 32 bits * machines at least, is directly accessible. However, doing so would * conflict with the current XFree drivers... * Ultimately, I hope XFree, GATOS and ATI binary drivers will all agree * on the proper way to set this up and duplicate this here. In the meantime, * I put the card's memory at 0 in card space and AGP at some random high * local (0xe0000000 for now) that will be changed by XFree/DRI anyway */#ifdef CONFIG_PPC_OF#undef SET_MC_FB_FROM_APERTUREstatic void fixup_memory_mappings(struct radeonfb_info *rinfo){	u32 save_crtc_gen_cntl, save_crtc2_gen_cntl = 0;	u32 save_crtc_ext_cntl;	u32 aper_base, aper_size;	u32 agp_base;	/* First, we disable display to avoid interfering */	if (rinfo->has_CRTC2) {		save_crtc2_gen_cntl = INREG(CRTC2_GEN_CNTL);		OUTREG(CRTC2_GEN_CNTL, save_crtc2_gen_cntl | CRTC2_DISP_REQ_EN_B);	}	save_crtc_gen_cntl = INREG(CRTC_GEN_CNTL);	save_crtc_ext_cntl = INREG(CRTC_EXT_CNTL);		OUTREG(CRTC_EXT_CNTL, save_crtc_ext_cntl | CRTC_DISPLAY_DIS);	OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl | CRTC_DISP_REQ_EN_B);	mdelay(100);	aper_base = INREG(CNFG_APER_0_BASE);	aper_size = INREG(CNFG_APER_SIZE);#ifdef SET_MC_FB_FROM_APERTURE	/* Set framebuffer to be at the same address as set in PCI BAR */	OUTREG(MC_FB_LOCATION, 		((aper_base + aper_size - 1) & 0xffff0000) | (aper_base >> 16));	rinfo->fb_local_base = aper_base;#else	OUTREG(MC_FB_LOCATION, 0x7fff0000);	rinfo->fb_local_base = 0;#endif	agp_base = aper_base + aper_size;	if (agp_base & 0xf0000000)		agp_base = (aper_base | 0x0fffffff) + 1;	/* Set AGP to be just after the framebuffer on a 256Mb boundary. This	 * assumes the FB isn't mapped to 0xf0000000 or above, but this is	 * always the case on PPCs afaik.	 */#ifdef SET_MC_FB_FROM_APERTURE	OUTREG(MC_AGP_LOCATION, 0xffff0000 | (agp_base >> 16));#else	OUTREG(MC_AGP_LOCATION, 0xffffe000);#endif	/* Fixup the display base addresses & engine offsets while we	 * are at it as well	 */#ifdef SET_MC_FB_FROM_APERTURE	OUTREG(DISPLAY_BASE_ADDR, aper_base);	if (rinfo->has_CRTC2)		OUTREG(CRTC2_DISPLAY_BASE_ADDR, aper_base);	OUTREG(OV0_BASE_ADDR, aper_base);#else	OUTREG(DISPLAY_BASE_ADDR, 0);	if (rinfo->has_CRTC2)		OUTREG(CRTC2_DISPLAY_BASE_ADDR, 0);	OUTREG(OV0_BASE_ADDR, 0);#endif	mdelay(100);	/* Restore display settings */	OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl);	OUTREG(CRTC_EXT_CNTL, save_crtc_ext_cntl);	if (rinfo->has_CRTC2)		OUTREG(CRTC2_GEN_CNTL, save_crtc2_gen_cntl);		pr_debug("aper_base: %08x MC_FB_LOC to: %08x, MC_AGP_LOC to: %08x\n",		aper_base,		((aper_base + aper_size - 1) & 0xffff0000) | (aper_base >> 16),		0xffff0000 | (agp_base >> 16));}#endif /* CONFIG_PPC_OF */static void radeon_identify_vram(struct radeonfb_info *rinfo){	u32 tmp;	/* framebuffer size */        if ((rinfo->family == CHIP_FAMILY_RS100) ||            (rinfo->family == CHIP_FAMILY_RS200) ||            (rinfo->family == CHIP_FAMILY_RS300) ||            (rinfo->family == CHIP_FAMILY_RC410) ||            (rinfo->family == CHIP_FAMILY_RS400) ||	    (rinfo->family == CHIP_FAMILY_RS480) ) {          u32 tom = INREG(NB_TOM);          tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); 		radeon_fifo_wait(6);          OUTREG(MC_FB_LOCATION, tom);          OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);          OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);          OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16);          /* This is supposed to fix the crtc2 noise problem. */          OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000);          if ((rinfo->family == CHIP_FAMILY_RS100) ||              (rinfo->family == CHIP_FAMILY_RS200)) {             /* This is to workaround the asic bug for RMX, some versions                of BIOS dosen't have this register initialized correctly.             */             OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN,                     ~CRTC_H_CUTOFF_ACTIVE_EN);          }        } else {          tmp = INREG(CNFG_MEMSIZE);        }	/* mem size is bits [28:0], mask off the rest */	rinfo->video_ram = tmp & CNFG_MEMSIZE_MASK;	/*	 * Hack to get around some busted production M6's	 * reporting no ram	 */	if (rinfo->video_ram == 0) {		switch (rinfo->pdev->device) {	       	case PCI_CHIP_RADEON_LY:		case PCI_CHIP_RADEON_LZ:	       		rinfo->video_ram = 8192 * 1024;	       		break;	       	default:	       		break;		}	}	/*	 * Now try to identify VRAM type	 */	if (rinfo->is_IGP || (rinfo->family >= CHIP_FAMILY_R300) ||	    (INREG(MEM_SDRAM_MODE_REG) & (1<<30)))		rinfo->vram_ddr = 1;	else		rinfo->vram_ddr = 0;	tmp = INREG(MEM_CNTL);	if (IS_R300_VARIANT(rinfo)) {		tmp &=  R300_MEM_NUM_CHANNELS_MASK;		switch (tmp) {		case 0:  rinfo->vram_width = 64; break;		case 1:  rinfo->vram_width = 128; break;		case 2:  rinfo->vram_width = 256; break;		default: rinfo->vram_width = 128; break;		}	} else if ((rinfo->family == CHIP_FAMILY_RV100) ||		   (rinfo->family == CHIP_FAMILY_RS100) ||		   (rinfo->family == CHIP_FAMILY_RS200)){		if (tmp & RV100_MEM_HALF_MODE)			rinfo->vram_width = 32;		else			rinfo->vram_width = 64;	} else {		if (tmp & MEM_NUM_CHANNELS_MASK)			rinfo->vram_width = 128;		else			rinfo->vram_width = 64;	}	/* This may not be correct, as some cards can have half of channel disabled	 * ToDo: identify these cases	 */	pr_debug("radeonfb (%s): Found %ldk of %s %d bits wide videoram\n",	       pci_name(rinfo->pdev),	       rinfo->video_ram / 1024,	       rinfo->vram_ddr ? "DDR" : "SDRAM",	       rinfo->vram_width);}/* * Sysfs */static ssize_t radeon_show_one_edid(char *buf, loff_t off, size_t count, const u8 *edid){	return memory_read_from_buffer(buf, count, &off, edid, EDID_LENGTH);}static ssize_t radeon_show_edid1(struct kobject *kobj,				 struct bin_attribute *bin_attr,				 char *buf, loff_t off, size_t count){	struct device *dev = container_of(kobj, struct device, kobj);	struct pci_dev *pdev = to_pci_dev(dev);        struct fb_info *info = pci_get_drvdata(pdev);        struct radeonfb_info *rinfo = info->par;	return radeon_show_one_edid(buf, off, count, rinfo->mon1_EDID);}static ssize_t radeon_show_edid2(struct kobject *kobj,				 struct bin_attribute *bin_attr,				 char *buf, loff_t off, size_t count){	struct device *dev = container_of(kobj, struct device, kobj);	struct pci_dev *pdev = to_pci_dev(dev);        struct fb_info *info = pci_get_drvdata(pdev);        struct radeonfb_info *rinfo = info->par;	return radeon_show_one_edid(buf, off, count, rinfo->mon2_EDID);}static struct bin_attribute edid1_attr = {	.attr   = {		.name	= "edid1",		.mode	= 0444,	},	.size	= EDID_LENGTH,	.read	= radeon_show_edid1,};static struct bin_attribute edid2_attr = {	.attr   = {		.name	= "edid2",		.mode	= 0444,	},	.size	= EDID_LENGTH,	.read	= radeon_show_edid2,};static int __devinit radeonfb_pci_register (struct pci_dev *pdev,				  const struct pci_device_id *ent){	struct fb_info *info;	struct radeonfb_info *rinfo;	int ret;	unsigned char c1, c2;	int err = 0;	pr_debug("radeonfb_pci_register BEGIN\n");		/* Enable device in PCI config */	ret = pci_enable_device(pdev);	if (ret < 0) {		printk(KERN_ERR "radeonfb (%s): Cannot enable PCI device\n",		       pci_name(pdev));		goto err_out;	}	info = framebuffer_alloc(sizeof(struct radeonfb_info), &pdev->dev);	if (!info) {		printk (KERN_ERR "radeonfb (%s): could not allocate memory\n",			pci_name(pdev));		ret = -ENOMEM;		goto err_disable;	}	rinfo = info->par;	rinfo->info = info;		rinfo->pdev = pdev;		spin_lock_init(&rinfo->reg_lock);	init_timer(&rinfo->lvds_timer);	rinfo->lvds_timer.function = radeon_lvds_timer_func;	rinfo->lvds_timer.data = (unsigned long)rinfo;	c1 = ent->device >> 8;	c2 = ent->device & 0xff;	if (isprint(c1) && isprint(c2))		snprintf(rinfo->name, sizeof(rinfo->name),			 "ATI Radeon %x \"%c%c\"", ent->device & 0xffff, c1, c2);	else		snprintf

⌨️ 快捷键说明

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