+ 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_i830_private.i830_dev, 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_i830_private.registers+I810_PGETBL_CTL);
+ readl(intel_i830_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
+
+ if (agp_bridge->driver->needs_scratch_page) {
+ for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
+ writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
+ readl(intel_i830_private.gtt+i); /* PCI Posting. */
+ }
+ }
+
+ global_cache_flush();
+ return 0;
+}
+
+static void intel_i915_cleanup(void)
+{
+ iounmap(intel_i830_private.gtt);
+ iounmap(intel_i830_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;
+
+ if (mem->page_count == 0)
+ return 0;
+
+ temp = agp_bridge->current_size;
+ num_entries = A_SIZE_FIX(temp)->num_entries;
+
+ if (pg_start < intel_i830_private.gtt_entries) {
+ printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
+ pg_start,intel_i830_private.gtt_entries);
+
+ printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
+ return -EINVAL;
+ }
+
+ if ((pg_start + mem->page_count) > num_entries)
+ return -EINVAL;
+
+ /* 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 != 0 && type != AGP_PHYS_MEMORY) ||
+ (mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
+ return -EINVAL;
+
+ if (!mem->is_flushed) {
+ global_cache_flush();
+ mem->is_flushed = TRUE;
+ }
+
+ for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+ writel(agp_bridge->driver->mask_memory(agp_bridge,
+ mem->memory[i], mem->type), intel_i830_private.gtt+j);
+ }
+ readl(intel_i830_private.gtt+j-1);
+
+ agp_bridge->driver->tlb_flush(mem);
+ return 0;
+}
+
+static int intel_i915_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_i830_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_i830_private.gtt+i);
+ }
+ readl(intel_i830_private.gtt+i-1);
+
+ agp_bridge->driver->tlb_flush(mem);
+ return 0;
+}
+
+/* Return the aperture size by just checking the resource length. The effect
+ * described in the spec of the MSAC registers is just changing of the
+ * resource size.
+ */
+static int intel_i9xx_fetch_size(void)
+{
+ int num_sizes = sizeof(intel_i830_sizes) / sizeof(*intel_i830_sizes);
+ int aper_size; /* size in megabytes */
+ int i;
+
+ aper_size = pci_resource_len(intel_i830_private.i830_dev, 2) / MB(1);
+
+ for (i = 0; i < num_sizes; i++) {
+ if (aper_size == intel_i830_sizes[i].size) {
+ agp_bridge->current_size = intel_i830_sizes + i;
+ agp_bridge->previous_size = agp_bridge->current_size;
+ return aper_size;
+ }
+ }
+
+ return 0;
+}
+
+/* The intel i915 automatically initializes the agp aperture during POST.
+ * Use the memory already set aside for in the GTT.
+ */
+static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
+{
+ int page_order;
+ struct aper_size_info_fixed *size;
+ int num_entries;
+ u32 temp, temp2;
+
+ 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_i830_private.i830_dev, I915_MMADDR, &temp);
+ pci_read_config_dword(intel_i830_private.i830_dev, I915_PTEADDR,&temp2);
+
+ intel_i830_private.gtt = ioremap(temp2, 256 * 1024);
+ if (!intel_i830_private.gtt)
+ return -ENOMEM;
+
+ temp &= 0xfff80000;
+
+ intel_i830_private.registers = ioremap(temp,128 * 4096);
+ if (!intel_i830_private.registers)
+ return -ENOMEM;
+
+ temp = readl(intel_i830_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;
+}
+
+/*
+ * The i965 supports 36-bit physical addresses, but to keep
+ * the format of the GTT the same, the bits that don't fit
+ * in a 32-bit word are shifted down to bits 4..7.
+ *
+ * Gcc is smart enough to notice that "(addr >> 28) & 0xf0"
+ * is always zero on 32-bit architectures, so no need to make
+ * this conditional.
+ */
+static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
+ unsigned long addr, int type)
+{
+ /* Shift high bits down */
+ addr |= (addr >> 28) & 0xf0;
+
+ /* Type checking must be done elsewhere */
+ return addr | bridge->driver->masks[type].mask;
+}
+
+/* The intel i965 automatically initializes the agp aperture during POST.
+ * Use the memory already set aside for in the GTT.
+ */
+static int intel_i965_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_i830_private.i830_dev, I915_MMADDR, &temp);
+
+ temp &= 0xfff00000;
+ intel_i830_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024);
+
+ if (!intel_i830_private.gtt)
+ return -ENOMEM;
+
+
+ intel_i830_private.registers = ioremap(temp,128 * 4096);
+ if (!intel_i830_private.registers)
+ return -ENOMEM;
+
+ temp = readl(intel_i830_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;