// SPDX-License-Identifier: GPL-2.0+
/*
 * SiFive FU740 DesignWare PCIe Controller
 *
 * Copyright (C) 2020-2021 SiFive, Inc.
 *
 * Based in early part on the i.MX6 PCIe host controller shim which is:
 *
 * Copyright (C) 2013 Kosagi
 *		http://www.kosagi.com
 *
 * Based on driver from author: Alan Mikhak <amikhak@wirelessfabric.com>
 */
#include <asm/io.h>
#include <asm-generic/gpio.h>
#include <clk.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <generic-phy.h>
#include <linux/bitops.h>
#include <linux/log2.h>
#include <pci.h>
#include <pci_ep.h>
#include <pci_ids.h>
#include <regmap.h>
#include <reset.h>
#include <syscon.h>

#include "pcie_dw_common.h"

struct pcie_sifive {
	/* Must be first member of the struct */
	struct pcie_dw dw;

	/* private control regs */
	void __iomem *priv_base;

	/* reset, power, clock resources */
	int sys_int_pin;
	struct gpio_desc pwren_gpio;
	struct gpio_desc reset_gpio;
	struct clk aux_ck;
	struct reset_ctl reset;
};

enum pcie_sifive_devtype {
	SV_PCIE_UNKNOWN_TYPE = 0,
	SV_PCIE_ENDPOINT_TYPE = 1,
	SV_PCIE_HOST_TYPE = 3
};

#define ASSERTION_DELAY		100
#define PCIE_PERST_ASSERT	0x0
#define PCIE_PERST_DEASSERT	0x1
#define PCIE_PHY_RESET		0x1
#define PCIE_PHY_RESET_DEASSERT	0x0
#define GPIO_LOW		0x0
#define GPIO_HIGH		0x1
#define PCIE_PHY_SEL		0x1

#define sv_info(sv, fmt, arg...)	printf(fmt, ## arg)
#define sv_warn(sv, fmt, arg...)	printf(fmt, ## arg)
#define sv_debug(sv, fmt, arg...)	debug(fmt, ## arg)
#define sv_err(sv, fmt, arg...)		printf(fmt, ## arg)

/* Doorbell Interface */
#define DBI_OFFSET			0x0
#define DBI_SIZE			0x1000

#define PL_OFFSET			0x700

#define PHY_DEBUG_R0			(PL_OFFSET + 0x28)

#define PHY_DEBUG_R1			(PL_OFFSET + 0x2c)
#define PHY_DEBUG_R1_LINK_UP		(0x1 << 4)
#define PHY_DEBUG_R1_LINK_IN_TRAINING	(0x1 << 29)

#define PCIE_MISC_CONTROL_1		0x8bc
#define DBI_RO_WR_EN			BIT(0)

/* pcie reset */
#define PCIEX8MGMT_PERST_N		0x0

/* LTSSM */
#define PCIEX8MGMT_APP_LTSSM_ENABLE	0x10
#define LTSSM_ENABLE_BIT		BIT(0)

/* phy reset */
#define PCIEX8MGMT_APP_HOLD_PHY_RST	0x18

/* device type */
#define PCIEX8MGMT_DEVICE_TYPE		0x708
#define DEVICE_TYPE_EP			0x0
#define DEVICE_TYPE_RC			0x4

/* phy control registers*/
#define PCIEX8MGMT_PHY0_CR_PARA_ADDR	0x860
#define PCIEX8MGMT_PHY0_CR_PARA_RD_EN	0x870
#define PCIEX8MGMT_PHY0_CR_PARA_RD_DATA	0x878
#define PCIEX8MGMT_PHY0_CR_PARA_SEL	0x880
#define PCIEX8MGMT_PHY0_CR_PARA_WR_DATA	0x888
#define PCIEX8MGMT_PHY0_CR_PARA_WR_EN	0x890
#define PCIEX8MGMT_PHY0_CR_PARA_ACK	0x898
#define PCIEX8MGMT_PHY1_CR_PARA_ADDR	0x8a0
#define PCIEX8MGMT_PHY1_CR_PARA_RD_EN	0x8b0
#define PCIEX8MGMT_PHY1_CR_PARA_RD_DATA	0x8b8
#define PCIEX8MGMT_PHY1_CR_PARA_SEL	0x8c0
#define PCIEX8MGMT_PHY1_CR_PARA_WR_DATA	0x8c8
#define PCIEX8MGMT_PHY1_CR_PARA_WR_EN	0x8d0
#define PCIEX8MGMT_PHY1_CR_PARA_ACK	0x8d8

#define PCIEX8MGMT_LANE_NUM		8
#define PCIEX8MGMT_LANE			0x1008
#define PCIEX8MGMT_LANE_OFF		0x100
#define PCIEX8MGMT_TERM_MODE		0x0e21

