// SPDX-License-Identifier: GPL-2.0+ OR X11
/*
 * Copyright 2018-2019 NXP
 *
 * PCIe Gen4 driver for NXP Layerscape SoCs
 * Author: Hou Zhiqiang <Minder.Hou@gmail.com>
 */

#include <common.h>
#include <log.h>
#include <asm/arch/fsl_serdes.h>
#include <pci.h>
#include <asm/io.h>
#include <errno.h>
#include <malloc.h>
#include <dm.h>
#include <linux/sizes.h>

#include "pcie_layerscape_gen4.h"

DECLARE_GLOBAL_DATA_PTR;

LIST_HEAD(ls_pcie_g4_list);

static u64 bar_size[4] = {
	PCIE_BAR0_SIZE,
	PCIE_BAR1_SIZE,
	PCIE_BAR2_SIZE,
	PCIE_BAR4_SIZE
};

static int ls_pcie_g4_ltssm(struct ls_pcie_g4 *pcie)
{
	u32 state;

	state = pf_ctrl_readl(pcie, PCIE_LTSSM_STA) & LTSSM_STATE_MASK;

	return state;
}

static int ls_pcie_g4_link_up(struct ls_pcie_g4 *pcie)
{
	int ltssm;

	ltssm = ls_pcie_g4_ltssm(pcie);
	if (ltssm != LTSSM_PCIE_L0)
		return 0;

	return 1;
}

static void ls_pcie_g4_ep_enable_cfg(struct ls_pcie_g4 *pcie)
{
	ccsr_writel(pcie, GPEX_CFG_READY, PCIE_CONFIG_READY);
}

static void ls_pcie_g4_cfg_set_target(struct ls_pcie_g4 *pcie, u32 target)
{
	ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_L(0), target);
	ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_H(0), 0);
}

static int ls_pcie_g4_outbound_win_set(struct ls_pcie_g4 *pcie, int idx,
				       int type, u64 phys, u64 bus_addr,
				       pci_size_t size)
{
	u32 val;
	u32 size_h, size_l;

	if (idx >= PAB_WINS_NUM)
		return -EINVAL;

	size_h = upper_32_bits(~(size - 1));
	size_l = lower_32_bits(~(size - 1));

	val = ccsr_readl(pcie, PAB_AXI_AMAP_CTRL(idx));
	val &= ~((AXI_AMAP_CTRL_TYPE_MASK << AXI_AMAP_CTRL_TYPE_SHIFT) |
		(AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT) |
		AXI_AMAP_CTRL_EN);
	val |= ((type & AXI_AMAP_CTRL_TYPE_MASK) << AXI_AMAP_CTRL_TYPE_SHIFT) |
		((size_l >> AXI_AMAP_CTRL_SIZE_SHIFT) <<
		AXI_AMAP_CTRL_SIZE_SHIFT) | AXI_AMAP_CTRL_EN;

	ccsr_writel(pcie, PAB_AXI_AMAP_CTRL(idx), val);

	ccsr_writel(pcie, PAB_AXI_AMAP_AXI_WIN(idx), lower_32_bits(phys));
	ccsr_writel(pcie, PAB_EXT_AXI_AMAP_AXI_WIN(idx), upper_32_bits(phys));
	ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_L(idx), lower_32_bits(bus_addr));
	ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_H(idx), upper_32_bits(bus_addr));
	ccsr_writel(pcie, PAB_EXT_AXI_AMAP_SIZE(idx), size_h);

	return 0;
}

static int ls_pcie_g4_rc_inbound_win_set(struct ls_pcie_g4 *pcie, int idx,
					 int type, u64 phys, u64 bus_addr,
					 pci_size_t size)
{
	u32 val;
	pci_size_t win_size = ~(size - 1);

	val = ccsr_readl(pcie, PAB_PEX_AMAP_CTRL(idx));

	val &= ~(PEX_AMAP_CTRL_TYPE_MASK << PEX_AMAP_CTRL_TYPE_SHIFT);
	val &= ~(PEX_AMAP_CTRL_EN_MASK << PEX_AMAP_CTRL_EN_SHIFT);
	val = (val | (type << PEX_AMAP_CTRL_TYPE_SHIFT));
	val = (val | (1 << PEX_AMAP_CTRL_EN_SHIFT));

	ccsr_writel(pcie, PAB_PEX_AMAP_CTRL(idx),
		    val | lower_32_bits(win_size));

	ccsr_writel(pcie, PAB_EXT_PEX_AMAP_SIZE(idx), upper_32_bits(win_size));
	ccsr_writel(pcie, PAB_PEX_AMAP_AXI_WIN(idx), lower_32_bits(phys));
	ccsr_writel(pcie, PAB_EXT_PEX_AMAP_AXI_WIN(idx), upper_32_bits(phys));
	ccsr_writel(pcie, PAB_PEX_AMAP_PEX_WIN_L(idx), lower_32_bits(bus_addr));
	ccsr_writel(pcie, PAB_PEX_AMAP_PEX_WIN_H(idx), upper_32_bits(bus_addr));

	return 0;
}

