/*
 *  Ralink RT3662/RT3883 SoC PCI support
 *
 *  Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
 *
 *  Parts of this file are based on Ralink's 2.6.21 BSP
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License version 2 as published
 *  by the Free Software Foundation.
 */

#include <linux/types.h>
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_pci.h>
#include <linux/platform_device.h>

#include <asm/mach-ralink/rt3883.h>
#include <asm/mach-ralink/ralink_regs.h>

#define RT3883_MEMORY_BASE		0x00000000
#define RT3883_MEMORY_SIZE		0x02000000

#define RT3883_PCI_REG_PCICFG		0x00
#define   RT3883_PCICFG_P2P_BR_DEVNUM_M 0xf
#define   RT3883_PCICFG_P2P_BR_DEVNUM_S 16
#define   RT3883_PCICFG_PCIRST		BIT(1)
#define RT3883_PCI_REG_PCIRAW		0x04
#define RT3883_PCI_REG_PCIINT		0x08
#define RT3883_PCI_REG_PCIENA		0x0c

#define RT3883_PCI_REG_CFGADDR		0x20
#define RT3883_PCI_REG_CFGDATA		0x24
#define RT3883_PCI_REG_MEMBASE		0x28
#define RT3883_PCI_REG_IOBASE		0x2c
#define RT3883_PCI_REG_ARBCTL		0x80

#define RT3883_PCI_REG_BASE(_x)		(0x1000 + (_x) * 0x1000)
#define RT3883_PCI_REG_BAR0SETUP(_x)	(RT3883_PCI_REG_BASE((_x)) + 0x10)
#define RT3883_PCI_REG_IMBASEBAR0(_x)	(RT3883_PCI_REG_BASE((_x)) + 0x18)
#define RT3883_PCI_REG_ID(_x)		(RT3883_PCI_REG_BASE((_x)) + 0x30)
#define RT3883_PCI_REG_CLASS(_x)	(RT3883_PCI_REG_BASE((_x)) + 0x34)
#define RT3883_PCI_REG_SUBID(_x)	(RT3883_PCI_REG_BASE((_x)) + 0x38)
#define RT3883_PCI_REG_STATUS(_x)	(RT3883_PCI_REG_BASE((_x)) + 0x50)

#define RT3883_PCI_MODE_NONE	0
#define RT3883_PCI_MODE_PCI	BIT(0)
#define RT3883_PCI_MODE_PCIE	BIT(1)
#define RT3883_PCI_MODE_BOTH	(RT3883_PCI_MODE_PCI | RT3883_PCI_MODE_PCIE)

#define RT3883_PCI_IRQ_COUNT	32

#define RT3883_P2P_BR_DEVNUM	1

struct rt3883_pci_controller {
	void __iomem *base;

	struct device_node *intc_of_node;
	struct irq_domain *irq_domain;

	struct pci_controller pci_controller;
	struct resource io_res;
	struct resource mem_res;

	bool pcie_ready;
};

static inline struct rt3883_pci_controller *
pci_bus_to_rt3883_controller(struct pci_bus *bus)
{
	struct pci_controller *hose;

	hose = (struct pci_controller *) bus->sysdata;
	return container_of(hose, struct rt3883_pci_controller, pci_controller);
}

static inline u32 rt3883_pci_r32(struct rt3883_pci_controller *rpc,
				 unsigned reg)
{
	return ioread32(rpc->base + reg);
}

static inline void rt3883_pci_w32(struct rt3883_pci_controller *rpc,
				  u32 val, unsigned reg)
{
	iowrite32(val, rpc->base + reg);
}

static inline u32 rt3883_pci_get_cfgaddr(unsigned int bus, unsigned int slot,
					 unsigned int func, unsigned int where)
{
	return (bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) |
	       0x80000000;
}

static u32 rt3883_pci_read_cfg32(struct rt3883_pci_controller *rpc,
			       unsigned bus, unsigned slot,
			       unsigned func, unsigned reg)
{
	unsigned long flags;
	u32 address;
	u32 ret;

	address = rt3883_pci_get_cfgaddr(bus, slot, func, reg);

	rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
	ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA);

	return ret;
}

static void rt3883_pci_write_cfg32(struct rt3883_pci_controller *rpc,
				 unsigned bus, unsigned slot,
				 unsigned func, unsigned reg, u32 val)
{
	unsigned long flags;
	u32 address;

	address = rt3883_pci_get_cfgaddr(bus, slot, func, reg);

	rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
	rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA);
}

static void rt3883_pci_irq_handler(struct irq_desc *desc)
{
	struct rt3883_pci_controller *rpc;
	u32 pending;

	rpc = irq_desc_get_handler_data(desc);

	pending = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIINT) &
		  rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA);

	if (!pending) {
		spurious_interrupt();
		return;
	}

	while (pending) {
		unsigned irq, bit = __ffs(pending);

		irq = irq_find_mapping(rpc->irq_domain, bit);
		generic_handle_irq(irq);

		pending &= ~BIT(bit);
	}
}

