// SPDX-License-Identifier: GPL-2.0+ OR X11
/*
 * Copyright 2019 NXP
 *
 * PCIe DM U-Boot driver for Freescale PowerPC SoCs
 * Author: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
 */

#include <common.h>
#include <dm.h>
#include <malloc.h>
#include <mapmem.h>
#include <pci.h>
#include <asm/fsl_pci.h>
#include <asm/fsl_serdes.h>
#include <asm/io.h>
#include <linux/delay.h>
#include "pcie_fsl.h"
#include <dm/device_compat.h>

LIST_HEAD(fsl_pcie_list);

static int fsl_pcie_link_up(struct fsl_pcie *pcie);

static int fsl_pcie_addr_valid(struct fsl_pcie *pcie, pci_dev_t bdf)
{
	struct udevice *bus = pcie->bus;

	if (!pcie->enabled)
		return -ENXIO;

	if (PCI_BUS(bdf) < bus->seq)
		return -EINVAL;

	if (PCI_BUS(bdf) > bus->seq && (!fsl_pcie_link_up(pcie) || pcie->mode))
		return -EINVAL;

	if (PCI_BUS(bdf) == bus->seq && (PCI_DEV(bdf) > 0 || PCI_FUNC(bdf) > 0))
		return -EINVAL;

	if (PCI_BUS(bdf) == (bus->seq + 1) && (PCI_DEV(bdf) > 0))
		return -EINVAL;

	return 0;
}

static int fsl_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
				uint offset, ulong *valuep,
				enum pci_size_t size)
{
	struct fsl_pcie *pcie = dev_get_priv(bus);
	ccsr_fsl_pci_t *regs = pcie->regs;
	u32 val;

	if (fsl_pcie_addr_valid(pcie, bdf)) {
		*valuep = pci_get_ff(size);
		return 0;
	}

	bdf = bdf - PCI_BDF(bus->seq, 0, 0);
	val = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000;
	out_be32(&regs->cfg_addr, val);

	sync();

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

	return 0;
}

static int fsl_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
				 uint offset, ulong value,
				 enum pci_size_t size)
{
	struct fsl_pcie *pcie = dev_get_priv(bus);
	ccsr_fsl_pci_t *regs = pcie->regs;
	u32 val;
	u8 val_8;
	u16 val_16;
	u32 val_32;

	if (fsl_pcie_addr_valid(pcie, bdf))
		return 0;

	bdf = bdf - PCI_BDF(bus->seq, 0, 0);
	val = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000;
	out_be32(&regs->cfg_addr, val);

	sync();

	switch (size) {
	case PCI_SIZE_8:
		val_8 = value;
		out_8((u8 *)&regs->cfg_data + (offset & 3), val_8);
		break;
	case PCI_SIZE_16:
		val_16 = value;
		out_le16((u16 *)((u8 *)&regs->cfg_data + (offset & 2)), val_16);
		break;
	case PCI_SIZE_32:
		val_32 = value;
		out_le32(&regs->cfg_data, val_32);
		break;
	}

	return 0;
}

static int fsl_pcie_hose_read_config(struct fsl_pcie *pcie, uint offset,
				     ulong *valuep, enum pci_size_t size)
{
	int ret;
	struct udevice *bus = pcie->bus;

	ret = fsl_pcie_read_config(bus, PCI_BDF(bus->seq, 0, 0),
				   offset, valuep, size);

	return ret;
}

static int fsl_pcie_hose_write_config(struct fsl_pcie *pcie, uint offset,
				      ulong value, enum pci_size_t size)
{
	struct udevice *bus = pcie->bus;

	return fsl_pcie_write_config(bus, PCI_BDF(bus->seq, 0, 0),
				     offset, value, size);
}

static int fsl_pcie_hose_read_config_byte(struct fsl_pcie *pcie, uint offset,
					  u8 *valuep)
{
	ulong val;
	int ret;

	ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_8);
	*valuep = val;

	return ret;
}

static int fsl_pcie_hose_read_config_word(struct fsl_pcie *pcie, uint offset,
					  u16 *valuep)
{
	ulong val;
	int ret;

	ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_16);
	*valuep = val;

	return ret;
}

