/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2003-2006 Silicon Graphics, Inc.  All Rights Reserved.
 */

#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/addrs.h>
#include <asm/sn/io.h>
#include <asm/sn/pcidev.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/tioce_provider.h>
#include <asm/sn/sn2/sn_hwperf.h>

/*
 * 1/26/2006
 *
 * WAR for SGI PV 944642.  For revA TIOCE, need to use the following recipe
 * (taken from the above PV) before and after accessing tioce internal MMR's
 * to avoid tioce lockups.
 *
 * The recipe as taken from the PV:
 *
 *	if(mmr address < 0x45000) {
 *		if(mmr address == 0 or 0x80)
 *			mmr wrt or read address 0xc0
 *		else if(mmr address == 0x148 or 0x200)
 *			mmr wrt or read address 0x28
 *		else
 *			mmr wrt or read address 0x158
 *
 *		do desired mmr access (rd or wrt)
 *
 *		if(mmr address == 0x100)
 *			mmr wrt or read address 0x38
 *		mmr wrt or read address 0xb050
 *	} else
 *		do desired mmr access
 *
 * According to hw, we can use reads instead of writes to the above addres
 *
 * Note this WAR can only to be used for accessing internal MMR's in the
 * TIOCE Coretalk Address Range 0x0 - 0x07ff_ffff.  This includes the
 * "Local CE Registers and Memories" and "PCI Compatible Config Space" address
 * spaces from table 2-1 of the "CE Programmer's Reference Overview" document.
 *
 * All registers defined in struct tioce will meet that criteria.
 */

static void inline
tioce_mmr_war_pre(struct tioce_kernel *kern, void *mmr_addr)
{
	u64 mmr_base;
	u64 mmr_offset;

	if (kern->ce_common->ce_rev != TIOCE_REV_A)
		return;

	mmr_base = kern->ce_common->ce_pcibus.bs_base;
	mmr_offset = (u64)mmr_addr - mmr_base;

	if (mmr_offset < 0x45000) {
		u64 mmr_war_offset;

		if (mmr_offset == 0 || mmr_offset == 0x80)
			mmr_war_offset = 0xc0;
		else if (mmr_offset == 0x148 || mmr_offset == 0x200)
			mmr_war_offset = 0x28;
		else
			mmr_war_offset = 0x158;

		readq_relaxed((void *)(mmr_base + mmr_war_offset));
	}
}

static void inline
tioce_mmr_war_post(struct tioce_kernel *kern, void *mmr_addr)
{
	u64 mmr_base;
	u64 mmr_offset;

	if (kern->ce_common->ce_rev != TIOCE_REV_A)
		return;

	mmr_base = kern->ce_common->ce_pcibus.bs_base;
	mmr_offset = (u64)mmr_addr - mmr_base;

	if (mmr_offset < 0x45000) {
		if (mmr_offset == 0x100)
			readq_relaxed((void *)(mmr_base + 0x38));
		readq_relaxed((void *)(mmr_base + 0xb050));
	}
}

/* load mmr contents into a variable */
#define tioce_mmr_load(kern, mmrp, varp) do {\
	tioce_mmr_war_pre(kern, mmrp); \
	*(varp) = readq_relaxed(mmrp); \
	tioce_mmr_war_post(kern, mmrp); \
} while (0)

/* store variable contents into mmr */
#define tioce_mmr_store(kern, mmrp, varp) do {\
	tioce_mmr_war_pre(kern, mmrp); \
	writeq(*varp, mmrp); \
	tioce_mmr_war_post(kern, mmrp); \
} while (0)

/* store immediate value into mmr */
#define tioce_mmr_storei(kern, mmrp, val) do {\
	tioce_mmr_war_pre(kern, mmrp); \
	writeq(val, mmrp); \
	tioce_mmr_war_post(kern, mmrp); \
} while (0)

/* set bits (immediate value) into mmr */
#define tioce_mmr_seti(kern, mmrp, bits) do {\
	u64 tmp; \
	tioce_mmr_load(kern, mmrp, &tmp); \
	tmp |= (bits); \
	tioce_mmr_store(kern, mmrp, &tmp); \
} while (0)

/* clear bits (immediate value) into mmr */
#define tioce_mmr_clri(kern, mmrp, bits) do { \
	u64 tmp; \
	tioce_mmr_load(kern, mmrp, &tmp); \
	tmp &= ~(bits); \
	tioce_mmr_store(kern, mmrp, &tmp); \
} while (0)

/**
 * Bus address ranges for the 5 flavors of TIOCE DMA
 */

#define TIOCE_D64_MIN	0x8000000000000000UL
#define TIOCE_D64_MAX	0xffffffffffffffffUL
#define TIOCE_D64_ADDR(a)	((a) >= TIOCE_D64_MIN)

