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

📄 radeon_base.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	rinfo->depth = depth;	RTRACE("pixclock = %lu\n", (unsigned long)pixClock);	RTRACE("freq = %lu\n", (unsigned long)freq);	/* We use PPLL_DIV_3 */	newmode->clk_cntl_index = 0x300;	/* Calculate PPLL value if necessary */	if (!nopllcalc)		radeon_calc_pll_regs(rinfo, newmode, freq);	newmode->vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl;	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {		unsigned int hRatio, vRatio;		if (mode->xres > rinfo->panel_info.xres)			mode->xres = rinfo->panel_info.xres;		if (mode->yres > rinfo->panel_info.yres)			mode->yres = rinfo->panel_info.yres;		newmode->fp_horz_stretch = (((rinfo->panel_info.xres / 8) - 1)					   << HORZ_PANEL_SHIFT);		newmode->fp_vert_stretch = ((rinfo->panel_info.yres - 1)					   << VERT_PANEL_SHIFT);		if (mode->xres != rinfo->panel_info.xres) {			hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX,					   rinfo->panel_info.xres);			newmode->fp_horz_stretch = (((((unsigned long)hRatio) & HORZ_STRETCH_RATIO_MASK)) |						   (newmode->fp_horz_stretch &						    (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH |						     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;}#ifdef CONFIG_PMAC_BACKLIGHT/* TODO: Dbl check these tables, we don't go up to full ON backlight * in these, possibly because we noticed MacOS doesn't, but I'd prefer * having some more official numbers from ATI */static int backlight_conv_m6[] = {	0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,	0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24};static int backlight_conv_m7[] = {	0x00, 0x3f, 0x4a, 0x55, 0x60, 0x6b, 0x76, 0x81,	0x8c, 0x97, 0xa2, 0xad, 0xb8, 0xc3, 0xce, 0xd9};#define BACKLIGHT_LVDS_OFF#undef BACKLIGHT_DAC_OFF/* We turn off the LCD completely instead of just dimming the backlight. * This provides some greater power saving and the display is useless * without backlight anyway. */static int radeon_set_backlight_enable(int on, int level, void *data){	struct radeonfb_info *rinfo = (struct radeonfb_info *)data;	u32 lvds_gen_cntl, tmpPixclksCntl;	int* conv_table;	if (rinfo->mon1_type != MT_LCD)		return 0;	/* Pardon me for that hack... maybe some day we can figure	 * out in what direction backlight should work on a given	 * panel ?	 */	if ((rinfo->family == CHIP_FAMILY_RV200 ||	     rinfo->family == CHIP_FAMILY_RV250 ||	     rinfo->family == CHIP_FAMILY_RV280 ||	     rinfo->family == CHIP_FAMILY_RV350) &&	    !machine_is_compatible("PowerBook4,3") &&	    !machine_is_compatible("PowerBook6,3") &&	    !machine_is_compatible("PowerBook6,5"))		conv_table = backlight_conv_m7;	else		conv_table = backlight_conv_m6;	del_timer_sync(&rinfo->lvds_timer);	radeon_engine_idle();	lvds_gen_cntl = INREG(LVDS_GEN_CNTL);	if (on && (level > BACKLIGHT_OFF)) {		lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;		if (!(lvds_gen_cntl & LVDS_BLON) || !(lvds_gen_cntl & LVDS_ON)) {			lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_DIGON);			lvds_gen_cntl |= LVDS_BLON | LVDS_EN;			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);			lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;			lvds_gen_cntl |= (conv_table[level] <<					  LVDS_BL_MOD_LEVEL_SHIFT);			lvds_gen_cntl |= LVDS_ON;			lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_BL_MOD_EN);			rinfo->pending_lvds_gen_cntl = lvds_gen_cntl;			mod_timer(&rinfo->lvds_timer,				  jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay));		} else {			lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;			lvds_gen_cntl |= (conv_table[level] <<					  LVDS_BL_MOD_LEVEL_SHIFT);			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);		}		rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;		rinfo->init_state.lvds_gen_cntl |= rinfo->pending_lvds_gen_cntl			& LVDS_STATE_MASK;	} else {		/* Asic bug, when turning off LVDS_ON, we have to make sure		   RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off		*/		tmpPixclksCntl = INPLL(PIXCLKS_CNTL);		if (rinfo->is_mobility || rinfo->is_IGP)			OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb);		lvds_gen_cntl &= ~(LVDS_BL_MOD_LEVEL_MASK | LVDS_BL_MOD_EN);		lvds_gen_cntl |= (conv_table[0] <<				  LVDS_BL_MOD_LEVEL_SHIFT);		lvds_gen_cntl |= LVDS_DISPLAY_DIS;		OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);		udelay(100);		lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN);		OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);		lvds_gen_cntl &= ~(LVDS_DIGON);		rinfo->pending_lvds_gen_cntl = lvds_gen_cntl;		mod_timer(&rinfo->lvds_timer,			  jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay));		if (rinfo->is_mobility || rinfo->is_IGP)			OUTPLL(PIXCLKS_CNTL, tmpPixclksCntl);	}	rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;	rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);	return 0;}static int radeon_set_backlight_level(int level, void *data){	return radeon_set_backlight_enable(1, level, data);}#endif /* CONFIG_PMAC_BACKLIGHT *//* * 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(CONFIG_APER_0_BASE);	aper_size = INREG(CONFIG_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);		RTRACE("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)) {          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(CONFIG_MEMSIZE);        }	/* mem size is bits [28:0], mask off the rest */	rinfo->video_ram = tmp & CONFIG_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;	  

⌨️ 快捷键说明

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