static void rt3883_pci_irq_unmask(struct irq_data *d)
{
	struct rt3883_pci_controller *rpc;
	u32 t;

	rpc = irq_data_get_irq_chip_data(d);

	t = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA);
	rt3883_pci_w32(rpc, t | BIT(d->hwirq), RT3883_PCI_REG_PCIENA);
	/* flush write */
	rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA);
}

static void rt3883_pci_irq_mask(struct irq_data *d)
{
	struct rt3883_pci_controller *rpc;
	u32 t;

	rpc = irq_data_get_irq_chip_data(d);

	t = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA);
	rt3883_pci_w32(rpc, t & ~BIT(d->hwirq), RT3883_PCI_REG_PCIENA);
	/* flush write */
	rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA);
}

static struct irq_chip rt3883_pci_irq_chip = {
	.name		= "RT3883 PCI",
	.irq_mask	= rt3883_pci_irq_mask,
	.irq_unmask	= rt3883_pci_irq_unmask,
	.irq_mask_ack	= rt3883_pci_irq_mask,
};

static int rt3883_pci_irq_map(struct irq_domain *d, unsigned int irq,
			      irq_hw_number_t hw)
{
	irq_set_chip_and_handler(irq, &rt3883_pci_irq_chip, handle_level_irq);
	irq_set_chip_data(irq, d->host_data);

	return 0;
}

static const struct irq_domain_ops rt3883_pci_irq_domain_ops = {
	.map = rt3883_pci_irq_map,
	.xlate = irq_domain_xlate_onecell,
};

static int rt3883_pci_irq_init(struct device *dev,
			       struct rt3883_pci_controller *rpc)
{
	int irq;

	irq = irq_of_parse_and_map(rpc->intc_of_node, 0);
	if (irq == 0) {
		dev_err(dev, "%s has no IRQ",
			of_node_full_name(rpc->intc_of_node));
		return -EINVAL;
	}

	/* disable all interrupts */
	rt3883_pci_w32(rpc, 0, RT3883_PCI_REG_PCIENA);

	rpc->irq_domain =
		irq_domain_add_linear(rpc->intc_of_node, RT3883_PCI_IRQ_COUNT,
				      &rt3883_pci_irq_domain_ops,
				      rpc);
	if (!rpc->irq_domain) {
		dev_err(dev, "unable to add IRQ domain\n");
		return -ENODEV;
	}

	irq_set_chained_handler_and_data(irq, rt3883_pci_irq_handler, rpc);

	return 0;
}

static int rt3883_pci_config_read(struct pci_bus *bus, unsigned int devfn,
				  int where, int size, u32 *val)
{
	struct rt3883_pci_controller *rpc;
	unsigned long flags;
	u32 address;
	u32 data;

	rpc = pci_bus_to_rt3883_controller(bus);

	if (!rpc->pcie_ready && bus->number == 1)
		return PCIBIOS_DEVICE_NOT_FOUND;

	address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
					 PCI_FUNC(devfn), where);

	rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
	data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA);

	switch (size) {
	case 1:
		*val = (data >> ((where & 3) << 3)) & 0xff;
		break;
	case 2:
		*val = (data >> ((where & 3) << 3)) & 0xffff;
		break;
	case 4:
		*val = data;
		break;
	}

	return PCIBIOS_SUCCESSFUL;
}

static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn,
				   int where, int size, u32 val)
{
	struct rt3883_pci_controller *rpc;
	unsigned long flags;
	u32 address;
	u32 data;

	rpc = pci_bus_to_rt3883_controller(bus);

	if (!rpc->pcie_ready && bus->number == 1)
		return PCIBIOS_DEVICE_NOT_FOUND;

	address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
					 PCI_FUNC(devfn), where);

	rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
	data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA);

	switch (size) {
	case 1:
		data = (data & ~(0xff << ((where & 3) << 3))) |
		       (val << ((where & 3) << 3));
		break;
	case 2:
		data = (data & ~(0xffff << ((where & 3) << 3))) |
		       (val << ((where & 3) << 3));
		break;
	case 4:
		data = val;
		break;
	}

	rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA);

	return PCIBIOS_SUCCESSFUL;
}

static struct pci_ops rt3883_pci_ops = {
	.read	= rt3883_pci_config_read,
	.write	= rt3883_pci_config_write,
};