#define TIOCE_D32_MIN	0x0000000080000000UL
#define TIOCE_D32_MAX	0x00000000ffffffffUL
#define TIOCE_D32_ADDR(a)	((a) >= TIOCE_D32_MIN && (a) <= TIOCE_D32_MAX)

#define TIOCE_M32_MIN	0x0000000000000000UL
#define TIOCE_M32_MAX	0x000000007fffffffUL
#define TIOCE_M32_ADDR(a)	((a) >= TIOCE_M32_MIN && (a) <= TIOCE_M32_MAX)

#define TIOCE_M40_MIN	0x0000004000000000UL
#define TIOCE_M40_MAX	0x0000007fffffffffUL
#define TIOCE_M40_ADDR(a)	((a) >= TIOCE_M40_MIN && (a) <= TIOCE_M40_MAX)

#define TIOCE_M40S_MIN	0x0000008000000000UL
#define TIOCE_M40S_MAX	0x000000ffffffffffUL
#define TIOCE_M40S_ADDR(a)	((a) >= TIOCE_M40S_MIN && (a) <= TIOCE_M40S_MAX)

/*
 * ATE manipulation macros.
 */

#define ATE_PAGESHIFT(ps)	(__ffs(ps))
#define ATE_PAGEMASK(ps)	((ps)-1)

#define ATE_PAGE(x, ps) ((x) >> ATE_PAGESHIFT(ps))
#define ATE_NPAGES(start, len, pagesize) \
	(ATE_PAGE((start)+(len)-1, pagesize) - ATE_PAGE(start, pagesize) + 1)

#define ATE_VALID(ate)	((ate) & (1UL << 63))
#define ATE_MAKE(addr, ps, msi) \
	(((addr) & ~ATE_PAGEMASK(ps)) | (1UL << 63) | ((msi)?(1UL << 62):0))

/*
 * Flavors of ate-based mapping supported by tioce_alloc_map()
 */

#define TIOCE_ATE_M32	1
#define TIOCE_ATE_M40	2
#define TIOCE_ATE_M40S	3

#define KB(x)	((u64)(x) << 10)
#define MB(x)	((u64)(x) << 20)
#define GB(x)	((u64)(x) << 30)

/**
 * tioce_dma_d64 - create a DMA mapping using 64-bit direct mode
 * @ct_addr: system coretalk address
 *
 * Map @ct_addr into 64-bit CE bus space.  No device context is necessary
 * and no CE mapping are consumed.
 *
 * Bits 53:0 come from the coretalk address.  The remaining bits are set as
 * follows:
 *
 * 63    - must be 1 to indicate d64 mode to CE hardware
 * 62    - barrier bit ... controlled with tioce_dma_barrier()
 * 61    - msi bit ... specified through dma_flags
 * 60:54 - reserved, MBZ
 */
static u64
tioce_dma_d64(unsigned long ct_addr, int dma_flags)
{
	u64 bus_addr;

	bus_addr = ct_addr | (1UL << 63);
	if (dma_flags & SN_DMA_MSI)
		bus_addr |= (1UL << 61);

	return bus_addr;
}

/**
 * pcidev_to_tioce - return misc ce related pointers given a pci_dev
 * @pci_dev: pci device context
 * @base: ptr to store struct tioce_mmr * for the CE holding this device
 * @kernel: ptr to store struct tioce_kernel * for the CE holding this device
 * @port: ptr to store the CE port number that this device is on
 *
 * Return pointers to various CE-related structures for the CE upstream of
 * @pci_dev.
 */
static inline void
pcidev_to_tioce(struct pci_dev *pdev, struct tioce **base,
		struct tioce_kernel **kernel, int *port)
{
	struct pcidev_info *pcidev_info;
	struct tioce_common *ce_common;
	struct tioce_kernel *ce_kernel;

	pcidev_info = SN_PCIDEV_INFO(pdev);
	ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info;
	ce_kernel = (struct tioce_kernel *)ce_common->ce_kernel_private;

	if (base)
		*base = (struct tioce *)ce_common->ce_pcibus.bs_base;
	if (kernel)
		*kernel = ce_kernel;

	/*
	 * we use port as a zero-based value internally, even though the
	 * documentation is 1-based.
	 */
	if (port)
		*port =
		    (pdev->bus->number < ce_kernel->ce_port1_secondary) ? 0 : 1;
}

