/*
 * Transmeta's Efficeon AGPGART driver.
 * 
 * Based upon a diff by Linus around November '02.
 *
 * Ported to the 2.6 kernel by Carlos Puchol <cpglinux@puchol.com>
 * and H. Peter Anvin <hpa@transmeta.com>.
 */

/*
 * NOTE-cpg-040217:
 * 
 *   - when compiled as a module, after loading the module,
 *     it will refuse to unload, indicating it is in use,
 *     when it is not.
 *   - no s3 (suspend to ram) testing.
 *   - tested on the efficeon integrated nothbridge for tens
 *     of iterations of starting x and glxgears.
 *   - tested with radeon 9000 and radeon mobility m9 cards
 *   - tested with c3/c4 enabled (with the mobility m9 card)
 */

#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include <linux/gfp.h>
#include <linux/page-flags.h>
#include <linux/mm.h>
#include "agp.h"

/*
 * The real differences to the generic AGP code is
 * in the GART mappings - a two-level setup with the
 * first level being an on-chip 64-entry table.
 *
 * The page array is filled through the ATTPAGE register
 * (Aperture Translation Table Page Register) at 0xB8. Bits:
 *  31:20: physical page address
 *   11:9: Page Attribute Table Index (PATI)
 *	   must match the PAT index for the
 *	   mapped pages (the 2nd level page table pages
 *	   themselves should be just regular WB-cacheable,
 *	   so this is normally zero.)
 *      8: Present
 *    7:6: reserved, write as zero
 *    5:0: GATT directory index: which 1st-level entry
 * 
 * The Efficeon AGP spec requires pages to be WB-cacheable
 * but to be explicitly CLFLUSH'd after any changes.
 */
#define EFFICEON_ATTPAGE	0xb8
#define EFFICEON_L1_SIZE	64	/* Number of PDE pages */

#define EFFICEON_PATI		(0 << 9)
#define EFFICEON_PRESENT	(1 << 8)

static struct _efficeon_private {
	unsigned long l1_table[EFFICEON_L1_SIZE];
} efficeon_private;

static struct gatt_mask efficeon_generic_masks[] =
{
	{.mask = 0x00000001, .type = 0}
};

static struct aper_size_info_lvl2 efficeon_generic_sizes[4] =
{
	{256, 65536, 0},
	{128, 32768, 32},
	{64, 16384, 48},
	{32, 8192, 56}
};

/*
 * Control interfaces are largely identical to
 * the legacy Intel 440BX..
 */

static int efficeon_fetch_size(void)
{
	int i;
	u16 temp;
	struct aper_size_info_lvl2 *values;

	pci_read_config_word(agp_bridge->dev, INTEL_APSIZE, &temp);
	values = A_SIZE_LVL2(agp_bridge->driver->aperture_sizes);

	for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
		if (temp == values[i].size_value) {
			agp_bridge->previous_size =
			    agp_bridge->current_size = (void *) (values + i);
			agp_bridge->aperture_size_idx = i;
			return values[i].size;
		}
	}

	return 0;
}

static void efficeon_tlbflush(struct agp_memory * mem)
{
	printk(KERN_DEBUG PFX "efficeon_tlbflush()\n");
	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2200);
	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
}

static void efficeon_cleanup(void)
{
	u16 temp;
	struct aper_size_info_lvl2 *previous_size;

	printk(KERN_DEBUG PFX "efficeon_cleanup()\n");
	previous_size = A_SIZE_LVL2(agp_bridge->previous_size);
	pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
	pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
	pci_write_config_word(agp_bridge->dev, INTEL_APSIZE,
			      previous_size->size_value);
}

static int efficeon_configure(void)
{
	u32 temp;
	u16 temp2;
	struct aper_size_info_lvl2 *current_size;

	printk(KERN_DEBUG PFX "efficeon_configure()\n");
	
	current_size = A_SIZE_LVL2(agp_bridge->current_size);

	/* aperture size */
	pci_write_config_word(agp_bridge->dev, INTEL_APSIZE,
			      current_size->size_value);

	/* address to map to */
	pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);

	/* agpctrl */
	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);

	/* paccfg/nbxcfg */
	pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
	pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG,
			      (temp2 & ~(1 << 10)) | (1 << 9) | (1 << 11));
	/* clear any possible error conditions */
	pci_write_config_byte(agp_bridge->dev, INTEL_ERRSTS + 1, 7);
	return 0;
}