static void rt3883_pci_preinit(struct rt3883_pci_controller *rpc, unsigned mode)
{
	u32 syscfg1;
	u32 rstctrl;
	u32 clkcfg1;
	u32 t;

	rstctrl = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL);
	syscfg1 = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG1);
	clkcfg1 = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1);

	if (mode & RT3883_PCI_MODE_PCIE) {
		rstctrl |= RT3883_RSTCTRL_PCIE;
		rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL);

		/* setup PCI PAD drive mode */
		syscfg1 &= ~(0x30);
		syscfg1 |= (2 << 4);
		rt_sysc_w32(syscfg1, RT3883_SYSC_REG_SYSCFG1);

		t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0);
		t &= ~BIT(31);
		rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0);

		t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN1);
		t &= 0x80ffffff;
		rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN1);

		t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN1);
		t |= 0xa << 24;
		rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN1);

		t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0);
		t |= BIT(31);
		rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0);

		msleep(50);

		rstctrl &= ~RT3883_RSTCTRL_PCIE;
		rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL);
	}

	syscfg1 |= (RT3883_SYSCFG1_PCIE_RC_MODE | RT3883_SYSCFG1_PCI_HOST_MODE);

	clkcfg1 &= ~(RT3883_CLKCFG1_PCI_CLK_EN | RT3883_CLKCFG1_PCIE_CLK_EN);

	if (mode & RT3883_PCI_MODE_PCI) {
		clkcfg1 |= RT3883_CLKCFG1_PCI_CLK_EN;
		rstctrl &= ~RT3883_RSTCTRL_PCI;
	}

	if (mode & RT3883_PCI_MODE_PCIE) {
		clkcfg1 |= RT3883_CLKCFG1_PCIE_CLK_EN;
		rstctrl &= ~RT3883_RSTCTRL_PCIE;
	}

	rt_sysc_w32(syscfg1, RT3883_SYSC_REG_SYSCFG1);
	rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL);
	rt_sysc_w32(clkcfg1, RT3883_SYSC_REG_CLKCFG1);

	msleep(500);

	/*
	 * setup the device number of the P2P bridge
	 * and de-assert the reset line
	 */
	t = (RT3883_P2P_BR_DEVNUM << RT3883_PCICFG_P2P_BR_DEVNUM_S);
	rt3883_pci_w32(rpc, t, RT3883_PCI_REG_PCICFG);

	/* flush write */
	rt3883_pci_r32(rpc, RT3883_PCI_REG_PCICFG);
	msleep(500);

	if (mode & RT3883_PCI_MODE_PCIE) {
		msleep(500);

		t = rt3883_pci_r32(rpc, RT3883_PCI_REG_STATUS(1));

		rpc->pcie_ready = t & BIT(0);

		if (!rpc->pcie_ready) {
			/* reset the PCIe block */
			t = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL);
			t |= RT3883_RSTCTRL_PCIE;
			rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL);
			t &= ~RT3883_RSTCTRL_PCIE;
			rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL);

			/* turn off PCIe clock */
			t = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1);
			t &= ~RT3883_CLKCFG1_PCIE_CLK_EN;
			rt_sysc_w32(t, RT3883_SYSC_REG_CLKCFG1);

			t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0);
			t &= ~0xf000c080;
			rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0);
		}
	}

	/* enable PCI arbiter */
	rt3883_pci_w32(rpc, 0x79, RT3883_PCI_REG_ARBCTL);
}

