// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * IOMMU implementation for Cell Broadband Processor Architecture
 *
 * (C) Copyright IBM Corporation 2006-2008
 *
 * Author: Jeremy Kerr <jk@ozlabs.org>
 */

#undef DEBUG

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/notifier.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/memblock.h>

#include <asm/prom.h>
#include <asm/iommu.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
#include <asm/udbg.h>
#include <asm/firmware.h>
#include <asm/cell-regs.h>

#include "cell.h"
#include "interrupt.h"

/* Define CELL_IOMMU_REAL_UNMAP to actually unmap non-used pages
 * instead of leaving them mapped to some dummy page. This can be
 * enabled once the appropriate workarounds for spider bugs have
 * been enabled
 */
#define CELL_IOMMU_REAL_UNMAP

/* Define CELL_IOMMU_STRICT_PROTECTION to enforce protection of
 * IO PTEs based on the transfer direction. That can be enabled
 * once spider-net has been fixed to pass the correct direction
 * to the DMA mapping functions
 */
#define CELL_IOMMU_STRICT_PROTECTION


#define NR_IOMMUS			2

/* IOC mmap registers */
#define IOC_Reg_Size			0x2000

#define IOC_IOPT_CacheInvd		0x908
#define IOC_IOPT_CacheInvd_NE_Mask	0xffe0000000000000ul
#define IOC_IOPT_CacheInvd_IOPTE_Mask	0x000003fffffffff8ul
#define IOC_IOPT_CacheInvd_Busy		0x0000000000000001ul

#define IOC_IOST_Origin			0x918
#define IOC_IOST_Origin_E		0x8000000000000000ul
#define IOC_IOST_Origin_HW		0x0000000000000800ul
#define IOC_IOST_Origin_HL		0x0000000000000400ul

#define IOC_IO_ExcpStat			0x920
#define IOC_IO_ExcpStat_V		0x8000000000000000ul
#define IOC_IO_ExcpStat_SPF_Mask	0x6000000000000000ul
#define IOC_IO_ExcpStat_SPF_S		0x6000000000000000ul
#define IOC_IO_ExcpStat_SPF_P		0x2000000000000000ul
#define IOC_IO_ExcpStat_ADDR_Mask	0x00000007fffff000ul
#define IOC_IO_ExcpStat_RW_Mask		0x0000000000000800ul
#define IOC_IO_ExcpStat_IOID_Mask	0x00000000000007fful

#define IOC_IO_ExcpMask			0x928
#define IOC_IO_ExcpMask_SFE		0x4000000000000000ul
#define IOC_IO_ExcpMask_PFE		0x2000000000000000ul

#define IOC_IOCmd_Offset		0x1000

#define IOC_IOCmd_Cfg			0xc00
#define IOC_IOCmd_Cfg_TE		0x0000800000000000ul


/* Segment table entries */
#define IOSTE_V			0x8000000000000000ul /* valid */
#define IOSTE_H			0x4000000000000000ul /* cache hint */
#define IOSTE_PT_Base_RPN_Mask  0x3ffffffffffff000ul /* base RPN of IOPT */
#define IOSTE_NPPT_Mask		0x0000000000000fe0ul /* no. pages in IOPT */
#define IOSTE_PS_Mask		0x0000000000000007ul /* page size */
#define IOSTE_PS_4K		0x0000000000000001ul /*   - 4kB  */
#define IOSTE_PS_64K		0x0000000000000003ul /*   - 64kB */
#define IOSTE_PS_1M		0x0000000000000005ul /*   - 1MB  */
#define IOSTE_PS_16M		0x0000000000000007ul /*   - 16MB */


/* IOMMU sizing */
#define IO_SEGMENT_SHIFT	28
#define IO_PAGENO_BITS(shift)	(IO_SEGMENT_SHIFT - (shift))

/* The high bit needs to be set on every DMA address */
#define SPIDER_DMA_OFFSET	0x80000000ul

struct iommu_window {
	struct list_head list;
	struct cbe_iommu *iommu;
	unsigned long offset;
	unsigned long size;
	unsigned int ioid;
	struct iommu_table table;
};

#define NAMESIZE 8
struct cbe_iommu {
	int nid;
	char name[NAMESIZE];
	void __iomem *xlate_regs;
	void __iomem *cmd_regs;
	unsigned long *stab;
	unsigned long *ptab;
	void *pad_page;
	struct list_head windows;
};

/* Static array of iommus, one per node
 *   each contains a list of windows, keyed from dma_window property
 *   - on bus setup, look for a matching window, or create one
 *   - on dev setup, assign iommu_table ptr
 */
static struct cbe_iommu iommus[NR_IOMMUS];
static int cbe_nr_iommus;