/**
 * tioce_alloc_map - Given a coretalk address, map it to pcie bus address
 * space using one of the various ATE-based address modes.
 * @ce_kern: tioce context
 * @type: map mode to use
 * @port: 0-based port that the requesting device is downstream of
 * @ct_addr: the coretalk address to map
 * @len: number of bytes to map
 *
 * Given the addressing type, set up various paramaters that define the
 * ATE pool to use.  Search for a contiguous block of entries to cover the
 * length, and if enough resources exist, fill in the ATE's and construct a
 * tioce_dmamap struct to track the mapping.
 */
static u64
tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
		u64 ct_addr, int len, int dma_flags)
{
	int i;
	int j;
	int first;
	int last;
	int entries;
	int nates;
	u64 pagesize;
	int msi_capable, msi_wanted;
	u64 *ate_shadow;
	u64 *ate_reg;
	u64 addr;
	struct tioce *ce_mmr;
	u64 bus_base;
	struct tioce_dmamap *map;

	ce_mmr = (struct tioce *)ce_kern->ce_common->ce_pcibus.bs_base;

	switch (type) {
	case TIOCE_ATE_M32:
		/*
		 * The first 64 entries of the ate3240 pool are dedicated to
		 * super-page (TIOCE_ATE_M40S) mode.
		 */
		first = 64;
		entries = TIOCE_NUM_M3240_ATES - 64;
		ate_shadow = ce_kern->ce_ate3240_shadow;
		ate_reg = ce_mmr->ce_ure_ate3240;
		pagesize = ce_kern->ce_ate3240_pagesize;
		bus_base = TIOCE_M32_MIN;
		msi_capable = 1;
		break;
	case TIOCE_ATE_M40:
		first = 0;
		entries = TIOCE_NUM_M40_ATES;
		ate_shadow = ce_kern->ce_ate40_shadow;
		ate_reg = ce_mmr->ce_ure_ate40;
		pagesize = MB(64);
		bus_base = TIOCE_M40_MIN;
		msi_capable = 0;
		break;
	case TIOCE_ATE_M40S:
		/*
		 * ate3240 entries 0-31 are dedicated to port1 super-page
		 * mappings.  ate3240 entries 32-63 are dedicated to port2.
		 */
		first = port * 32;
		entries = 32;
		ate_shadow = ce_kern->ce_ate3240_shadow;
		ate_reg = ce_mmr->ce_ure_ate3240;
		pagesize = GB(16);
		bus_base = TIOCE_M40S_MIN;
		msi_capable = 0;
		break;
	default:
		return 0;
	}

	msi_wanted = dma_flags & SN_DMA_MSI;
	if (msi_wanted && !msi_capable)
		return 0;

	nates = ATE_NPAGES(ct_addr, len, pagesize);
	if (nates > entries)
		return 0;

	last = first + entries - nates;
	for (i = first; i <= last; i++) {
		if (ATE_VALID(ate_shadow[i]))
			continue;

		for (j = i; j < i + nates; j++)
			if (ATE_VALID(ate_shadow[j]))
				break;

		if (j >= i + nates)
			break;
	}

	if (i > last)
		return 0;

	map = kzalloc(sizeof(struct tioce_dmamap), GFP_ATOMIC);
	if (!map)
		return 0;

	addr = ct_addr;
	for (j = 0; j < nates; j++) {
		u64 ate;

		ate = ATE_MAKE(addr, pagesize, msi_wanted);
		ate_shadow[i + j] = ate;
		tioce_mmr_storei(ce_kern, &ate_reg[i + j], ate);
		addr += pagesize;
	}

	map->refcnt = 1;
	map->nbytes = nates * pagesize;
	map->ct_start = ct_addr & ~ATE_PAGEMASK(pagesize);
	map->pci_start = bus_base + (i * pagesize);
	map->ate_hw = &ate_reg[i];
	map->ate_shadow = &ate_shadow[i];
	map->ate_count = nates;

	list_add(&map->ce_dmamap_list, &ce_kern->ce_dmamap_list);

	return (map->pci_start + (ct_addr - map->ct_start));
}

/**
 * tioce_dma_d32 - create a DMA mapping using 32-bit direct mode
 * @pdev: linux pci_dev representing the function
 * @paddr: system physical address
 *
 * Map @paddr into 32-bit bus space of the CE associated with @pcidev_info.
 */
