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

📄 intelfbdrv.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* Enable device. */	if ((err = pci_enable_device(pdev))) {		ERR_MSG("Cannot enable device.\n");		cleanup(dinfo);		return -ENODEV;	}	/* Set base addresses. */	dinfo->fb_base_phys = pci_resource_start(pdev, 0);	dinfo->mmio_base_phys = pci_resource_start(pdev, 1);	DBG_MSG("fb region: 0x%lx/0x%lx, MMIO region: 0x%lx/0x%lx\n",		pci_resource_start(pdev, 0), pci_resource_len(pdev, 0),		pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));	/* Reserve the fb and MMIO regions */	if (!request_mem_region(dinfo->fb_base_phys, pci_resource_len(pdev, 0),				INTELFB_MODULE_NAME)) {		ERR_MSG("Cannot reserve FB region.\n");		cleanup(dinfo);		return -ENODEV;	}	if (!request_mem_region(dinfo->mmio_base_phys,				pci_resource_len(pdev, 1),				INTELFB_MODULE_NAME)) {		ERR_MSG("Cannot reserve MMIO region.\n");		cleanup(dinfo);		return -ENODEV;	}	/* Map the MMIO region. */	dinfo->mmio_base = (u32)ioremap(dinfo->mmio_base_phys, INTEL_REG_SIZE);	if (!dinfo->mmio_base) {		ERR_MSG("Cannot map MMIO.\n");		cleanup(dinfo);		return -ENODEV;	}	/* Get the chipset info. */	dinfo->pci_chipset = pdev->device;	if (intelfbhw_get_chipset(pdev, &dinfo->name, &dinfo->chipset,				  &dinfo->mobile)) {		cleanup(dinfo);		return -ENODEV;	}	if (intelfbhw_get_memory(pdev, &dinfo->aperture_size,				 &dinfo->stolen_size)) {		cleanup(dinfo);		return -ENODEV;	}	INF_MSG("%02x:%02x.%d: %s, aperture size %dMB, "		"stolen memory %dkB\n",		pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),		dinfo->name, BtoMB(dinfo->aperture_size),		BtoKB(dinfo->stolen_size));	/* Set these from the options. */	dinfo->accel = accel;	dinfo->hwcursor = hwcursor;	if (NOACCEL_CHIPSET(dinfo) && dinfo->accel == 1) {		INF_MSG("Acceleration is not supported for the %s chipset.\n",			dinfo->name);		dinfo->accel = 0;	}	/*	 * For now, set the video ram size to the stolen size rounded	 * down to a page multiple.  This means the agpgart driver doesn't	 * need to get involved.	 */	dinfo->video_ram = ROUND_DOWN_TO_PAGE(dinfo->stolen_size);	/* Allocate space for the ring buffer and HW cursor. */	if (dinfo->accel) {		dinfo->ring_size = RINGBUFFER_SIZE;		dinfo->video_ram -= dinfo->ring_size;		dinfo->ring_base_phys = dinfo->fb_base_phys + dinfo->video_ram;		dinfo->ring_tail_mask = dinfo->ring_size - 1;	}	if (dinfo->hwcursor && !dinfo->mobile) {		dinfo->cursor_size = HW_CURSOR_SIZE;		dinfo->video_ram -= dinfo->cursor_size;		dinfo->cursor_offset = dinfo->video_ram;		dinfo->cursor_base_phys = dinfo->fb_base_phys +					  dinfo->cursor_offset;	}	/* Framebuffer starts at offset 0. */	dinfo->fb_offset = 0;	dinfo->video_ram -= dinfo->fb_offset;	/* Map the FB region.  Only map the memory used as video ram. */	dinfo->fb_base = (u32)ioremap(dinfo->fb_base_phys + dinfo->fb_offset,				      dinfo->video_ram);	if (!dinfo->fb_base) {		ERR_MSG("Cannot map framebuffer.\n");		cleanup(dinfo);		return -ENODEV;	}	if (dinfo->accel) {		/* Map the ring buffer. */		dinfo->ring_base = (u32)ioremap(dinfo->ring_base_phys,						dinfo->ring_size);		if (!dinfo->ring_base) {			dinfo->accel = 0;			WRN_MSG("Cannot map ring buffer: "				"acceleration disabled.\n");		}	}	if (dinfo->hwcursor && !dinfo->mobile) {		/* Map the HW cursor buffer. */		dinfo->cursor_base = (u32)ioremap(dinfo->cursor_base_phys,						  dinfo->cursor_size);		if (!dinfo->cursor_base) {			WRN_MSG("Cannot map the HW cursor space: "				"HW cursor disabled.\n");			dinfo->hwcursor = 0;		}	}	/*	 * For mobile platforms, a physical page address is needed for the	 * HW cursor.  Allocate it here and insert it into the GTT.	 * If/when this driver is modified to be aware of the agpgart	 * driver, it can be used to obtain/insert the page.	 */	if (dinfo->hwcursor && dinfo->mobile) {#if !MOBILE_HW_CURSOR		dinfo->hwcursor = 0;		INF_MSG("HW cursor is not supported for mobile platforms.\n");#else		struct page *pg;		/*		 * Allocate a page of physical memory for the graphics		 * engine to write to for synchronisation purposes.		 */		pg = alloc_page(GFP_KERNEL);		if (!pg) {			WRN_MSG("Cannot allocate a page for the HW cursor.  "				"Disabling the HW cursor.");			dinfo->hwcursor = 0;		} else {			get_page(pg);			LockPage(pg);			dinfo->cursor_page_virt = (u32)page_address(pg);			dinfo->cursor_base_real =						virt_to_phys(page_address(pg));			/*			 * XXX Add code to insert GTT entry and map the			 * appropriate part of the aperture as			 * dinfo->cursor_base.			 */		}#endif	}	DBG_MSG("fb: 0x%x(+ 0x%x)/0x%x (0x%x)\n",		dinfo->fb_base_phys, dinfo->fb_offset, dinfo->video_ram,		dinfo->fb_base);	DBG_MSG("MMIO: 0x%x/0x%x (0x%x)\n",		dinfo->mmio_base_phys, INTEL_REG_SIZE, dinfo->mmio_base);	DBG_MSG("ring buffer: 0x%x/0x%x (0x%x)\n",		dinfo->ring_base_phys, dinfo->ring_size, dinfo->ring_base);	DBG_MSG("HW cursor: 0x%x/0x%x (0x%x) (offset 0x%x) (phys 0x%x)\n",		dinfo->cursor_base_phys, dinfo->cursor_size,		dinfo->cursor_base, dinfo->cursor_offset,		dinfo->cursor_base_real);	DBG_MSG("options: accel = %d, fixed = %d, noinit = %d\n",		accel, fixed, noinit);	DBG_MSG("options: mode = \"%s\", font = \"%s\"\n",		mode ? mode : "", font ? font : "");	if (probeonly)		bailout(dinfo);	dinfo->fixed_mode = fixed;	/*	 * Check if the LVDS port or any DVO ports are enabled.  If so,	 * don't allow mode switching.	 */	if ((s = intelfbhw_check_non_crt(dinfo))) {		WRN_MSG("Non-CRT device is enabled (%s).  "			"Disabling mode switching.\n", s);		dinfo->fixed_mode = 1;	}	if (bailearly == 1)		bailout(dinfo);	if (dinfo->fixed_mode && ORIG_VIDEO_ISVGA != VIDEO_TYPE_VLFB) {		ERR_MSG("Video mode must be programmed at boot time.\n");		cleanup(dinfo);		return -ENODEV;	}	if (bailearly == 2)		bailout(dinfo);	/* Initialise dinfo and related data. */	/* If an initial mode was programmed at boot time, get its details. */	if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB)		get_initial_mode(dinfo);	if (bailearly == 3)		bailout(dinfo);#if 0	if (dinfo->fixed_mode) {		/*		 * XXX Check video ram amounts and remap if the region already		 * mapped is too small because of ring/cursor allocations.		 */		update_dinfo(dinfo, &dinfo->initial_var, NULL);	}#endif	/* currcon will be set by the first switch. */	dinfo->currcon = -1;	dinfo->vc_mode = KD_TEXT;#if USE_SYNC_PAGE	if (dinfo->accel) {		struct page *pg;		/*		 * Allocate a page of physical memory for the graphics		 * engine to write to for synchronisation purposes.		 */		pg = alloc_page(GFP_KERNEL);		if (!pg) {			WRN_MSG("Cannot allocate a page for 2D accel.  "				"Disabling acceleration.");			dinfo->accel = 0;		} else {			get_page(pg);			LockPage(pg);			dinfo->syncpage_virt = (u32)page_address(pg);			dinfo->syncpage_phys = virt_to_phys(page_address(pg));			/* Write zero to the first dword */			writel(0, dinfo->syncpage_virt);			DBG_MSG("2D sync page: 0x%x (0x%x)\n",				dinfo->syncpage_phys, dinfo->syncpage_virt);		}	}#endif	if (bailearly == 4)		bailout(dinfo);	if (intelfb_set_fbinfo(dinfo)) {		cleanup(dinfo);		return -ENODEV;	}	if (bailearly == 5)		bailout(dinfo);	for (i = 0; i < 16; i++) {		j = color_table[i];		dinfo->palette[i].red = default_red[j];		dinfo->palette[i].green = default_grn[j];		dinfo->palette[i].blue = default_blu[j];	}	if (bailearly == 6)		bailout(dinfo);	pci_set_drvdata(pdev, dinfo);	/* Save the initial register state. */	i = intelfbhw_read_hw_state(dinfo, &dinfo->save_state,				    bailearly > 6 ? bailearly - 6 : 0);	if (i != 0) {		DBG_MSG("intelfbhw_read_hw_state returned %d\n", i);		bailout(dinfo);	}	intelfbhw_print_hw_state(dinfo, &dinfo->save_state);	if (bailearly == 18)		bailout(dinfo);#if TEST_MODE_TO_HW	{		struct intelfb_hwstate hw;		struct fb_var_screeninfo var;		int i;		for (i = 0; i < num_modes; i++) {			mode_to_var(&modedb[i], &var, 8);			intelfbhw_read_hw_state(dinfo, &hw, 0);			if (intelfbhw_mode_to_hw(dinfo, &hw, &var)) {				DGB_MSG("Failed to set hw for mode %dx%d\n",					var.xres, var.yres);			} else {				DGB_MSG("HW state for mode %dx%d\n",					var.xres, var.yres);				intelfbhw_print_hw_state(dinfo, &hw);			}		}	}#endif	/* Cursor initialisation */	if (dinfo->hwcursor) {		init_timer(&dinfo->cursor.timer);		dinfo->cursor.timer.function = intelfb_flashcursor;		dinfo->cursor.timer.data = (unsigned long)dinfo;		dinfo->cursor.state = CM_ERASE;		spin_lock_init(&dinfo->DAClock);	}		if (bailearly == 19)		bailout(dinfo);	if (noregister)		bailout(dinfo);	if (register_framebuffer(&(dinfo->info)) < 0) {		ERR_MSG("Cannot register framebuffer.\n");		cleanup(dinfo);		return -ENODEV;	}	dinfo->registered = 1;	return 0;}static void __devexitintelfb_pci_unregister(struct pci_dev *pdev){	struct intelfb_info *dinfo = pci_get_drvdata(pdev);	DBG_MSG("intelfb_pci_unregister\n");	if (!dinfo)		return;	cleanup(dinfo);	pci_set_drvdata(pdev, NULL);}/* * A simplified version of fb_find_mode.  The latter doesn't seem to work * too well -- haven't figured out why yet. */static intintelfb_find_mode(struct fb_var_screeninfo *var,		  struct fb_info *info, const char *mode_option,		  const struct fb_videomode *db, unsigned int dbsize,		  const struct fb_videomode *default_mode,		  unsigned int default_bpp){	int i;	char mname[20] = "", tmp[20] = "", *p, *q;	unsigned int bpp = 0;	DBG_MSG("intelfb_find_mode\n");	/* Set up defaults */	if (!db) {		db = modedb;		dbsize = sizeof(modedb) / sizeof(*modedb);	}	if (!default_bpp)#if defined(FBCON_HAS_CFB8)		default_bpp = 8;#elif defined(FBCON_HAS_CFB16)		default_bpp = 16;#elif defined(FBCON_HAS_CFB32)		default_bpp = 32;#endif	var->activate = FB_ACTIVATE_TEST;	if (mode_option && *mode_option) {		if (strlen(mode_option) < sizeof(tmp) - 1) {			strcat(tmp, mode_option);			q = tmp;			p = strsep(&q, "-");			strcat(mname, p);			if (q) {				p = strsep(&q, "@");				bpp = simple_strtoul(p, NULL, 10);				if (q) {					strcat(mname, "@");					strcat(mname, q);				}			}		}		if (!bpp)			bpp = default_bpp;		DBG_MSG("Mode is %s, bpp %d\n", mname, bpp);	}	if (*mname) {		for (i = 0; i < dbsize; i++) {			if (!strncmp(db[i].name, mname, strlen(mname))) {				mode_to_var(&db[i], var, bpp);				if (!intelfb_set_var(var, -1, info))					return 1;			}		}	}	if (!default_mode)		return 0;	mode_to_var(default_mode, var, default_bpp);	if (!intelfb_set_var(var, -1, info))		return 3;	for (i = 0; i < dbsize; i++) {		mode_to_var(&db[i], var, default_bpp);		if (!intelfb_set_var(var, -1, info))			return 4;	}	return 0;}static __inline__ intvar_to_refresh(const struct fb_var_screeninfo *var){	int xtot = var->xres + var->left_margin + var->right_margin +		   var->hsync_len;	int ytot = var->yres + var->upper_margin + var->lower_margin +		   var->vsync_len;	return (1000000000 / var->pixclock * 1000 + 500) / xtot / ytot;}/* Various intialisation functions */static int __devinitintelfb_init_disp_var(struct intelfb_info *dinfo){	int msrc = 0;	DBG_MSG("intelfb_init_disp_var\n");	if (dinfo->fixed_mode) {		dinfo->disp.var = dinfo->initial_var;		msrc = 5;	} else {		if (mode) {			msrc = intelfb_find_mode(&dinfo->disp.var,						 &dinfo->info, mode,						 modedb, num_modes, NULL, 0);			if (msrc)				msrc |= 8;		}		if (!msrc) {			msrc = intelfb_find_mode(&dinfo->disp.var,						 &dinfo->info, PREFERRED_MODE,						 modedb, num_modes,						 &modedb[DFLT_MODE], 0);		}	}	if (!msrc) {		ERR_MSG("Cannot find a suitable video mode.\n");		return 1;	}	INF_MSG("Initial video mode is %dx%d-%d@%d.\n", dinfo->disp.var.xres,		dinfo->disp.var.yres, intelfb_var_to_depth(&dinfo->disp.var),		var_to_refresh(&dinfo->disp.var));	DBG_MSG("Initial video mode is from %d.\n", msrc);	if (dinfo->accel)		dinfo->disp.var.accel_flags |= FB_ACCELF_TEXT;	else		dinfo->disp.var.accel_flags &= ~FB_ACCELF_TEXT;	return 0;}static voidintelfb_set_dispsw(struct intelfb_info *dinfo, struct display *disp){	DBG_MSG("intelfb_set_dispsw: (bpp is %d)\n", disp->var.bits_per_pixel);	disp->dispsw_data = NULL;	disp->dispsw = NULL;	switch (disp->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8	case 8:		break;#endif#ifdef FBCON_HAS_CFB16	case 16:		disp->dispsw_data = &dinfo->con_cmap.cfb16;		break;#endif#ifdef FBCON_HAS_CFB32	case 32:		disp->dispsw_data = &dinfo->con_cmap.cfb32;		break;#endif	default:		WRN_MSG("Setting fbcon_dummy renderer (bpp is %d).\n",			disp->var.bits_per_pixel);		disp->dispsw = &fbcon_dummy;	}	/* For all supported bpp. */	if (!disp->dispsw)		disp->dispsw = &fbcon_intelfb;}static int __devinitintelfb_init_disp(struct intelfb_info *dinfo){	struct fb_info *info;	struct display *disp;	DBG_MSG("intelfb_init_disp\n");	info = &dinfo->info;	disp = &dinfo->disp;	if (intelfb_init_disp_var(dinfo))		return 1;	info->disp = disp;	update_dinfo(dinfo, &disp->var, disp);	intelfb_set_dispsw(dinfo, disp);	dinfo->currcon_display = disp;	return 0;}static int __devinitintelfb_set_fbinfo(struct intelfb_info *dinfo){	struct fb_info *info;

⌨️ 快捷键说明

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