static int fsl_pcie_hose_read_config_dword(struct fsl_pcie *pcie, uint offset,
					   u32 *valuep)
{
	ulong val;
	int ret;

	ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_32);
	*valuep = val;

	return ret;
}

static int fsl_pcie_hose_write_config_byte(struct fsl_pcie *pcie, uint offset,
					   u8 value)
{
	return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_8);
}

static int fsl_pcie_hose_write_config_word(struct fsl_pcie *pcie, uint offset,
					   u16 value)
{
	return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_16);
}

static int fsl_pcie_hose_write_config_dword(struct fsl_pcie *pcie, uint offset,
					    u32 value)
{
	return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_32);
}

static int fsl_pcie_link_up(struct fsl_pcie *pcie)
{
	ccsr_fsl_pci_t *regs = pcie->regs;
	u16 ltssm;

	if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
		ltssm = (in_be32(&regs->pex_csr0)
			& PEX_CSR0_LTSSM_MASK) >> PEX_CSR0_LTSSM_SHIFT;
		return ltssm == LTSSM_L0_REV3;
	}

	fsl_pcie_hose_read_config_word(pcie, PCI_LTSSM, &ltssm);

	return ltssm == LTSSM_L0;
}

static bool fsl_pcie_is_agent(struct fsl_pcie *pcie)
{
	u8 header_type;

	fsl_pcie_hose_read_config_byte(pcie, PCI_HEADER_TYPE, &header_type);

	return (header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL;
}

static int fsl_pcie_setup_law(struct fsl_pcie *pcie)
{
	struct pci_region *io, *mem, *pref;

	pci_get_regions(pcie->bus, &io, &mem, &pref);

	if (mem)
		set_next_law(mem->phys_start,
			     law_size_bits(mem->size),
			     pcie->law_trgt_if);

	if (io)
		set_next_law(io->phys_start,
			     law_size_bits(io->size),
			     pcie->law_trgt_if);

	return 0;
}

static void fsl_pcie_config_ready(struct fsl_pcie *pcie)
{
	ccsr_fsl_pci_t *regs = pcie->regs;

	if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
		setbits_be32(&regs->config, FSL_PCIE_V3_CFG_RDY);
		return;
	}

	fsl_pcie_hose_write_config_byte(pcie, FSL_PCIE_CFG_RDY, 0x1);
}

static int fsl_pcie_setup_outbound_win(struct fsl_pcie *pcie, int idx,
				       int type, u64 phys, u64 bus_addr,
				       pci_size_t size)
{
	ccsr_fsl_pci_t *regs = pcie->regs;
	pot_t *po = &regs->pot[idx];
	u32 war, sz;

	if (idx < 0)
		return -EINVAL;

	out_be32(&po->powbar, phys >> 12);
	out_be32(&po->potar, bus_addr >> 12);
#ifdef CONFIG_SYS_PCI_64BIT
	out_be32(&po->potear, bus_addr >> 44);
#else
	out_be32(&po->potear, 0);
#endif

	sz = (__ilog2_u64((u64)size) - 1);
	war = POWAR_EN | sz;

	if (type == PCI_REGION_IO)
		war |= POWAR_IO_READ | POWAR_IO_WRITE;
	else
		war |= POWAR_MEM_READ | POWAR_MEM_WRITE;

	out_be32(&po->powar, war);

	return 0;
}

static int fsl_pcie_setup_inbound_win(struct fsl_pcie *pcie, int idx,
				      bool pf, u64 phys, u64 bus_addr,
				      pci_size_t size)
{
	ccsr_fsl_pci_t *regs = pcie->regs;
	pit_t *pi = &regs->pit[idx];
	u32 sz = (__ilog2_u64(size) - 1);
	u32 flag = PIWAR_LOCAL;

	if (idx < 0)
		return -EINVAL;

	out_be32(&pi->pitar, phys >> 12);
	out_be32(&pi->piwbar, bus_addr >> 12);

#ifdef CONFIG_SYS_PCI_64BIT
	out_be32(&pi->piwbear, bus_addr >> 44);
#else
	out_be32(&pi->piwbear, 0);
#endif

#ifdef CONFIG_SYS_FSL_ERRATUM_A005434
	flag = 0;
#endif

	flag |= PIWAR_EN | PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
	if (pf)
		flag |= PIWAR_PF;
	out_be32(&pi->piwar, flag | sz);

	return 0;
}