static u64
tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr, int dma_flags)
{
	int dma_ok;
	int port;
	struct tioce *ce_mmr;
	struct tioce_kernel *ce_kern;
	u64 ct_upper;
	u64 ct_lower;
	dma_addr_t bus_addr;

	if (dma_flags & SN_DMA_MSI)
		return 0;

	ct_upper = ct_addr & ~0x3fffffffUL;
	ct_lower = ct_addr & 0x3fffffffUL;

	pcidev_to_tioce(pdev, &ce_mmr, &ce_kern, &port);

	if (ce_kern->ce_port[port].dirmap_refcnt == 0) {
		u64 tmp;

		ce_kern->ce_port[port].dirmap_shadow = ct_upper;
		tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_dir_map[port],
				 ct_upper);
		tmp = ce_mmr->ce_ure_dir_map[port];
		dma_ok = 1;
	} else
		dma_ok = (ce_kern->ce_port[port].dirmap_shadow == ct_upper);

	if (dma_ok) {
		ce_kern->ce_port[port].dirmap_refcnt++;
		bus_addr = TIOCE_D32_MIN + ct_lower;
	} else
		bus_addr = 0;

	return bus_addr;
}

/**
 * tioce_dma_barrier - swizzle a TIOCE bus address to include or exclude
 * the barrier bit.
 * @bus_addr:  bus address to swizzle
 *
 * Given a TIOCE bus address, set the appropriate bit to indicate barrier
 * attributes.
 */
static u64
tioce_dma_barrier(u64 bus_addr, int on)
{
	u64 barrier_bit;

	/* barrier not supported in M40/M40S mode */
	if (TIOCE_M40_ADDR(bus_addr) || TIOCE_M40S_ADDR(bus_addr))
		return bus_addr;

	if (TIOCE_D64_ADDR(bus_addr))
		barrier_bit = (1UL << 62);
	else			/* must be m32 or d32 */
		barrier_bit = (1UL << 30);

	return (on) ? (bus_addr | barrier_bit) : (bus_addr & ~barrier_bit);
}

/**
 * tioce_dma_unmap - release CE mapping resources
 * @pdev: linux pci_dev representing the function
 * @bus_addr: bus address returned by an earlier tioce_dma_map
 * @dir: mapping direction (unused)
 *
 * Locate mapping resources associated with @bus_addr and release them.
 * For mappings created using the direct modes there are no resources
 * to release.
 */
void
tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
{
	int i;
	int port;
	struct tioce_kernel *ce_kern;
	struct tioce *ce_mmr;
	unsigned long flags;

	bus_addr = tioce_dma_barrier(bus_addr, 0);
	pcidev_to_tioce(pdev, &ce_mmr, &ce_kern, &port);

	/* nothing to do for D64 */

	if (TIOCE_D64_ADDR(bus_addr))
		return;

	spin_lock_irqsave(&ce_kern->ce_lock, flags);

	if (TIOCE_D32_ADDR(bus_addr)) {
		if (--ce_kern->ce_port[port].dirmap_refcnt == 0) {
			ce_kern->ce_port[port].dirmap_shadow = 0;
			tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_dir_map[port],
					 0);
		}
	} else {
		struct tioce_dmamap *map;

		list_for_each_entry(map, &ce_kern->ce_dmamap_list,
				    ce_dmamap_list) {
			u64 last;

			last = map->pci_start + map->nbytes - 1;
			if (bus_addr >= map->pci_start && bus_addr <= last)
				break;
		}

		if (&map->ce_dmamap_list == &ce_kern->ce_dmamap_list) {
			printk(KERN_WARNING
			       "%s:  %s - no map found for bus_addr 0x%lx\n",
			       __FUNCTION__, pci_name(pdev), bus_addr);
		} else if (--map->refcnt == 0) {
			for (i = 0; i < map->ate_count; i++) {
				map->ate_shadow[i] = 0;
				tioce_mmr_storei(ce_kern, &map->ate_hw[i], 0);
			}

			list_del(&map->ce_dmamap_list);
			kfree(map);
		}
	}

	spin_unlock_irqrestore(&ce_kern->ce_lock, flags);
}

/**
 * tioce_do_dma_map - map pages for PCI DMA
 * @pdev: linux pci_dev representing the function
 * @paddr: host physical address to map
 * @byte_count: bytes to map
 *
 * This is the main wrapper for mapping host physical pages to CE PCI space.
 * The mapping mode used is based on the device's dma_mask.
 */
