// SPDX-License-Identifier: GPL-2.0
/*
 * Phytium PCIE host driver
 *
 * Heavily based on drivers/pci/pcie_xilinx.c
 *
 * Copyright (C) 2019
 */

#include <common.h>
#include <dm.h>
#include <pci.h>
#include <asm/io.h>

/**
 * struct phytium_pcie - phytium PCIe controller state
 * @cfg_base: The base address of memory mapped configuration space
 */
struct phytium_pcie {
	void *cfg_base;
};

/*
 * phytium_pci_skip_dev()
 * @parent: Identifies the PCIe device to access
 *
 * Checks whether the parent of the PCIe device is bridge
 *
 * Return: true if it is bridge, else false.
 */
static int phytium_pci_skip_dev(pci_dev_t parent)
{
	unsigned char pos, id;
	unsigned long addr = 0x40000000;
	unsigned short capreg;
	unsigned char port_type;

	addr += PCI_BUS(parent) << 20;
	addr += PCI_DEV(parent) << 15;
	addr += PCI_FUNC(parent) << 12;

	pos = 0x34;
	while (1) {
		pos = readb(addr + pos);
		if (pos < 0x40)
			break;
		pos &= ~3;
		id = readb(addr + pos);
		if (id == 0xff)
			break;
		if (id == 0x10) {
			capreg = readw(addr + pos + 2);
			port_type = (capreg >> 4) & 0xf;
			if (port_type == 0x6 || port_type == 0x4)
				return 1;
			else
				return 0;
		}
		pos += 1;
	}
	return 0;
}

/**
 * pci_phytium_conf_address() - Calculate the address of a config access
 * @bus: Pointer to the PCI bus
 * @bdf: Identifies the PCIe device to access
 * @offset: The offset into the device's configuration space
 * @paddress: Pointer to the pointer to write the calculates address to
 *
 * Calculates the address that should be accessed to perform a PCIe
 * configuration space access for a given device identified by the PCIe
 * controller device @pcie and the bus, device & function numbers in @bdf. If
 * access to the device is not valid then the function will return an error
 * code. Otherwise the address to access will be written to the pointer pointed
 * to by @paddress.
 */
static int pci_phytium_conf_address(const struct udevice *bus, pci_dev_t bdf,
				    uint offset, void **paddress)
{
	struct phytium_pcie *pcie = dev_get_priv(bus);
	void *addr;
	pci_dev_t bdf_parent;

	unsigned int bus_no = PCI_BUS(bdf);
	unsigned int dev_no = PCI_DEV(bdf);

	bdf_parent = PCI_BDF((bus_no - 1), 0, 0);

	addr = pcie->cfg_base;
	addr += PCI_BUS(bdf) << 20;
	addr += PCI_DEV(bdf) << 15;
	addr += PCI_FUNC(bdf) << 12;

	if (bus_no > 0 && dev_no > 0) {
		if ((readb(addr + PCI_HEADER_TYPE) & 0x7f) !=
				PCI_HEADER_TYPE_BRIDGE)
			return -ENODEV;
		if (phytium_pci_skip_dev(bdf_parent))
			return -ENODEV;
	}

	addr += offset;
	*paddress = addr;

	return 0;
}

/**
 * pci_phytium_read_config() - Read from configuration space
 * @bus: Pointer to the PCI bus
 * @bdf: Identifies the PCIe device to access
 * @offset: The offset into the device's configuration space
 * @valuep: A pointer at which to store the read value
 * @size: Indicates the size of access to perform
 *
 * Read a value of size @size from offset @offset within the configuration
 * space of the device identified by the bus, device & function numbers in @bdf
 * on the PCI bus @bus.
 */
static int pci_phytium_read_config(const struct udevice *bus, pci_dev_t bdf,
				   uint offset, ulong *valuep,
				   enum pci_size_t size)
{
	return pci_generic_mmap_read_config(bus, pci_phytium_conf_address,
					    bdf, offset, valuep, size);
}

/**
 * pci_phytium_write_config() - Write to configuration space
 * @bus: Pointer to the PCI bus
 * @bdf: Identifies the PCIe device to access
 * @offset: The offset into the device's configuration space
 * @value: The value to write
 * @size: Indicates the size of access to perform
 *
 * Write the value @value of size @size from offset @offset within the
 * configuration space of the device identified by the bus, device & function
 * numbers in @bdf on the PCI bus @bus.
 */
static int pci_phytium_write_config(struct udevice *bus, pci_dev_t bdf,
				    uint offset, ulong value,
				    enum pci_size_t size)
{
	return pci_generic_mmap_write_config(bus, pci_phytium_conf_address,
					     bdf, offset, value, size);
}

/**
 * pci_phytium_ofdata_to_platdata() - Translate from DT to device state
 * @dev: A pointer to the device being operated on
 *
 * Translate relevant data from the device tree pertaining to device @dev into
 * state that the driver will later make use of. This state is stored in the
 * device's private data structure.
 *
 * Return: 0 on success, else -EINVAL
 */
static int pci_phytium_ofdata_to_platdata(struct udevice *dev)
{
	struct phytium_pcie *pcie = dev_get_priv(dev);
	struct fdt_resource reg_res;

	DECLARE_GLOBAL_DATA_PTR;

	int err;

	err = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev), "reg",
			       0, &reg_res);
	if (err < 0) {
		pr_err("\"reg\" resource not found\n");
		return err;
	}

	pcie->cfg_base = map_physmem(reg_res.start,
				     fdt_resource_size(&reg_res),
				     MAP_NOCACHE);

	return 0;
}

static const struct dm_pci_ops pci_phytium_ops = {
	.read_config	= pci_phytium_read_config,
	.write_config	= pci_phytium_write_config,
};

static const struct udevice_id pci_phytium_ids[] = {
	{ .compatible = "phytium,pcie-host-1.0" },
	{ }
};

U_BOOT_DRIVER(pci_phytium) = {
	.name			= "pci_phytium",
	.id			= UCLASS_PCI,
	.of_match		= pci_phytium_ids,
	.ops			= &pci_phytium_ops,
	.ofdata_to_platdata	= pci_phytium_ofdata_to_platdata,
	.priv_auto_alloc_size	= sizeof(struct phytium_pcie),
};