static int fsl_pcie_setup_outbound_wins(struct fsl_pcie *pcie)
{
	struct pci_region *io, *mem, *pref;
	int idx = 1; /* skip 0 */

	pci_get_regions(pcie->bus, &io, &mem, &pref);

	if (io)
		/* ATU : OUTBOUND : IO */
		fsl_pcie_setup_outbound_win(pcie, idx++,
					    PCI_REGION_IO,
					    io->phys_start,
					    io->bus_start,
					    io->size);

	if (mem)
		/* ATU : OUTBOUND : MEM */
		fsl_pcie_setup_outbound_win(pcie, idx++,
					    PCI_REGION_MEM,
					    mem->phys_start,
					    mem->bus_start,
					    mem->size);
	return 0;
}

static int fsl_pcie_setup_inbound_wins(struct fsl_pcie *pcie)
{
	phys_addr_t phys_start = CONFIG_SYS_PCI_MEMORY_PHYS;
	pci_addr_t bus_start = CONFIG_SYS_PCI_MEMORY_BUS;
	u64 sz = min((u64)gd->ram_size, (1ull << 32));
	pci_size_t pci_sz;
	int idx;

	if (pcie->block_rev >= PEX_IP_BLK_REV_2_2)
		idx = 2;
	else
		idx = 3;

	pci_sz = 1ull << __ilog2_u64(sz);

	dev_dbg(pcie->bus, "R0 bus_start: %llx phys_start: %llx size: %llx\n",
		(u64)bus_start, (u64)phys_start, (u64)sz);

	/* if we aren't an exact power of two match, pci_sz is smaller
	 * round it up to the next power of two.  We report the actual
	 * size to pci region tracking.
	 */
	if (pci_sz != sz)
		sz = 2ull << __ilog2_u64(sz);

	fsl_pcie_setup_inbound_win(pcie, idx--, true,
				   CONFIG_SYS_PCI_MEMORY_PHYS,
				   CONFIG_SYS_PCI_MEMORY_BUS, sz);
#if defined(CONFIG_PHYS_64BIT) && defined(CONFIG_SYS_PCI_64BIT)
	/*
	 * On 64-bit capable systems, set up a mapping for all of DRAM
	 * in high pci address space.
	 */
	pci_sz = 1ull << __ilog2_u64(gd->ram_size);
	/* round up to the next largest power of two */
	if (gd->ram_size > pci_sz)
		pci_sz = 1ull << (__ilog2_u64(gd->ram_size) + 1);

	dev_dbg(pcie->bus, "R64 bus_start: %llx phys_start: %llx size: %llx\n",
		(u64)CONFIG_SYS_PCI64_MEMORY_BUS,
		(u64)CONFIG_SYS_PCI_MEMORY_PHYS, (u64)pci_sz);

	fsl_pcie_setup_inbound_win(pcie, idx--, true,
				   CONFIG_SYS_PCI_MEMORY_PHYS,
				   CONFIG_SYS_PCI64_MEMORY_BUS, pci_sz);
#endif

	return 0;
}

static int fsl_pcie_init_atmu(struct fsl_pcie *pcie)
{
	fsl_pcie_setup_outbound_wins(pcie);
	fsl_pcie_setup_inbound_wins(pcie);

	return 0;
}

static int fsl_pcie_init_port(struct fsl_pcie *pcie)
{
	ccsr_fsl_pci_t *regs = pcie->regs;
	u32 val_32;
	u16 val_16;

	fsl_pcie_init_atmu(pcie);

#ifdef CONFIG_FSL_PCIE_DISABLE_ASPM
	val_32 = 0;
	fsl_pcie_hose_read_config_dword(pcie, PCI_LCR, &val_32);
	val_32 &= ~0x03;
	fsl_pcie_hose_write_config_dword(pcie, PCI_LCR, val_32);
	udelay(1);
#endif

#ifdef CONFIG_FSL_PCIE_RESET
	u16 ltssm;
	int i;

	if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
		/* assert PCIe reset */
		setbits_be32(&regs->pdb_stat, 0x08000000);
		(void)in_be32(&regs->pdb_stat);
		udelay(1000);
		/* clear PCIe reset */
		clrbits_be32(&regs->pdb_stat, 0x08000000);
		asm("sync;isync");
		for (i = 0; i < 100 && !fsl_pcie_link_up(pcie); i++)
			udelay(1000);
	} else {
		fsl_pcie_hose_read_config_word(pcie, PCI_LTSSM, &ltssm);
		if (ltssm == 1) {
			/* assert PCIe reset */
			setbits_be32(&regs->pdb_stat, 0x08000000);
			(void)in_be32(&regs->pdb_stat);
			udelay(100);
			/* clear PCIe reset */
			clrbits_be32(&regs->pdb_stat, 0x08000000);
			asm("sync;isync");
			for (i = 0; i < 100 &&
			     !fsl_pcie_link_up(pcie); i++)
				udelay(1000);
		}
	}