static void invalidate_tce_cache(struct cbe_iommu *iommu, unsigned long *pte,
		long n_ptes)
{
	u64 __iomem *reg;
	u64 val;
	long n;

	reg = iommu->xlate_regs + IOC_IOPT_CacheInvd;

	while (n_ptes > 0) {
		/* we can invalidate up to 1 << 11 PTEs at once */
		n = min(n_ptes, 1l << 11);
		val = (((n /*- 1*/) << 53) & IOC_IOPT_CacheInvd_NE_Mask)
			| (__pa(pte) & IOC_IOPT_CacheInvd_IOPTE_Mask)
		        | IOC_IOPT_CacheInvd_Busy;

		out_be64(reg, val);
		while (in_be64(reg) & IOC_IOPT_CacheInvd_Busy)
			;

		n_ptes -= n;
		pte += n;
	}
}

static int tce_build_cell(struct iommu_table *tbl, long index, long npages,
		unsigned long uaddr, enum dma_data_direction direction,
		unsigned long attrs)
{
	int i;
	unsigned long *io_pte, base_pte;
	struct iommu_window *window =
		container_of(tbl, struct iommu_window, table);

	/* implementing proper protection causes problems with the spidernet
	 * driver - check mapping directions later, but allow read & write by
	 * default for now.*/
#ifdef CELL_IOMMU_STRICT_PROTECTION
	/* to avoid referencing a global, we use a trick here to setup the
	 * protection bit. "prot" is setup to be 3 fields of 4 bits appended
	 * together for each of the 3 supported direction values. It is then
	 * shifted left so that the fields matching the desired direction
	 * lands on the appropriate bits, and other bits are masked out.
	 */
	const unsigned long prot = 0xc48;
	base_pte =
		((prot << (52 + 4 * direction)) &
		 (CBE_IOPTE_PP_W | CBE_IOPTE_PP_R)) |
		CBE_IOPTE_M | CBE_IOPTE_SO_RW |
		(window->ioid & CBE_IOPTE_IOID_Mask);
#else
	base_pte = CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_M |
		CBE_IOPTE_SO_RW | (window->ioid & CBE_IOPTE_IOID_Mask);
#endif
	if (unlikely(attrs & DMA_ATTR_WEAK_ORDERING))
		base_pte &= ~CBE_IOPTE_SO_RW;

	io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);

	for (i = 0; i < npages; i++, uaddr += (1 << tbl->it_page_shift))
		io_pte[i] = base_pte | (__pa(uaddr) & CBE_IOPTE_RPN_Mask);

	mb();

	invalidate_tce_cache(window->iommu, io_pte, npages);

	pr_debug("tce_build_cell(index=%lx,n=%lx,dir=%d,base_pte=%lx)\n",
		 index, npages, direction, base_pte);
	return 0;
}

static void tce_free_cell(struct iommu_table *tbl, long index, long npages)
{

	int i;
	unsigned long *io_pte, pte;
	struct iommu_window *window =
		container_of(tbl, struct iommu_window, table);

	pr_debug("tce_free_cell(index=%lx,n=%lx)\n", index, npages);

#ifdef CELL_IOMMU_REAL_UNMAP
	pte = 0;
#else
	/* spider bridge does PCI reads after freeing - insert a mapping
	 * to a scratch page instead of an invalid entry */
	pte = CBE_IOPTE_PP_R | CBE_IOPTE_M | CBE_IOPTE_SO_RW |
		__pa(window->iommu->pad_page) |
		(window->ioid & CBE_IOPTE_IOID_Mask);
#endif

	io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);

	for (i = 0; i < npages; i++)
		io_pte[i] = pte;

	mb();

	invalidate_tce_cache(window->iommu, io_pte, npages);
}

static irqreturn_t ioc_interrupt(int irq, void *data)
{
	unsigned long stat, spf;
	struct cbe_iommu *iommu = data;

	stat = in_be64(iommu->xlate_regs + IOC_IO_ExcpStat);
	spf = stat & IOC_IO_ExcpStat_SPF_Mask;

	/* Might want to rate limit it */
	printk(KERN_ERR "iommu: DMA exception 0x%016lx\n", stat);
	printk(KERN_ERR "  V=%d, SPF=[%c%c], RW=%s, IOID=0x%04x\n",
	       !!(stat & IOC_IO_ExcpStat_V),
	       (spf == IOC_IO_ExcpStat_SPF_S) ? 'S' : ' ',
	       (spf == IOC_IO_ExcpStat_SPF_P) ? 'P' : ' ',
	       (stat & IOC_IO_ExcpStat_RW_Mask) ? "Read" : "Write",
	       (unsigned int)(stat & IOC_IO_ExcpStat_IOID_Mask));
	printk(KERN_ERR "  page=0x%016lx\n",
	       stat & IOC_IO_ExcpStat_ADDR_Mask);

	/* clear interrupt */
	stat &= ~IOC_IO_ExcpStat_V;
	out_be64(iommu->xlate_regs + IOC_IO_ExcpStat, stat);

	return IRQ_HANDLED;
}

