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

📄 radeonfb.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* save current mode regs before we switch into the new one	 * so we can restore this upon __exit	 */	radeon_save_state (rinfo, &rinfo->init_state);	/* init palette */	for (i=0; i<16; i++) {		j = color_table[i];		rinfo->palette[i].red = default_red[j];		rinfo->palette[i].green = default_grn[j];		rinfo->palette[i].blue = default_blu[j];	}	pci_set_drvdata(pdev, rinfo);	rinfo->next = board_list;	board_list = rinfo;	if (register_framebuffer ((struct fb_info *) rinfo) < 0) {		printk ("radeonfb: could not register framebuffer\n");		iounmap ((void*)rinfo->fb_base);		iounmap ((void*)rinfo->mmio_base);		release_mem_region (rinfo->mmio_base_phys,				    pci_resource_len(pdev, 2));		release_mem_region (rinfo->fb_base_phys,				    pci_resource_len(pdev, 0));		kfree (rinfo);		return -ENODEV;	}	if (!noaccel) {		/* initialize the engine */		radeon_engine_init (rinfo);	}#ifdef CONFIG_PMAC_BACKLIGHT	if (rinfo->dviDisp_type == MT_LCD)		register_backlight_controller(&radeon_backlight_controller,					      rinfo, "ati");#endif#ifdef CONFIG_PMAC_PBOOK	if (rinfo->dviDisp_type == MT_LCD) {		rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);		pmu_register_sleep_notifier(&radeon_sleep_notifier);	}#endif	printk ("radeonfb: ATI %s %s %d MB\n", rinfo->name, rinfo->ram_type,		(rinfo->video_ram/(1024*1024)));	if (rinfo->hasCRTC2) {		printk("radeonfb: DVI port %s monitor connected\n",			GET_MON_NAME(rinfo->dviDisp_type));		printk("radeonfb: CRT port %s monitor connected\n",			GET_MON_NAME(rinfo->crtDisp_type));	} else {		printk("radeonfb: CRT port %s monitor connected\n",			GET_MON_NAME(rinfo->crtDisp_type));	}	RTRACE("radeonfb_pci_register END\n");	return 0;}static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev){        struct radeonfb_info *rinfo = pci_get_drvdata(pdev);         if (!rinfo)                return; 	/* restore original state */        radeon_write_mode (rinfo, &rinfo->init_state);         unregister_framebuffer ((struct fb_info *) rinfo);                        iounmap ((void*)rinfo->mmio_base);        iounmap ((void*)rinfo->fb_base); 	release_mem_region (rinfo->mmio_base_phys,			    pci_resource_len(pdev, 2));	release_mem_region (rinfo->fb_base_phys,			    pci_resource_len(pdev, 0));                kfree (rinfo);}static char *radeon_find_rom(struct radeonfb_info *rinfo){       #if defined(__i386__)        u32  segstart;        char *rom_base;        char *rom;        int  stage;        int  i,j;               char aty_rom_sig[] = "761295520";        char *radeon_sig[] = {          "RG6",          "RADEON"        };                                                        for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {                                        stage = 1;                                rom_base = (char *)ioremap(segstart, 0x1000);                if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))                        stage = 2;                                                    if (stage != 2) {                        iounmap(rom_base);                        continue;                }                                                              rom = rom_base;                                     for (i = 0; (i < 128 - strlen(aty_rom_sig)) && (stage != 3); i++) {                        if (aty_rom_sig[0] == *rom)                                if (strncmp(aty_rom_sig, rom,                                                strlen(aty_rom_sig)) == 0)                                        stage = 3;                        rom++;                }                if (stage != 3) {                        iounmap(rom_base);                        continue;                }                rom = rom_base;                        for (i = 0; (i < 512) && (stage != 4); i++) {                    for(j = 0;j < sizeof(radeon_sig)/sizeof(char *);j++) {                        if (radeon_sig[j][0] == *rom)                                if (strncmp(radeon_sig[j], rom,                                            strlen(radeon_sig[j])) == 0) {                                              stage = 4;                                              break;                                            }                    }                                                   rom++;                }                       if (stage != 4) {                        iounmap(rom_base);                        continue;                }                                       return rom_base;        }#endif                  return NULL;}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);                	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;		}#endif		/* no BIOS or BIOS not found, use defaults */		switch (rinfo->chipset) {			case PCI_DEVICE_ID_RADEON_QW:				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 PCI_DEVICE_ID_RADEON_QL:				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 PCI_DEVICE_ID_RADEON_QD:			case PCI_DEVICE_ID_RADEON_QE:			case PCI_DEVICE_ID_RADEON_QF:			case PCI_DEVICE_ID_RADEON_QG:			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){	unsigned int tmp;	if (force_dfp) {		rinfo->dviDisp_type = MT_DFP;		return;	}	tmp = INREG(RADEON_BIOS_4_SCRATCH);	if (rinfo->hasCRTC2) {		/* 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;	}}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_PPCstatic int radeon_get_EDID_OF(struct radeonfb_info *rinfo){	struct device_node *dp;	unsigned char *pedid = NULL;	dp = pci_device_to_OF_node(rinfo->pdev);	pedid = (unsigned char *) get_property(dp, "DFP,EDID", 0);	if (!pedid)		pedid = (unsigned char *) get_property(dp, "LCD,EDID", 0);	if (!pedid)		pedid = (unsigned char *) get_property(dp, "EDID", 0);	if (pedid) {		rinfo->EDID = pedid;		return 1;	} else		return 0;}#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;	}	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){	struct fb_var_screeninfo *var = &radeonfb_default_var;	var->xres = rinfo->panel_xres;	var->yres = rinfo->panel_yres;	var->xres_virtual = rinfo->panel_xres;	var->yres_virtual = rinfo->panel_yres;	var->xoffset = var->yoffset = 0;	var->bits_per_pixel = 8;	var->pixclock = 100000000 / rinfo->clock;	var->left_margin = (rinfo->hblank - rinfo->hOver_plus - rinfo->hSync_width);	var->right_margin = rinfo->hOver_plus;	var->upper_margin = (rinfo->vblank - rinfo->vOver_plus - rinfo->vSync_width);	var->lower_margin = rinfo->vOver_plus;	var->hsync_len = rinfo->hSync_width;	var->vsync_len = rinfo->vSync_width;	var->sync = 0;	if (rinfo->synct == 3) {		if (rinfo->hAct_high)			var->sync |= FB_SYNC_HOR_HIGH_ACT;		if (rinfo->vAct_high)			var->sync |= FB_SYNC_VERT_HIGH_ACT;	}	var->vmode = 0;	if (rinfo->interlaced)		var->vmode |= FB_VMODE_INTERLACED;	rinfo->use_default_var = 1;}static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo){	char *fpbiosstart, *tmp, *tmp0;	char stmp[30];	int i;	if (!rinfo->bios_seg)		return 0;	if (!(fpbiosstart = rinfo->bios_seg + readw(rinfo->bios_seg + 0x48))) {		printk("radeonfb: Failed to detect DFP panel info using BIOS\n");		return 0;	}	if (!(tmp = rinfo->bios_seg + readw(fpbiosstart + 0x40))) {		printk("radeonfb: Failed to detect DFP panel info using BIOS\n");		return 0;	}	for(i=0; i<24; i++)		stmp[i] = readb(tmp+i+1);	stmp[24] = 0;	printk("radeonfb: panel ID string: %s\n", stmp);	rinfo->panel_xres = readw(tmp + 25);	rinfo->panel_yres = readw(tmp + 27);	printk("radeonfb: detected DFP panel size from BIOS: %dx%d\n",		rinfo->panel_xres, rinfo->panel_yres);	for(i=0; i<20; i++) {		tmp0 = rinfo->bios_seg + readw(tmp+64+i*2);		if (tmp0 == 0)			break;		if ((readw(tmp0) == rinfo->panel_xres) &&		    (readw(tmp0+2) == rinfo->panel_yres)) {			rinfo->hblank = (readw(tmp0+17) - readw(tmp0+19)) * 8;			rinfo->hOver_plus = ((readw(tmp0+21) - readw(tmp0+19) -1) * 8) & 0x7fff;			rinfo->hSync_width = readb(tmp0+23) * 8;			rinfo->vblank = readw(tmp0+24) - readw(tmp0+26);			rinfo->vOver_plus = (readw(tmp0+28) & 0x7ff) - readw(tmp0+26);			rinfo->vSync_width = (readw(tmp0+28) & 0xf800) >> 11;			rinfo->clock = readw(tmp0+9);			rinfo->got_dfpinfo = 1;			return 1;		}	}	return 0;}static int radeon_get_dfpinfo (struct radeonfb_info *rinfo){	unsigned int tmp;	unsigned short a, b;	if (radeon_get_dfpinfo_BIOS(rinfo))		radeon_update_default_var(rinfo);	if (radeon_dfp_parse_EDID(rinfo))		radeon_update_default_var(rinfo);	if (!rinfo->got_dfpinfo) {		/*		 * it seems all else has failed now and we		 * resort to probing registers for our DFP info	         */		if (panel_yres) {			rinfo->panel_yres = panel_yres;		} else {			tmp = INREG(FP_VERT_STRETCH);			tmp &= 0x00fff000;			rinfo->panel_yres = (unsigned short)(tmp >> 0x0c) + 1;		}		switch (rinfo->panel_yres) {			case 480:				rinfo->panel_xres = 640;				break;			case 600:

⌨️ 快捷键说明

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