#define PCIE_CAP_BASE			0x70
#define PCI_CONFIG(r)			(DBI_OFFSET + (r))
#define PCIE_CAPABILITIES(r)		PCI_CONFIG(PCIE_CAP_BASE + (r))

/* Link capability */
#define PF0_PCIE_CAP_LINK_CAP		PCIE_CAPABILITIES(0xc)
#define PCIE_LINK_CAP_MAX_SPEED_MASK	0xf
#define PCIE_LINK_CAP_MAX_SPEED_GEN1	BIT(0)
#define PCIE_LINK_CAP_MAX_SPEED_GEN2	BIT(1)
#define PCIE_LINK_CAP_MAX_SPEED_GEN3	BIT(2)
#define PCIE_LINK_CAP_MAX_SPEED_GEN4	BIT(3)

static enum pcie_sifive_devtype pcie_sifive_get_devtype(struct pcie_sifive *sv)
{
	u32 val;

	val = readl(sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);
	switch (val) {
	case DEVICE_TYPE_RC:
		return SV_PCIE_HOST_TYPE;
	case DEVICE_TYPE_EP:
		return SV_PCIE_ENDPOINT_TYPE;
	default:
		return SV_PCIE_UNKNOWN_TYPE;
	}
}

static void pcie_sifive_priv_set_state(struct pcie_sifive *sv, u32 reg,
				       u32 bits, int state)
{
	u32 val;

	val = readl(sv->priv_base + reg);
	val = state ? (val | bits) : (val & !bits);
	writel(val, sv->priv_base + reg);
}

static void pcie_sifive_assert_reset(struct pcie_sifive *sv)
{
	dm_gpio_set_value(&sv->reset_gpio, GPIO_LOW);
	writel(PCIE_PERST_ASSERT, sv->priv_base + PCIEX8MGMT_PERST_N);
	mdelay(ASSERTION_DELAY);
}

static void pcie_sifive_power_on(struct pcie_sifive *sv)
{
	dm_gpio_set_value(&sv->pwren_gpio, GPIO_HIGH);
	mdelay(ASSERTION_DELAY);
}

static void pcie_sifive_deassert_reset(struct pcie_sifive *sv)
{
	writel(PCIE_PERST_DEASSERT, sv->priv_base + PCIEX8MGMT_PERST_N);
	dm_gpio_set_value(&sv->reset_gpio, GPIO_HIGH);
	mdelay(ASSERTION_DELAY);
}

static int pcie_sifive_setphy(const u8 phy, const u8 write,
			      const u16 addr, const u16 wrdata,
			      u16 *rddata, struct pcie_sifive *sv)
{
	unsigned char ack = 0;

	if (!(phy == 0 || phy == 1))
		return -2;

	/* setup phy para */
	writel(addr, sv->priv_base +
	       (phy ? PCIEX8MGMT_PHY1_CR_PARA_ADDR :
		PCIEX8MGMT_PHY0_CR_PARA_ADDR));

	if (write)
		writel(wrdata, sv->priv_base +
		       (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_DATA :
			PCIEX8MGMT_PHY0_CR_PARA_WR_DATA));

	/* enable access if write */
	if (write)
		writel(1, sv->priv_base +
		       (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_EN :
			PCIEX8MGMT_PHY0_CR_PARA_WR_EN));
	else
		writel(1, sv->priv_base +
		       (phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_EN :
			PCIEX8MGMT_PHY0_CR_PARA_RD_EN));

	/* wait for wait_idle */
	do {
		u32 val;

		val = readl(sv->priv_base +
			    (phy ? PCIEX8MGMT_PHY1_CR_PARA_ACK :
			     PCIEX8MGMT_PHY0_CR_PARA_ACK));
		if (val) {
			ack = 1;
			if (!write)
				readl(sv->priv_base +
				      (phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_DATA :
				       PCIEX8MGMT_PHY0_CR_PARA_RD_DATA));
			mdelay(1);
		}
	} while (!ack);

	/* clear */
	if (write)
		writel(0, sv->priv_base +
		       (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_EN :
			PCIEX8MGMT_PHY0_CR_PARA_WR_EN));
	else
		writel(0, sv->priv_base +
		       (phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_EN :
			PCIEX8MGMT_PHY0_CR_PARA_RD_EN));

	while (readl(sv->priv_base +
		     (phy ? PCIEX8MGMT_PHY1_CR_PARA_ACK :
		      PCIEX8MGMT_PHY0_CR_PARA_ACK))) {
		/* wait for ~wait_idle */
	}

	return 0;
}