static int __init cell_iommu_find_ioc(int nid, unsigned long *base)
{
	struct device_node *np;
	struct resource r;

	*base = 0;

	/* First look for new style /be nodes */
	for_each_node_by_name(np, "ioc") {
		if (of_node_to_nid(np) != nid)
			continue;
		if (of_address_to_resource(np, 0, &r)) {
			printk(KERN_ERR "iommu: can't get address for %pOF\n",
			       np);
			continue;
		}
		*base = r.start;
		of_node_put(np);
		return 0;
	}

	/* Ok, let's try the old way */
	for_each_node_by_type(np, "cpu") {
		const unsigned int *nidp;
		const unsigned long *tmp;

		nidp = of_get_property(np, "node-id", NULL);
		if (nidp && *nidp == nid) {
			tmp = of_get_property(np, "ioc-translation", NULL);
			if (tmp) {
				*base = *tmp;
				of_node_put(np);
				return 0;
			}
		}
	}

	return -ENODEV;
}

static void __init cell_iommu_setup_stab(struct cbe_iommu *iommu,
				unsigned long dbase, unsigned long dsize,
				unsigned long fbase, unsigned long fsize)
{
	struct page *page;
	unsigned long segments, stab_size;

	segments = max(dbase + dsize, fbase + fsize) >> IO_SEGMENT_SHIFT;

	pr_debug("%s: iommu[%d]: segments: %lu\n",
			__func__, iommu->nid, segments);

	/* set up the segment table */
	stab_size = segments * sizeof(unsigned long);
	page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size));
	BUG_ON(!page);
	iommu->stab = page_address(page);
	memset(iommu->stab, 0, stab_size);
}

static unsigned long *__init cell_iommu_alloc_ptab(struct cbe_iommu *iommu,
		unsigned long base, unsigned long size, unsigned long gap_base,
		unsigned long gap_size, unsigned long page_shift)
{
	struct page *page;
	int i;
	unsigned long reg, segments, pages_per_segment, ptab_size,
		      n_pte_pages, start_seg, *ptab;

	start_seg = base >> IO_SEGMENT_SHIFT;
	segments  = size >> IO_SEGMENT_SHIFT;
	pages_per_segment = 1ull << IO_PAGENO_BITS(page_shift);
	/* PTEs for each segment must start on a 4K boundary */
	pages_per_segment = max(pages_per_segment,
				(1 << 12) / sizeof(unsigned long));

	ptab_size = segments * pages_per_segment * sizeof(unsigned long);
	pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __func__,
			iommu->nid, ptab_size, get_order(ptab_size));
	page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size));
	BUG_ON(!page);

	ptab = page_address(page);
	memset(ptab, 0, ptab_size);

	/* number of 4K pages needed for a page table */
	n_pte_pages = (pages_per_segment * sizeof(unsigned long)) >> 12;

	pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n",
			__func__, iommu->nid, iommu->stab, ptab,
			n_pte_pages);

	/* initialise the STEs */
	reg = IOSTE_V | ((n_pte_pages - 1) << 5);

	switch (page_shift) {
	case 12: reg |= IOSTE_PS_4K;  break;
	case 16: reg |= IOSTE_PS_64K; break;
	case 20: reg |= IOSTE_PS_1M;  break;
	case 24: reg |= IOSTE_PS_16M; break;
	default: BUG();
	}

	gap_base = gap_base >> IO_SEGMENT_SHIFT;
	gap_size = gap_size >> IO_SEGMENT_SHIFT;

	pr_debug("Setting up IOMMU stab:\n");
	for (i = start_seg; i < (start_seg + segments); i++) {
		if (i >= gap_base && i < (gap_base + gap_size)) {
			pr_debug("\toverlap at %d, skipping\n", i);
			continue;
		}
		iommu->stab[i] = reg | (__pa(ptab) + (n_pte_pages << 12) *
					(i - start_seg));
		pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]);
	}

	return ptab;
}

