📄 intel-agp.c
字号:
{ {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 + -