static void ls_pcie_g4_dump_wins(struct ls_pcie_g4 *pcie, int wins)
{
	int i;

	for (i = 0; i < wins; i++) {
		debug("APIO Win%d:\n", i);
		debug("\tLOWER PHYS:	0x%08x\n",
		      ccsr_readl(pcie, PAB_AXI_AMAP_AXI_WIN(i)));
		debug("\tUPPER PHYS:	0x%08x\n",
		      ccsr_readl(pcie, PAB_EXT_AXI_AMAP_AXI_WIN(i)));
		debug("\tLOWER BUS:	0x%08x\n",
		      ccsr_readl(pcie, PAB_AXI_AMAP_PEX_WIN_L(i)));
		debug("\tUPPER BUS:	0x%08x\n",
		      ccsr_readl(pcie, PAB_AXI_AMAP_PEX_WIN_H(i)));
		debug("\tSIZE:		0x%08x\n",
		      ccsr_readl(pcie, PAB_AXI_AMAP_CTRL(i)) &
		      (AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT));
		debug("\tEXT_SIZE:	0x%08x\n",
		      ccsr_readl(pcie, PAB_EXT_AXI_AMAP_SIZE(i)));
		debug("\tPARAM:		0x%08x\n",
		      ccsr_readl(pcie, PAB_AXI_AMAP_PCI_HDR_PARAM(i)));
		debug("\tCTRL:		0x%08x\n",
		      ccsr_readl(pcie, PAB_AXI_AMAP_CTRL(i)));
	}
}

static void ls_pcie_g4_setup_wins(struct ls_pcie_g4 *pcie)
{
	struct pci_region *io, *mem, *pref;
	int idx = 1;

	/* INBOUND WIN */
	ls_pcie_g4_rc_inbound_win_set(pcie, 0, IB_TYPE_MEM_F, 0, 0, SIZE_1T);

	/* OUTBOUND WIN 0: CFG */
	ls_pcie_g4_outbound_win_set(pcie, 0, PAB_AXI_TYPE_CFG,
				    pcie->cfg_res.start, 0,
				    fdt_resource_size(&pcie->cfg_res));

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

	if (io)
		/* OUTBOUND WIN: IO */
		ls_pcie_g4_outbound_win_set(pcie, idx++, PAB_AXI_TYPE_IO,
					    io->phys_start, io->bus_start,
					    io->size);

	if (mem)
		/* OUTBOUND WIN: MEM */
		ls_pcie_g4_outbound_win_set(pcie, idx++, PAB_AXI_TYPE_MEM,
					    mem->phys_start, mem->bus_start,
					    mem->size);

	if (pref)
		/* OUTBOUND WIN: perf MEM */
		ls_pcie_g4_outbound_win_set(pcie, idx++, PAB_AXI_TYPE_MEM,
					    pref->phys_start, pref->bus_start,
					    pref->size);

	ls_pcie_g4_dump_wins(pcie, idx);
}

/* Return 0 if the address is valid, -errno if not valid */
static int ls_pcie_g4_addr_valid(struct ls_pcie_g4 *pcie, pci_dev_t bdf)
{
	struct udevice *bus = pcie->bus;

	if (pcie->mode == PCI_HEADER_TYPE_NORMAL)
		return -ENODEV;

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

	if (PCI_BUS(bdf) < dev_seq(bus))
		return -EINVAL;

	if ((PCI_BUS(bdf) > dev_seq(bus)) && (!ls_pcie_g4_link_up(pcie)))
		return -EINVAL;

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

	return 0;
}