static void __init cell_iommu_enable_hardware(struct cbe_iommu *iommu)
{
	int ret;
	unsigned long reg, xlate_base;
	unsigned int virq;

	if (cell_iommu_find_ioc(iommu->nid, &xlate_base))
		panic("%s: missing IOC register mappings for node %d\n",
		      __func__, iommu->nid);

	iommu->xlate_regs = ioremap(xlate_base, IOC_Reg_Size);
	iommu->cmd_regs = iommu->xlate_regs + IOC_IOCmd_Offset;

	/* ensure that the STEs have updated */
	mb();

	/* setup interrupts for the iommu. */
	reg = in_be64(iommu->xlate_regs + IOC_IO_ExcpStat);
	out_be64(iommu->xlate_regs + IOC_IO_ExcpStat,
			reg & ~IOC_IO_ExcpStat_V);
	out_be64(iommu->xlate_regs + IOC_IO_ExcpMask,
			IOC_IO_ExcpMask_PFE | IOC_IO_ExcpMask_SFE);

	virq = irq_create_mapping(NULL,
			IIC_IRQ_IOEX_ATI | (iommu->nid << IIC_IRQ_NODE_SHIFT));
	BUG_ON(!virq);

	ret = request_irq(virq, ioc_interrupt, 0, iommu->name, iommu);
	BUG_ON(ret);

	/* set the IOC segment table origin register (and turn on the iommu) */
	reg = IOC_IOST_Origin_E | __pa(iommu->stab) | IOC_IOST_Origin_HW;
	out_be64(iommu->xlate_regs + IOC_IOST_Origin, reg);
	in_be64(iommu->xlate_regs + IOC_IOST_Origin);

	/* turn on IO translation */
	reg = in_be64(iommu->cmd_regs + IOC_IOCmd_Cfg) | IOC_IOCmd_Cfg_TE;
	out_be64(iommu->cmd_regs + IOC_IOCmd_Cfg, reg);
}

static void __init cell_iommu_setup_hardware(struct cbe_iommu *iommu,
	unsigned long base, unsigned long size)
{
	cell_iommu_setup_stab(iommu, base, size, 0, 0);
	iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size, 0, 0,
					    IOMMU_PAGE_SHIFT_4K);
	cell_iommu_enable_hardware(iommu);
}

#if 0/* Unused for now */
static struct iommu_window *find_window(struct cbe_iommu *iommu,
		unsigned long offset, unsigned long size)
{
	struct iommu_window *window;

	/* todo: check for overlapping (but not equal) windows) */

	list_for_each_entry(window, &(iommu->windows), list) {
		if (window->offset == offset && window->size == size)
			return window;
	}

	return NULL;
}
#endif

static inline u32 cell_iommu_get_ioid(struct device_node *np)
{
	const u32 *ioid;

	ioid = of_get_property(np, "ioid", NULL);
	if (ioid == NULL) {
		printk(KERN_WARNING "iommu: missing ioid for %pOF using 0\n",
		       np);
		return 0;
	}

	return *ioid;
}

static struct iommu_table_ops cell_iommu_ops = {
	.set = tce_build_cell,
	.clear = tce_free_cell
};

static struct iommu_window * __init
cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
			unsigned long offset, unsigned long size,
			unsigned long pte_offset)
{
	struct iommu_window *window;
	struct page *page;
	u32 ioid;

	ioid = cell_iommu_get_ioid(np);

	window = kzalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid);
	BUG_ON(window == NULL);

	window->offset = offset;
	window->size = size;
	window->ioid = ioid;
	window->iommu = iommu;

	window->table.it_blocksize = 16;
	window->table.it_base = (unsigned long)iommu->ptab;
	window->table.it_index = iommu->nid;
	window->table.it_page_shift = IOMMU_PAGE_SHIFT_4K;
	window->table.it_offset =
		(offset >> window->table.it_page_shift) + pte_offset;
	window->table.it_size = size >> window->table.it_page_shift;
	window->table.it_ops = &cell_iommu_ops;

	if (!iommu_init_table(&window->table, iommu->nid, 0, 0))
		panic("Failed to initialize iommu table");

	pr_debug("\tioid      %d\n", window->ioid);
	pr_debug("\tblocksize %ld\n", window->table.it_blocksize);
	pr_debug("\tbase      0x%016lx\n", window->table.it_base);
	pr_debug("\toffset    0x%lx\n", window->table.it_offset);
	pr_debug("\tsize      %ld\n", window->table.it_size);

	list_add(&window->list, &iommu->windows);

	if (offset != 0)
		return window;

	/* We need to map and reserve the first IOMMU page since it's used
	 * by the spider workaround. In theory, we only need to do that when
	 * running on spider but it doesn't really matter.
	 *
	 * This code also assumes that we have a window that starts at 0,
	 * which is the case on all spider based blades.
	 */
	page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0);
	BUG_ON(!page);
	iommu->pad_page = page_address(page);
	clear_page(iommu->pad_page);

	__set_bit(0, window->table.it_map);
	tce_build_cell(&window->table, window->table.it_offset, 1,
		       (unsigned long)iommu->pad_page, DMA_TO_DEVICE, 0);

	return window;
}

static struct cbe_iommu *cell_iommu_for_node(int nid)
{
	int i;