static void pcie_sifive_init_phy(struct pcie_sifive *sv)
{
	int lane;

	/* enable phy cr_para_sel interfaces */
	writel(PCIE_PHY_SEL, sv->priv_base + PCIEX8MGMT_PHY0_CR_PARA_SEL);
	writel(PCIE_PHY_SEL, sv->priv_base + PCIEX8MGMT_PHY1_CR_PARA_SEL);
	mdelay(1);

	/* set PHY AC termination mode */
	for (lane = 0; lane < PCIEX8MGMT_LANE_NUM; lane++) {
		pcie_sifive_setphy(0, 1,
				   PCIEX8MGMT_LANE +
				   (PCIEX8MGMT_LANE_OFF * lane),
				   PCIEX8MGMT_TERM_MODE, NULL, sv);
		pcie_sifive_setphy(1, 1,
				   PCIEX8MGMT_LANE +
				   (PCIEX8MGMT_LANE_OFF * lane),
				   PCIEX8MGMT_TERM_MODE, NULL, sv);
	}
}

static int pcie_sifive_check_link(struct pcie_sifive *sv)
{
	u32 val;

	val = readl(sv->dw.dbi_base + PHY_DEBUG_R1);
	return (val & PHY_DEBUG_R1_LINK_UP) &&
		!(val & PHY_DEBUG_R1_LINK_IN_TRAINING);
}

static void pcie_sifive_force_gen1(struct pcie_sifive *sv)
{
	u32 val, linkcap;

	/*
	 * Force Gen1 operation when starting the link. In case the link is
	 * started in Gen2 mode, there is a possibility the devices on the
	 * bus will not be detected at all. This happens with PCIe switches.
	 */

	/* ctrl_ro_wr_enable */
	val = readl(sv->dw.dbi_base + PCIE_MISC_CONTROL_1);
	val |= DBI_RO_WR_EN;
	writel(val, sv->dw.dbi_base + PCIE_MISC_CONTROL_1);

	/* configure link cap */
	linkcap = readl(sv->dw.dbi_base + PF0_PCIE_CAP_LINK_CAP);
	linkcap |= PCIE_LINK_CAP_MAX_SPEED_MASK;
	writel(linkcap, sv->dw.dbi_base + PF0_PCIE_CAP_LINK_CAP);

	/* ctrl_ro_wr_disable */
	val &= ~DBI_RO_WR_EN;
	writel(val, sv->dw.dbi_base + PCIE_MISC_CONTROL_1);
}

static void pcie_sifive_print_phy_debug(struct pcie_sifive *sv)
{
	sv_err(sv, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
	       readl(sv->dw.dbi_base + PHY_DEBUG_R0),
	       readl(sv->dw.dbi_base + PHY_DEBUG_R1));
}

