Пример #1
0
static int ati_create_gatt_table(struct agp_bridge_data *bridge)
{
	struct aper_size_info_lvl2 *value;
	ati_page_map page_dir;
	unsigned long addr;
	int retval;
	u32 temp;
	int i;
	struct aper_size_info_lvl2 *current_size;

	value = A_SIZE_LVL2(agp_bridge->current_size);
	retval = ati_create_page_map(&page_dir);
	if (retval != 0)
		return retval;

	retval = ati_create_gatt_pages(value->num_entries / 1024);
	if (retval != 0) {
		ati_free_page_map(&page_dir);
		return retval;
	}

	agp_bridge->gatt_table_real = (u32 *)page_dir.real;
	agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped;
	agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);

	/* Write out the size register */
	current_size = A_SIZE_LVL2(agp_bridge->current_size);

	if (is_r200()) {
		pci_read_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, &temp);
		temp = (((temp & ~(0x0000000e)) | current_size->size_value)
			| 0x00000001);
		pci_write_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, temp);
		pci_read_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, &temp);
	} else {
		pci_read_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, &temp);
		temp = (((temp & ~(0x0000000e)) | current_size->size_value)
			| 0x00000001);
		pci_write_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, temp);
		pci_read_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, &temp);
	}

	/*
	 * Get the address for the gart region.
	 * This is a bus address even on the alpha, b/c its
	 * used to program the agp master not the cpu
	 */
	pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
	addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
	agp_bridge->gart_bus_addr = addr;

	/* Calculate the agp offset */
	for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
		writel(virt_to_gart(ati_generic_private.gatt_pages[i]->real) | 1,
			page_dir.remapped+GET_PAGE_DIR_OFF(addr));
		readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));	/* PCI Posting. */
	}

	return 0;
}
Пример #2
0
static int serverworks_create_gatt_table(struct agp_bridge_data *bridge)
{
	struct aper_size_info_lvl2 *value;
	struct serverworks_page_map page_dir;
	int retval;
	u32 temp;
	int i;

	value = A_SIZE_LVL2(agp_bridge->current_size);
	retval = serverworks_create_page_map(&page_dir);
	if (retval != 0) {
		return retval;
	}
	retval = serverworks_create_page_map(&serverworks_private.scratch_dir);
	if (retval != 0) {
		serverworks_free_page_map(&page_dir);
		return retval;
	}
	/* Create a fake scratch directory */
	for(i = 0; i < 1024; i++) {
		writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i);
		writel(virt_to_gart(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i);
	}

	retval = serverworks_create_gatt_pages(value->num_entries / 1024);
	if (retval != 0) {
		serverworks_free_page_map(&page_dir);
		serverworks_free_page_map(&serverworks_private.scratch_dir);
		return retval;
	}

	agp_bridge->gatt_table_real = (u32 *)page_dir.real;
	agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped;
	agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);

	/* Get the address for the gart region.
	 * This is a bus address even on the alpha, b/c its
	 * used to program the agp master not the cpu
	 */

	pci_read_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,&temp);
	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);

	/* Calculate the agp offset */	

	for(i = 0; i < value->num_entries / 1024; i++)
		writel(virt_to_gart(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i);

	return 0;
}
Пример #3
0
static int amd_create_page_map(struct amd_page_map *page_map)
{
	int i;

	page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL);
	if (page_map->real == NULL)
		return -ENOMEM;

#ifndef CONFIG_X86
	SetPageReserved(virt_to_page(page_map->real));
	global_cache_flush();
	page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
					    PAGE_SIZE);
	if (page_map->remapped == NULL) {
		ClearPageReserved(virt_to_page(page_map->real));
		free_page((unsigned long) page_map->real);
		page_map->real = NULL;
		return -ENOMEM;
	}
	global_cache_flush();
#else
	set_memory_uc((unsigned long)page_map->real, 1);
	page_map->remapped = page_map->real;