	for (i = 0; i < cbe_nr_iommus; i++)
		if (iommus[i].nid == nid)
			return &iommus[i];
	return NULL;
}

static unsigned long cell_dma_nommu_offset;

static unsigned long dma_iommu_fixed_base;
static bool cell_iommu_enabled;

/* iommu_fixed_is_weak is set if booted with iommu_fixed=weak */
bool iommu_fixed_is_weak;

static struct iommu_table *cell_get_iommu_table(struct device *dev)
{
	struct iommu_window *window;
	struct cbe_iommu *iommu;

	/* Current implementation uses the first window available in that
	 * node's iommu. We -might- do something smarter later though it may
	 * never be necessary
	 */
	iommu = cell_iommu_for_node(dev_to_node(dev));
	if (iommu == NULL || list_empty(&iommu->windows)) {
		dev_err(dev, "iommu: missing iommu for %pOF (node %d)\n",
		       dev->of_node, dev_to_node(dev));
		return NULL;
	}
	window = list_entry(iommu->windows.next, struct iommu_window, list);

	return &window->table;
}

static u64 cell_iommu_get_fixed_address(struct device *dev);

static void cell_dma_dev_setup(struct device *dev)
{
	if (cell_iommu_enabled) {
		u64 addr = cell_iommu_get_fixed_address(dev);

		if (addr != OF_BAD_ADDR)
			dev->archdata.dma_offset = addr + dma_iommu_fixed_base;
		set_iommu_table_base(dev, cell_get_iommu_table(dev));
	} else {
		dev->archdata.dma_offset = cell_dma_nommu_offset;
	}
}

static void cell_pci_dma_dev_setup(struct pci_dev *dev)
{
	cell_dma_dev_setup(&dev->dev);
}

static int cell_of_bus_notify(struct notifier_block *nb, unsigned long action,
			      void *data)
{
	struct device *dev = data;

	/* We are only interested in device addition */
	if (action != BUS_NOTIFY_ADD_DEVICE)
		return 0;

	if (cell_iommu_enabled)
		dev->dma_ops = &dma_iommu_ops;
	cell_dma_dev_setup(dev);
	return 0;
}

static struct notifier_block cell_of_bus_notifier = {
	.notifier_call = cell_of_bus_notify
};

static int __init cell_iommu_get_window(struct device_node *np,
					 unsigned long *base,
					 unsigned long *size)
{
	const __be32 *dma_window;
	unsigned long index;

	/* Use ibm,dma-window if available, else, hard code ! */
	dma_window = of_get_property(np, "ibm,dma-window", NULL);
	if (dma_window == NULL) {
		*base = 0;
		*size = 0x80000000u;
		return -ENODEV;
	}

	of_parse_dma_window(np, dma_window, &index, base, size);
	return 0;
}

static struct cbe_iommu * __init cell_iommu_alloc(struct device_node *np)
{
	struct cbe_iommu *iommu;
	int nid, i;

	/* Get node ID */
	nid = of_node_to_nid(np);
	if (nid < 0) {
		printk(KERN_ERR "iommu: failed to get node for %pOF\n",
		       np);
		return NULL;
	}
	pr_debug("iommu: setting up iommu for node %d (%pOF)\n",
		 nid, np);

	/* XXX todo: If we can have multiple windows on the same IOMMU, which
	 * isn't the case today, we probably want here to check whether the
	 * iommu for that node is already setup.
	 * However, there might be issue with getting the size right so let's
	 * ignore that for now. We might want to completely get rid of the
	 * multiple window support since the cell iommu supports per-page ioids
	 */

	if (cbe_nr_iommus >= NR_IOMMUS) {
		printk(KERN_ERR "iommu: too many IOMMUs detected ! (%pOF)\n",
		       np);
		return NULL;
	}

	/* Init base fields */
	i = cbe_nr_iommus++;
	iommu = &iommus[i];
	iommu->stab = NULL;
	iommu->nid = nid;
	snprintf(iommu->name, sizeof(iommu->name), "iommu%d", i);
	INIT_LIST_HEAD(&iommu->windows);

	return iommu;
}

static void __init cell_iommu_init_one(struct device_node *np,
				       unsigned long offset)
{
	struct cbe_iommu *iommu;
	unsigned long base, size;

	iommu = cell_iommu_alloc(np);
	if (!iommu)
		return;

	/* Obtain a window for it */
	cell_iommu_get_window(np, &base, &size);

	pr_debug("\ttranslating window 0x%lx...0x%lx\n",
		 base, base + size - 1);

	/* Initialize the hardware */
	cell_iommu_setup_hardware(iommu, base, size);

	/* Setup the iommu_table */
	cell_iommu_setup_window(iommu, np, base, size,
				offset >> IOMMU_PAGE_SHIFT_4K);
}

