#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/mcb.h>

#include "mcb-internal.h"

struct mcb_parse_priv {
	phys_addr_t mapbase;
	void __iomem *base;
};

#define for_each_chameleon_cell(dtype, p)	\
	for ((dtype) = get_next_dtype((p));	\
	     (dtype) != CHAMELEON_DTYPE_END;	\
	     (dtype) = get_next_dtype((p)))

static inline uint32_t get_next_dtype(void __iomem *p)
{
	uint32_t dtype;

	dtype = readl(p);
	return dtype >> 28;
}

static int chameleon_parse_bdd(struct mcb_bus *bus,
			struct chameleon_bar *cb,
			void __iomem *base)
{
	return 0;
}

static int chameleon_parse_gdd(struct mcb_bus *bus,
			struct chameleon_bar *cb,
			void __iomem *base, int bar_count)
{
	struct chameleon_gdd __iomem *gdd =
		(struct chameleon_gdd __iomem *) base;
	struct mcb_device *mdev;
	u32 dev_mapbase;
	u32 offset;
	u32 size;
	int ret;
	__le32 reg1;
	__le32 reg2;

	mdev = mcb_alloc_dev(bus);
	if (!mdev)
		return -ENOMEM;

	reg1 = readl(&gdd->reg1);
	reg2 = readl(&gdd->reg2);
	offset = readl(&gdd->offset);
	size = readl(&gdd->size);

	mdev->id = GDD_DEV(reg1);
	mdev->rev = GDD_REV(reg1);
	mdev->var = GDD_VAR(reg1);
	mdev->bar = GDD_BAR(reg2);
	mdev->group = GDD_GRP(reg2);
	mdev->inst = GDD_INS(reg2);

	/*
	 * If the BAR is missing, dev_mapbase is zero, or if the
	 * device is IO mapped we just print a warning and go on with the
	 * next device, instead of completely stop the gdd parser
	 */
	if (mdev->bar > bar_count - 1) {
		pr_info("No BAR for 16z%03d\n", mdev->id);
		ret = 0;
		goto err;
	}

	dev_mapbase = cb[mdev->bar].addr;
	if (!dev_mapbase) {
		pr_info("BAR not assigned for 16z%03d\n", mdev->id);
		ret = 0;
		goto err;
	}

	if (dev_mapbase & 0x01) {
		pr_info("IO mapped Device (16z%03d) not yet supported\n",
			mdev->id);
		ret = 0;
		goto err;
	}

	pr_debug("Found a 16z%03d\n", mdev->id);

	mdev->irq.start = GDD_IRQ(reg1);
	mdev->irq.end = GDD_IRQ(reg1);
	mdev->irq.flags = IORESOURCE_IRQ;

	mdev->mem.start = dev_mapbase + offset;

	mdev->mem.end = mdev->mem.start + size - 1;
	mdev->mem.flags = IORESOURCE_MEM;

	mdev->is_added = false;

	ret = mcb_device_register(bus, mdev);
	if (ret < 0)
		goto err;

	return 0;

err:
	put_device(&mdev->dev);

	return ret;
}

static void chameleon_parse_bar(void __iomem *base,
				struct chameleon_bar *cb, int bar_count)
{
	char __iomem *p = base;
	int i;

	/* skip reg1 */
	p += sizeof(__le32);

	for (i = 0; i < bar_count; i++) {
		cb[i].addr = readl(p);
		cb[i].size = readl(p + 4);

		p += sizeof(struct chameleon_bar);
	}
}

static int chameleon_get_bar(char __iomem **base, phys_addr_t mapbase,
			     struct chameleon_bar **cb)
{
	struct chameleon_bar *c;
	int bar_count;
	__le32 reg;
	u32 dtype;

	/*
	 * For those devices which are not connected
	 * to the PCI Bus (e.g. LPC) there is a bar
	 * descriptor located directly after the
	 * chameleon header. This header is comparable
	 * to a PCI header.
	 */
	dtype = get_next_dtype(*base);
	if (dtype == CHAMELEON_DTYPE_BAR) {
		reg = readl(*base);

		bar_count = BAR_CNT(reg);
		if (bar_count <= 0 || bar_count > CHAMELEON_BAR_MAX)
			return -ENODEV;

		c = kcalloc(bar_count, sizeof(struct chameleon_bar),
			    GFP_KERNEL);
		if (!c)
			return -ENOMEM;

		chameleon_parse_bar(*base, c, bar_count);
		*base += BAR_DESC_SIZE(bar_count);
	} else {
		c = kzalloc(sizeof(struct chameleon_bar), GFP_KERNEL);
		if (!c)
			return -ENOMEM;

		bar_count = 1;
		c->addr = mapbase;
	}

	*cb = c;

	return bar_count;
}

int chameleon_parse_cells(struct mcb_bus *bus, phys_addr_t mapbase,
			void __iomem *base)
{
	struct chameleon_fpga_header *header;
	struct chameleon_bar *cb;
	char __iomem *p = base;
	int num_cells = 0;
	uint32_t dtype;
	int bar_count;
	int ret;
	u32 hsize;

	hsize = sizeof(struct chameleon_fpga_header);

	header = kzalloc(hsize, GFP_KERNEL);
	if (!header)
		return -ENOMEM;

	/* Extract header information */
	memcpy_fromio(header, p, hsize);
	/* We only support chameleon v2 at the moment */
	header->magic = le16_to_cpu(header->magic);
	if (header->magic != CHAMELEONV2_MAGIC) {
		pr_err("Unsupported chameleon version 0x%x\n",
				header->magic);
		ret = -ENODEV;
		goto free_header;
	}
	p += hsize;

	bus->revision = header->revision;
	bus->model = header->model;
	bus->minor = header->minor;
	snprintf(bus->name, CHAMELEON_FILENAME_LEN + 1, "%s",
		 header->filename);

	bar_count = chameleon_get_bar(&p, mapbase, &cb);
	if (bar_count < 0) {
		ret = bar_count;
		goto free_header;
	}

	for_each_chameleon_cell(dtype, p) {
		switch (dtype) {
		case CHAMELEON_DTYPE_GENERAL:
			ret = chameleon_parse_gdd(bus, cb, p, bar_count);
			if (ret < 0)
				goto free_bar;
			p += sizeof(struct chameleon_gdd);
			break;
		case CHAMELEON_DTYPE_BRIDGE:
			chameleon_parse_bdd(bus, cb, p);
			p += sizeof(struct chameleon_bdd);
			break;
		case CHAMELEON_DTYPE_END:
			break;
		default:
			pr_err("Invalid chameleon descriptor type 0x%x\n",
				dtype);
			ret = -EINVAL;
			goto free_bar;
		}
		num_cells++;
	}

	if (num_cells == 0)
		num_cells = -EINVAL;

	kfree(cb);
	kfree(header);
	return num_cells;

free_bar:
	kfree(cb);
free_header:
	kfree(header);

	return ret;
}
EXPORT_SYMBOL_GPL(chameleon_parse_cells);