void *ls_pcie_g4_conf_address(struct ls_pcie_g4 *pcie, pci_dev_t bdf,
			      int offset)
{
	struct udevice *bus = pcie->bus;
	u32 target;

	if (PCI_BUS(bdf) == dev_seq(bus)) {
		if (offset < INDIRECT_ADDR_BNDRY) {
			ccsr_set_page(pcie, 0);
			return pcie->ccsr + offset;
		}

		ccsr_set_page(pcie, OFFSET_TO_PAGE_IDX(offset));
		return pcie->ccsr + OFFSET_TO_PAGE_ADDR(offset);
	}

	target = PAB_TARGET_BUS(PCI_BUS(bdf) - dev_seq(bus)) |
		 PAB_TARGET_DEV(PCI_DEV(bdf)) |
		 PAB_TARGET_FUNC(PCI_FUNC(bdf));

	ls_pcie_g4_cfg_set_target(pcie, target);

	return pcie->cfg + offset;
}

static int ls_pcie_g4_read_config(const struct udevice *bus, pci_dev_t bdf,
				  uint offset, ulong *valuep,
				  enum pci_size_t size)
{
	struct ls_pcie_g4 *pcie = dev_get_priv(bus);
	void *address;
	int ret = 0;

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

	address = ls_pcie_g4_conf_address(pcie, bdf, offset);

	switch (size) {
	case PCI_SIZE_8:
		*valuep = readb(address);
		break;
	case PCI_SIZE_16:
		*valuep = readw(address);
		break;
	case PCI_SIZE_32:
		*valuep = readl(address);
		break;
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}

static int ls_pcie_g4_write_config(struct udevice *bus, pci_dev_t bdf,
				   uint offset, ulong value,
				   enum pci_size_t size)
{
	struct ls_pcie_g4 *pcie = dev_get_priv(bus);
	void *address;

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

	address = ls_pcie_g4_conf_address(pcie, bdf, offset);