static void __init cell_disable_iommus(void)
{
	int node;
	unsigned long base, val;
	void __iomem *xregs, *cregs;

	/* Make sure IOC translation is disabled on all nodes */
	for_each_online_node(node) {
		if (cell_iommu_find_ioc(node, &base))
			continue;
		xregs = ioremap(base, IOC_Reg_Size);
		if (xregs == NULL)
			continue;
		cregs = xregs + IOC_IOCmd_Offset;

		pr_debug("iommu: cleaning up iommu on node %d\n", node);

		out_be64(xregs + IOC_IOST_Origin, 0);
		(void)in_be64(xregs + IOC_IOST_Origin);
		val = in_be64(cregs + IOC_IOCmd_Cfg);
		val &= ~IOC_IOCmd_Cfg_TE;
		out_be64(cregs + IOC_IOCmd_Cfg, val);
		(void)in_be64(cregs + IOC_IOCmd_Cfg);

		iounmap(xregs);
	}
}

static int __init cell_iommu_init_disabled(void)
{
	struct device_node *np = NULL;
	unsigned long base = 0, size;

	/* When no iommu is present, we use direct DMA ops */

	/* First make sure all IOC translation is turned off */
	cell_disable_iommus();

	/* If we have no Axon, we set up the spider DMA magic offset */
	np = of_find_node_by_name(NULL, "axon");
	if (!np)
		cell_dma_nommu_offset = SPIDER_DMA_OFFSET;
	of_node_put(np);

	/* Now we need to check to see where the memory is mapped
	 * in PCI space. We assume that all busses use the same dma
	 * window which is always the case so far on Cell, thus we
	 * pick up the first pci-internal node we can find and check
	 * the DMA window from there.
	 */
	for_each_node_by_name(np, "axon") {
		if (np->parent == NULL || np->parent->parent != NULL)
			continue;
		if (cell_iommu_get_window(np, &base, &size) == 0)
			break;
	}
	if (np == NULL) {
		for_each_node_by_name(np, "pci-internal") {
			if (np->parent == NULL || np->parent->parent != NULL)
				continue;
			if (cell_iommu_get_window(np, &base, &size) == 0)
				break;
		}
	}
	of_node_put(np);

	/* If we found a DMA window, we check if it's big enough to enclose
	 * all of physical memory. If not, we force enable IOMMU
	 */
	if (np && size < memblock_end_of_DRAM()) {
		printk(KERN_WARNING "iommu: force-enabled, dma window"
		       " (%ldMB) smaller than total memory (%lldMB)\n",
		       size >> 20, memblock_end_of_DRAM() >> 20);
		return -ENODEV;
	}

	cell_dma_nommu_offset += base;

	if (cell_dma_nommu_offset != 0)
		cell_pci_controller_ops.dma_dev_setup = cell_pci_dma_dev_setup;

	printk("iommu: disabled, direct DMA offset is 0x%lx\n",
	       cell_dma_nommu_offset);

	return 0;
}

/*
 *  Fixed IOMMU mapping support
 *
 *  This code adds support for setting up a fixed IOMMU mapping on certain
 *  cell machines. For 64-bit devices this avoids the performance overhead of
 *  mapping and unmapping pages at runtime. 32-bit devices are unable to use
 *  the fixed mapping.
 *
 *  The fixed mapping is established at boot, and maps all of physical memory
 *  1:1 into device space at some offset. On machines with < 30 GB of memory
 *  we setup the fixed mapping immediately above the normal IOMMU window.
 *
 *  For example a machine with 4GB of memory would end up with the normal
 *  IOMMU window from 0-2GB and the fixed mapping window from 2GB to 6GB. In
 *  this case a 64-bit device wishing to DMA to 1GB would be told to DMA to
 *  3GB, plus any offset required by firmware. The firmware offset is encoded
 *  in the "dma-ranges" property.
 *
 *  On machines with 30GB or more of memory, we are unable to place the fixed
 *  mapping above the normal IOMMU window as we would run out of address space.
 *  Instead we move the normal IOMMU window to coincide with the hash page
 *  table, this region does not need to be part of the fixed mapping as no
 *  device should ever be DMA'ing to it. We then setup the fixed mapping
 *  from 0 to 32GB.
 */

