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

📄 radeonfb.c

📁 ati driver
💻 C
📖 第 1 页 / 共 5 页
字号:
	rinfo->depth = depth;	if (freq > rinfo->pll.ppll_max)		freq = rinfo->pll.ppll_max;	if (freq*12 < rinfo->pll.ppll_min)		freq = rinfo->pll.ppll_min / 12;	{		struct {			int divider;			int bitvalue;		} *post_div,		  post_divs[] = {			{ 1,  0 },			{ 2,  1 },			{ 4,  2 },			{ 8,  3 },			{ 3,  4 },			{ 16, 5 },			{ 6,  6 },			{ 12, 7 },			{ 0,  0 },		};		for (post_div = &post_divs[0]; post_div->divider; ++post_div) {			rinfo->pll_output_freq = post_div->divider * freq;			if (rinfo->pll_output_freq >= rinfo->pll.ppll_min  &&			    rinfo->pll_output_freq <= rinfo->pll.ppll_max)				break;		}		rinfo->post_div = post_div->divider;		rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq,					  rinfo->pll.ref_clk);		newmode.ppll_ref_div = rinfo->pll.ref_div;		newmode.ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);	}	newmode.vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl;#ifdef CONFIG_ALL_PPC	/* Gross hack for iBook with M7 until I find out a proper fix */	if (machine_is_compatible("PowerBook4,3") && rinfo->arch == RADEON_M7)		newmode.ppll_div_3 = 0x000600ad;#endif /* CONFIG_ALL_PPC */		RTRACE("post div = 0x%x\n", rinfo->post_div);	RTRACE("fb_div = 0x%x\n", rinfo->fb_div);	RTRACE("ppll_div_3 = 0x%x\n", newmode.ppll_div_3);	/* DDA */	vclk_freq = round_div(rinfo->pll.ref_clk * rinfo->fb_div,			      rinfo->pll.ref_div * rinfo->post_div);	xclk_freq = rinfo->pll.xclk;	xclk_per_trans = round_div(xclk_freq * 128, vclk_freq * mode->bits_per_pixel);	min_bits = min_bits_req(xclk_per_trans);	useable_precision = min_bits + 1;	xclk_per_trans_precise = round_div((xclk_freq * 128) << (11 - useable_precision),					   vclk_freq * mode->bits_per_pixel);	ron = (4 * rinfo->ram.mb + 3 * _max(rinfo->ram.trcd - 2, 0) +	       2 * rinfo->ram.trp + rinfo->ram.twr + rinfo->ram.cl + rinfo->ram.tr2w +	       xclk_per_trans) << (11 - useable_precision);	roff = xclk_per_trans_precise * (32 - 4);	RTRACE("ron = %d, roff = %d\n", ron, roff);	RTRACE("vclk_freq = %d, per = %d\n", vclk_freq, xclk_per_trans_precise);	if ((ron + rinfo->ram.rloop) >= roff) {		printk("radeonfb: error ron out of range\n");		return -EINVAL;	}	newmode.dda_config = (xclk_per_trans_precise |			      (useable_precision << 16) |			      (rinfo->ram.rloop << 20));	newmode.dda_on_off = (ron << 16) | roff;	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {		unsigned int hRatio, vRatio;		/* We force the pixel clock to be always enabled. Allowing it		 * to be power managed during blanking would save power, but has		 * nasty interactions with the 2D engine & sleep code that haven't		 * been solved yet. --BenH		 */		newmode.vclk_ecp_cntl &= ~PIXCLK_DAC_ALWAYS_ONb;				if (mode->xres > rinfo->panel_xres)			mode->xres = rinfo->panel_xres;		if (mode->yres > rinfo->panel_yres)			mode->yres = rinfo->panel_yres;		newmode.fp_horz_stretch = (((rinfo->panel_xres / 8) - 1)					   << HORZ_PANEL_SHIFT);		newmode.fp_vert_stretch = ((rinfo->panel_yres - 1)					   << VERT_PANEL_SHIFT);		if (mode->xres != rinfo->panel_xres) {			hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX,					   rinfo->panel_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);		}		newmode.fp_horz_stretch &= ~HORZ_AUTO_RATIO;		if (mode->yres != rinfo->panel_yres) {			vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX,					   rinfo->panel_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);		}		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);		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_RAN_PAT_RST |							 ICHCSEL | TMDS_PLL_EN) &							 ~(TMDS_PLLRST);			newmode.crtc_ext_cntl &= ~CRTC_CRT_ON;		}		newmode.fp_crtc_h_total_disp = (((rinfo->hblank / 8) & 0x3ff) |				(((mode->xres / 8) - 1) << 16));		newmode.fp_crtc_v_total_disp = (rinfo->vblank & 0xffff) |				((mode->yres - 1) << 16);		newmode.fp_h_sync_strt_wid = ((rinfo->hOver_plus & 0x1fff) |				(hsync_wid << 16) | (h_sync_pol << 23));		newmode.fp_v_sync_strt_wid = ((rinfo->vOver_plus & 0xfff) |				(vsync_wid << 16) | (v_sync_pol  << 23));	}	/* do it! */	if (!rinfo->asleep) {		radeon_write_mode (rinfo, &newmode);		/* (re)initialize the engine */		if (!noaccel)			radeon_engine_init (rinfo);		}	/* Update fix */        info->fix.line_length = rinfo->pitch*64;        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, rinfo->pitch*64);#endif	return 0;}static void radeon_write_mode (struct radeonfb_info *rinfo,                               struct radeon_regs *mode){	int i;	int primary_mon = PRIMARY_MONITOR(rinfo);	radeonfb_blank(VESA_POWERDOWN, (struct fb_info *)rinfo);	if (rinfo->arch == RADEON_M6) {		for (i=0; i<8; i++)			OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val);	} else {		for (i=0; i<9; i++)			OUTREG(common_regs[i].reg, common_regs[i].val);	}	OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);	OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,		CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);	OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);	OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);	OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);	OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);	OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);	OUTREG(CRTC_OFFSET, 0);	OUTREG(CRTC_OFFSET_CNTL, 0);	OUTREG(CRTC_PITCH, mode->crtc_pitch);#if defined(__BIG_ENDIAN)	OUTREG(SURFACE_CNTL, mode->surface_cntl);#endif	while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) !=	       PPLL_DIV_SEL_MASK) {		OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff);	}	OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff);	while ((INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) !=	       (mode->ppll_ref_div & PPLL_REF_DIV_MASK)) {		OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);	}	while ((INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) !=	       (mode->ppll_div_3 & PPLL_FB3_DIV_MASK)) {		OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);	}	while ((INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) !=	       (mode->ppll_div_3 & PPLL_POST3_DIV_MASK)) {		OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);	}	OUTPLL(HTOTAL_CNTL, 0);	OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET);//	OUTREG(DDA_CONFIG, mode->dda_config);//	OUTREG(DDA_ON_OFF, mode->dda_on_off);	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {		OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);		OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);		OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);		OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid);		OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch);		OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch);		OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl);		OUTREG(TMDS_CRC, mode->tmds_crc);		OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);		if (primary_mon == MT_LCD) {			unsigned int tmp = INREG(LVDS_GEN_CNTL);			mode->lvds_gen_cntl &= ~LVDS_STATE_MASK;			mode->lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_STATE_MASK);			if ((tmp & (LVDS_ON | LVDS_BLON)) ==			    (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON))) {				OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);			} else {				if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {					udelay(1000);					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);				} else {					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl |					       LVDS_BLON);					udelay(1000);					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);				}			}		}	}	radeonfb_blank(VESA_NO_BLANKING, (struct fb_info *)rinfo);	OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);		return;}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_pan_display 	= radeonfb_pan_display,	.fb_blank		= radeonfb_blank,	.fb_ioctl		= radeonfb_ioctl,#if 0	.fb_fillrect	= radeonfb_fillrect,	.fb_copyarea	= radeonfb_copyarea,	.fb_imageblit	= radeonfb_imageblit,	.fb_rasterimg	= radeonfb_rasterimg,#else	.fb_fillrect	= cfb_fillrect,	.fb_copyarea	= cfb_copyarea,	.fb_imageblit	= cfb_imageblit,#endif};static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo){	struct fb_info *info;	info = &rinfo->info;	info->currcon = -1;	info->par = rinfo;	info->pseudo_palette = rinfo->pseudo_palette;        info->node = NODEV;        info->flags = FBINFO_FLAG_DEFAULT;        info->fbops = &radeonfb_ops;        info->display_fg = NULL;        info->screen_base = (char *)rinfo->fb_base;	/* Fill fix common fields */	strncpy(info->fix.id, rinfo->name, sizeof(info->fix.id));	info->fix.id[sizeof(info->fix.id) - 1] = '\0';        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;	if (noaccel)	        info->fix.accel = FB_ACCEL_NONE;	else		info->fix.accel = FB_ACCEL_ATI_RADEON;        if (radeon_init_disp (rinfo) < 0)                return -1;           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;	unsigned int lvds_gen_cntl = INREG(LVDS_GEN_CNTL);	int* conv_table;	/* Pardon me for that hack... maybe some day we can figure	 * out in what direction backlight should work on a given	 * panel ?	 */	if ((rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9)		&& !machine_is_compatible("PowerBook4,3"))		conv_table = backlight_conv_m7;	else		conv_table = backlight_conv_m6;	lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON);	if (on && (level > BACKLIGHT_OFF)) {		lvds_gen_cntl |= LVDS_DIGON;		if (!lvds_gen_cntl & LVDS_ON) {			lvds_gen_cntl &= ~LVDS_BLON;			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);			(void)INREG(LVDS_GEN_CNTL);			mdelay(10);			lvds_gen_cntl |= LVDS_BLON;			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_EN);		lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;	} else {		lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;		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(10);		lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGON);	}	OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);	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 */#ifdef CONFIG_PMAC_PBOOKstatic u32 dbg_clk;/* * Radeon M6 Power Management code. This code currently only supports * the mobile chips, it's based from some informations provided by ATI * along with hours of tracing of MacOS drivers */ static void radeon_pm_save_regs(struct radeonfb_info *rinfo){	rinfo->save_regs[0] = INPLL(PLL_PWRMGT_CNTL);	rinfo->save_regs[1] = INPLL(CLK_PWRMGT_CNTL);	rinfo->save_regs[2] = INPLL(MCLK_CNTL);	rinfo->save_regs[3] = INPLL(SCLK_CNTL);	rinfo->save_regs[4] = INPLL(CLK_PIN_CNTL);	rinfo->save_regs[5] = INPLL(VCLK_ECP_CNTL);	rinfo->save_regs[6] = INPLL(PIXCLKS_CNTL);	rinfo->save_regs[7] = INPLL(MCLK_MISC);	rinfo->save_regs[8] = INPLL(P2PLL_CNTL);		rinfo->save_regs[9] = INREG(DISP_MISC_CNTL);	rinfo->save_regs[10] = INREG(DISP_PWR_MAN);	rinfo->save_regs[11] = INREG(LVDS_GEN_CNTL);	rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL);	rinfo->save_regs[13] = INREG(TV_DAC_CNTL);	rinfo->save_regs[14] = INREG(BUS_CNTL1);	rinfo->save_regs[15] = INREG(CRTC_OFFSET_CNTL);	rinfo->save_regs[16] = INREG(AGP_CNTL);	rinfo->save_regs[17] = (INREG(CRTC_GEN_CNTL) & 0xfdffffff) | 0x04000000;	rinfo->save_regs[18] = (INREG(CRTC2_GEN_CNTL) & 0xfdffffff) | 0x04000000;	rinfo->save_regs[19] = INREG(GPIOPAD_A);	rinfo->save_regs[20] = INREG(GPIOPAD_EN);	rinfo->save_regs[21] = INREG(GPIOPAD_MASK);	rinfo->save_regs[22] = INREG(ZV_LCDPAD_A);	rinfo->save_regs[23] = INREG(ZV_LCDPAD_EN);	rinfo->save_regs[24] = INREG(ZV_LCDPAD_MASK);	rinfo->save_regs[25] = INREG(GPIO_VGA_DDC);	rinfo->save_regs[26] = INREG(GPIO_DVI_DDC);	rinfo->save_regs[27] = INREG(GPIO_MONID);	rinfo->save_regs[28] = INREG(GPIO_CRT2_DDC);	rinfo->save_regs[29] = INREG(SURFACE_CNTL);	rinfo->save_regs[30] = INREG(MC_FB_LOCATION);	rinfo->save_regs[31] = INREG(DISPLAY_BASE_ADDR);	rinfo->save_regs[32] = INREG(MC_AGP_LOCATION);	rin

⌨️ 快捷键说明

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