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

📄 intel-agp.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
{	{128, 32768, 5},	/* The 64M mode still requires a 128k gatt */	{64, 16384, 5},	{256, 65536, 6},	{512, 131072, 7},};static void intel_i830_init_gtt_entries(void){	u16 gmch_ctrl;	int gtt_entries;	u8 rdct;	int local = 0;	static const int ddt[4] = { 0, 16, 32, 64 };	int size; /* reserved space (in kb) at the top of stolen memory */	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);	if (IS_I965) {		u32 pgetbl_ctl;		pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL);		/* The 965 has a field telling us the size of the GTT,		 * which may be larger than what is necessary to map the		 * aperture.		 */		switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) {		case I965_PGETBL_SIZE_128KB:			size = 128;			break;		case I965_PGETBL_SIZE_256KB:			size = 256;			break;		case I965_PGETBL_SIZE_512KB:			size = 512;			break;		default:			printk(KERN_INFO PFX "Unknown page table size, "			       "assuming 512KB\n");			size = 512;		}		size += 4; /* add in BIOS popup space */	} else if (IS_G33) {	/* G33's GTT size defined in gmch_ctrl */		switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {		case G33_PGETBL_SIZE_1M:			size = 1024;			break;		case G33_PGETBL_SIZE_2M:			size = 2048;			break;		default:			printk(KERN_INFO PFX "Unknown page table size 0x%x, "				"assuming 512KB\n",				(gmch_ctrl & G33_PGETBL_SIZE_MASK));			size = 512;		}		size += 4;	} else {		/* On previous hardware, the GTT size was just what was		 * required to map the aperture.		 */		size = agp_bridge->driver->fetch_size() + 4;	}	if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||	    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {		switch (gmch_ctrl & I830_GMCH_GMS_MASK) {		case I830_GMCH_GMS_STOLEN_512:			gtt_entries = KB(512) - KB(size);			break;		case I830_GMCH_GMS_STOLEN_1024:			gtt_entries = MB(1) - KB(size);			break;		case I830_GMCH_GMS_STOLEN_8192:			gtt_entries = MB(8) - KB(size);			break;		case I830_GMCH_GMS_LOCAL:			rdct = readb(intel_private.registers+I830_RDRAM_CHANNEL_TYPE);			gtt_entries = (I830_RDRAM_ND(rdct) + 1) *					MB(ddt[I830_RDRAM_DDT(rdct)]);			local = 1;			break;		default:			gtt_entries = 0;			break;		}	} else {		switch (gmch_ctrl & I855_GMCH_GMS_MASK) {		case I855_GMCH_GMS_STOLEN_1M:			gtt_entries = MB(1) - KB(size);			break;		case I855_GMCH_GMS_STOLEN_4M:			gtt_entries = MB(4) - KB(size);			break;		case I855_GMCH_GMS_STOLEN_8M:			gtt_entries = MB(8) - KB(size);			break;		case I855_GMCH_GMS_STOLEN_16M:			gtt_entries = MB(16) - KB(size);			break;		case I855_GMCH_GMS_STOLEN_32M:			gtt_entries = MB(32) - KB(size);			break;		case I915_GMCH_GMS_STOLEN_48M:			/* Check it's really I915G */			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB ||			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB ||			    IS_I965 || IS_G33)				gtt_entries = MB(48) - KB(size);			else				gtt_entries = 0;			break;		case I915_GMCH_GMS_STOLEN_64M:			/* Check it's really I915G */			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB ||			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB ||			    IS_I965 || IS_G33)				gtt_entries = MB(64) - KB(size);			else				gtt_entries = 0;			break;		case G33_GMCH_GMS_STOLEN_128M:			if (IS_G33)				gtt_entries = MB(128) - KB(size);			else				gtt_entries = 0;			break;		case G33_GMCH_GMS_STOLEN_256M:			if (IS_G33)				gtt_entries = MB(256) - KB(size);			else				gtt_entries = 0;			break;		default:			gtt_entries = 0;			break;		}	}	if (gtt_entries > 0)		printk(KERN_INFO PFX "Detected %dK %s memory.\n",		       gtt_entries / KB(1), local ? "local" : "stolen");	else		printk(KERN_INFO PFX		       "No pre-allocated video memory detected.\n");	gtt_entries /= KB(4);	intel_private.gtt_entries = gtt_entries;}/* The intel i830 automatically initializes the agp aperture during POST. * Use the memory already set aside for in the GTT. */static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge){	int page_order;	struct aper_size_info_fixed *size;	int num_entries;	u32 temp;	size = agp_bridge->current_size;	page_order = size->page_order;	num_entries = size->num_entries;	agp_bridge->gatt_table_real = NULL;	pci_read_config_dword(intel_private.pcidev,I810_MMADDR,&temp);	temp &= 0xfff80000;	intel_private.registers = ioremap(temp,128 * 4096);	if (!intel_private.registers)		return -ENOMEM;	temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;	global_cache_flush();	/* FIXME: ?? */	/* we have to call this as early as possible after the MMIO base address is known */	intel_i830_init_gtt_entries();	agp_bridge->gatt_table = NULL;	agp_bridge->gatt_bus_addr = temp;	return 0;}/* Return the gatt table to a sane state. Use the top of stolen * memory for the GTT. */static int intel_i830_free_gatt_table(struct agp_bridge_data *bridge){	return 0;}static int intel_i830_fetch_size(void){	u16 gmch_ctrl;	struct aper_size_info_fixed *values;	values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);	if (agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82830_HB &&	    agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82845G_HB) {		/* 855GM/852GM/865G has 128MB aperture size */		agp_bridge->previous_size = agp_bridge->current_size = (void *) values;		agp_bridge->aperture_size_idx = 0;		return values[0].size;	}	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);	if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {		agp_bridge->previous_size = agp_bridge->current_size = (void *) values;		agp_bridge->aperture_size_idx = 0;		return values[0].size;	} else {		agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + 1);		agp_bridge->aperture_size_idx = 1;		return values[1].size;	}	return 0;}static int intel_i830_configure(void){	struct aper_size_info_fixed *current_size;	u32 temp;	u16 gmch_ctrl;	int i;	current_size = A_SIZE_FIX(agp_bridge->current_size);	pci_read_config_dword(intel_private.pcidev,I810_GMADDR,&temp);	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);	gmch_ctrl |= I830_GMCH_ENABLED;	pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);	writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);	readl(intel_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */	if (agp_bridge->driver->needs_scratch_page) {		for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {			writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));			readl(intel_private.registers+I810_PTE_BASE+(i*4));	/* PCI Posting. */		}	}	global_cache_flush();	return 0;}static void intel_i830_cleanup(void){	iounmap(intel_private.registers);}static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int type){	int i,j,num_entries;	void *temp;	int ret = -EINVAL;	int mask_type;	if (mem->page_count == 0)		goto out;	temp = agp_bridge->current_size;	num_entries = A_SIZE_FIX(temp)->num_entries;	if (pg_start < intel_private.gtt_entries) {		printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n",				pg_start,intel_private.gtt_entries);		printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");		goto out_err;	}	if ((pg_start + mem->page_count) > num_entries)		goto out_err;	/* The i830 can't check the GTT for entries since its read only,	 * depend on the caller to make the correct offset decisions.	 */	if (type != mem->type)		goto out_err;	mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);	if (mask_type != 0 && mask_type != AGP_PHYS_MEMORY &&	    mask_type != INTEL_AGP_CACHED_MEMORY)		goto out_err;	if (!mem->is_flushed)		global_cache_flush();	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {		writel(agp_bridge->driver->mask_memory(agp_bridge,						       mem->memory[i], mask_type),		       intel_private.registers+I810_PTE_BASE+(j*4));	}	readl(intel_private.registers+I810_PTE_BASE+((j-1)*4));	agp_bridge->driver->tlb_flush(mem);out:	ret = 0;out_err:	mem->is_flushed = 1;	return ret;}static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,				int type){	int i;	if (mem->page_count == 0)		return 0;	if (pg_start < intel_private.gtt_entries) {		printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");		return -EINVAL;	}	for (i = pg_start; i < (mem->page_count + pg_start); i++) {		writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));	}	readl(intel_private.registers+I810_PTE_BASE+((i-1)*4));	agp_bridge->driver->tlb_flush(mem);	return 0;}static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type){	if (type == AGP_PHYS_MEMORY)		return alloc_agpphysmem_i8xx(pg_count, type);	/* always return NULL for other allocation types for now */	return NULL;}static int intel_i915_configure(void){	struct aper_size_info_fixed *current_size;	u32 temp;	u16 gmch_ctrl;	int i;	current_size = A_SIZE_FIX(agp_bridge->current_size);	pci_read_config_dword(intel_private.pcidev, I915_GMADDR, &temp);	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);	gmch_ctrl |= I830_GMCH_ENABLED;	pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);	writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);	readl(intel_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */	if (agp_bridge->driver->needs_scratch_page) {		for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {			writel(agp_bridge->scratch_page, intel_private.gtt+i);			readl(intel_private.gtt+i);	/* PCI Posting. */		}	}	global_cache_flush();	return 0;}static void intel_i915_cleanup(void){	iounmap(intel_private.gtt);	iounmap(intel_private.registers);}static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,				int type){	int i,j,num_entries;	void *temp;	int ret = -EINVAL;	int mask_type;	if (mem->page_count == 0)		goto out;	temp = agp_bridge->current_size;	num_entries = A_SIZE_FIX(temp)->num_entries;	if (pg_start < intel_private.gtt_entries) {		printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n",				pg_start,intel_private.gtt_entries);		printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");		goto out_err;	}	if ((pg_start + mem->page_count) > num_entries)		goto out_err;	/* The i915 can't check the GTT for entries since its read only,	 * depend on the caller to make the correct offset decisions.	 */	if (type != mem->type)		goto out_err;	mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);

⌨️ 快捷键说明

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