// SPDX-License-Identifier: GPL-2.0+
/*
 * PLDA XpressRich PCIe host controller common functions.
 *
 * Copyright (C) 2023 StarFive Technology Co., Ltd.
 *
 */

#include <clk.h>
#include <dm.h>
#include <pci.h>
#include <pci_ids.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <dm/device_compat.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
#include "pcie_plda_common.h"

static bool plda_pcie_addr_valid(struct pcie_plda *plda, pci_dev_t bdf)
{
	/*
	 * Single device limitation.
	 * PCIe controller contain HW issue that secondary bus of
	 * host bridge emumerate duplicate devices.
	 * Only can access device 0 in secondary bus.
	 */
	if (PCI_BUS(bdf) == plda->sec_busno && PCI_DEV(bdf) > 0)
		return false;

	return true;
}

static int plda_pcie_conf_address(const struct udevice *udev, pci_dev_t bdf,
				  uint offset, void **paddr)
{
	struct pcie_plda *priv = dev_get_priv(udev);
	int where = PCIE_ECAM_OFFSET(PCI_BUS(bdf) - dev_seq(udev),
				     PCI_DEV(bdf), PCI_FUNC(bdf), offset);

	if (!plda_pcie_addr_valid(priv, bdf))
		return -ENODEV;

	*paddr = (void *)(priv->cfg_base + where);
	return 0;
}

int plda_pcie_config_read(const struct udevice *udev, pci_dev_t bdf,
			  uint offset, ulong *valuep,
			  enum pci_size_t size)
{
	return pci_generic_mmap_read_config(udev, plda_pcie_conf_address,
					    bdf, offset, valuep, size);
}

int plda_pcie_config_write(struct udevice *udev, pci_dev_t bdf,
			   uint offset, ulong value,
			   enum pci_size_t size)
{
	struct pcie_plda *priv = dev_get_priv(udev);
	int ret;

	ret = pci_generic_mmap_write_config(udev, plda_pcie_conf_address,
					    bdf, offset, value, size);

	/* record secondary bus number */
	if (!ret && PCI_BUS(bdf) == dev_seq(udev) &&
	    PCI_DEV(bdf) == 0 && PCI_FUNC(bdf) == 0 &&
	    (offset == PCI_SECONDARY_BUS ||
	    (offset == PCI_PRIMARY_BUS && size != PCI_SIZE_8))) {
		priv->sec_busno =
			((offset == PCI_PRIMARY_BUS) ? (value >> 8) : value) & 0xff;
		priv->sec_busno += dev_seq(udev);
		debug("Secondary bus number was changed to %d\n",
		      priv->sec_busno);
	}
	return ret;
}

int plda_pcie_set_atr_entry(struct pcie_plda *plda, phys_addr_t src_addr,
			    phys_addr_t trsl_addr, phys_size_t window_size,
			    int trsl_param)
{
	void __iomem *base =
		plda->reg_base + XR3PCI_ATR_AXI4_SLV0;

	/* Support AXI4 Slave 0 Address Translation Tables 0-7. */
	if (plda->atr_table_num >= XR3PCI_ATR_MAX_TABLE_NUM) {
		dev_err(plda->dev, "ATR table number %d exceeds max num\n",
			plda->atr_table_num);
		return -EINVAL;
	}
	base +=  XR3PCI_ATR_TABLE_OFFSET * plda->atr_table_num;
	plda->atr_table_num++;

	/*
	 * X3PCI_ATR_SRC_ADDR_LOW:
	 *   - bit 0: enable entry,
	 *   - bits 1-6: ATR window size: total size in bytes: 2^(ATR_WSIZE + 1)
	 *   - bits 7-11: reserved
	 *   - bits 12-31: start of source address
	 */
	writel((lower_32_bits(src_addr) & XR3PCI_ATR_SRC_ADDR_MASK) |
			(fls(window_size) - 1) << XR3PCI_ATR_SRC_WIN_SIZE_SHIFT | 1,
			base + XR3PCI_ATR_SRC_ADDR_LOW);
	writel(upper_32_bits(src_addr), base + XR3PCI_ATR_SRC_ADDR_HIGH);
	writel((lower_32_bits(trsl_addr) & XR3PCI_ATR_TRSL_ADDR_MASK),
	       base + XR3PCI_ATR_TRSL_ADDR_LOW);
	writel(upper_32_bits(trsl_addr), base + XR3PCI_ATR_TRSL_ADDR_HIGH);
	writel(trsl_param, base + XR3PCI_ATR_TRSL_PARAM);

	dev_dbg(plda->dev, "ATR entry: 0x%010llx %s 0x%010llx [0x%010llx] (param: 0x%06x)\n",
		src_addr, (trsl_param & XR3PCI_ATR_TRSL_DIR) ? "<-" : "->",
		trsl_addr, (u64)window_size, trsl_param);
	return 0;
}
