/*
 * 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) 2006 Silicon Graphics, Inc. All rights reserved.
 */

#include <linux/bootmem.h>
#include <asm/sn/types.h>
#include <asm/sn/addrs.h>
#include <asm/sn/sn_feature_sets.h>
#include <asm/sn/geo.h>
#include <asm/sn/io.h>
#include <asm/sn/l1.h>
#include <asm/sn/module.h>
#include <asm/sn/pcibr_provider.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h>
#include <asm/sn/simulator.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/tioca_provider.h>
#include <asm/sn/tioce_provider.h>
#include "xtalk/hubdev.h"
#include "xtalk/xwidgetdev.h"
#include <linux/acpi.h>
#include <asm/sn/sn2/sn_hwperf.h>
#include <asm/sn/acpi.h>
#include "acpi/acglobal.h"

extern void sn_init_cpei_timer(void);
extern void register_sn_procfs(void);
extern void sn_io_acpi_init(void);
extern void sn_io_init(void);


static struct list_head sn_sysdata_list;

/* sysdata list struct */
struct sysdata_el {
	struct list_head entry;
	void *sysdata;
};

int sn_ioif_inited;		/* SN I/O infrastructure initialized? */

int sn_acpi_rev;		/* SN ACPI revision */
EXPORT_SYMBOL_GPL(sn_acpi_rev);

struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES];	/* indexed by asic type */

/*
 * Hooks and struct for unsupported pci providers
 */

static dma_addr_t
sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type)
{
	return 0;
}

static void
sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction)
{
	return;
}

static void *
sn_default_pci_bus_fixup(struct pcibus_bussoft *soft, struct pci_controller *controller)
{
	return NULL;
}

static struct sn_pcibus_provider sn_pci_default_provider = {
	.dma_map = sn_default_pci_map,
	.dma_map_consistent = sn_default_pci_map,
	.dma_unmap = sn_default_pci_unmap,
	.bus_fixup = sn_default_pci_bus_fixup,
};

/*
 * Retrieve the DMA Flush List given nasid, widget, and device.
 * This list is needed to implement the WAR - Flush DMA data on PIO Reads.
 */
static inline u64
sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num,
			     u64 address)
{
	struct ia64_sal_retval ret_stuff;
	ret_stuff.status = 0;
	ret_stuff.v0 = 0;

	SAL_CALL_NOLOCK(ret_stuff,
			(u64) SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST,
			(u64) nasid, (u64) widget_num,
			(u64) device_num, (u64) address, 0, 0, 0);
	return ret_stuff.status;
}

/*
 * sn_pcidev_info_get() - Retrieve the pcidev_info struct for the specified
 *			  device.
 */
inline struct pcidev_info *
sn_pcidev_info_get(struct pci_dev *dev)
{
	struct pcidev_info *pcidev;

	list_for_each_entry(pcidev,
			    &(SN_PLATFORM_DATA(dev)->pcidev_info), pdi_list) {
		if (pcidev->pdi_linux_pcidev == dev)
			return pcidev;
	}
	return NULL;
}

/* Older PROM flush WAR
 *
 * 01/16/06 -- This war will be in place until a new official PROM is released.
 * Additionally note that the struct sn_flush_device_war also has to be
 * removed from arch/ia64/sn/include/xtalk/hubdev.h
 */
static u8 war_implemented = 0;

static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device,
			       struct sn_flush_device_common *common)
{
	struct sn_flush_device_war *war_list;
	struct sn_flush_device_war *dev_entry;
	struct ia64_sal_retval isrv = {0,0,0,0};

	if (!war_implemented) {
		printk(KERN_WARNING "PROM version < 4.50 -- implementing old "
		       "PROM flush WAR\n");
		war_implemented = 1;
	}

	war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL);
	if (!war_list)
		BUG();

	SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST,
			nasid, widget, __pa(war_list), 0, 0, 0 ,0);
	if (isrv.status)
		panic("sn_device_fixup_war failed: %s\n",
		      ia64_sal_strerror(isrv.status));

	dev_entry = war_list + device;
	memcpy(common,dev_entry, sizeof(*common));
	kfree(war_list);

	return isrv.status;
}

/*
 * sn_common_hubdev_init() - This routine is called to initialize the HUB data
 *			     structure for each node in the system.
 */