static int efficeon_free_gatt_table(struct agp_bridge_data *bridge)
{
	int index, freed = 0;

	for (index = 0; index < EFFICEON_L1_SIZE; index++) {
		unsigned long page = efficeon_private.l1_table[index];
		if (page) {
			efficeon_private.l1_table[index] = 0;
			ClearPageReserved(virt_to_page((char *)page));
			free_page(page);
			freed++;
		}
		printk(KERN_DEBUG PFX "efficeon_free_gatt_table(%p, %02x, %08x)\n",
			agp_bridge->dev, EFFICEON_ATTPAGE, index);
		pci_write_config_dword(agp_bridge->dev,
			EFFICEON_ATTPAGE, index);
	}
	printk(KERN_DEBUG PFX "efficeon_free_gatt_table() freed %d pages\n", freed);
	return 0;
}


/*
 * Since we don't need contigious memory we just try
 * to get the gatt table once
 */

#define GET_PAGE_DIR_OFF(addr) (addr >> 22)
#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
	GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr))
#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12)
#undef  GET_GATT
#define GET_GATT(addr) (efficeon_private.gatt_pages[\
	GET_PAGE_DIR_IDX(addr)]->remapped)

static int efficeon_create_gatt_table(struct agp_bridge_data *bridge)
{
	int index;
	const int pati    = EFFICEON_PATI;
	const int present = EFFICEON_PRESENT;
	const int clflush_chunk = ((cpuid_ebx(1) >> 8) & 0xff) << 3;
	int num_entries, l1_pages;
	
	num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;

	printk(KERN_DEBUG PFX "efficeon_create_gatt_table(%d)\n", num_entries);

	/* There are 2^10 PTE pages per PDE page */
	BUG_ON(num_entries & 0x3ff);
	l1_pages = num_entries >> 10;

	for (index = 0 ; index < l1_pages ; index++) {
		int offset;
		unsigned long page;
		unsigned long value;

		page = efficeon_private.l1_table[index];
		BUG_ON(page);

		page = get_zeroed_page(GFP_KERNEL);
		if (!page) {
			efficeon_free_gatt_table(agp_bridge);
			return -ENOMEM;
		}
		SetPageReserved(virt_to_page((char *)page));

		for (offset = 0; offset < PAGE_SIZE; offset += clflush_chunk)
			asm volatile("clflush %0" : : "m" (*(char *)(page+offset)));

		efficeon_private.l1_table[index] = page;

		value = __pa(page) | pati | present | index;

		pci_write_config_dword(agp_bridge->dev,
			EFFICEON_ATTPAGE, value);
	}

	return 0;
}

static int efficeon_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
{
	int i, count = mem->page_count, num_entries;
	unsigned int *page, *last_page;
	const int clflush_chunk = ((cpuid_ebx(1) >> 8) & 0xff) << 3;
	const unsigned long clflush_mask = ~(clflush_chunk-1);

	printk(KERN_DEBUG PFX "efficeon_insert_memory(%lx, %d)\n", pg_start, count);

	num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;
	if ((pg_start + mem->page_count) > num_entries)
		return -EINVAL;
	if (type != 0 || mem->type != 0)
		return -EINVAL;

	if (mem->is_flushed == FALSE) {
		global_cache_flush();
		mem->is_flushed = TRUE;
	}

	last_page = NULL;
	for (i = 0; i < count; i++) {
		int index = pg_start + i;
		unsigned long insert = mem->memory[i];

		page = (unsigned int *) efficeon_private.l1_table[index >> 10];

		if (!page)
			continue;
		
		page += (index & 0x3ff);
		*page = insert;

		/* clflush is slow, so don't clflush until we have to */
		if ( last_page && 
		     ((unsigned long)page^(unsigned long)last_page) & clflush_mask )
		    asm volatile("clflush %0" : : "m" (*last_page));

		last_page = page;
	}

	if ( last_page )
		asm volatile("clflush %0" : : "m" (*last_page));

	agp_bridge->driver->tlb_flush(mem);
	return 0;
}

static int efficeon_remove_memory(struct agp_memory * mem, off_t pg_start, int type)
{
	int i, count = mem->page_count, num_entries;

	printk(KERN_DEBUG PFX "efficeon_remove_memory(%lx, %d)\n", pg_start, count);

	num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;

	if ((pg_start + mem->page_count) > num_entries)
		return -EINVAL;
	if (type != 0 || mem->type != 0)
		return -EINVAL;

	for (i = 0; i < count; i++) {
		int index = pg_start + i;
		unsigned int *page = (unsigned int *) efficeon_private.l1_table[index >> 10];

		if (!page)
			continue;
		page += (index & 0x3ff);
		*page = 0;
	}
	agp_bridge->driver->tlb_flush(mem);
	return 0;
}


