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

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/proc_fs.h>
#include <linux/capability.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/addrs.h>
#include <asm/sn/io.h>
#include <asm/sn/types.h>
#include <asm/sn/shubio.h>
#include <asm/sn/tiocx.h>
#include <asm/sn/l1.h>
#include <asm/sn/module.h>
#include "tio.h"
#include "xtalk/xwidgetdev.h"
#include "xtalk/hubdev.h"

#define CX_DEV_NONE 0
#define DEVICE_NAME "tiocx"
#define WIDGET_ID 0
#define TIOCX_DEBUG 0

#if TIOCX_DEBUG
#define DBG(fmt...)    printk(KERN_ALERT fmt)
#else
#define DBG(fmt...)
#endif

struct device_attribute dev_attr_cxdev_control;

/**
 * tiocx_match - Try to match driver id list with device.
 * @dev: device pointer
 * @drv: driver pointer
 *
 * Returns 1 if match, 0 otherwise.
 */
static int tiocx_match(struct device *dev, struct device_driver *drv)
{
	struct cx_dev *cx_dev = to_cx_dev(dev);
	struct cx_drv *cx_drv = to_cx_driver(drv);
	const struct cx_device_id *ids = cx_drv->id_table;

	if (!ids)
		return 0;

	while (ids->part_num) {
		if (ids->part_num == cx_dev->cx_id.part_num)
			return 1;
		ids++;
	}
	return 0;

}

static int tiocx_uevent(struct device *dev, struct kobj_uevent_env *env)
{
	return -ENODEV;
}

static void tiocx_bus_release(struct device *dev)
{
	kfree(to_cx_dev(dev));
}

/**
 * cx_device_match - Find cx_device in the id table.
 * @ids: id table from driver
 * @cx_device: part/mfg id for the device
 *
 */
static const struct cx_device_id *cx_device_match(const struct cx_device_id
						  *ids,
						  struct cx_dev *cx_device)
{
	/*
	 * NOTES: We may want to check for CX_ANY_ID too.
	 *        Do we want to match against nasid too?
	 *        CX_DEV_NONE == 0, if the driver tries to register for
	 *        part/mfg == 0 we should return no-match (NULL) here.
	 */
	while (ids->part_num && ids->mfg_num) {
		if (ids->part_num == cx_device->cx_id.part_num &&
		    ids->mfg_num == cx_device->cx_id.mfg_num)
			return ids;
		ids++;
	}

	return NULL;
}

/**
 * cx_device_probe - Look for matching device.
 *			Call driver probe routine if found.
 * @cx_driver: driver table (cx_drv struct) from driver
 * @cx_device: part/mfg id for the device
 */
static int cx_device_probe(struct device *dev)
{
	const struct cx_device_id *id;
	struct cx_drv *cx_drv = to_cx_driver(dev->driver);
	struct cx_dev *cx_dev = to_cx_dev(dev);
	int error = 0;

	if (!cx_dev->driver && cx_drv->probe) {
		id = cx_device_match(cx_drv->id_table, cx_dev);
		if (id) {
			if ((error = cx_drv->probe(cx_dev, id)) < 0)
				return error;
			else
				cx_dev->driver = cx_drv;
		}
	}

	return error;
}

/**
 * cx_driver_remove - Remove driver from device struct.
 * @dev: device
 */
static int cx_driver_remove(struct device *dev)
{
	struct cx_dev *cx_dev = to_cx_dev(dev);
	struct cx_drv *cx_drv = cx_dev->driver;
	if (cx_drv->remove)
		cx_drv->remove(cx_dev);
	cx_dev->driver = NULL;
	return 0;
}

struct bus_type tiocx_bus_type = {
	.name = "tiocx",
	.match = tiocx_match,
	.uevent = tiocx_uevent,
	.probe = cx_device_probe,
	.remove = cx_driver_remove,
};

/**
 * cx_driver_register - Register the driver.
 * @cx_driver: driver table (cx_drv struct) from driver
 * 
 * Called from the driver init routine to register a driver.
 * The cx_drv struct contains the driver name, a pointer to
 * a table of part/mfg numbers and a pointer to the driver's
 * probe/attach routine.
 */
int cx_driver_register(struct cx_drv *cx_driver)
{
	cx_driver->driver.name = cx_driver->name;
	cx_driver->driver.bus = &tiocx_bus_type;

	return driver_register(&cx_driver->driver);
}