	switch (size) {
	case PCI_SIZE_8:
		writeb(value, address);
		return 0;
	case PCI_SIZE_16:
		writew(value, address);
		return 0;
	case PCI_SIZE_32:
		writel(value, address);
		return 0;
	default:
		return -EINVAL;
	}
}

static void ls_pcie_g4_setup_ctrl(struct ls_pcie_g4 *pcie)
{
	u32 val;

	/* Fix class code */
	val = ccsr_readl(pcie, GPEX_CLASSCODE);
	val &= ~(GPEX_CLASSCODE_MASK << GPEX_CLASSCODE_SHIFT);
	val |= PCI_CLASS_BRIDGE_PCI << GPEX_CLASSCODE_SHIFT;
	ccsr_writel(pcie, GPEX_CLASSCODE, val);

	/* Enable APIO and Memory/IO/CFG Wins */
	val = ccsr_readl(pcie, PAB_AXI_PIO_CTRL(0));
	val |= APIO_EN | MEM_WIN_EN | IO_WIN_EN | CFG_WIN_EN;
	ccsr_writel(pcie, PAB_AXI_PIO_CTRL(0), val);

	ls_pcie_g4_setup_wins(pcie);

	pcie->stream_id_cur = 0;
}

static void ls_pcie_g4_ep_inbound_win_set(struct ls_pcie_g4 *pcie, int pf,
					  int bar, u64 phys)
{
	u32 val;

	/* PF BAR1 is for MSI-X and only need to enable */
	if (bar == 1) {
		ccsr_writel(pcie, PAB_PEX_BAR_AMAP(pf, bar), BAR_AMAP_EN);
		return;
	}

	val = upper_32_bits(phys);
	ccsr_writel(pcie, PAB_EXT_PEX_BAR_AMAP(pf, bar), val);
	val = lower_32_bits(phys) | BAR_AMAP_EN;
	ccsr_writel(pcie, PAB_PEX_BAR_AMAP(pf, bar), val);
}

static void ls_pcie_g4_ep_setup_wins(struct ls_pcie_g4 *pcie, int pf)
{
	u64 phys;
	int bar;
	u32 val;

	if ((!pcie->sriov_support && pf > LS_G4_PF0) || pf > LS_G4_PF1)
		return;

	phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR_SIZE * 4 * pf;
	for (bar = 0; bar < PF_BAR_NUM; bar++) {
		ls_pcie_g4_ep_inbound_win_set(pcie, pf, bar, phys);
		phys += PCIE_BAR_SIZE;
	}

	/* OUTBOUND: map MEM */
	ls_pcie_g4_outbound_win_set(pcie, pf, PAB_AXI_TYPE_MEM,
				    pcie->cfg_res.start +
				    CONFIG_SYS_PCI_MEMORY_SIZE * pf, 0x0,
				    CONFIG_SYS_PCI_MEMORY_SIZE);

	val = ccsr_readl(pcie, PAB_AXI_AMAP_PCI_HDR_PARAM(pf));
	val &= ~FUNC_NUM_PCIE_MASK;
	val |= pf;
	ccsr_writel(pcie, PAB_AXI_AMAP_PCI_HDR_PARAM(pf), val);
}

static void ls_pcie_g4_ep_enable_bar(struct ls_pcie_g4 *pcie, int pf,
				     int bar, bool vf_bar, bool enable)
{
	u32 val;
	u32 bar_pos = BAR_POS(bar, pf, vf_bar);

	val = ccsr_readl(pcie, GPEX_BAR_ENABLE);
	if (enable)
		val |= 1 << bar_pos;
	else
		val &= ~(1 << bar_pos);
	ccsr_writel(pcie, GPEX_BAR_ENABLE, val);
}

static void ls_pcie_g4_ep_set_bar_size(struct ls_pcie_g4 *pcie, int pf,
				       int bar, bool vf_bar, u64 size)
{
	u32 bar_pos = BAR_POS(bar, pf, vf_bar);
	u32 mask_l = lower_32_bits(~(size - 1));
	u32 mask_h = upper_32_bits(~(size - 1));

	ccsr_writel(pcie, GPEX_BAR_SELECT, bar_pos);
	ccsr_writel(pcie, GPEX_BAR_SIZE_LDW, mask_l);
	ccsr_writel(pcie, GPEX_BAR_SIZE_UDW, mask_h);
}

static void ls_pcie_g4_ep_setup_bar(struct ls_pcie_g4 *pcie, int pf,
				    int bar, bool vf_bar, u64 size)
{
	bool en = size ? true : false;

	ls_pcie_g4_ep_enable_bar(pcie, pf, bar, vf_bar, en);
	ls_pcie_g4_ep_set_bar_size(pcie, pf, bar, vf_bar, size);
}

static void ls_pcie_g4_ep_setup_bars(struct ls_pcie_g4 *pcie, int pf)
{
	int bar;

	/* Setup PF BARs */
	for (bar = 0; bar < PF_BAR_NUM; bar++)
		ls_pcie_g4_ep_setup_bar(pcie, pf, bar, false, bar_size[bar]);

	if (!pcie->sriov_support)
		return;

	/* Setup VF BARs */
	for (bar = 0; bar < VF_BAR_NUM; bar++)
		ls_pcie_g4_ep_setup_bar(pcie, pf, bar, true, bar_size[bar]);
}

static void ls_pcie_g4_set_sriov(struct ls_pcie_g4 *pcie, int pf)
{
	unsigned int val;

	val =  ccsr_readl(pcie, GPEX_SRIOV_INIT_VFS_TOTAL_VF(pf));
	val &= ~(TTL_VF_MASK << TTL_VF_SHIFT);
	val |= PCIE_VF_NUM << TTL_VF_SHIFT;
	val &= ~(INI_VF_MASK << INI_VF_SHIFT);
	val |= PCIE_VF_NUM << INI_VF_SHIFT;
	ccsr_writel(pcie, GPEX_SRIOV_INIT_VFS_TOTAL_VF(pf), val);

	val =  ccsr_readl(pcie, PCIE_SRIOV_VF_OFFSET_STRIDE);
	val += PCIE_VF_NUM * pf - pf;
	ccsr_writel(pcie, GPEX_SRIOV_VF_OFFSET_STRIDE(pf), val);
}

static void ls_pcie_g4_setup_ep(struct ls_pcie_g4 *pcie)
{
	u32 pf, sriov;
	u32 val;
	int i;

	/* Enable APIO and Memory Win */
	val = ccsr_readl(pcie, PAB_AXI_PIO_CTRL(0));
	val |= APIO_EN | MEM_WIN_EN;
	ccsr_writel(pcie, PAB_AXI_PIO_CTRL(0), val);

	sriov = ccsr_readl(pcie, PCIE_SRIOV_CAPABILITY);
	if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV)
		pcie->sriov_support = 1;

	pf = pcie->sriov_support ? PCIE_PF_NUM : 1;

	for (i = 0; i < pf; i++) {
		ls_pcie_g4_ep_setup_bars(pcie, i);
		ls_pcie_g4_ep_setup_wins(pcie, i);
		if (pcie->sriov_support)
			ls_pcie_g4_set_sriov(pcie, i);
	}

	ls_pcie_g4_ep_enable_cfg(pcie);
	ls_pcie_g4_dump_wins(pcie, pf);
}