void __init
sn_common_hubdev_init(struct hubdev_info *hubdev)
{

	struct sn_flush_device_kernel *sn_flush_device_kernel;
	struct sn_flush_device_kernel *dev_entry;
	s64 status;
	int widget, device, size;

	/* Attach the error interrupt handlers */
	if (hubdev->hdi_nasid & 1)	/* If TIO */
		ice_error_init(hubdev);
	else
		hub_error_init(hubdev);

	for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++)
		hubdev->hdi_xwidget_info[widget].xwi_hubinfo = hubdev;

	if (!hubdev->hdi_flush_nasid_list.widget_p)
		return;

	size = (HUB_WIDGET_ID_MAX + 1) *
		sizeof(struct sn_flush_device_kernel *);
	hubdev->hdi_flush_nasid_list.widget_p =
		kzalloc(size, GFP_KERNEL);
	if (!hubdev->hdi_flush_nasid_list.widget_p)
		BUG();

	for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) {
		size = DEV_PER_WIDGET *
			sizeof(struct sn_flush_device_kernel);
		sn_flush_device_kernel = kzalloc(size, GFP_KERNEL);
		if (!sn_flush_device_kernel)
			BUG();

		dev_entry = sn_flush_device_kernel;
		for (device = 0; device < DEV_PER_WIDGET;
		     device++, dev_entry++) {
			size = sizeof(struct sn_flush_device_common);
			dev_entry->common = kzalloc(size, GFP_KERNEL);
			if (!dev_entry->common)
				BUG();
			if (sn_prom_feature_available(PRF_DEVICE_FLUSH_LIST))
				status = sal_get_device_dmaflush_list(
					     hubdev->hdi_nasid, widget, device,
					     (u64)(dev_entry->common));
			else
				status = sn_device_fixup_war(hubdev->hdi_nasid,
							     widget, device,
							     dev_entry->common);
			if (status != SALRET_OK)
				panic("SAL call failed: %s\n",
				      ia64_sal_strerror(status));

			spin_lock_init(&dev_entry->sfdl_flush_lock);
		}

		if (sn_flush_device_kernel)
			hubdev->hdi_flush_nasid_list.widget_p[widget] =
							 sn_flush_device_kernel;
	}
}

void sn_pci_unfixup_slot(struct pci_dev *dev)
{
	struct pci_dev *host_pci_dev = SN_PCIDEV_INFO(dev)->host_pci_dev;

	sn_irq_unfixup(dev);
	pci_dev_put(host_pci_dev);
	pci_dev_put(dev);
}

/*
 * sn_pci_fixup_slot()
 */
void sn_pci_fixup_slot(struct pci_dev *dev, struct pcidev_info *pcidev_info,
		       struct sn_irq_info *sn_irq_info)
{
	int segment = pci_domain_nr(dev->bus);
	struct pcibus_bussoft *bs;
	struct pci_bus *host_pci_bus;
	struct pci_dev *host_pci_dev;
	unsigned int bus_no, devfn;

	pci_dev_get(dev); /* for the sysdata pointer */

	/* Add pcidev_info to list in pci_controller.platform_data */
	list_add_tail(&pcidev_info->pdi_list,
		      &(SN_PLATFORM_DATA(dev->bus)->pcidev_info));
	/*
	 * Using the PROMs values for the PCI host bus, get the Linux
	 * PCI host_pci_dev struct and set up host bus linkages
 	 */

	bus_no = (pcidev_info->pdi_slot_host_handle >> 32) & 0xff;
	devfn = pcidev_info->pdi_slot_host_handle & 0xffffffff;
 	host_pci_bus = pci_find_bus(segment, bus_no);
 	host_pci_dev = pci_get_slot(host_pci_bus, devfn);

	pcidev_info->host_pci_dev = host_pci_dev;
	pcidev_info->pdi_linux_pcidev = dev;
	pcidev_info->pdi_host_pcidev_info = SN_PCIDEV_INFO(host_pci_dev);
	bs = SN_PCIBUS_BUSSOFT(dev->bus);
	pcidev_info->pdi_pcibus_info = bs;

	if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) {
		SN_PCIDEV_BUSPROVIDER(dev) = sn_pci_provider[bs->bs_asic_type];
	} else {
		SN_PCIDEV_BUSPROVIDER(dev) = &sn_pci_default_provider;
	}

	/* Only set up IRQ stuff if this device has a host bus context */
	if (bs && sn_irq_info->irq_irq) {
		pcidev_info->pdi_sn_irq_info = sn_irq_info;
		dev->irq = pcidev_info->pdi_sn_irq_info->irq_irq;
		sn_irq_fixup(dev, sn_irq_info);
	} else {
		pcidev_info->pdi_sn_irq_info = NULL;
		kfree(sn_irq_info);
	}
}

/*
 * sn_common_bus_fixup - Perform platform specific bus fixup.
 *			 Execute the ASIC specific fixup routine
 *			 for this bus.
 */