/**
 * cx_driver_unregister - Unregister the driver.
 * @cx_driver: driver table (cx_drv struct) from driver
 */
int cx_driver_unregister(struct cx_drv *cx_driver)
{
	driver_unregister(&cx_driver->driver);
	return 0;
}

/**
 * cx_device_register - Register a device.
 * @nasid: device's nasid
 * @part_num: device's part number
 * @mfg_num: device's manufacturer number
 * @hubdev: hub info associated with this device
 * @bt: board type of the device
 *
 */
int
cx_device_register(nasid_t nasid, int part_num, int mfg_num,
		   struct hubdev_info *hubdev, int bt)
{
	struct cx_dev *cx_dev;
	int r;

	cx_dev = kzalloc(sizeof(struct cx_dev), GFP_KERNEL);
	DBG("cx_dev= 0x%p\n", cx_dev);
	if (cx_dev == NULL)
		return -ENOMEM;

	cx_dev->cx_id.part_num = part_num;
	cx_dev->cx_id.mfg_num = mfg_num;
	cx_dev->cx_id.nasid = nasid;
	cx_dev->hubdev = hubdev;
	cx_dev->bt = bt;

	cx_dev->dev.parent = NULL;
	cx_dev->dev.bus = &tiocx_bus_type;
	cx_dev->dev.release = tiocx_bus_release;
	dev_set_name(&cx_dev->dev, "%d", cx_dev->cx_id.nasid);
	r = device_register(&cx_dev->dev);
	if (r) {
		kfree(cx_dev);
		return r;
	}
	get_device(&cx_dev->dev);

	device_create_file(&cx_dev->dev, &dev_attr_cxdev_control);

	return 0;
}

/**
 * cx_device_unregister - Unregister a device.
 * @cx_dev: part/mfg id for the device
 */
int cx_device_unregister(struct cx_dev *cx_dev)
{
	put_device(&cx_dev->dev);
	device_unregister(&cx_dev->dev);
	return 0;
}

/**
 * cx_device_reload - Reload the device.
 * @nasid: device's nasid
 * @part_num: device's part number
 * @mfg_num: device's manufacturer number
 *
 * Remove the device associated with 'nasid' from device list and then
 * call device-register with the given part/mfg numbers.
 */
static int cx_device_reload(struct cx_dev *cx_dev)
{
	cx_device_unregister(cx_dev);
	return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num,
				  cx_dev->cx_id.mfg_num, cx_dev->hubdev,
				  cx_dev->bt);
}

static inline u64 tiocx_intr_alloc(nasid_t nasid, int widget,
					u64 sn_irq_info,
					int req_irq, nasid_t req_nasid,
					int req_slice)
{
	struct ia64_sal_retval rv;
	rv.status = 0;
	rv.v0 = 0;

	ia64_sal_oemcall_nolock(&rv, SN_SAL_IOIF_INTERRUPT,
				SAL_INTR_ALLOC, nasid,
				widget, sn_irq_info, req_irq,
				req_nasid, req_slice);
	return rv.status;
}

static inline void tiocx_intr_free(nasid_t nasid, int widget,
				   struct sn_irq_info *sn_irq_info)
{
	struct ia64_sal_retval rv;
	rv.status = 0;
	rv.v0 = 0;

	ia64_sal_oemcall_nolock(&rv, SN_SAL_IOIF_INTERRUPT,
				SAL_INTR_FREE, nasid,
				widget, sn_irq_info->irq_irq,
				sn_irq_info->irq_cookie, 0, 0);
}

struct sn_irq_info *tiocx_irq_alloc(nasid_t nasid, int widget, int irq,
				    nasid_t req_nasid, int slice)
{
	struct sn_irq_info *sn_irq_info;
	int status;
	int sn_irq_size = sizeof(struct sn_irq_info);

	if ((nasid & 1) == 0)
		return NULL;

	sn_irq_info = kzalloc(sn_irq_size, GFP_KERNEL);
	if (sn_irq_info == NULL)
		return NULL;

	status = tiocx_intr_alloc(nasid, widget, __pa(sn_irq_info), irq,
				  req_nasid, slice);
	if (status) {
		kfree(sn_irq_info);
		return NULL;
	} else {
		return sn_irq_info;
	}
}

