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

📄 radeonfb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
static void radeon_pm_yclk_mclk_sync(struct radeonfb_info *rinfo);static void radeon_pm_program_mode_reg(struct radeonfb_info *rinfo, u16 value, u8 delay_required);static void radeon_pm_enable_dll(struct radeonfb_info *rinfo);static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo);#endif /* CONFIG_PMAC_BACKLIGHT */static struct fb_ops radeon_fb_ops = {	fb_get_fix:		radeonfb_get_fix,	fb_get_var:		radeonfb_get_var,	fb_set_var:		radeonfb_set_var,	fb_get_cmap:		radeonfb_get_cmap,	fb_set_cmap:		radeonfb_set_cmap,	fb_pan_display:		radeonfb_pan_display,	fb_ioctl:		radeonfb_ioctl,};static struct pci_driver radeonfb_driver = {	name:		"radeonfb",	id_table:	radeonfb_pci_table,	probe:		radeonfb_pci_register,	remove:		__devexit_p(radeonfb_pci_unregister),};int __init radeonfb_init (void){	return pci_module_init (&radeonfb_driver);}void __exit radeonfb_exit (void){	pci_unregister_driver (&radeonfb_driver);}int __init radeonfb_setup (char *options){        char *this_opt;        if (!options || !*options)                return 0; 	while ((this_opt = strsep (&options, ",")) != NULL) {		if (!*this_opt)			continue;                if (!strncmp (this_opt, "font:", 5)) {                        char *p;                        int i;                                p = this_opt + 5;                        for (i=0; i<sizeof (fontname) - 1; i++)                                if (!*p || *p == ' ' || *p == ',')                                        break;                        memcpy(fontname, this_opt + 5, i);                } else if (!strncmp(this_opt, "noaccel", 7)) {			noaccel = 1;                } else if (!strncmp(this_opt, "mirror", 6)) {			mirror = 1;		} else if (!strncmp(this_opt, "dfp", 3)) {			force_dfp = 1;			force_nolcd = 1;		} else if (!strncmp(this_opt, "crt", 3)) {			force_crt = 1;			force_nolcd = 1;		} else if (!strncmp(this_opt, "nolcd", 5)) {			force_nolcd = 1;		} else if (!strncmp(this_opt, "panel_yres:", 11)) {			panel_yres = simple_strtoul((this_opt+11), NULL, 0);		} else if (!strncmp(this_opt, "nomtrr", 6)) {			nomtrr = 1;                } else			mode_option = this_opt;        }	return 0;}#ifdef MODULEmodule_init(radeonfb_init);module_exit(radeonfb_exit);#endifMODULE_AUTHOR("Ani Joshi");MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");MODULE_LICENSE("GPL");MODULE_PARM(noaccel, "i");MODULE_PARM_DESC(noaccel, "Disable (1) or enable (0) the usage of the 2d accel engine");MODULE_PARM(force_dfp, "i");MODULE_PARM_DESC(force_dfp,"Force (1) the usage of a digital flat panel");MODULE_PARM(force_crt, "i");MODULE_PARM_DESC(force_crt,"Force (1) the usage of a CRT monitor");MODULE_PARM(force_nolcd, "i");MODULE_PARM_DESC(force_nolcd,"Avoid (1) the usage of a digital flat panel");static unsigned char *radeon_find_rom(struct radeonfb_info *rinfo){       #if defined(__i386__)	/* I simplified this code as we used to miss the signatures in	 * a lot of case. It's now closer to XFree, we just don't check	 * for signatures at all... Something better will have to be done	 * later obviously	 */        u32  segstart;        unsigned char *rom_base;                                                        for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {                rom_base = (char *)ioremap(segstart, 0x1000);                if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))	                return rom_base;                iounmap(rom_base);        }#endif                  return NULL;}#ifdef CONFIG_ALL_PPCstatic int radeon_read_OF (struct radeonfb_info *rinfo){	struct device_node *dp;	unsigned int *xtal;	dp = pci_device_to_OF_node(rinfo->pdev);	if (dp == NULL)		return 0;	xtal = (unsigned int *) get_property(dp, "ATY,RefCLK", 0);	if ((xtal == NULL) || (*xtal == 0))		return 0;	rinfo->pll.ref_clk = *xtal / 10;	return 1;}#endif	static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg){        void *bios_header;        void *header_ptr;        u16 bios_header_offset, pll_info_offset;        PLL_BLOCK pll;	if (bios_seg) {	        bios_header = bios_seg + 0x48L;       		header_ptr  = bios_header;                	bios_header_offset = readw(header_ptr);	        bios_header = bios_seg + bios_header_offset;        	bios_header += 0x30;                	header_ptr = bios_header;        	pll_info_offset = readw(header_ptr);        	header_ptr = bios_seg + pll_info_offset;                	memcpy_fromio(&pll, header_ptr, 50);                	/* Consider ref clock to be sane between 1000 and 5000,        	 * just in case we tapped the wrong BIOS...        	 */		if (pll.PCLK_ref_freq < 1000 || pll.PCLK_ref_freq > 5000)			goto use_defaults;        	rinfo->pll.xclk = (u32)pll.XCLK;        	rinfo->pll.ref_clk = (u32)pll.PCLK_ref_freq;        	rinfo->pll.ref_div = (u32)pll.PCLK_ref_divider;        	rinfo->pll.ppll_min = pll.PCLK_min_freq;        	rinfo->pll.ppll_max = pll.PCLK_max_freq;		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOS\n",			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);	} else {#ifdef CONFIG_ALL_PPC		if (radeon_read_OF(rinfo)) {			unsigned int tmp, Nx, M, ref_div, xclk;			tmp = INPLL(M_SPLL_REF_FB_DIV);			ref_div = INPLL(PPLL_REF_DIV) & 0x3ff;			Nx = (tmp & 0xff00) >> 8;			M = (tmp & 0xff);			xclk = ((((2 * Nx * rinfo->pll.ref_clk) + (M)) /				(2 * M)));			rinfo->pll.xclk = xclk;			rinfo->pll.ref_div = ref_div;			rinfo->pll.ppll_min = 12000;			rinfo->pll.ppll_max = 35000;			printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from OF\n",				rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);			return;		}#endifuse_defaults:		/* No BIOS or BIOS not found, use defaults		 * 		 * NOTE: Those defaults settings are rather "randomly" picked from		 * informations we found so far, but we would really need some		 * better mecanism to get them. Recent XFree can +/- probe for		 * the proper clocks.		 */		switch (rinfo->arch) {			case RADEON_RV200:				rinfo->pll.ppll_max = 35000;				rinfo->pll.ppll_min = 12000;				rinfo->pll.xclk = 23000;				rinfo->pll.ref_div = 12;				rinfo->pll.ref_clk = 2700;				break;			case RADEON_R200:				rinfo->pll.ppll_max = 35000;				rinfo->pll.ppll_min = 12000;				rinfo->pll.xclk = 27500;				rinfo->pll.ref_div = 12;				rinfo->pll.ref_clk = 2700;				break;			case RADEON_RV250:				rinfo->pll.ppll_max = 35000;				rinfo->pll.ppll_min = 12000;				rinfo->pll.xclk = 25000;				rinfo->pll.ref_div = 12;				rinfo->pll.ref_clk = 2700;				break;			case RADEON_R300:				rinfo->pll.ppll_max = 40000;				rinfo->pll.ppll_min = 20000;				rinfo->pll.xclk = 27000;				rinfo->pll.ref_div = 12;				rinfo->pll.ref_clk = 2700;				break;			case RADEON_R100:			default:				rinfo->pll.ppll_max = 35000;				rinfo->pll.ppll_min = 12000;				rinfo->pll.xclk = 16600;				rinfo->pll.ref_div = 67;				rinfo->pll.ref_clk = 2700;				break;		}		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d defaults\n",			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);	}}static void radeon_get_moninfo (struct radeonfb_info *rinfo){	u32 tmp = INREG(RADEON_BIOS_4_SCRATCH);	if (force_dfp) {		printk("radeonfb: forcing DFP\n");		rinfo->dviDisp_type = MT_DFP;		return;	} else if (force_crt) {		printk("radeonfb: forcing CRT\n");		rinfo->dviDisp_type = MT_NONE;		rinfo->crtDisp_type = MT_CRT;		return;	}	if (rinfo->hasCRTC2 && tmp) {		/* primary DVI port */		if (tmp & 0x08)			rinfo->dviDisp_type = MT_DFP;		else if (tmp & 0x4)			rinfo->dviDisp_type = MT_LCD;		else if (tmp & 0x200)			rinfo->dviDisp_type = MT_CRT;		else if (tmp & 0x10)			rinfo->dviDisp_type = MT_CTV;		else if (tmp & 0x20)			rinfo->dviDisp_type = MT_STV;		/* secondary CRT port */		if (tmp & 0x2)			rinfo->crtDisp_type = MT_CRT;		else if (tmp & 0x800)			rinfo->crtDisp_type = MT_DFP;		else if (tmp & 0x400)			rinfo->crtDisp_type = MT_LCD;		else if (tmp & 0x1000)			rinfo->crtDisp_type = MT_CTV;		else if (tmp & 0x2000)			rinfo->crtDisp_type = MT_STV;	} else {		rinfo->dviDisp_type = MT_NONE;		tmp = INREG(FP_GEN_CNTL);		if (tmp & FP_EN_TMDS)			rinfo->crtDisp_type = MT_DFP;		else			rinfo->crtDisp_type = MT_CRT;	}}#ifdef CONFIG_ALL_PPCstatic int radeon_get_EDID_OF(struct radeonfb_info *rinfo){        struct device_node *dp;        unsigned char *pedid = NULL;        static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", "EDID1", NULL };        int i;          dp = pci_device_to_OF_node(rinfo->pdev);        while (dp != NULL) {                for (i = 0; propnames[i] != NULL; ++i) {                        pedid = (unsigned char *)                                get_property(dp, propnames[i], NULL);                        if (pedid != NULL) {                                rinfo->EDID = pedid;                                return 1;                        }                }                dp = dp->child;        }        return 0;}#endif /* CONFIG_ALL_PPC */static void radeon_get_EDID(struct radeonfb_info *rinfo){#ifdef CONFIG_ALL_PPC	if (!radeon_get_EDID_OF(rinfo))		RTRACE("radeonfb: could not retrieve EDID from OF\n");#else	/* XXX use other methods later */#endif}#ifdef CONFIG_ALL_PPC#undef SET_MC_FB_FROM_APERTUREstatic voidradeon_fixup_apertures(struct radeonfb_info *rinfo){	u32 save_crtc_gen_cntl, save_crtc2_gen_cntl;	u32 save_crtc_ext_cntl;	u32 aper_base, aper_size;	u32 agp_base;	/* First, we disable display to avoid interfering */	if (rinfo->hasCRTC2) {		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->hasCRTC2)		OUTREG(CRTC2_DISPLAY_BASE_ADDR, aper_base);#else	OUTREG(DISPLAY_BASE_ADDR, 0);	if (rinfo->hasCRTC2)		OUTREG(CRTC2_DISPLAY_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->hasCRTC2)		OUTREG(CRTC2_GEN_CNTL, save_crtc2_gen_cntl);	#if 0	printk("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}#endif /* CONFIG_ALL_PPC */static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo){	unsigned char *block = rinfo->EDID;	if (!block)		return 0;	/* jump to the detailed timing block section */	block += 54;	rinfo->clock = (block[0] + (block[1] << 8));	rinfo->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));	rinfo->hblank = (block[3] + ((block[4] & 0x0f) << 8));	rinfo->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));	rinfo->vblank = (block[6] + ((block[7] & 0x0f) << 8));	rinfo->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));	rinfo->hSync_width = (block[9] + ((block[11] & 0x30) << 4));	rinfo->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));	rinfo->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));	rinfo->interlaced = ((block[17] & 0x80) >> 7);	rinfo->synct = ((block[17] & 0x18) >> 3);	rinfo->misc = ((block[17] & 0x06) >> 1);	rinfo->hAct_high = rinfo->vAct_high = 0;	if (rinfo->synct == 3) {		if (rinfo->misc & 2)			rinfo->hAct_high = 1;		if (rinfo->misc & 1)			rinfo->vAct_high = 1;	}	RTRACE("hOver_plus = %d\t hSync_width = %d\n", rinfo->hOver_plus,		rinfo->hSync_width);	RTRACE("vOver_plus = %d\t vSync_width = %d\n", rinfo->vOver_plus,		rinfo->vSync_width);	RTRACE("hblank = %d\t vblank = %d\n", rinfo->hblank,		rinfo->vblank);	RTRACE("sync = %d\n", rinfo->synct);	RTRACE("misc = %d\n", rinfo->misc);	RTRACE("clock = %d\n", rinfo->clock);	printk("radeonfb: detected DFP panel size from EDID: %dx%d\n",		rinfo->panel_xres, rinfo->panel_yres);	rinfo->got_dfpinfo = 1;	return 1;}static void radeon_update_default_var(struct radeonfb_info *rinfo)

⌨️ 快捷键说明

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