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

📄 radeonfb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
{	struct fb_var_screeninfo *var = &radeonfb_default_var;        /*         * Update default var to match the lcd monitor's native resolution         */	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->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;}/* Copied from XFree86 4.3 --BenH */static intradeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo, unsigned char *fpbiosstart){	unsigned char *tmp;	unsigned short offset;	offset = readw(fpbiosstart + 0x34);	if (offset != 0)		offset = readw(rinfo->bios_seg + offset + 2);	if (offset == 0) {		printk("radeonfb: Failed to detect DFP panel info using BIOS\n");		return 0;	}	tmp = rinfo->bios_seg + offset;	/* This is an EDID block */	rinfo->clock = readw(tmp);	rinfo->panel_xres = (readb(tmp + 2) + ((readb(tmp + 4) & 0xf0) << 4));	rinfo->hblank = (readb(tmp + 3) + ((readb(tmp + 4) & 0x0f) << 8));	rinfo->panel_yres = (readb(tmp + 5) + ((readb(tmp + 7) & 0xf0) << 4));	rinfo->vblank = (readb(tmp + 6) + ((readb(tmp + 7) & 0x0f) << 8));	rinfo->hOver_plus = (readb(tmp + 8) + ((readb(tmp + 11) & 0xc0) << 2));	rinfo->hSync_width = (readb(tmp + 9) + ((readb(tmp + 11) & 0x30) << 4));	rinfo->vOver_plus = ((readb(tmp + 10) >> 4) + ((readb(tmp + 11) & 0x0c) << 2));	rinfo->vSync_width = ((readb(tmp + 10) & 0x0f) + ((readb(tmp + 11) & 0x03) << 4));	rinfo->interlaced = ((readb(tmp + 17) & 0x80) >> 7);	rinfo->synct = ((readb(tmp + 17) & 0x18) >> 3);	rinfo->misc = ((readb(tmp + 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 BIOS: %dx%d\n",		rinfo->panel_xres, rinfo->panel_yres);	rinfo->got_dfpinfo = 1;	return 1;}static intradeon_get_lcdinfo_BIOS(struct radeonfb_info *rinfo, unsigned char *fpbiosstart){	unsigned char *tmp, *tmp0;	unsigned char stmp[30];	unsigned short offset;	int i;	offset = readw(fpbiosstart + 0x40);	if (offset == 0) {		printk("radeonfb: Failed to detect LCD panel info using BIOS\n");		return 0;	}	tmp = rinfo->bios_seg + offset;	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 LCD 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);                        /* We don't know that the H/V sync active level should be                           make the same assumptions as XFree does - High Active */                        rinfo->vAct_high=1;                        rinfo->hAct_high=1;			rinfo->got_dfpinfo = 1;			return 1;		}	}	return 0;}static int radeon_get_panelinfo_BIOS(struct radeonfb_info *rinfo){	unsigned char *fpbiosstart;	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 (rinfo->dviDisp_type == MT_LCD)		return radeon_get_lcdinfo_BIOS(rinfo, fpbiosstart);	else if (rinfo->dviDisp_type == MT_DFP)		return radeon_get_dfpinfo_BIOS(rinfo, fpbiosstart);	return 0;}static int radeon_get_dfpinfo (struct radeonfb_info *rinfo){	unsigned int tmp;	unsigned short a, b;	if (radeon_get_panelinfo_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:				rinfo->panel_xres = 800;				break;			case 768:				rinfo->panel_xres = 1024;				break;			case 1024:				rinfo->panel_xres = 1280;				break;			case 1050:				rinfo->panel_xres = 1400;				break;			case 1200:				rinfo->panel_xres = 1600;				break;			default:				printk("radeonfb: Failed to detect DFP panel size\n");				return 0;		}		printk("radeonfb: detected DFP panel size from registers: %dx%d\n",			rinfo->panel_xres, rinfo->panel_yres);		tmp = INREG(FP_CRTC_H_TOTAL_DISP);		a = (tmp & FP_CRTC_H_TOTAL_MASK) + 4;		b = (tmp & 0x01ff0000) >> FP_CRTC_H_DISP_SHIFT;		rinfo->hblank = (a - b + 1) * 8;		tmp = INREG(FP_H_SYNC_STRT_WID);		rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >>					FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;		rinfo->hOver_plus *= 8;		rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >>					FP_H_SYNC_WID_SHIFT);		rinfo->hSync_width *= 8;		tmp = INREG(FP_CRTC_V_TOTAL_DISP);		a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1;		b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;		rinfo->vblank = a - b /* + 24 */ ;		tmp = INREG(FP_V_SYNC_STRT_WID);		rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK)					- b + 1;		rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>					FP_V_SYNC_WID_SHIFT);		/* XXX */		/* We should calculate the pixclock as well here... --BenH.		 */		return 1;	}	return 1;}static int radeonfb_pci_register (struct pci_dev *pdev,				  const struct pci_device_id *ent){	struct radeonfb_info *rinfo;	struct radeon_chip_info *rci = &radeon_chip_info[ent->driver_data];	u32 tmp;	int i, j;	RTRACE("radeonfb_pci_register BEGIN\n");	rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);	if (!rinfo) {		printk ("radeonfb: could not allocate memory\n");		return -ENODEV;	}	memset (rinfo, 0, sizeof (struct radeonfb_info));	rinfo->pdev = pdev;	strncpy(rinfo->name, rci->name, 16);	rinfo->arch = rci->arch;	/* enable device */	{		int err;		if ((err = pci_enable_device(pdev))) {			printk("radeonfb: cannot enable device\n");			kfree (rinfo);			return -ENODEV;		}	}	/* set base addrs */	rinfo->fb_base_phys = pci_resource_start (pdev, 0);	rinfo->mmio_base_phys = pci_resource_start (pdev, 2);	/* request the mem regions */	if (!request_mem_region (rinfo->fb_base_phys,				 pci_resource_len(pdev, 0), "radeonfb")) {		printk ("radeonfb: cannot reserve FB region\n");		kfree (rinfo);		return -ENODEV;	}	if (!request_mem_region (rinfo->mmio_base_phys,				 pci_resource_len(pdev, 2), "radeonfb")) {		printk ("radeonfb: cannot reserve MMIO region\n");		release_mem_region (rinfo->fb_base_phys,				    pci_resource_len(pdev, 0));		kfree (rinfo);		return -ENODEV;	}	/* map the regions */	rinfo->mmio_base = (unsigned long) ioremap (rinfo->mmio_base_phys,				    		    RADEON_REGSIZE);	if (!rinfo->mmio_base) {		printk ("radeonfb: cannot map MMIO\n");		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;	}	rinfo->chipset = pdev->device;	switch (rinfo->arch) {		case RADEON_R100:			rinfo->hasCRTC2 = 0;			break;		default:			/* all the rest have it */			rinfo->hasCRTC2 = 1;			break;	}	if (mirror)		printk("radeonfb: mirroring display to CRT\n");	/* framebuffer size */	tmp = INREG(CONFIG_MEMSIZE);	/* mem size is bits [28:0], mask off the rest */	rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;	/* ram type */	tmp = INREG(MEM_SDRAM_MODE_REG);	switch ((MEM_CFG_TYPE & tmp) >> 30) {		case 0:			/* SDR SGRAM (2:1) */			strcpy(rinfo->ram_type, "SDR SGRAM");			rinfo->ram.ml = 4;			rinfo->ram.mb = 4;			rinfo->ram.trcd = 1;			rinfo->ram.trp = 2;			rinfo->ram.twr = 1;			rinfo->ram.cl = 2;			rinfo->ram.loop_latency = 16;			rinfo->ram.rloop = 16;				break;		case 1:			/* DDR SGRAM */			strcpy(rinfo->ram_type, "DDR SGRAM");			rinfo->ram.ml = 4;			rinfo->ram.mb = 4;			rinfo->ram.trcd = 3;			rinfo->ram.trp = 3;			rinfo->ram.twr = 2;			rinfo->ram.cl = 3;			rinfo->ram.tr2w = 1;			rinfo->ram.loop_latency = 16;			rinfo->ram.rloop = 16;			break;		default:			/* 64-bit SDR SGRAM */			strcpy(rinfo->ram_type, "SDR SGRAM 64");			rinfo->ram.ml = 4;			rinfo->ram.mb = 8;			rinfo->ram.trcd = 3;			rinfo->ram.trp = 3;			rinfo->ram.twr = 1;			rinfo->ram.cl = 3;			rinfo->ram.tr2w = 1;			rinfo->ram.loop_latency = 17;			rinfo->ram.rloop = 17;			break;	}	rinfo->bios_seg = radeon_find_rom(rinfo);	radeon_get_pllinfo(rinfo, rinfo->bios_seg);	/*	 * Hack to get around some busted production M6's	 * reporting no ram	 */	if (rinfo->video_ram == 0) {		switch (pdev->device) {			case PCI_DEVICE_ID_ATI_RADEON_LY:			case PCI_DEVICE_ID_ATI_RADEON_LZ:				rinfo->video_ram = 8192 * 1024;				break;			default:				break;		}	}	RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));	RTRACE("BIOS 4 scratch = %x\n", INREG(RADEON_BIOS_4_SCRATCH));	RTRACE("FP_GEN_CNTL: %x, FP2_GEN_CNTL: %x\n",		INREG(FP_GEN_CNTL), INREG(FP2_GEN_CNTL));	RTRACE("TMDS_TRANSMITTER_CNTL: %x, TMDS_CNTL: %x, LVDS_GEN_CNTL: %x\n",		INREG(TMDS_TRANSMITTER_CNTL), INREG(TMDS_CNTL), INREG(LVDS_GEN_CNTL));	RTRACE("DAC_CNTL: %x, DAC_CNTL2: %x, CRTC_GEN_CNTL: %x\n",		INREG(DAC_CNTL), INREG(DAC_CNTL2), INREG(CRTC_GEN_CNTL));#if !defined(__powerpc__)	radeon_get_moninfo(rinfo);#else	switch (rinfo->arch) {		case RADEON_M6:		case RADEON_M7:		case RADEON_M9:			/* If forced to no-LCD, we shut down the backlight */			if (force_nolcd) {#ifdef CONFIG_PMAC_BACKLIGHT				radeon_set_backlight_enable(0, BACKLIGHT_OFF, rinfo);#endif			} else {				rinfo->dviDisp_type = MT_LCD;				break;			}			/* Fall through */		default:			radeon_get_moninfo(rinfo);			break;	}#endif	radeon_get_EDID(rinfo);	if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) ||	    (rinfo->crtDisp_type == MT_DFP)) {		if (!radeon_get_dfpinfo(rinfo)) {			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;		}	}	rinfo->fb_base = (unsigned long) ioremap (rinfo->fb_base_phys,				  		  rinfo->video_ram);	if (!rinfo->fb_base) {		printk ("radeonfb: cannot map FB\n");		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;	}	/* currcon not yet configured, will be set by first switch */	rinfo->currcon = -1;	/* On PPC, the firmware sets up a memory mapping that tends	 * to cause lockups when enabling the engine. We reconfigure	 * the card internal memory mappings properly	 */#ifdef CONFIG_ALL_PPC	radeon_fixup_apertures(rinfo);#else		rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;#endif /* CONFIG_ALL_PPC */	/* save current mode regs before we switch into the new one	 * so we can restore this upon __exit	 */

⌨️ 快捷键说明

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