#endif

#ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003
	if (!fsl_pcie_link_up(pcie)) {
		serdes_corenet_t *srds_regs;

		srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
		val_32 = in_be32(&srds_regs->srdspccr0);

		if ((val_32 >> 28) == 3) {
			int i;

			out_be32(&srds_regs->srdspccr0, 2 << 28);
			setbits_be32(&regs->pdb_stat, 0x08000000);
			in_be32(&regs->pdb_stat);
			udelay(100);
			clrbits_be32(&regs->pdb_stat, 0x08000000);
			asm("sync;isync");
			for (i = 0; i < 100 && !fsl_pcie_link_up(pcie); i++)
				udelay(1000);
		}
	}
#endif

	/*
	 * The Read-Only Write Enable bit defaults to 1 instead of 0.
	 * Set to 0 to protect the read-only registers.
	 */
#ifdef CONFIG_SYS_FSL_ERRATUM_A007815
	clrbits_be32(&regs->dbi_ro_wr_en, 0x01);
#endif

	/*
	 * Enable All Error Interrupts except
	 * - Master abort (pci)
	 * - Master PERR (pci)
	 * - ICCA (PCIe)
	 */
	out_be32(&regs->peer, ~0x20140);

	/* set URR, FER, NFER (but not CER) */
	fsl_pcie_hose_read_config_dword(pcie, PCI_DCR, &val_32);
	val_32 |= 0xf000e;
	fsl_pcie_hose_write_config_dword(pcie, PCI_DCR, val_32);

	/* Clear all error indications */
	out_be32(&regs->pme_msg_det, 0xffffffff);
	out_be32(&regs->pme_msg_int_en, 0xffffffff);
	out_be32(&regs->pedr, 0xffffffff);

	fsl_pcie_hose_read_config_word(pcie, PCI_DSR, &val_16);
	if (val_16)
		fsl_pcie_hose_write_config_word(pcie, PCI_DSR, 0xffff);

	fsl_pcie_hose_read_config_word(pcie, PCI_SEC_STATUS, &val_16);
	if (val_16)
		fsl_pcie_hose_write_config_word(pcie, PCI_SEC_STATUS, 0xffff);

	return 0;
}

static int fsl_pcie_fixup_classcode(struct fsl_pcie *pcie)
{
	ccsr_fsl_pci_t *regs = pcie->regs;
	u32 classcode_reg;
	u32 val;

	if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
		classcode_reg = PCI_CLASS_REVISION;
		setbits_be32(&regs->dbi_ro_wr_en, 0x01);
	} else {
		classcode_reg = CSR_CLASSCODE;
	}

	fsl_pcie_hose_read_config_dword(pcie, classcode_reg, &val);
	val &= 0xff;
	val |= PCI_CLASS_BRIDGE_PCI << 16;
	fsl_pcie_hose_write_config_dword(pcie, classcode_reg, val);

	if (pcie->block_rev >= PEX_IP_BLK_REV_3_0)
		clrbits_be32(&regs->dbi_ro_wr_en, 0x01);

	return 0;
}

static int fsl_pcie_init_rc(struct fsl_pcie *pcie)
{
	return fsl_pcie_fixup_classcode(pcie);
}

static int fsl_pcie_init_ep(struct fsl_pcie *pcie)
{
	fsl_pcie_config_ready(pcie);

	return 0;
}