#endif

	for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
		writel(agp_bridge->scratch_page, page_map->remapped+i);
		readl(page_map->remapped+i);	/* PCI Posting. */
	}

	return 0;
}
Пример #4
0
static int serverworks_create_page_map(struct serverworks_page_map *page_map)
{
	int i;

	page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL);
	if (page_map->real == NULL) {
		return -ENOMEM;
	}
	SetPageReserved(virt_to_page(page_map->real));
	global_cache_flush();
	page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
					    PAGE_SIZE);
	if (page_map->remapped == NULL) {
		ClearPageReserved(virt_to_page(page_map->real));
		free_page((unsigned long) page_map->real);
		page_map->real = NULL;
		return -ENOMEM;
	}
	global_cache_flush();

	for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++)
		writel(agp_bridge->scratch_page, page_map->remapped+i);

	return 0;
}
Пример #5
0
static int ati_create_page_map(ati_page_map *page_map)
{
	int i, err = 0;

	page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL);
	if (page_map->real == NULL)
		return -ENOMEM;

	SetPageReserved(virt_to_page(page_map->real));
	err = map_page_into_agp(virt_to_page(page_map->real));
	page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
					    PAGE_SIZE);
	if (page_map->remapped == NULL || err) {
		ClearPageReserved(virt_to_page(page_map->real));
		free_page((unsigned long) page_map->real);
		page_map->real = NULL;
		return -ENOMEM;
	}
	/*CACHE_FLUSH();*/
	global_cache_flush();

	for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
		writel(agp_bridge->scratch_page, page_map->remapped+i);
		readl(page_map->remapped+i);	/* PCI Posting. */
	}

	return 0;
}
Пример #6
0
static int i460_alloc_large_page (struct lp_desc *lp)
{
	unsigned long order = I460_IO_PAGE_SHIFT - PAGE_SHIFT;
	size_t map_size;
	void *lpage;

	lpage = (void *) __get_free_pages(GFP_KERNEL, order);
	if (!lpage) {
		printk(KERN_ERR PFX "Couldn't alloc 4M GART page...\n");
		return -ENOMEM;
	}

	map_size = ((I460_KPAGES_PER_IOPAGE + BITS_PER_LONG - 1) & -BITS_PER_LONG)/8;
	lp->alloced_map = kzalloc(map_size, GFP_KERNEL);
	if (!lp->alloced_map) {
		free_pages((unsigned long) lpage, order);
		printk(KERN_ERR PFX "Out of memory, we're in trouble...\n");
		return -ENOMEM;
	}

	lp->paddr = virt_to_gart(lpage);
	lp->refcount = 0;
	atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
	return 0;
}
Пример #7
0
static int amd_8151_configure(void)
{
	unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real);
	int i;

	/* Configure AGP regs in each x86-64 host bridge. */
        for (i = 0; i < num_k8_northbridges; i++) {
		agp_bridge->gart_bus_addr =
				amd64_configure(k8_northbridges[i], gatt_bus);
	}
	k8_flush_garts();
	return 0;
}
Пример #8
0
static int
hp_zx1_configure (void)
{
	struct _hp_private *hp = &hp_private;

	agp_bridge->gart_bus_addr = hp->gart_base;
	agp_bridge->capndx = hp->lba_cap_offset;
	agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS);

	if (hp->io_pdir_owner) {
		writel(virt_to_gart(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE);
		readl(hp->ioc_regs+HP_ZX1_PDIR_BASE);
		writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG);
		readl(hp->ioc_regs+HP_ZX1_TCNFG);
		writel((unsigned int)(~(HP_ZX1_IOVA_SIZE-1)), hp->ioc_regs+HP_ZX1_IMASK);
		readl(hp->ioc_regs+HP_ZX1_IMASK);
		writel(hp->iova_base|1, hp->ioc_regs+HP_ZX1_IBASE);
		readl(hp->ioc_regs+HP_ZX1_IBASE);
		writel(hp->iova_base|ilog2(HP_ZX1_IOVA_SIZE), hp->ioc_regs+HP_ZX1_PCOM);
		readl(hp->ioc_regs+HP_ZX1_PCOM);
	}

	return 0;
}
Пример #9
0
static int agp_backend_initialize(struct agp_bridge_data *bridge)
{
	int size_value, rc, got_gatt=0, got_keylist=0;

	bridge->max_memory_agp = agp_find_max();
	bridge->version = &agp_current_version;

	if (bridge->driver->needs_scratch_page) {
		void *addr = bridge->driver->agp_alloc_page(bridge);

		if (!addr) {
			printk(KERN_ERR PFX "unable to get memory for scratch page.\n");
			return -ENOMEM;
		}

		bridge->scratch_page_real = virt_to_gart(addr);
		bridge->scratch_page =
		    bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0);
	}

	size_value = bridge->driver->fetch_size();
	if (size_value == 0) {
		printk(KERN_ERR PFX "unable to determine aperture size.\n");
		rc = -EINVAL;
		goto err_out;
	}
	if (bridge->driver->create_gatt_table(bridge)) {
		printk(KERN_ERR PFX
		    "unable to get memory for graphics translation table.\n");
		rc = -ENOMEM;
		goto err_out;
	}
	got_gatt = 1;

	bridge->key_list = vmalloc(PAGE_SIZE * 4);
	if (bridge->key_list == NULL) {
		printk(KERN_ERR PFX "error allocating memory for key lists.\n");
		rc = -ENOMEM;
		goto err_out;
	}
	got_keylist = 1;

	/* FIXME vmalloc'd memory not guaranteed contiguous */
	memset(bridge->key_list, 0, PAGE_SIZE * 4);

	if (bridge->driver->configure()) {
		printk(KERN_ERR PFX "error configuring host chipset.\n");
		rc = -EINVAL;
		goto err_out;
	}

	return 0;

err_out:
	if (bridge->driver->needs_scratch_page)
		bridge->driver->agp_destroy_page(
				gart_to_virt(bridge->scratch_page_real));
	if (got_gatt)
		bridge->driver->free_gatt_table(bridge);
	if (got_keylist) {
		vfree(bridge->key_list);
		bridge->key_list = NULL;
	}
	return rc;
}