static int pcie_sifive_wait_for_link(struct pcie_sifive *sv)
{
	u32 val;
	int timeout;

	/* Wait for the link to train */
	mdelay(20);
	timeout = 20;

	do {
		mdelay(1);
	} while (--timeout && !pcie_sifive_check_link(sv));

	val = readl(sv->dw.dbi_base + PHY_DEBUG_R1);
	if (!(val & PHY_DEBUG_R1_LINK_UP) ||
	    (val & PHY_DEBUG_R1_LINK_IN_TRAINING)) {
		sv_info(sv, "Failed to negotiate PCIe link!\n");
		pcie_sifive_print_phy_debug(sv);
		writel(PCIE_PHY_RESET,
		       sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
		return -ETIMEDOUT;
	}

	return 0;
}

static int pcie_sifive_start_link(struct pcie_sifive *sv)
{
	if (pcie_sifive_check_link(sv))
		return -EALREADY;

	pcie_sifive_force_gen1(sv);

	/* set ltssm */
	pcie_sifive_priv_set_state(sv, PCIEX8MGMT_APP_LTSSM_ENABLE,
				   LTSSM_ENABLE_BIT, 1);
	return 0;
}

static int pcie_sifive_init_port(struct udevice *dev,
				 enum pcie_sifive_devtype mode)
{
	struct pcie_sifive *sv = dev_get_priv(dev);
	int ret;

	/* Power on reset */
	pcie_sifive_assert_reset(sv);
	pcie_sifive_power_on(sv);
	pcie_sifive_deassert_reset(sv);

	/* Enable pcieauxclk */
	ret = clk_enable(&sv->aux_ck);
	if (ret)
		dev_err(dev, "unable to enable pcie_aux clock\n");

	/*
	 * assert hold_phy_rst (hold the controller LTSSM in reset
	 * after power_up_rst_n for register programming with cr_para)
	 */
	writel(PCIE_PHY_RESET, sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);

	/* deassert power_up_rst_n */
	ret = reset_deassert(&sv->reset);
	if (ret < 0) {
		dev_err(dev, "failed to deassert reset");
		return -EINVAL;
	}

	pcie_sifive_init_phy(sv);

	/* disable pcieauxclk */
	clk_disable(&sv->aux_ck);

	/* deassert hold_phy_rst */
	writel(PCIE_PHY_RESET_DEASSERT,
	       sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);

	/* enable pcieauxclk */
	clk_enable(&sv->aux_ck);

	/* Set desired mode while core is not operational */
	if (mode == SV_PCIE_HOST_TYPE)
		writel(DEVICE_TYPE_RC,
		       sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);
	else
		writel(DEVICE_TYPE_EP,
		       sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);

	/* Confirm desired mode from operational core */
	if (pcie_sifive_get_devtype(sv) != mode)
		return -EINVAL;

	pcie_dw_setup_host(&sv->dw);

	if (pcie_sifive_start_link(sv) == -EALREADY)
		sv_info(sv, "PCIe link is already up\n");
	else if (pcie_sifive_wait_for_link(sv) == -ETIMEDOUT)
		return -ETIMEDOUT;

	return 0;
}

static int pcie_sifive_probe(struct udevice *dev)
{
	struct pcie_sifive *sv = dev_get_priv(dev);
	struct udevice *parent = pci_get_controller(dev);
	struct pci_controller *hose = dev_get_uclass_priv(parent);
	int err;

	sv->dw.first_busno = dev_seq(dev);
	sv->dw.dev = dev;

	err = pcie_sifive_init_port(dev, SV_PCIE_HOST_TYPE);
	if (err) {
		sv_info(sv, "Failed to init port.\n");
		return err;
	}

	printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n",
	       dev_seq(dev), pcie_dw_get_link_speed(&sv->dw),
	       pcie_dw_get_link_width(&sv->dw),
	       hose->first_busno);

	return pcie_dw_prog_outbound_atu_unroll(&sv->dw,
						PCIE_ATU_REGION_INDEX0,
						PCIE_ATU_TYPE_MEM,
						sv->dw.mem.phys_start,
						sv->dw.mem.bus_start,
						sv->dw.mem.size);
}

static void __iomem *get_fdt_addr(struct udevice *dev, const char *name)
{
	fdt_addr_t addr;

	addr = dev_read_addr_name(dev, name);

	return (addr == FDT_ADDR_T_NONE) ? NULL : (void __iomem *)addr;
}

static int pcie_sifive_of_to_plat(struct udevice *dev)
{
	struct pcie_sifive *sv = dev_get_priv(dev);
	int err;

	/* get designware DBI base addr */
	sv->dw.dbi_base = get_fdt_addr(dev, "dbi");
	if (!sv->dw.dbi_base)
		return -EINVAL;

	/* get private control base addr */
	sv->priv_base = get_fdt_addr(dev, "mgmt");
	if (!sv->priv_base)
		return -EINVAL;

	gpio_request_by_name(dev, "pwren-gpios", 0, &sv->pwren_gpio,
			     GPIOD_IS_OUT);

	if (!dm_gpio_is_valid(&sv->pwren_gpio)) {
		sv_info(sv, "pwren_gpio is invalid\n");
		return -EINVAL;
	}

	gpio_request_by_name(dev, "reset-gpios", 0, &sv->reset_gpio,
			     GPIOD_IS_OUT);

	if (!dm_gpio_is_valid(&sv->reset_gpio)) {
		sv_info(sv, "reset_gpio is invalid\n");
		return -EINVAL;
	}

	err = clk_get_by_index(dev, 0, &sv->aux_ck);
	if (err) {
		sv_info(sv, "clk_get_by_index(aux_ck) failed: %d\n", err);
		return err;
	}

	err = reset_get_by_index(dev, 0, &sv->reset);
	if (err) {
		sv_info(sv, "reset_get_by_index(reset) failed: %d\n", err);
		return err;
	}

	return 0;
}

static const struct dm_pci_ops pcie_sifive_ops = {
	.read_config	= pcie_dw_read_config,
	.write_config	= pcie_dw_write_config,
};

static const struct udevice_id pcie_sifive_ids[] = {
	{ .compatible = "sifive,fu740-pcie" },
	{}
};

U_BOOT_DRIVER(pcie_sifive) = {
	.name		= "pcie_sifive",
	.id		= UCLASS_PCI,
	.of_match	= pcie_sifive_ids,
	.ops		= &pcie_sifive_ops,
	.of_to_plat	= pcie_sifive_of_to_plat,
	.probe		= pcie_sifive_probe,
	.priv_auto	= sizeof(struct pcie_sifive),
};