static int fsl_pcie_probe(struct udevice *dev)
{
	struct fsl_pcie *pcie = dev_get_priv(dev);
	ccsr_fsl_pci_t *regs = pcie->regs;
	u16 val_16;

	pcie->bus = dev;
	pcie->block_rev = in_be32(&regs->block_rev1);

	list_add(&pcie->list, &fsl_pcie_list);
	pcie->enabled = is_serdes_configured(PCIE1 + pcie->idx);
	if (!pcie->enabled) {
		printf("PCIe%d: %s disabled\n", pcie->idx, dev->name);
		return 0;
	}

	fsl_pcie_setup_law(pcie);

	pcie->mode = fsl_pcie_is_agent(pcie);

	fsl_pcie_init_port(pcie);

	printf("PCIe%d: %s ", pcie->idx, dev->name);

	if (pcie->mode) {
		printf("Endpoint");
		fsl_pcie_init_ep(pcie);
	} else {
		printf("Root Complex");
		fsl_pcie_init_rc(pcie);
	}

	if (!fsl_pcie_link_up(pcie)) {
		printf(": %s\n", pcie->mode ? "undetermined link" : "no link");
		return 0;
	}

	fsl_pcie_hose_read_config_word(pcie, PCI_LSR, &val_16);
	printf(": x%d gen%d\n", (val_16 & 0x3f0) >> 4, (val_16 & 0xf));

	return 0;
}

static int fsl_pcie_ofdata_to_platdata(struct udevice *dev)
{
	struct fsl_pcie *pcie = dev_get_priv(dev);
	struct fsl_pcie_data *info;
	int ret;

	pcie->regs = dev_remap_addr(dev);
	if (!pcie->regs) {
		pr_err("\"reg\" resource not found\n");
		return -EINVAL;
	}

	ret = dev_read_u32(dev, "law_trgt_if", &pcie->law_trgt_if);
	if (ret < 0) {
		pr_err("\"law_trgt_if\" not found\n");
		return ret;
	}

	info = (struct fsl_pcie_data *)dev_get_driver_data(dev);
	pcie->info = info;
	pcie->idx = abs((u32)(dev_read_addr(dev) & info->block_offset_mask) -
		    info->block_offset) / info->stride;

	return 0;
}

static const struct dm_pci_ops fsl_pcie_ops = {
	.read_config	= fsl_pcie_read_config,
	.write_config	= fsl_pcie_write_config,
};

static struct fsl_pcie_data p1_p2_data = {
	.block_offset = 0xa000,
	.block_offset_mask = 0xffff,
	.stride = 0x1000,
};

static struct fsl_pcie_data p2041_data = {
	.block_offset = 0x200000,
	.block_offset_mask = 0x3fffff,
	.stride = 0x1000,
};

static struct fsl_pcie_data t2080_data = {
	.block_offset = 0x240000,
	.block_offset_mask = 0x3fffff,
	.stride = 0x10000,
};

static const struct udevice_id fsl_pcie_ids[] = {
	{ .compatible = "fsl,pcie-mpc8548", .data = (ulong)&p1_p2_data },
	{ .compatible = "fsl,pcie-p1_p2", .data = (ulong)&p1_p2_data },
	{ .compatible = "fsl,pcie-p2041", .data = (ulong)&p2041_data },
	{ .compatible = "fsl,pcie-p3041", .data = (ulong)&p2041_data },
	{ .compatible = "fsl,pcie-p4080", .data = (ulong)&p2041_data },
	{ .compatible = "fsl,pcie-p5040", .data = (ulong)&p2041_data },
	{ .compatible = "fsl,pcie-t102x", .data = (ulong)&t2080_data },
	{ .compatible = "fsl,pcie-t104x", .data = (ulong)&t2080_data },
	{ .compatible = "fsl,pcie-t2080", .data = (ulong)&t2080_data },
	{ .compatible = "fsl,pcie-t4240", .data = (ulong)&t2080_data },
	{ }
};

U_BOOT_DRIVER(fsl_pcie) = {
	.name = "fsl_pcie",
	.id = UCLASS_PCI,
	.of_match = fsl_pcie_ids,
	.ops = &fsl_pcie_ops,
	.ofdata_to_platdata = fsl_pcie_ofdata_to_platdata,
	.probe = fsl_pcie_probe,
	.priv_auto_alloc_size = sizeof(struct fsl_pcie),
};