static u64 cell_iommu_get_fixed_address(struct device *dev)
{
	u64 cpu_addr, size, best_size, dev_addr = OF_BAD_ADDR;
	struct device_node *np;
	const u32 *ranges = NULL;
	int i, len, best, naddr, nsize, pna, range_size;

	/* We can be called for platform devices that have no of_node */
	np = of_node_get(dev->of_node);
	if (!np)
		goto out;

	while (1) {
		naddr = of_n_addr_cells(np);
		nsize = of_n_size_cells(np);
		np = of_get_next_parent(np);
		if (!np)
			break;

		ranges = of_get_property(np, "dma-ranges", &len);

		/* Ignore empty ranges, they imply no translation required */
		if (ranges && len > 0)
			break;
	}

	if (!ranges) {
		dev_dbg(dev, "iommu: no dma-ranges found\n");
		goto out;
	}

	len /= sizeof(u32);

	pna = of_n_addr_cells(np);
	range_size = naddr + nsize + pna;

	/* dma-ranges format:
	 * child addr	: naddr cells
	 * parent addr	: pna cells
	 * size		: nsize cells
	 */
	for (i = 0, best = -1, best_size = 0; i < len; i += range_size) {
		cpu_addr = of_translate_dma_address(np, ranges + i + naddr);
		size = of_read_number(ranges + i + naddr + pna, nsize);

		if (cpu_addr == 0 && size > best_size) {
			best = i;
			best_size = size;
		}
	}

	if (best >= 0) {
		dev_addr = of_read_number(ranges + best, naddr);
	} else
		dev_dbg(dev, "iommu: no suitable range found!\n");

out:
	of_node_put(np);

	return dev_addr;
}

static bool cell_pci_iommu_bypass_supported(struct pci_dev *pdev, u64 mask)
{
	return mask == DMA_BIT_MASK(64) &&
		cell_iommu_get_fixed_address(&pdev->dev) != OF_BAD_ADDR;
}

static void __init insert_16M_pte(unsigned long addr, unsigned long *ptab,
			   unsigned long base_pte)
{
	unsigned long segment, offset;

	segment = addr >> IO_SEGMENT_SHIFT;
	offset = (addr >> 24) - (segment << IO_PAGENO_BITS(24));
	ptab = ptab + (segment * (1 << 12) / sizeof(unsigned long));

	pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n",
		  addr, ptab, segment, offset);

	ptab[offset] = base_pte | (__pa(addr) & CBE_IOPTE_RPN_Mask);
}

static void __init cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
	struct device_node *np, unsigned long dbase, unsigned long dsize,
	unsigned long fbase, unsigned long fsize)
{
	unsigned long base_pte, uaddr, ioaddr, *ptab;

	ptab = cell_iommu_alloc_ptab(iommu, fbase, fsize, dbase, dsize, 24);

	dma_iommu_fixed_base = fbase;

	pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase);

	base_pte = CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_M |
		(cell_iommu_get_ioid(np) & CBE_IOPTE_IOID_Mask);

	if (iommu_fixed_is_weak)
		pr_info("IOMMU: Using weak ordering for fixed mapping\n");
	else {
		pr_info("IOMMU: Using strong ordering for fixed mapping\n");
		base_pte |= CBE_IOPTE_SO_RW;
	}

	for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) {
		/* Don't touch the dynamic region */
		ioaddr = uaddr + fbase;
		if (ioaddr >= dbase && ioaddr < (dbase + dsize)) {
			pr_debug("iommu: fixed/dynamic overlap, skipping\n");
			continue;
		}

		insert_16M_pte(uaddr, ptab, base_pte);
	}

	mb();
}