static u64
tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count,
		 int barrier, int dma_flags)
{
	unsigned long flags;
	u64 ct_addr;
	u64 mapaddr = 0;
	struct tioce_kernel *ce_kern;
	struct tioce_dmamap *map;
	int port;
	u64 dma_mask;

	dma_mask = (barrier) ? pdev->dev.coherent_dma_mask : pdev->dma_mask;

	/* cards must be able to address at least 31 bits */
	if (dma_mask < 0x7fffffffUL)
		return 0;

	if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS)
		ct_addr = PHYS_TO_TIODMA(paddr);
	else
		ct_addr = paddr;

	/*
	 * If the device can generate 64 bit addresses, create a D64 map.
	 */
	if (dma_mask == ~0UL) {
		mapaddr = tioce_dma_d64(ct_addr, dma_flags);
		if (mapaddr)
			goto dma_map_done;
	}

	pcidev_to_tioce(pdev, NULL, &ce_kern, &port);

	spin_lock_irqsave(&ce_kern->ce_lock, flags);

	/*
	 * D64 didn't work ... See if we have an existing map that covers
	 * this address range.  Must account for devices dma_mask here since
	 * an existing map might have been done in a mode using more pci
	 * address bits than this device can support.
	 */
	list_for_each_entry(map, &ce_kern->ce_dmamap_list, ce_dmamap_list) {
		u64 last;

		last = map->ct_start + map->nbytes - 1;
		if (ct_addr >= map->ct_start &&
		    ct_addr + byte_count - 1 <= last &&
		    map->pci_start <= dma_mask) {
			map->refcnt++;
			mapaddr = map->pci_start + (ct_addr - map->ct_start);
			break;
		}
	}

	/*
	 * If we don't have a map yet, and the card can generate 40
	 * bit addresses, try the M40/M40S modes.  Note these modes do not
	 * support a barrier bit, so if we need a consistent map these
	 * won't work.
	 */
	if (!mapaddr && !barrier && dma_mask >= 0xffffffffffUL) {
		/*
		 * We have two options for 40-bit mappings:  16GB "super" ATE's
		 * and 64MB "regular" ATE's.  We'll try both if needed for a
		 * given mapping but which one we try first depends on the
		 * size.  For requests >64MB, prefer to use a super page with
		 * regular as the fallback. Otherwise, try in the reverse order.
		 */

		if (byte_count > MB(64)) {
			mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40S,
						  port, ct_addr, byte_count,
						  dma_flags);
			if (!mapaddr)
				mapaddr =
				    tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1,
						    ct_addr, byte_count,
						    dma_flags);
		} else {
			mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1,
						  ct_addr, byte_count,
						  dma_flags);
			if (!mapaddr)
				mapaddr =
				    tioce_alloc_map(ce_kern, TIOCE_ATE_M40S,
						    port, ct_addr, byte_count,
						    dma_flags);
		}
	}

	/*
	 * 32-bit direct is the next mode to try
	 */
	if (!mapaddr && dma_mask >= 0xffffffffUL)
		mapaddr = tioce_dma_d32(pdev, ct_addr, dma_flags);

	/*
	 * Last resort, try 32-bit ATE-based map.
	 */
	if (!mapaddr)
		mapaddr =
		    tioce_alloc_map(ce_kern, TIOCE_ATE_M32, -1, ct_addr,
				    byte_count, dma_flags);

	spin_unlock_irqrestore(&ce_kern->ce_lock, flags);

dma_map_done:
	if (mapaddr && barrier)
		mapaddr = tioce_dma_barrier(mapaddr, 1);

	return mapaddr;
}

/**
 * tioce_dma - standard pci dma map interface
 * @pdev: pci device requesting the map
 * @paddr: system physical address to map into pci space
 * @byte_count: # bytes to map
 *
 * Simply call tioce_do_dma_map() to create a map with the barrier bit clear
 * in the address.
 */
static u64
tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags)
{
	return tioce_do_dma_map(pdev, paddr, byte_count, 0, dma_flags);
}

/**
 * tioce_dma_consistent - consistent pci dma map interface
 * @pdev: pci device requesting the map
 * @paddr: system physical address to map into pci space
 * @byte_count: # bytes to map
 *
 * Simply call tioce_do_dma_map() to create a map with the barrier bit set
 * in the address.
 */ static u64
tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags)
{
	return tioce_do_dma_map(pdev, paddr, byte_count, 1, dma_flags);
}

/**
 * tioce_error_intr_handler - SGI TIO CE error interrupt handler
 * @irq: unused
 * @arg: pointer to tioce_common struct for the given CE
 * @pt: unused
 *
 * Handle a CE error interrupt.  Simply a wrapper around a SAL call which
 * defers processing to the SGI prom.
 */ static irqreturn_t
tioce_error_intr_handler(int irq, void *arg, struct pt_regs *pt)
{
	struct tioce_common *soft = arg;
	struct ia64_sal_retval ret_stuff;
	ret_stuff.status = 0;
	ret_stuff.v0 = 0;

	SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_ERROR_INTERRUPT,
			soft->ce_pcibus.bs_persist_segment,
			soft->ce_pcibus.bs_persist_busnum, 0, 0, 0, 0, 0);

	if (ret_stuff.v0)
		panic("tioce_error_intr_handler:  Fatal TIOCE error");

	return IRQ_HANDLED;
}

