// SPDX-License-Identifier: GPL-2.0-only
/*
 *  Ralink RT288x SoC PCI register definitions
 *
 *  Copyright (C) 2009 John Crispin <john@phrozen.org>
 *  Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
 *
 *  Parts of this file are based on Ralink's 2.6.21 BSP
 */

#include <linux/delay.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/of_platform.h>
#include <linux/of_irq.h>
#include <linux/of_pci.h>

#include <asm/mach-ralink/rt288x.h>

#define RT2880_PCI_BASE		0x00440000
#define RT288X_CPU_IRQ_PCI	4

#define RT2880_PCI_MEM_BASE	0x20000000
#define RT2880_PCI_MEM_SIZE	0x10000000
#define RT2880_PCI_IO_BASE	0x00460000
#define RT2880_PCI_IO_SIZE	0x00010000

#define RT2880_PCI_REG_PCICFG_ADDR	0x00
#define RT2880_PCI_REG_PCIMSK_ADDR	0x0c
#define RT2880_PCI_REG_BAR0SETUP_ADDR	0x10
#define RT2880_PCI_REG_IMBASEBAR0_ADDR	0x18
#define RT2880_PCI_REG_CONFIG_ADDR	0x20
#define RT2880_PCI_REG_CONFIG_DATA	0x24
#define RT2880_PCI_REG_MEMBASE		0x28
#define RT2880_PCI_REG_IOBASE		0x2c
#define RT2880_PCI_REG_ID		0x30
#define RT2880_PCI_REG_CLASS		0x34
#define RT2880_PCI_REG_SUBID		0x38
#define RT2880_PCI_REG_ARBCTL		0x80

static void __iomem *rt2880_pci_base;
static DEFINE_SPINLOCK(rt2880_pci_lock);

static u32 rt2880_pci_reg_read(u32 reg)
{
	return readl(rt2880_pci_base + reg);
}

static void rt2880_pci_reg_write(u32 val, u32 reg)
{
	writel(val, rt2880_pci_base + reg);
}

static inline u32 rt2880_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 int rt2880_pci_config_read(struct pci_bus *bus, unsigned int devfn,
				  int where, int size, u32 *val)
{
	unsigned long flags;
	u32 address;
	u32 data;

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

	spin_lock_irqsave(&rt2880_pci_lock, flags);
	rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
	data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
	spin_unlock_irqrestore(&rt2880_pci_lock, flags);

	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 rt2880_pci_config_write(struct pci_bus *bus, unsigned int devfn,
				   int where, int size, u32 val)
{
	unsigned long flags;
	u32 address;
	u32 data;

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

	spin_lock_irqsave(&rt2880_pci_lock, flags);
	rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
	data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);

	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;
	}

	rt2880_pci_reg_write(data, RT2880_PCI_REG_CONFIG_DATA);
	spin_unlock_irqrestore(&rt2880_pci_lock, flags);

	return PCIBIOS_SUCCESSFUL;
}

static struct pci_ops rt2880_pci_ops = {
	.read	= rt2880_pci_config_read,
	.write	= rt2880_pci_config_write,
};

static struct resource rt2880_pci_mem_resource = {
	.name	= "PCI MEM space",
	.start	= RT2880_PCI_MEM_BASE,
	.end	= RT2880_PCI_MEM_BASE + RT2880_PCI_MEM_SIZE - 1,
	.flags	= IORESOURCE_MEM,
};

static struct resource rt2880_pci_io_resource = {
	.name	= "PCI IO space",
	.start	= RT2880_PCI_IO_BASE,
	.end	= RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1,
	.flags	= IORESOURCE_IO,
};

static struct pci_controller rt2880_pci_controller = {
	.pci_ops	= &rt2880_pci_ops,
	.mem_resource	= &rt2880_pci_mem_resource,
	.io_resource	= &rt2880_pci_io_resource,
};

static inline u32 rt2880_pci_read_u32(unsigned long reg)
{
	unsigned long flags;
	u32 address;
	u32 ret;

	address = rt2880_pci_get_cfgaddr(0, 0, 0, reg);

	spin_lock_irqsave(&rt2880_pci_lock, flags);
	rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
	ret = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
	spin_unlock_irqrestore(&rt2880_pci_lock, flags);

	return ret;
}