void tiocx_irq_free(struct sn_irq_info *sn_irq_info)
{
	u64 bridge = (u64) sn_irq_info->irq_bridge;
	nasid_t nasid = NASID_GET(bridge);
	int widget;

	if (nasid & 1) {
		widget = TIO_SWIN_WIDGETNUM(bridge);
		tiocx_intr_free(nasid, widget, sn_irq_info);
		kfree(sn_irq_info);
	}
}

u64 tiocx_dma_addr(u64 addr)
{
	return PHYS_TO_TIODMA(addr);
}

u64 tiocx_swin_base(int nasid)
{
	return TIO_SWIN_BASE(nasid, TIOCX_CORELET);
}

EXPORT_SYMBOL(cx_driver_register);
EXPORT_SYMBOL(cx_driver_unregister);
EXPORT_SYMBOL(cx_device_register);
EXPORT_SYMBOL(cx_device_unregister);
EXPORT_SYMBOL(tiocx_irq_alloc);
EXPORT_SYMBOL(tiocx_irq_free);
EXPORT_SYMBOL(tiocx_bus_type);
EXPORT_SYMBOL(tiocx_dma_addr);
EXPORT_SYMBOL(tiocx_swin_base);

static void tio_conveyor_set(nasid_t nasid, int enable_flag)
{
	u64 ice_frz;
	u64 disable_cb = (1ull << 61);

	if (!(nasid & 1))
		return;

	ice_frz = REMOTE_HUB_L(nasid, TIO_ICE_FRZ_CFG);
	if (enable_flag) {
		if (!(ice_frz & disable_cb))	/* already enabled */
			return;
		ice_frz &= ~disable_cb;
	} else {
		if (ice_frz & disable_cb)	/* already disabled */
			return;
		ice_frz |= disable_cb;
	}
	DBG(KERN_ALERT "TIO_ICE_FRZ_CFG= 0x%lx\n", ice_frz);
	REMOTE_HUB_S(nasid, TIO_ICE_FRZ_CFG, ice_frz);
}

#define tio_conveyor_enable(nasid) tio_conveyor_set(nasid, 1)
#define tio_conveyor_disable(nasid) tio_conveyor_set(nasid, 0)

static void tio_corelet_reset(nasid_t nasid, int corelet)
{
	if (!(nasid & 1))
		return;

	REMOTE_HUB_S(nasid, TIO_ICE_PMI_TX_CFG, 1 << corelet);
	udelay(2000);
	REMOTE_HUB_S(nasid, TIO_ICE_PMI_TX_CFG, 0);
	udelay(2000);
}

static int is_fpga_tio(int nasid, int *bt)
{
	u16 uninitialized_var(ioboard_type);	/* GCC be quiet */
	long rc;

	rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard_type);
	if (rc) {
		printk(KERN_WARNING "ia64_sn_sysctl_ioboard_get failed: %ld\n",
		       rc);
		return 0;
	}

	switch (ioboard_type) {
	case L1_BRICKTYPE_SA:
	case L1_BRICKTYPE_ATHENA:
	case L1_BOARDTYPE_DAYTONA:
		*bt = ioboard_type;
		return 1;
	}

	return 0;
}

static int bitstream_loaded(nasid_t nasid)
{
	u64 cx_credits;

	cx_credits = REMOTE_HUB_L(nasid, TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3);
	cx_credits &= TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3_CREDIT_CNT_MASK;
	DBG("cx_credits= 0x%lx\n", cx_credits);

	return (cx_credits == 0xf) ? 1 : 0;
}