struct agp_bridge_driver efficeon_driver = {
	.owner			= THIS_MODULE,
	.aperture_sizes		= efficeon_generic_sizes,
	.size_type		= LVL2_APER_SIZE,
	.num_aperture_sizes	= 4,
	.configure		= efficeon_configure,
	.fetch_size		= efficeon_fetch_size,
	.cleanup		= efficeon_cleanup,
	.tlb_flush		= efficeon_tlbflush,
	.mask_memory		= agp_generic_mask_memory,
	.masks			= efficeon_generic_masks,
	.agp_enable		= agp_generic_enable,
	.cache_flush		= global_cache_flush,

	// Efficeon-specific GATT table setup / populate / teardown
	.create_gatt_table	= efficeon_create_gatt_table,
	.free_gatt_table	= efficeon_free_gatt_table,
	.insert_memory		= efficeon_insert_memory,
	.remove_memory		= efficeon_remove_memory,
	.cant_use_aperture	= 0,	// 1 might be faster?

	// Generic
	.alloc_by_type		= agp_generic_alloc_by_type,
	.free_by_type		= agp_generic_free_by_type,
	.agp_alloc_page		= agp_generic_alloc_page,
	.agp_destroy_page	= agp_generic_destroy_page,
};


static int agp_efficeon_resume(struct pci_dev *pdev)
{
	printk(KERN_DEBUG PFX "agp_efficeon_resume()\n");
	return efficeon_configure();
}

static int __devinit agp_efficeon_probe(struct pci_dev *pdev,
				     const struct pci_device_id *ent)
{
	struct agp_bridge_data *bridge;
	u8 cap_ptr;
	struct resource *r;

	cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
	if (!cap_ptr)
		return -ENODEV;

	/* Probe for Efficeon controller */
	if (pdev->device != PCI_DEVICE_ID_EFFICEON) {
		printk(KERN_ERR PFX "Unsupported Efficeon chipset (device id: %04x)\n",
		    pdev->device);
		return -ENODEV;
	}

	printk(KERN_INFO PFX "Detected Transmeta Efficeon TM8000 series chipset\n");

	bridge = agp_alloc_bridge();
	if (!bridge)
		return -ENOMEM;

	bridge->driver = &efficeon_driver;
	bridge->dev = pdev;
	bridge->capndx = cap_ptr;

	/*
	* The following fixes the case where the BIOS has "forgotten" to
	* provide an address range for the GART.
	* 20030610 - hamish@zot.org
	*/
	r = &pdev->resource[0];
	if (!r->start && r->end) {
		if(pci_assign_resource(pdev, 0)) {
			printk(KERN_ERR PFX "could not assign resource 0\n");
			return -ENODEV;
		}
	}

	/*
	* If the device has not been properly setup, the following will catch
	* the problem and should stop the system from crashing.
	* 20030610 - hamish@zot.org
	*/
	if (pci_enable_device(pdev)) {
		printk(KERN_ERR PFX "Unable to Enable PCI device\n");
		return -ENODEV;
	}

	/* Fill in the mode register */
	if (cap_ptr) {
		pci_read_config_dword(pdev,
				bridge->capndx+PCI_AGP_STATUS,
				&bridge->mode);
	}

	pci_set_drvdata(pdev, bridge);
	return agp_add_bridge(bridge);
}

static void __devexit agp_efficeon_remove(struct pci_dev *pdev)
{
	struct agp_bridge_data *bridge = pci_get_drvdata(pdev);

	agp_remove_bridge(bridge);
	agp_put_bridge(bridge);
}

static int agp_efficeon_suspend(struct pci_dev *dev, u32 state)
{
	return 0;
}


static struct pci_device_id agp_efficeon_pci_table[] = {
	{
	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
	.class_mask	= ~0,
	.vendor		= PCI_VENDOR_ID_TRANSMETA,
	.device		= PCI_ANY_ID,
	.subvendor	= PCI_ANY_ID,
	.subdevice	= PCI_ANY_ID,
	},
	{ }
};

MODULE_DEVICE_TABLE(pci, agp_efficeon_pci_table);

static struct pci_driver agp_efficeon_pci_driver = {
	.name		= "agpgart-efficeon",
	.id_table	= agp_efficeon_pci_table,
	.probe		= agp_efficeon_probe,
	.remove		= agp_efficeon_remove,
	.suspend	= agp_efficeon_suspend,
	.resume		= agp_efficeon_resume,
};

static int __init agp_efficeon_init(void)
{
	static int agp_initialised=0;

	if (agp_off)
		return -EINVAL;

	if (agp_initialised == 1)
		return 0;
	agp_initialised=1;

	return pci_register_driver(&agp_efficeon_pci_driver);
}

static void __exit agp_efficeon_cleanup(void)
{
	pci_unregister_driver(&agp_efficeon_pci_driver);
}

module_init(agp_efficeon_init);
module_exit(agp_efficeon_cleanup);

MODULE_AUTHOR("Carlos Puchol <cpglinux@puchol.com>");
MODULE_LICENSE("GPL and additional rights");