/**
 * tioce_reserve_m32 - reserve M32 ate's for the indicated address range
 * @tioce_kernel: TIOCE context to reserve ate's for
 * @base: starting bus address to reserve
 * @limit: last bus address to reserve
 *
 * If base/limit falls within the range of bus space mapped through the
 * M32 space, reserve the resources corresponding to the range.
 */
static void
tioce_reserve_m32(struct tioce_kernel *ce_kern, u64 base, u64 limit)
{
	int ate_index, last_ate, ps;
	struct tioce *ce_mmr;

	ce_mmr = (struct tioce *)ce_kern->ce_common->ce_pcibus.bs_base;
	ps = ce_kern->ce_ate3240_pagesize;
	ate_index = ATE_PAGE(base, ps);
	last_ate = ate_index + ATE_NPAGES(base, limit-base+1, ps) - 1;

	if (ate_index < 64)
		ate_index = 64;

	if (last_ate >= TIOCE_NUM_M3240_ATES)
		last_ate = TIOCE_NUM_M3240_ATES - 1;

	while (ate_index <= last_ate) {
		u64 ate;

		ate = ATE_MAKE(0xdeadbeef, ps, 0);
		ce_kern->ce_ate3240_shadow[ate_index] = ate;
		tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_ate3240[ate_index],
				 ate);
		ate_index++;
	}
}

/**
 * tioce_kern_init - init kernel structures related to a given TIOCE
 * @tioce_common: ptr to a cached tioce_common struct that originated in prom
 */
static struct tioce_kernel *
tioce_kern_init(struct tioce_common *tioce_common)
{
	int i;
	int ps;
	int dev;
	u32 tmp;
	unsigned int seg, bus;
	struct tioce *tioce_mmr;
	struct tioce_kernel *tioce_kern;

	tioce_kern = kzalloc(sizeof(struct tioce_kernel), GFP_KERNEL);
	if (!tioce_kern) {
		return NULL;
	}

	tioce_kern->ce_common = tioce_common;
	spin_lock_init(&tioce_kern->ce_lock);
	INIT_LIST_HEAD(&tioce_kern->ce_dmamap_list);
	tioce_common->ce_kernel_private = (u64) tioce_kern;

	/*
	 * Determine the secondary bus number of the port2 logical PPB.
	 * This is used to decide whether a given pci device resides on
	 * port1 or port2.  Note:  We don't have enough plumbing set up
	 * here to use pci_read_config_xxx() so use the raw_pci_ops vector.
	 */

	seg = tioce_common->ce_pcibus.bs_persist_segment;
	bus = tioce_common->ce_pcibus.bs_persist_busnum;

	raw_pci_ops->read(seg, bus, PCI_DEVFN(2, 0), PCI_SECONDARY_BUS, 1,&tmp);
	tioce_kern->ce_port1_secondary = (u8) tmp;

	/*
	 * Set PMU pagesize to the largest size available, and zero out
	 * the ate's.
	 */

	tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base;
	tioce_mmr_clri(tioce_kern, &tioce_mmr->ce_ure_page_map,
		       CE_URE_PAGESIZE_MASK);
	tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_ure_page_map,
		       CE_URE_256K_PAGESIZE);
	ps = tioce_kern->ce_ate3240_pagesize = KB(256);

	for (i = 0; i < TIOCE_NUM_M40_ATES; i++) {
		tioce_kern->ce_ate40_shadow[i] = 0;
		tioce_mmr_storei(tioce_kern, &tioce_mmr->ce_ure_ate40[i], 0);
	}

	for (i = 0; i < TIOCE_NUM_M3240_ATES; i++) {
		tioce_kern->ce_ate3240_shadow[i] = 0;
		tioce_mmr_storei(tioce_kern, &tioce_mmr->ce_ure_ate3240[i], 0);
	}

	/*
	 * Reserve ATE's corresponding to reserved address ranges.  These
	 * include:
	 *
	 *	Memory space covered by each PPB mem base/limit register
	 * 	Memory space covered by each PPB prefetch base/limit register
	 *
	 * These bus ranges are for pio (downstream) traffic only, and so
	 * cannot be used for DMA.
	 */

	for (dev = 1; dev <= 2; dev++) {
		u64 base, limit;

		/* mem base/limit */

		raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0),
				  PCI_MEMORY_BASE, 2, &tmp);
		base = (u64)tmp << 16;

		raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0),
				  PCI_MEMORY_LIMIT, 2, &tmp);
		limit = (u64)tmp << 16;
		limit |= 0xfffffUL;

		if (base < limit)
			tioce_reserve_m32(tioce_kern, base, limit);

		/*
		 * prefetch mem base/limit.  The tioce ppb's have 64-bit
		 * decoders, so read the upper portions w/o checking the
		 * attributes.
		 */

		raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0),
				  PCI_PREF_MEMORY_BASE, 2, &tmp);
		base = ((u64)tmp & PCI_PREF_RANGE_MASK) << 16;

		raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0),
				  PCI_PREF_BASE_UPPER32, 4, &tmp);
		base |= (u64)tmp << 32;

		raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0),
				  PCI_PREF_MEMORY_LIMIT, 2, &tmp);

		limit = ((u64)tmp & PCI_PREF_RANGE_MASK) << 16;
		limit |= 0xfffffUL;

		raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0),
				  PCI_PREF_LIMIT_UPPER32, 4, &tmp);
		limit |= (u64)tmp << 32;

		if ((base < limit) && TIOCE_M32_ADDR(base))
			tioce_reserve_m32(tioce_kern, base, limit);
	}

	return tioce_kern;
}

