// SPDX-License-Identifier: GPL-2.0-only
#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;

	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(void __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;
	void __iomem *p = base;
	int num_cells = 0;
	uint32_t dtype;
	int bar_count;
	int ret;
	u32 hsize;
	u32 table_size;

	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) {
		ret = -EINVAL;
		goto free_bar;
	}

	table_size = p - base;
	pr_debug("%d cell(s) found. Chameleon table size: 0x%04x bytes\n", num_cells, table_size);
	kfree(cb);
	kfree(header);
	return table_size;

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

	return ret;
}
EXPORT_SYMBOL_NS_GPL(chameleon_parse_cells, MCB);