void
sn_common_bus_fixup(struct pci_bus *bus,
		    struct pcibus_bussoft *prom_bussoft_ptr)
{
	int cnode;
	struct pci_controller *controller;
	struct hubdev_info *hubdev_info;
	int nasid;
	void *provider_soft;
	struct sn_pcibus_provider *provider;
	struct sn_platform_data *sn_platform_data;

	controller = PCI_CONTROLLER(bus);
	/*
	 * Per-provider fixup.  Copies the bus soft structure from prom
	 * to local area and links SN_PCIBUS_BUSSOFT().
	 */

	if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) {
		printk(KERN_WARNING "sn_common_bus_fixup: Unsupported asic type, %d",
		       prom_bussoft_ptr->bs_asic_type);
		return;
	}

	if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB)
		return;	/* no further fixup necessary */

	provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type];
	if (provider == NULL)
		panic("sn_common_bus_fixup: No provider registered for this asic type, %d",
		      prom_bussoft_ptr->bs_asic_type);

	if (provider->bus_fixup)
		provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr,
				 controller);
	else
		provider_soft = NULL;

	/*
	 * Generic bus fixup goes here.  Don't reference prom_bussoft_ptr
	 * after this point.
	 */
	controller->platform_data = kzalloc(sizeof(struct sn_platform_data),
					    GFP_KERNEL);
	if (controller->platform_data == NULL)
		BUG();
	sn_platform_data =
			(struct sn_platform_data *) controller->platform_data;
	sn_platform_data->provider_soft = provider_soft;
	INIT_LIST_HEAD(&((struct sn_platform_data *)
			 controller->platform_data)->pcidev_info);
	nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base);
	cnode = nasid_to_cnodeid(nasid);
	hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo);
	SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info =
	    &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]);

	/*
	 * If the node information we obtained during the fixup phase is
	 * invalid then set controller->node to -1 (undetermined)
	 */
	if (controller->node >= num_online_nodes()) {
		struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus);

		printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%u"
		       "L_IO=%lx L_MEM=%lx BASE=%lx\n",
		       b->bs_asic_type, b->bs_xid, b->bs_persist_busnum,
		       b->bs_legacy_io, b->bs_legacy_mem, b->bs_base);
		printk(KERN_WARNING "on node %d but only %d nodes online."
		       "Association set to undetermined.\n",
		       controller->node, num_online_nodes());
		controller->node = -1;
	}
}

void sn_bus_store_sysdata(struct pci_dev *dev)
{
	struct sysdata_el *element;

	element = kzalloc(sizeof(struct sysdata_el), GFP_KERNEL);
	if (!element) {
		dev_dbg(&dev->dev, "%s: out of memory!\n", __FUNCTION__);
		return;
	}
	element->sysdata = SN_PCIDEV_INFO(dev);
	list_add(&element->entry, &sn_sysdata_list);
}

void sn_bus_free_sysdata(void)
{
	struct sysdata_el *element;
	struct list_head *list, *safe;

	list_for_each_safe(list, safe, &sn_sysdata_list) {
		element = list_entry(list, struct sysdata_el, entry);
		list_del(&element->entry);
		list_del(&(((struct pcidev_info *)
			     (element->sysdata))->pdi_list));
		kfree(element->sysdata);
		kfree(element);
	}
	return;
}

/*
 * hubdev_init_node() - Creates the HUB data structure and link them to it's
 *			own NODE specific data area.
 */
void hubdev_init_node(nodepda_t * npda, cnodeid_t node)
{
	struct hubdev_info *hubdev_info;
	int size;
	pg_data_t *pg;

	size = sizeof(struct hubdev_info);

	if (node >= num_online_nodes())	/* Headless/memless IO nodes */
		pg = NODE_DATA(0);
	else
		pg = NODE_DATA(node);

	hubdev_info = (struct hubdev_info *)alloc_bootmem_node(pg, size);

	npda->pdinfo = (void *)hubdev_info;
}

geoid_t
cnodeid_get_geoid(cnodeid_t cnode)
{
	struct hubdev_info *hubdev;

	hubdev = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo);
	return hubdev->hdi_geoid;
}