static int ls_pcie_g4_probe(struct udevice *dev)
{
	struct ls_pcie_g4 *pcie = dev_get_priv(dev);
	const void *fdt = gd->fdt_blob;
	int node = dev_of_offset(dev);
	u32 link_ctrl_sta;
	u32 val;
	int ret;

	pcie->bus = dev;

	ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
				     "ccsr", &pcie->ccsr_res);
	if (ret) {
		printf("ls-pcie-g4: resource \"ccsr\" not found\n");
		return ret;
	}

	pcie->idx = (pcie->ccsr_res.start - PCIE_SYS_BASE_ADDR) /
		    PCIE_CCSR_SIZE;

	list_add(&pcie->list, &ls_pcie_g4_list);

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

	pcie->ccsr = map_physmem(pcie->ccsr_res.start,
				 fdt_resource_size(&pcie->ccsr_res),
				 MAP_NOCACHE);

	ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
				     "config", &pcie->cfg_res);
	if (ret) {
		printf("%s: resource \"config\" not found\n", dev->name);
		return ret;
	}

	pcie->cfg = map_physmem(pcie->cfg_res.start,
				fdt_resource_size(&pcie->cfg_res),
				MAP_NOCACHE);

	ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
				     "lut", &pcie->lut_res);
	if (ret) {
		printf("ls-pcie-g4: resource \"lut\" not found\n");
		return ret;
	}

	pcie->lut = map_physmem(pcie->lut_res.start,
				fdt_resource_size(&pcie->lut_res),
				MAP_NOCACHE);

	ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
				     "pf_ctrl", &pcie->pf_ctrl_res);
	if (ret) {
		printf("ls-pcie-g4: resource \"pf_ctrl\" not found\n");
		return ret;
	}

	pcie->pf_ctrl = map_physmem(pcie->pf_ctrl_res.start,
				    fdt_resource_size(&pcie->pf_ctrl_res),
				    MAP_NOCACHE);

	pcie->big_endian = fdtdec_get_bool(fdt, node, "big-endian");

	debug("%s ccsr:%lx, cfg:0x%lx, big-endian:%d\n",
	      dev->name, (unsigned long)pcie->ccsr, (unsigned long)pcie->cfg,
	      pcie->big_endian);

	pcie->mode = readb(pcie->ccsr + PCI_HEADER_TYPE) & 0x7f;

	if (pcie->mode == PCI_HEADER_TYPE_NORMAL) {
		printf("PCIe%u: %s %s", pcie->idx, dev->name, "Endpoint");
		ls_pcie_g4_setup_ep(pcie);
	} else {
		printf("PCIe%u: %s %s", pcie->idx, dev->name, "Root Complex");
		ls_pcie_g4_setup_ctrl(pcie);
	}

	/* Enable Amba & PEX PIO */
	val = ccsr_readl(pcie, PAB_CTRL);
	val |= PAB_CTRL_APIO_EN | PAB_CTRL_PPIO_EN;
	ccsr_writel(pcie, PAB_CTRL, val);

	val = ccsr_readl(pcie, PAB_PEX_PIO_CTRL(0));
	val |= PPIO_EN;
	ccsr_writel(pcie, PAB_PEX_PIO_CTRL(0), val);

	if (!ls_pcie_g4_link_up(pcie)) {
		/* Let the user know there's no PCIe link */
		printf(": no link\n");
		return 0;
	}

	/* Print the negotiated PCIe link width */
	link_ctrl_sta = ccsr_readl(pcie, PCIE_LINK_CTRL_STA);
	printf(": x%d gen%d\n",
	       (link_ctrl_sta >> PCIE_LINK_WIDTH_SHIFT & PCIE_LINK_WIDTH_MASK),
	       (link_ctrl_sta >> PCIE_LINK_SPEED_SHIFT) & PCIE_LINK_SPEED_MASK);

	return 0;
}

static const struct dm_pci_ops ls_pcie_g4_ops = {
	.read_config	= ls_pcie_g4_read_config,
	.write_config	= ls_pcie_g4_write_config,
};

static const struct udevice_id ls_pcie_g4_ids[] = {
	{ .compatible = "fsl,lx2160a-pcie" },
	{ }
};

U_BOOT_DRIVER(pcie_layerscape_gen4) = {
	.name = "pcie_layerscape_gen4",
	.id = UCLASS_PCI,
	.of_match = ls_pcie_g4_ids,
	.ops = &ls_pcie_g4_ops,
	.probe	= ls_pcie_g4_probe,
	.priv_auto	= sizeof(struct ls_pcie_g4),
};