/**
 * tioce_force_interrupt - implement altix force_interrupt() backend for CE
 * @sn_irq_info: sn asic irq that we need an interrupt generated for
 *
 * Given an sn_irq_info struct, set the proper bit in ce_adm_force_int to
 * force a secondary interrupt to be generated.  This is to work around an
 * asic issue where there is a small window of opportunity for a legacy device
 * interrupt to be lost.
 */
static void
tioce_force_interrupt(struct sn_irq_info *sn_irq_info)
{
	struct pcidev_info *pcidev_info;
	struct tioce_common *ce_common;
	struct tioce_kernel *ce_kern;
	struct tioce *ce_mmr;
	u64 force_int_val;

	if (!sn_irq_info->irq_bridge)
		return;

	if (sn_irq_info->irq_bridge_type != PCIIO_ASIC_TYPE_TIOCE)
		return;

	pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
	if (!pcidev_info)
		return;

	ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info;
	ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base;
	ce_kern = (struct tioce_kernel *)ce_common->ce_kernel_private;

	/*
	 * TIOCE Rev A workaround (PV 945826), force an interrupt by writing
	 * the TIO_INTx register directly (1/26/2006)
	 */
	if (ce_common->ce_rev == TIOCE_REV_A) {
		u64 int_bit_mask = (1ULL << sn_irq_info->irq_int_bit);
		u64 status;

		tioce_mmr_load(ce_kern, &ce_mmr->ce_adm_int_status, &status);
		if (status & int_bit_mask) {
			u64 force_irq = (1 << 8) | sn_irq_info->irq_irq;
			u64 ctalk = sn_irq_info->irq_xtalkaddr;
			u64 nasid, offset;

			nasid = (ctalk & CTALK_NASID_MASK) >> CTALK_NASID_SHFT;
			offset = (ctalk & CTALK_NODE_OFFSET);
			HUB_S(TIO_IOSPACE_ADDR(nasid, offset), force_irq);
		}

		return;
	}

	/*
	 * irq_int_bit is originally set up by prom, and holds the interrupt
	 * bit shift (not mask) as defined by the bit definitions in the
	 * ce_adm_int mmr.  These shifts are not the same for the
	 * ce_adm_force_int register, so do an explicit mapping here to make
	 * things clearer.
	 */

	switch (sn_irq_info->irq_int_bit) {
	case CE_ADM_INT_PCIE_PORT1_DEV_A_SHFT:
		force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT1_DEV_A_SHFT;
		break;
	case CE_ADM_INT_PCIE_PORT1_DEV_B_SHFT:
		force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT1_DEV_B_SHFT;
		break;
	case CE_ADM_INT_PCIE_PORT1_DEV_C_SHFT:
		force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT1_DEV_C_SHFT;
		break;
	case CE_ADM_INT_PCIE_PORT1_DEV_D_SHFT:
		force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT1_DEV_D_SHFT;
		break;
	case CE_ADM_INT_PCIE_PORT2_DEV_A_SHFT:
		force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT2_DEV_A_SHFT;
		break;
	case CE_ADM_INT_PCIE_PORT2_DEV_B_SHFT:
		force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT2_DEV_B_SHFT;
		break;
	case CE_ADM_INT_PCIE_PORT2_DEV_C_SHFT:
		force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT2_DEV_C_SHFT;
		break;
	case CE_ADM_INT_PCIE_PORT2_DEV_D_SHFT:
		force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT2_DEV_D_SHFT;
		break;
	default:
		return;
	}
	tioce_mmr_storei(ce_kern, &ce_mmr->ce_adm_force_int, force_int_val);
}