void sn_generate_path(struct pci_bus *pci_bus, char *address)
{
	nasid_t nasid;
	cnodeid_t cnode;
	geoid_t geoid;
	moduleid_t moduleid;
	u16 bricktype;

	nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base);
	cnode = nasid_to_cnodeid(nasid);
	geoid = cnodeid_get_geoid(cnode);
	moduleid = geo_module(geoid);

	sprintf(address, "module_%c%c%c%c%.2d",
		'0'+RACK_GET_CLASS(MODULE_GET_RACK(moduleid)),
		'0'+RACK_GET_GROUP(MODULE_GET_RACK(moduleid)),
		'0'+RACK_GET_NUM(MODULE_GET_RACK(moduleid)),
		MODULE_GET_BTCHAR(moduleid), MODULE_GET_BPOS(moduleid));

	/* Tollhouse requires slot id to be displayed */
	bricktype = MODULE_GET_BTYPE(moduleid);
	if ((bricktype == L1_BRICKTYPE_191010) ||
	    (bricktype == L1_BRICKTYPE_1932))
			sprintf(address, "%s^%d", address, geo_slot(geoid));
}

void __devinit
sn_pci_fixup_bus(struct pci_bus *bus)
{

	if (SN_ACPI_BASE_SUPPORT())
		sn_acpi_bus_fixup(bus);
	else
		sn_bus_fixup(bus);
}

/*
 * sn_io_early_init - Perform early IO (and some non-IO) initialization.
 *		      In particular, setup the sn_pci_provider[] array.
 *		      This needs to be done prior to any bus scanning
 *		      (acpi_scan_init()) in the ACPI case, as the SN
 *		      bus fixup code will reference the array.
 */
static int __init
sn_io_early_init(void)
{
	int i;

	if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM())
		return 0;

	/* we set the acpi revision to that of the DSDT table OEM rev. */
	{
		struct acpi_table_header *header = NULL;

		acpi_get_table_by_index(ACPI_TABLE_INDEX_DSDT, &header);
		BUG_ON(header == NULL);
		sn_acpi_rev = header->oem_revision;
	}

	/*
	 * prime sn_pci_provider[].  Individual provider init routines will
	 * override their respective default entries.
	 */

	for (i = 0; i < PCIIO_ASIC_MAX_TYPES; i++)
		sn_pci_provider[i] = &sn_pci_default_provider;

	pcibr_init_provider();
	tioca_init_provider();
	tioce_init_provider();

	/*
	 * This is needed to avoid bounce limit checks in the blk layer
	 */
	ia64_max_iommu_merge_mask = ~PAGE_MASK;

	sn_irq_lh_init();
	INIT_LIST_HEAD(&sn_sysdata_list);
	sn_init_cpei_timer();

#ifdef CONFIG_PROC_FS
	register_sn_procfs();
#endif

	{
		struct acpi_table_header *header;
		(void)acpi_get_table_by_index(ACPI_TABLE_INDEX_DSDT, &header);
		printk(KERN_INFO "ACPI  DSDT OEM Rev 0x%x\n",
			header->oem_revision);
	}
	if (SN_ACPI_BASE_SUPPORT())
		sn_io_acpi_init();
	else
		sn_io_init();
	return 0;
}

arch_initcall(sn_io_early_init);

/*
 * sn_io_late_init() - Perform any final platform specific IO initialization.
 */

int __init
sn_io_late_init(void)
{
	struct pci_bus *bus;
	struct pcibus_bussoft *bussoft;
	cnodeid_t cnode;
	nasid_t nasid;
	cnodeid_t near_cnode;

	if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM())
		return 0;

	/*
	 * Setup closest node in pci_controller->node for
	 * PIC, TIOCP, TIOCE (TIOCA does it during bus fixup using
	 * info from the PROM).
	 */
	bus = NULL;
	while ((bus = pci_find_next_bus(bus)) != NULL) {
		bussoft = SN_PCIBUS_BUSSOFT(bus);
		nasid = NASID_GET(bussoft->bs_base);
		cnode = nasid_to_cnodeid(nasid);
		if ((bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) ||
		    (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCE)) {
			/* TIO PCI Bridge: find nearest node with CPUs */
			int e = sn_hwperf_get_nearest_node(cnode, NULL,
							   &near_cnode);
			if (e < 0) {
				near_cnode = (cnodeid_t)-1; /* use any node */
				printk(KERN_WARNING "pcibr_bus_fixup: failed "
				       "to find near node with CPUs to TIO "
				       "node %d, err=%d\n", cnode, e);
			}
			PCI_CONTROLLER(bus)->node = near_cnode;
		} else if (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_PIC) {
			PCI_CONTROLLER(bus)->node = cnode;
		}
	}

	sn_ioif_inited = 1;	/* SN I/O infrastructure now initialized */

	return 0;
}

fs_initcall(sn_io_late_init);

EXPORT_SYMBOL(sn_pci_unfixup_slot);
EXPORT_SYMBOL(sn_bus_store_sysdata);
EXPORT_SYMBOL(sn_bus_free_sysdata);
EXPORT_SYMBOL(sn_generate_path);