static int tiocx_reload(struct cx_dev *cx_dev)
{
	int part_num = CX_DEV_NONE;
	int mfg_num = CX_DEV_NONE;
	nasid_t nasid = cx_dev->cx_id.nasid;

	if (bitstream_loaded(nasid)) {
		u64 cx_id;
		int rv;

		rv = ia64_sn_sysctl_tio_clock_reset(nasid);
		if (rv) {
			printk(KERN_ALERT "CX port JTAG reset failed.\n");
		} else {
			cx_id = *(volatile u64 *)
				(TIO_SWIN_BASE(nasid, TIOCX_CORELET) +
					  WIDGET_ID);
			part_num = XWIDGET_PART_NUM(cx_id);
			mfg_num = XWIDGET_MFG_NUM(cx_id);
			DBG("part= 0x%x, mfg= 0x%x\n", part_num, mfg_num);
			/* just ignore it if it's a CE */
			if (part_num == TIO_CE_ASIC_PARTNUM)
				return 0;
		}
	}

	cx_dev->cx_id.part_num = part_num;
	cx_dev->cx_id.mfg_num = mfg_num;

	/*
	 * Delete old device and register the new one.  It's ok if
	 * part_num/mfg_num == CX_DEV_NONE.  We want to register
	 * devices in the table even if a bitstream isn't loaded.
	 * That allows use to see that a bitstream isn't loaded via
	 * TIOCX_IOCTL_DEV_LIST.
	 */
	return cx_device_reload(cx_dev);
}

static ssize_t show_cxdev_control(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct cx_dev *cx_dev = to_cx_dev(dev);

	return sprintf(buf, "0x%x 0x%x 0x%x 0x%x\n",
		       cx_dev->cx_id.nasid,
		       cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num,
		       cx_dev->bt);
}

static ssize_t store_cxdev_control(struct device *dev, struct device_attribute *attr, const char *buf,
				   size_t count)
{
	int n;
	struct cx_dev *cx_dev = to_cx_dev(dev);

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	if (count <= 0)
		return 0;

	n = simple_strtoul(buf, NULL, 0);

	switch (n) {
	case 1:
		tio_corelet_reset(cx_dev->cx_id.nasid, TIOCX_CORELET);
		tiocx_reload(cx_dev);
		break;
	case 2:
		tiocx_reload(cx_dev);
		break;
	case 3:
		tio_corelet_reset(cx_dev->cx_id.nasid, TIOCX_CORELET);
		break;
	default:
		break;
	}

	return count;
}

DEVICE_ATTR(cxdev_control, 0644, show_cxdev_control, store_cxdev_control);

static int __init tiocx_init(void)
{
	cnodeid_t cnodeid;
	int found_tiocx_device = 0;
	int err;

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

	err = bus_register(&tiocx_bus_type);
	if (err)
		return err;

	for (cnodeid = 0; cnodeid < num_cnodes; cnodeid++) {
		nasid_t nasid;
		int bt;

		nasid = cnodeid_to_nasid(cnodeid);

		if ((nasid & 0x1) && is_fpga_tio(nasid, &bt)) {
			struct hubdev_info *hubdev;
			struct xwidget_info *widgetp;

			DBG("Found TIO at nasid 0x%x\n", nasid);

			hubdev =
			    (struct hubdev_info *)(NODEPDA(cnodeid)->pdinfo);

			widgetp = &hubdev->hdi_xwidget_info[TIOCX_CORELET];

			/* The CE hangs off of the CX port but is not an FPGA */
			if (widgetp->xwi_hwid.part_num == TIO_CE_ASIC_PARTNUM)
				continue;

			tio_corelet_reset(nasid, TIOCX_CORELET);
			tio_conveyor_enable(nasid);

			if (cx_device_register
			    (nasid, widgetp->xwi_hwid.part_num,
			     widgetp->xwi_hwid.mfg_num, hubdev, bt) < 0)
				return -ENXIO;
			else
				found_tiocx_device++;
		}
	}

	/* It's ok if we find zero devices. */
	DBG("found_tiocx_device= %d\n", found_tiocx_device);

	return 0;
}

static int cx_remove_device(struct device * dev, void * data)
{
	struct cx_dev *cx_dev = to_cx_dev(dev);
	device_remove_file(dev, &dev_attr_cxdev_control);
	cx_device_unregister(cx_dev);
	return 0;
}

static void __exit tiocx_exit(void)
{
	DBG("tiocx_exit\n");

	/*
	 * Unregister devices.
	 */
	bus_for_each_dev(&tiocx_bus_type, NULL, NULL, cx_remove_device);
	bus_unregister(&tiocx_bus_type);
}

fs_initcall(tiocx_init);
module_exit(tiocx_exit);

/************************************************************************
 * Module licensing and description
 ************************************************************************/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Bruce Losure <blosure@sgi.com>");
MODULE_DESCRIPTION("TIOCX module");
MODULE_SUPPORTED_DEVICE(DEVICE_NAME);