/**
 * tioce_target_interrupt - implement set_irq_affinity for tioce resident
 * functions.  Note:  only applies to line interrupts, not MSI's.
 *
 * @sn_irq_info: SN IRQ context
 *
 * Given an sn_irq_info, set the associated CE device's interrupt destination
 * register.  Since the interrupt destination registers are on a per-ce-slot
 * basis, this will retarget line interrupts for all functions downstream of
 * the slot.
 */
static void
tioce_target_interrupt(struct sn_irq_info *sn_irq_info)
{
	struct pcidev_info *pcidev_info;
	struct tioce_common *ce_common;
	struct tioce_kernel *ce_kern;
	struct tioce *ce_mmr;
	int bit;
	u64 vector;

	pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
	if (!pcidev_info)
		return;

	ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info;
	ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base;
	ce_kern = (struct tioce_kernel *)ce_common->ce_kernel_private;

	bit = sn_irq_info->irq_int_bit;

	tioce_mmr_seti(ce_kern, &ce_mmr->ce_adm_int_mask, (1UL << bit));
	vector = (u64)sn_irq_info->irq_irq << INTR_VECTOR_SHFT;
	vector |= sn_irq_info->irq_xtalkaddr;
	tioce_mmr_storei(ce_kern, &ce_mmr->ce_adm_int_dest[bit], vector);
	tioce_mmr_clri(ce_kern, &ce_mmr->ce_adm_int_mask, (1UL << bit));

	tioce_force_interrupt(sn_irq_info);
}

/**
 * tioce_bus_fixup - perform final PCI fixup for a TIO CE bus
 * @prom_bussoft: Common prom/kernel struct representing the bus
 *
 * Replicates the tioce_common pointed to by @prom_bussoft in kernel
 * space.  Allocates and initializes a kernel-only area for a given CE,
 * and sets up an irq for handling CE error interrupts.
 *
 * On successful setup, returns the kernel version of tioce_common back to
 * the caller.
 */
static void *
tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
{
	int my_nasid;
	cnodeid_t my_cnode, mem_cnode;
	struct tioce_common *tioce_common;
	struct tioce_kernel *tioce_kern;
	struct tioce *tioce_mmr;

	/*
	 * Allocate kernel bus soft and copy from prom.
	 */

	tioce_common = kzalloc(sizeof(struct tioce_common), GFP_KERNEL);
	if (!tioce_common)
		return NULL;

	memcpy(tioce_common, prom_bussoft, sizeof(struct tioce_common));
	tioce_common->ce_pcibus.bs_base |= __IA64_UNCACHED_OFFSET;

	tioce_kern = tioce_kern_init(tioce_common);
	if (tioce_kern == NULL) {
		kfree(tioce_common);
		return NULL;
	}

	/*
	 * Clear out any transient errors before registering the error
	 * interrupt handler.
	 */

	tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base;
	tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_int_status_alias, ~0ULL);
	tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_error_summary_alias,
		       ~0ULL);
	tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_dre_comp_err_addr, 0ULL);

	if (request_irq(SGI_PCIASIC_ERROR,
			tioce_error_intr_handler,
			SA_SHIRQ, "TIOCE error", (void *)tioce_common))
		printk(KERN_WARNING
		       "%s:  Unable to get irq %d.  "
		       "Error interrupts won't be routed for "
		       "TIOCE bus %04x:%02x\n",
		       __FUNCTION__, SGI_PCIASIC_ERROR,
		       tioce_common->ce_pcibus.bs_persist_segment,
		       tioce_common->ce_pcibus.bs_persist_busnum);

	/*
	 * identify closest nasid for memory allocations
	 */

	my_nasid = NASID_GET(tioce_common->ce_pcibus.bs_base);
	my_cnode = nasid_to_cnodeid(my_nasid);

	if (sn_hwperf_get_nearest_node(my_cnode, &mem_cnode, NULL) < 0) {
		printk(KERN_WARNING "tioce_bus_fixup: failed to find "
		       "closest node with MEM to TIO node %d\n", my_cnode);
		mem_cnode = (cnodeid_t)-1; /* use any node */
	}

	controller->node = mem_cnode;

	return tioce_common;
}

static struct sn_pcibus_provider tioce_pci_interfaces = {
	.dma_map = tioce_dma,
	.dma_map_consistent = tioce_dma_consistent,
	.dma_unmap = tioce_dma_unmap,
	.bus_fixup = tioce_bus_fixup,
	.force_interrupt = tioce_force_interrupt,
	.target_interrupt = tioce_target_interrupt
};

/**
 * tioce_init_provider - init SN PCI provider ops for TIO CE
 */
int
tioce_init_provider(void)
{
	sn_pci_provider[PCIIO_ASIC_TYPE_TIOCE] = &tioce_pci_interfaces;
	return 0;
}
