/*
 * arch/ppc64/kernel/iSeries_iommu.c
 *
 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
 *
 * Rewrite, cleanup:
 *
 * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
 *
 * Dynamic DMA mapping support, iSeries-specific parts.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

#include <linux/types.h>
#include <linux/dma-mapping.h>
#include <linux/list.h>

#include <asm/iommu.h>
#include <asm/machdep.h>
#include <asm/iSeries/HvCallXm.h>
#include <asm/iSeries/iSeries_pci.h>

extern struct list_head iSeries_Global_Device_List;


static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
		unsigned long uaddr, enum dma_data_direction direction)
{
	u64 rc;
	union tce_entry tce;

	while (npages--) {
		tce.te_word = 0;
		tce.te_bits.tb_rpn = virt_to_abs(uaddr) >> PAGE_SHIFT;

		if (tbl->it_type == TCE_VB) {
			/* Virtual Bus */
			tce.te_bits.tb_valid = 1;
			tce.te_bits.tb_allio = 1;
			if (direction != DMA_TO_DEVICE)
				tce.te_bits.tb_rdwr = 1;
		} else {
			/* PCI Bus */
			tce.te_bits.tb_rdwr = 1; /* Read allowed */
			if (direction != DMA_TO_DEVICE)
				tce.te_bits.tb_pciwr = 1;
		}

		rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index,
				tce.te_word);
		if (rc)
			panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n",
					rc);
		index++;
		uaddr += PAGE_SIZE;
	}
}

static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)
{
	u64 rc;

	while (npages--) {
		rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0);
		if (rc)
			panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n",
					rc);
		index++;
	}
}


/*
 * This function compares the known tables to find an iommu_table
 * that has already been built for hardware TCEs.
 */
static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
{
	struct iSeries_Device_Node *dp;

	list_for_each_entry(dp, &iSeries_Global_Device_List, Device_List) {
		if ((dp->iommu_table != NULL) &&
		    (dp->iommu_table->it_type == TCE_PCI) &&
		    (dp->iommu_table->it_offset == tbl->it_offset) &&
		    (dp->iommu_table->it_index == tbl->it_index) &&
		    (dp->iommu_table->it_size == tbl->it_size))
			return dp->iommu_table;
	}
	return NULL;
}

/*
 * Call Hv with the architected data structure to get TCE table info.
 * info. Put the returned data into the Linux representation of the
 * TCE table data.
 * The Hardware Tce table comes in three flavors.
 * 1. TCE table shared between Buses.
 * 2. TCE table per Bus.
 * 3. TCE Table per IOA.
 */
static void iommu_table_getparms(struct iSeries_Device_Node* dn,
				 struct iommu_table* tbl)
{
	struct iommu_table_cb *parms;

	parms = kmalloc(sizeof(*parms), GFP_KERNEL);
	if (parms == NULL)
		panic("PCI_DMA: TCE Table Allocation failed.");

	memset(parms, 0, sizeof(*parms));

	parms->itc_busno = ISERIES_BUS(dn);
	parms->itc_slotno = dn->LogicalSlot;
	parms->itc_virtbus = 0;

	HvCallXm_getTceTableParms(ISERIES_HV_ADDR(parms));

	if (parms->itc_size == 0)
		panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms);

	/* itc_size is in pages worth of table, it_size is in # of entries */
	tbl->it_size = (parms->itc_size * PAGE_SIZE) / sizeof(union tce_entry);
	tbl->it_busno = parms->itc_busno;
	tbl->it_offset = parms->itc_offset;
	tbl->it_index = parms->itc_index;
	tbl->it_blocksize = 1;
	tbl->it_type = TCE_PCI;

	kfree(parms);
}


void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn)
{
	struct iommu_table *tbl;

	tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);

	iommu_table_getparms(dn, tbl);

	/* Look for existing tce table */
	dn->iommu_table = iommu_table_find(tbl);
	if (dn->iommu_table == NULL)
		dn->iommu_table = iommu_init_table(tbl);
	else
		kfree(tbl);
}

static void iommu_dev_setup_iSeries(struct pci_dev *dev) { }
static void iommu_bus_setup_iSeries(struct pci_bus *bus) { }

void iommu_init_early_iSeries(void)
{
	ppc_md.tce_build = tce_build_iSeries;
	ppc_md.tce_free  = tce_free_iSeries;

	ppc_md.iommu_dev_setup = iommu_dev_setup_iSeries;
	ppc_md.iommu_bus_setup = iommu_bus_setup_iSeries;

	pci_iommu_init();
}
