// SPDX-License-Identifier: GPL-2.0
/*
 * (C) Copyright 2019
 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
 *
 */
#include <asm/bitops.h>
#include <pci.h>
#include <dm.h>
#include <asm/fsl_law.h>

struct mpc85xx_pci_priv {
	void __iomem		*cfg_addr;
	void __iomem		*cfg_data;
};

static int mpc85xx_pci_dm_read_config(const struct udevice *dev, pci_dev_t bdf,
				      uint offset, ulong *value,
				      enum pci_size_t size)
{
	struct mpc85xx_pci_priv *priv = dev_get_priv(dev);
	u32 addr;

	if (offset > 0xff) {
		*value = pci_get_ff(size);
		return 0;
	}

	/* Skip mpc85xx PCI controller's ATMU inbound registers */
	if (PCI_BUS(bdf) == 0 && PCI_DEV(bdf) == 0 && PCI_FUNC(bdf) == 0 &&
	    (offset & ~3) >= PCI_BASE_ADDRESS_0 && (offset & ~3) <= PCI_BASE_ADDRESS_5) {
		*value = 0;
		return 0;
	}

	addr = PCI_CONF1_ADDRESS(PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), offset);
	out_be32(priv->cfg_addr, addr);
	sync();

	switch (size) {
	case PCI_SIZE_8:
		*value = in_8(priv->cfg_data + (offset & 3));
		break;
	case PCI_SIZE_16:
		*value = in_le16(priv->cfg_data + (offset & 2));
		break;
	case PCI_SIZE_32:
		*value = in_le32(priv->cfg_data);
		break;
	}

	return 0;
}

static int mpc85xx_pci_dm_write_config(struct udevice *dev, pci_dev_t bdf,
				       uint offset, ulong value,
				       enum pci_size_t size)
{
	struct mpc85xx_pci_priv *priv = dev_get_priv(dev);
	u32 addr;

	if (offset > 0xff)
		return 0;

	/* Skip mpc85xx PCI controller's ATMU inbound registers */
	if (PCI_BUS(bdf) == 0 && PCI_DEV(bdf) == 0 && PCI_FUNC(bdf) == 0 &&
	    (offset & ~3) >= PCI_BASE_ADDRESS_0 && (offset & ~3) <= PCI_BASE_ADDRESS_5)
		return 0;

	addr = PCI_CONF1_ADDRESS(PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), offset);
	out_be32(priv->cfg_addr, addr);
	sync();

	switch (size) {
	case PCI_SIZE_8:
		out_8(priv->cfg_data + (offset & 3), value);
		break;
	case PCI_SIZE_16:
		out_le16(priv->cfg_data + (offset & 2), value);
		break;
	case PCI_SIZE_32:
		out_le32(priv->cfg_data, value);
		break;
	}
	sync();

	return 0;
}

#ifdef CONFIG_FSL_LAW
static int
mpc85xx_pci_dm_setup_laws(struct pci_region *io, struct pci_region *mem,
			  struct pci_region *pre)
{
	/*
	 * Unfortunately we have defines for this addresse,
	 * as we have to setup the TLB, and at this stage
	 * we have no access to DT ... may we check here
	 * if the value in the define is the same ?
	 */
	if (mem)
		set_next_law(mem->phys_start, law_size_bits(mem->size),
			     LAW_TRGT_IF_PCI);
	if (io)
		set_next_law(io->phys_start, law_size_bits(io->size),
			     LAW_TRGT_IF_PCI);
	if (pre)
		set_next_law(pre->phys_start, law_size_bits(pre->size),
			     LAW_TRGT_IF_PCI);

	return 0;
}
#endif

static int mpc85xx_pci_dm_probe(struct udevice *dev)
{
	struct mpc85xx_pci_priv *priv = dev_get_priv(dev);
	struct pci_region *io;
	struct pci_region *mem;
	struct pci_region *pre;
	int count;
	ccsr_pcix_t *pcix;

	count = pci_get_regions(dev, &io, &mem, &pre);
	if (count != 2) {
		printf("%s: wrong count of regions %d only 2 allowed\n",
		       __func__, count);
		return -EINVAL;
	}

#ifdef CONFIG_FSL_LAW
	mpc85xx_pci_dm_setup_laws(io, mem, pre);
#endif

	pcix = priv->cfg_addr;
	/* BAR 1: memory */
	out_be32(&pcix->potar1, mem->bus_start >> 12);
	out_be32(&pcix->potear1, (u64)mem->bus_start >> 44);
	out_be32(&pcix->powbar1, mem->phys_start >> 12);
	out_be32(&pcix->powbear1, (u64)mem->phys_start >> 44);
	out_be32(&pcix->powar1, (POWAR_EN | POWAR_MEM_READ |
		 POWAR_MEM_WRITE | (__ilog2(mem->size) - 1)));

	/* BAR 1: IO */
	out_be32(&pcix->potar2, io->bus_start >> 12);
	out_be32(&pcix->potear2, (u64)io->bus_start >> 44);
	out_be32(&pcix->powbar2, io->phys_start >> 12);
	out_be32(&pcix->powbear2, (u64)io->phys_start >> 44);
	out_be32(&pcix->powar2, (POWAR_EN | POWAR_IO_READ |
		 POWAR_IO_WRITE | (__ilog2(io->size) - 1)));

	out_be32(&pcix->pitar1, 0);
	out_be32(&pcix->piwbar1, 0);
	out_be32(&pcix->piwar1, (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
		 PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G));

	out_be32(&pcix->powar3, 0);
	out_be32(&pcix->powar4, 0);
	out_be32(&pcix->piwar2, 0);
	out_be32(&pcix->piwar3, 0);

	return 0;
}

static int mpc85xx_pci_dm_remove(struct udevice *dev)
{
	return 0;
}

static int mpc85xx_pci_of_to_plat(struct udevice *dev)
{
	struct mpc85xx_pci_priv *priv = dev_get_priv(dev);
	fdt_addr_t addr;

	addr = devfdt_get_addr_index(dev, 0);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;
	priv->cfg_addr = (void __iomem *)map_physmem(addr, 0, MAP_NOCACHE);
	priv->cfg_data = (void __iomem *)((ulong)priv->cfg_addr + 4);

	return 0;
}

static const struct dm_pci_ops mpc85xx_pci_ops = {
	.read_config	= mpc85xx_pci_dm_read_config,
	.write_config	= mpc85xx_pci_dm_write_config,
};

static const struct udevice_id mpc85xx_pci_ids[] = {
	{ .compatible = "fsl,mpc8540-pci" },
	{ }
};

U_BOOT_DRIVER(mpc85xx_pci) = {
	.name			= "mpc85xx_pci",
	.id			= UCLASS_PCI,
	.of_match		= mpc85xx_pci_ids,
	.ops			= &mpc85xx_pci_ops,
	.probe			= mpc85xx_pci_dm_probe,
	.remove			= mpc85xx_pci_dm_remove,
	.of_to_plat	= mpc85xx_pci_of_to_plat,
	.priv_auto	= sizeof(struct mpc85xx_pci_priv),
};