static int __init cell_iommu_fixed_mapping_init(void)
{
	unsigned long dbase, dsize, fbase, fsize, hbase, hend;
	struct cbe_iommu *iommu;
	struct device_node *np;

	/* The fixed mapping is only supported on axon machines */
	np = of_find_node_by_name(NULL, "axon");
	of_node_put(np);

	if (!np) {
		pr_debug("iommu: fixed mapping disabled, no axons found\n");
		return -1;
	}

	/* We must have dma-ranges properties for fixed mapping to work */
	np = of_find_node_with_property(NULL, "dma-ranges");
	of_node_put(np);

	if (!np) {
		pr_debug("iommu: no dma-ranges found, no fixed mapping\n");
		return -1;
	}

	/* The default setup is to have the fixed mapping sit after the
	 * dynamic region, so find the top of the largest IOMMU window
	 * on any axon, then add the size of RAM and that's our max value.
	 * If that is > 32GB we have to do other shennanigans.
	 */
	fbase = 0;
	for_each_node_by_name(np, "axon") {
		cell_iommu_get_window(np, &dbase, &dsize);
		fbase = max(fbase, dbase + dsize);
	}

	fbase = ALIGN(fbase, 1 << IO_SEGMENT_SHIFT);
	fsize = memblock_phys_mem_size();

	if ((fbase + fsize) <= 0x800000000ul)
		hbase = 0; /* use the device tree window */
	else {
		/* If we're over 32 GB we need to cheat. We can't map all of
		 * RAM with the fixed mapping, and also fit the dynamic
		 * region. So try to place the dynamic region where the hash
		 * table sits, drivers never need to DMA to it, we don't
		 * need a fixed mapping for that area.
		 */
		if (!htab_address) {
			pr_debug("iommu: htab is NULL, on LPAR? Huh?\n");
			return -1;
		}
		hbase = __pa(htab_address);
		hend  = hbase + htab_size_bytes;

		/* The window must start and end on a segment boundary */
		if ((hbase != ALIGN(hbase, 1 << IO_SEGMENT_SHIFT)) ||
		    (hend != ALIGN(hend, 1 << IO_SEGMENT_SHIFT))) {
			pr_debug("iommu: hash window not segment aligned\n");
			return -1;
		}

		/* Check the hash window fits inside the real DMA window */
		for_each_node_by_name(np, "axon") {
			cell_iommu_get_window(np, &dbase, &dsize);

			if (hbase < dbase || (hend > (dbase + dsize))) {
				pr_debug("iommu: hash window doesn't fit in"
					 "real DMA window\n");
				of_node_put(np);
				return -1;
			}
		}

		fbase = 0;
	}

	/* Setup the dynamic regions */
	for_each_node_by_name(np, "axon") {
		iommu = cell_iommu_alloc(np);
		BUG_ON(!iommu);

		if (hbase == 0)
			cell_iommu_get_window(np, &dbase, &dsize);
		else {
			dbase = hbase;
			dsize = htab_size_bytes;
		}

		printk(KERN_DEBUG "iommu: node %d, dynamic window 0x%lx-0x%lx "
			"fixed window 0x%lx-0x%lx\n", iommu->nid, dbase,
			 dbase + dsize, fbase, fbase + fsize);

		cell_iommu_setup_stab(iommu, dbase, dsize, fbase, fsize);
		iommu->ptab = cell_iommu_alloc_ptab(iommu, dbase, dsize, 0, 0,
						    IOMMU_PAGE_SHIFT_4K);
		cell_iommu_setup_fixed_ptab(iommu, np, dbase, dsize,
					     fbase, fsize);
		cell_iommu_enable_hardware(iommu);
		cell_iommu_setup_window(iommu, np, dbase, dsize, 0);
	}

	cell_pci_controller_ops.iommu_bypass_supported =
		cell_pci_iommu_bypass_supported;
	return 0;
}

static int iommu_fixed_disabled;

static int __init setup_iommu_fixed(char *str)
{
	struct device_node *pciep;

	if (strcmp(str, "off") == 0)
		iommu_fixed_disabled = 1;

	/* If we can find a pcie-endpoint in the device tree assume that
	 * we're on a triblade or a CAB so by default the fixed mapping
	 * should be set to be weakly ordered; but only if the boot
	 * option WASN'T set for strong ordering
	 */
	pciep = of_find_node_by_type(NULL, "pcie-endpoint");

	if (strcmp(str, "weak") == 0 || (pciep && strcmp(str, "strong") != 0))
		iommu_fixed_is_weak = true;

	of_node_put(pciep);

	return 1;
}
__setup("iommu_fixed=", setup_iommu_fixed);

static int __init cell_iommu_init(void)
{
	struct device_node *np;

	/* If IOMMU is disabled or we have little enough RAM to not need
	 * to enable it, we setup a direct mapping.
	 *
	 * Note: should we make sure we have the IOMMU actually disabled ?
	 */
	if (iommu_is_off ||
	    (!iommu_force_on && memblock_end_of_DRAM() <= 0x80000000ull))
		if (cell_iommu_init_disabled() == 0)
			goto bail;

	/* Setup various callbacks */
	cell_pci_controller_ops.dma_dev_setup = cell_pci_dma_dev_setup;

	if (!iommu_fixed_disabled && cell_iommu_fixed_mapping_init() == 0)
		goto done;

	/* Create an iommu for each /axon node.  */
	for_each_node_by_name(np, "axon") {
		if (np->parent == NULL || np->parent->parent != NULL)
			continue;
		cell_iommu_init_one(np, 0);
	}

	/* Create an iommu for each toplevel /pci-internal node for
	 * old hardware/firmware
	 */
	for_each_node_by_name(np, "pci-internal") {
		if (np->parent == NULL || np->parent->parent != NULL)
			continue;
		cell_iommu_init_one(np, SPIDER_DMA_OFFSET);
	}
 done:
	/* Setup default PCI iommu ops */
	set_pci_dma_ops(&dma_iommu_ops);
	cell_iommu_enabled = true;
 bail:
	/* Register callbacks on OF platform device addition/removal
	 * to handle linking them to the right DMA operations
	 */
	bus_register_notifier(&platform_bus_type, &cell_of_bus_notifier);

	return 0;
}
machine_arch_initcall(cell, cell_iommu_init);