static int rt3883_pci_probe(struct platform_device *pdev)
{
	struct rt3883_pci_controller *rpc;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct resource *res;
	struct device_node *child;
	u32 val;
	int err;
	int mode;

	rpc = devm_kzalloc(dev, sizeof(*rpc), GFP_KERNEL);
	if (!rpc)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	rpc->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(rpc->base))
		return PTR_ERR(rpc->base);

	/* find the interrupt controller child node */
	for_each_child_of_node(np, child) {
		if (of_get_property(child, "interrupt-controller", NULL)) {
			rpc->intc_of_node = child;
			break;
		}
	}

	if (!rpc->intc_of_node) {
		dev_err(dev, "%s has no %s child node",
			of_node_full_name(rpc->intc_of_node),
			"interrupt controller");
		return -EINVAL;
	}

	/* find the PCI host bridge child node */
	for_each_child_of_node(np, child) {
		if (child->type &&
		    of_node_cmp(child->type, "pci") == 0) {
			rpc->pci_controller.of_node = child;
			break;
		}
	}

	if (!rpc->pci_controller.of_node) {
		dev_err(dev, "%s has no %s child node",
			of_node_full_name(rpc->intc_of_node),
			"PCI host bridge");
		err = -EINVAL;
		goto err_put_intc_node;
	}

	mode = RT3883_PCI_MODE_NONE;
	for_each_available_child_of_node(rpc->pci_controller.of_node, child) {
		int devfn;

		if (!child->type ||
		    of_node_cmp(child->type, "pci") != 0)
			continue;

		devfn = of_pci_get_devfn(child);
		if (devfn < 0)
			continue;

		switch (PCI_SLOT(devfn)) {
		case 1:
			mode |= RT3883_PCI_MODE_PCIE;
			break;

		case 17:
		case 18:
			mode |= RT3883_PCI_MODE_PCI;
			break;
		}
	}

	if (mode == RT3883_PCI_MODE_NONE) {
		dev_err(dev, "unable to determine PCI mode\n");
		err = -EINVAL;
		goto err_put_hb_node;
	}

	dev_info(dev, "mode:%s%s\n",
		 (mode & RT3883_PCI_MODE_PCI) ? " PCI" : "",
		 (mode & RT3883_PCI_MODE_PCIE) ? " PCIe" : "");

	rt3883_pci_preinit(rpc, mode);

	rpc->pci_controller.pci_ops = &rt3883_pci_ops;
	rpc->pci_controller.io_resource = &rpc->io_res;
	rpc->pci_controller.mem_resource = &rpc->mem_res;

	/* Load PCI I/O and memory resources from DT */
	pci_load_of_ranges(&rpc->pci_controller,
			   rpc->pci_controller.of_node);

	rt3883_pci_w32(rpc, rpc->mem_res.start, RT3883_PCI_REG_MEMBASE);
	rt3883_pci_w32(rpc, rpc->io_res.start, RT3883_PCI_REG_IOBASE);

	ioport_resource.start = rpc->io_res.start;
	ioport_resource.end = rpc->io_res.end;

	/* PCI */
	rt3883_pci_w32(rpc, 0x03ff0000, RT3883_PCI_REG_BAR0SETUP(0));
	rt3883_pci_w32(rpc, RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0(0));
	rt3883_pci_w32(rpc, 0x08021814, RT3883_PCI_REG_ID(0));
	rt3883_pci_w32(rpc, 0x00800001, RT3883_PCI_REG_CLASS(0));
	rt3883_pci_w32(rpc, 0x28801814, RT3883_PCI_REG_SUBID(0));

	/* PCIe */
	rt3883_pci_w32(rpc, 0x03ff0000, RT3883_PCI_REG_BAR0SETUP(1));
	rt3883_pci_w32(rpc, RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0(1));
	rt3883_pci_w32(rpc, 0x08021814, RT3883_PCI_REG_ID(1));
	rt3883_pci_w32(rpc, 0x06040001, RT3883_PCI_REG_CLASS(1));
	rt3883_pci_w32(rpc, 0x28801814, RT3883_PCI_REG_SUBID(1));

	err = rt3883_pci_irq_init(dev, rpc);
	if (err)
		goto err_put_hb_node;

	/* PCIe */
	val = rt3883_pci_read_cfg32(rpc, 0, 0x01, 0, PCI_COMMAND);
	val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
	rt3883_pci_write_cfg32(rpc, 0, 0x01, 0, PCI_COMMAND, val);

	/* PCI */
	val = rt3883_pci_read_cfg32(rpc, 0, 0x00, 0, PCI_COMMAND);
	val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
	rt3883_pci_write_cfg32(rpc, 0, 0x00, 0, PCI_COMMAND, val);

	if (mode == RT3883_PCI_MODE_PCIE) {
		rt3883_pci_w32(rpc, 0x03ff0001, RT3883_PCI_REG_BAR0SETUP(0));
		rt3883_pci_w32(rpc, 0x03ff0001, RT3883_PCI_REG_BAR0SETUP(1));

		rt3883_pci_write_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0,
				       PCI_BASE_ADDRESS_0,
				       RT3883_MEMORY_BASE);
		/* flush write */
		rt3883_pci_read_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0,
				      PCI_BASE_ADDRESS_0);
	} else {
		rt3883_pci_write_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0,
				       PCI_IO_BASE, 0x00000101);
	}

	register_pci_controller(&rpc->pci_controller);

	return 0;

err_put_hb_node:
	of_node_put(rpc->pci_controller.of_node);
err_put_intc_node:
	of_node_put(rpc->intc_of_node);
	return err;
}

int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
	return of_irq_parse_and_map_pci(dev, slot, pin);
}

int pcibios_plat_dev_init(struct pci_dev *dev)
{
	return 0;
}

static const struct of_device_id rt3883_pci_ids[] = {
	{ .compatible = "ralink,rt3883-pci" },
	{},
};

static struct platform_driver rt3883_pci_driver = {
	.probe = rt3883_pci_probe,
	.driver = {
		.name = "rt3883-pci",
		.of_match_table = of_match_ptr(rt3883_pci_ids),
	},
};

static int __init rt3883_pci_init(void)
{
	return platform_driver_register(&rt3883_pci_driver);
}

postcore_initcall(rt3883_pci_init);