static inline void rt2880_pci_write_u32(unsigned long reg, u32 val)
{
	unsigned long flags;
	u32 address;

	address = rt2880_pci_get_cfgaddr(0, 0, 0, reg);

	spin_lock_irqsave(&rt2880_pci_lock, flags);
	rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
	rt2880_pci_reg_write(val, RT2880_PCI_REG_CONFIG_DATA);
	spin_unlock_irqrestore(&rt2880_pci_lock, flags);
}

int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
	u16 cmd;
	int irq = -1;

	if (dev->bus->number != 0)
		return irq;

	switch (PCI_SLOT(dev->devfn)) {
	case 0x00:
		rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
		(void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);
		break;
	case 0x11:
		irq = RT288X_CPU_IRQ_PCI;
		break;
	default:
		pr_err("%s:%s[%d] trying to alloc unknown pci irq\n",
		       __FILE__, __func__, __LINE__);
		BUG();
		break;
	}

	pci_write_config_byte((struct pci_dev *) dev,
		PCI_CACHE_LINE_SIZE, 0x14);
	pci_write_config_byte((struct pci_dev *) dev, PCI_LATENCY_TIMER, 0xFF);
	pci_read_config_word((struct pci_dev *) dev, PCI_COMMAND, &cmd);
	cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
		PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK |
		PCI_COMMAND_SERR | PCI_COMMAND_WAIT | PCI_COMMAND_PARITY;
	pci_write_config_word((struct pci_dev *) dev, PCI_COMMAND, cmd);
	pci_write_config_byte((struct pci_dev *) dev, PCI_INTERRUPT_LINE,
			      dev->irq);
	return irq;
}

static int rt288x_pci_probe(struct platform_device *pdev)
{
	void __iomem *io_map_base;

	rt2880_pci_base = ioremap(RT2880_PCI_BASE, PAGE_SIZE);

	io_map_base = ioremap(RT2880_PCI_IO_BASE, RT2880_PCI_IO_SIZE);
	rt2880_pci_controller.io_map_base = (unsigned long) io_map_base;
	set_io_port_base((unsigned long) io_map_base);

	ioport_resource.start = RT2880_PCI_IO_BASE;
	ioport_resource.end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1;

	rt2880_pci_reg_write(0, RT2880_PCI_REG_PCICFG_ADDR);
	udelay(1);

	rt2880_pci_reg_write(0x79, RT2880_PCI_REG_ARBCTL);
	rt2880_pci_reg_write(0x07FF0001, RT2880_PCI_REG_BAR0SETUP_ADDR);
	rt2880_pci_reg_write(RT2880_PCI_MEM_BASE, RT2880_PCI_REG_MEMBASE);
	rt2880_pci_reg_write(RT2880_PCI_IO_BASE, RT2880_PCI_REG_IOBASE);
	rt2880_pci_reg_write(0x08000000, RT2880_PCI_REG_IMBASEBAR0_ADDR);
	rt2880_pci_reg_write(0x08021814, RT2880_PCI_REG_ID);
	rt2880_pci_reg_write(0x00800001, RT2880_PCI_REG_CLASS);
	rt2880_pci_reg_write(0x28801814, RT2880_PCI_REG_SUBID);
	rt2880_pci_reg_write(0x000c0000, RT2880_PCI_REG_PCIMSK_ADDR);

	rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
	(void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);

	rt2880_pci_controller.of_node = pdev->dev.of_node;

	register_pci_controller(&rt2880_pci_controller);
	return 0;
}

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

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

static struct platform_driver rt288x_pci_driver = {
	.probe = rt288x_pci_probe,
	.driver = {
		.name = "rt288x-pci",
		.of_match_table = rt288x_pci_match,
	},
};

int __init pcibios_init(void)
{
	int ret = platform_driver_register(&rt288x_pci_driver);

	if (ret)
		pr_info("rt288x-pci: Error registering platform driver!");

	return ret;
}

arch_initcall(pcibios_init);
