// SPDX-License-Identifier: GPL-2.0+
/*
 * Amlogic DesignWare based PCIe host controller driver
 *
 * Copyright (c) 2021 BayLibre, SAS
 * Author: Neil Armstrong <narmstrong@baylibre.com>
 *
 * Based on pcie_dw_rockchip.c
 * Copyright (c) 2021 Rockchip, Inc.
 */

#include <common.h>
#include <clk.h>
#include <dm.h>
#include <generic-phy.h>
#include <pci.h>
#include <power-domain.h>
#include <reset.h>
#include <syscon.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm-generic/gpio.h>
#include <dm/device_compat.h>
#include <linux/iopoll.h>
#include <linux/delay.h>
#include <linux/log2.h>
#include <linux/bitfield.h>

#include "pcie_dw_common.h"

DECLARE_GLOBAL_DATA_PTR;

/**
 * struct meson_pcie - Amlogic Meson DW PCIe controller state
 *
 * @pci: The common PCIe DW structure
 * @meson_cfg_base: The base address of vendor regs
 * @phy
 * @clk_port
 * @clk_general
 * @clk_pclk
 * @rsts
 * @rst_gpio: The #PERST signal for slot
 */
struct meson_pcie {
	/* Must be first member of the struct */
	struct pcie_dw dw;
	void *meson_cfg_base;
	struct phy phy;
	struct clk clk_port;
	struct clk clk_general;
	struct clk clk_pclk;
	struct reset_ctl_bulk rsts;
	struct gpio_desc rst_gpio;
};

#define PCI_EXP_DEVCTL_PAYLOAD	0x00e0	/* Max_Payload_Size */

#define PCIE_CAP_MAX_PAYLOAD_SIZE(x)	((x) << 5)
#define PCIE_CAP_MAX_READ_REQ_SIZE(x)	((x) << 12)

/* PCIe specific config registers */
#define PCIE_CFG0			0x0
#define APP_LTSSM_ENABLE		BIT(7)

#define PCIE_CFG_STATUS12		0x30
#define IS_SMLH_LINK_UP(x)		((x) & (1 << 6))
#define IS_RDLH_LINK_UP(x)		((x) & (1 << 16))
#define IS_LTSSM_UP(x)			((((x) >> 10) & 0x1f) == 0x11)

#define PCIE_CFG_STATUS17		0x44
#define PM_CURRENT_STATE(x)		(((x) >> 7) & 0x1)

#define WAIT_LINKUP_TIMEOUT		4000
#define PORT_CLK_RATE			100000000UL
#define MAX_PAYLOAD_SIZE		256
#define MAX_READ_REQ_SIZE		256
#define PCIE_RESET_DELAY		500
#define PCIE_SHARED_RESET		1
#define PCIE_NORMAL_RESET		0

enum pcie_data_rate {
	PCIE_GEN1,
	PCIE_GEN2,
	PCIE_GEN3,
	PCIE_GEN4
};

/* Parameters for the waiting for #perst signal */
#define PERST_WAIT_US			1000000

static inline u32 meson_cfg_readl(struct meson_pcie *priv, u32 reg)
{
	return readl(priv->meson_cfg_base + reg);
}

static inline void meson_cfg_writel(struct meson_pcie *priv, u32 val, u32 reg)
{
	writel(val, priv->meson_cfg_base + reg);
}

/**
 * meson_pcie_configure() - Configure link
 *
 * @meson_pcie: Pointer to the PCI controller state
 *
 * Configure the link mode and width
 */
static void meson_pcie_configure(struct meson_pcie *priv)
{
	u32 val;

	dw_pcie_dbi_write_enable(&priv->dw, true);

	val = readl(priv->dw.dbi_base + PCIE_PORT_LINK_CONTROL);
	val &= ~PORT_LINK_FAST_LINK_MODE;
	val |= PORT_LINK_DLL_LINK_EN;
	val &= ~PORT_LINK_MODE_MASK;
	val |= PORT_LINK_MODE_1_LANES;
	writel(val, priv->dw.dbi_base + PCIE_PORT_LINK_CONTROL);

	val = readl(priv->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
	val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
	val |= PORT_LOGIC_LINK_WIDTH_1_LANES;
	writel(val, priv->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);

	dw_pcie_dbi_write_enable(&priv->dw, false);
}

static inline void meson_pcie_enable_ltssm(struct meson_pcie *priv)
{
	u32 val;

	val = meson_cfg_readl(priv, PCIE_CFG0);
	val |= APP_LTSSM_ENABLE;
	meson_cfg_writel(priv, val, PCIE_CFG0);
}

static int meson_pcie_wait_link_up(struct meson_pcie *priv)
{
	u32 speed_okay = 0;
	u32 cnt = 0;
	u32 state12, state17, smlh_up, ltssm_up, rdlh_up;

	do {
		state12 = meson_cfg_readl(priv, PCIE_CFG_STATUS12);
		state17 = meson_cfg_readl(priv, PCIE_CFG_STATUS17);
		smlh_up = IS_SMLH_LINK_UP(state12);
		rdlh_up = IS_RDLH_LINK_UP(state12);
		ltssm_up = IS_LTSSM_UP(state12);

		if (PM_CURRENT_STATE(state17) < PCIE_GEN3)
			speed_okay = 1;

		if (smlh_up)
			debug("%s: smlh_link_up is on\n", __func__);
		if (rdlh_up)
			debug("%s: rdlh_link_up is on\n", __func__);
		if (ltssm_up)
			debug("%s: ltssm_up is on\n", __func__);
		if (speed_okay)
			debug("%s: speed_okay\n", __func__);

		if (smlh_up && rdlh_up && ltssm_up && speed_okay)
			return 0;

		cnt++;

		udelay(10);
	} while (cnt < WAIT_LINKUP_TIMEOUT);

	printf("%s: error: wait linkup timeout\n", __func__);
	return -EIO;
}

/**
 * meson_pcie_link_up() - Wait for the link to come up
 *
 * @meson_pcie: Pointer to the PCI controller state
 * @cap_speed: Desired link speed
 *
 * Return: 1 (true) for active line and negative (false) for no link (timeout)
 */
static int meson_pcie_link_up(struct meson_pcie *priv, u32 cap_speed)
{
	/* DW link configurations */
	meson_pcie_configure(priv);

	/* Reset the device */
	if (dm_gpio_is_valid(&priv->rst_gpio)) {
		dm_gpio_set_value(&priv->rst_gpio, 1);
		/*
		 * Minimal is 100ms from spec but we see
		 * some wired devices need much more, such as 600ms.
		 * Add a enough delay to cover all cases.
		 */
		udelay(PERST_WAIT_US);
		dm_gpio_set_value(&priv->rst_gpio, 0);
	}

	/* Enable LTSSM */
	meson_pcie_enable_ltssm(priv);

	return meson_pcie_wait_link_up(priv);
}

static int meson_size_to_payload(int size)
{
	/*
	 * dwc supports 2^(val+7) payload size, which val is 0~5 default to 1.
	 * So if input size is not 2^order alignment or less than 2^7 or bigger
	 * than 2^12, just set to default size 2^(1+7).
	 */
	if (!is_power_of_2(size) || size < 128 || size > 4096) {
		debug("%s: payload size %d, set to default 256\n", __func__, size);
		return 1;
	}

	return fls(size) - 8;
}

static void meson_set_max_payload(struct meson_pcie *priv, int size)
{
	u32 val;
	u16 offset = dm_pci_find_capability(priv->dw.dev, PCI_CAP_ID_EXP);
	int max_payload_size = meson_size_to_payload(size);

	dw_pcie_dbi_write_enable(&priv->dw, true);

	val = readl(priv->dw.dbi_base + offset + PCI_EXP_DEVCTL);
	val &= ~PCI_EXP_DEVCTL_PAYLOAD;
	writel(val, priv->dw.dbi_base + offset + PCI_EXP_DEVCTL);

	val = readl(priv->dw.dbi_base + offset + PCI_EXP_DEVCTL);
	val |= PCIE_CAP_MAX_PAYLOAD_SIZE(max_payload_size);
	writel(val, priv->dw.dbi_base + PCI_EXP_DEVCTL);

	dw_pcie_dbi_write_enable(&priv->dw, false);
}

static void meson_set_max_rd_req_size(struct meson_pcie *priv, int size)
{
	u32 val;
	u16 offset = dm_pci_find_capability(priv->dw.dev, PCI_CAP_ID_EXP);
	int max_rd_req_size = meson_size_to_payload(size);

	dw_pcie_dbi_write_enable(&priv->dw, true);

	val = readl(priv->dw.dbi_base + offset + PCI_EXP_DEVCTL);
	val &= ~PCI_EXP_DEVCTL_PAYLOAD;
	writel(val, priv->dw.dbi_base + offset + PCI_EXP_DEVCTL);

	val = readl(priv->dw.dbi_base + offset + PCI_EXP_DEVCTL);
	val |= PCIE_CAP_MAX_READ_REQ_SIZE(max_rd_req_size);
	writel(val, priv->dw.dbi_base + PCI_EXP_DEVCTL);

	dw_pcie_dbi_write_enable(&priv->dw, false);
}

static int meson_pcie_init_port(struct udevice *dev)
{
	int ret;
	struct meson_pcie *priv = dev_get_priv(dev);

	ret = generic_phy_init(&priv->phy);
	if (ret) {
		dev_err(dev, "failed to init phy (ret=%d)\n", ret);
		return ret;
	}

	ret = generic_phy_power_on(&priv->phy);
	if (ret) {
		dev_err(dev, "failed to power on phy (ret=%d)\n", ret);
		goto err_exit_phy;
	}

	ret = generic_phy_reset(&priv->phy);
	if (ret) {
		dev_err(dev, "failed to reset phy (ret=%d)\n", ret);
		goto err_exit_phy;
	}

	ret = reset_assert_bulk(&priv->rsts);
	if (ret) {
		dev_err(dev, "failed to assert resets (ret=%d)\n", ret);
		goto err_power_off_phy;
	}

	udelay(PCIE_RESET_DELAY);

	ret = reset_deassert_bulk(&priv->rsts);
	if (ret) {
		dev_err(dev, "failed to deassert resets (ret=%d)\n", ret);
		goto err_power_off_phy;
	}

	udelay(PCIE_RESET_DELAY);

	ret = clk_set_rate(&priv->clk_port, PORT_CLK_RATE);
	if (ret) {
		dev_err(dev, "failed to set port clk rate (ret=%d)\n", ret);
		goto err_deassert_bulk;
	}

	ret = clk_enable(&priv->clk_general);
	if (ret) {
		dev_err(dev, "failed to enable clk general (ret=%d)\n", ret);
		goto err_deassert_bulk;
	}

	ret = clk_enable(&priv->clk_pclk);
	if (ret) {
		dev_err(dev, "failed to enable pclk (ret=%d)\n", ret);
		goto err_deassert_bulk;
	}

	meson_set_max_payload(priv, MAX_PAYLOAD_SIZE);
	meson_set_max_rd_req_size(priv, MAX_READ_REQ_SIZE);

	pcie_dw_setup_host(&priv->dw);

	ret = meson_pcie_link_up(priv, LINK_SPEED_GEN_2);
	if (ret < 0)
		goto err_link_up;

	return 0;
err_link_up:
	clk_disable(&priv->clk_port);
	clk_disable(&priv->clk_general);
	clk_disable(&priv->clk_pclk);
err_deassert_bulk:
	reset_assert_bulk(&priv->rsts);
err_power_off_phy:
	generic_phy_power_off(&priv->phy);
err_exit_phy:
	generic_phy_exit(&priv->phy);

	return ret;
}

static int meson_pcie_parse_dt(struct udevice *dev)
{
	struct meson_pcie *priv = dev_get_priv(dev);
	int ret;

	priv->dw.dbi_base = (void *)dev_read_addr_index(dev, 0);
	if (!priv->dw.dbi_base)
		return -ENODEV;

	dev_dbg(dev, "ELBI address is 0x%p\n", priv->dw.dbi_base);

	priv->meson_cfg_base = (void *)dev_read_addr_index(dev, 1);
	if (!priv->meson_cfg_base)
		return -ENODEV;

	dev_dbg(dev, "CFG address is 0x%p\n", priv->meson_cfg_base);

	ret = gpio_request_by_name(dev, "reset-gpios", 0,
				   &priv->rst_gpio, GPIOD_IS_OUT);
	if (ret) {
		dev_err(dev, "failed to find reset-gpios property\n");
		return ret;
	}

	ret = reset_get_bulk(dev, &priv->rsts);
	if (ret) {
		dev_err(dev, "Can't get reset: %d\n", ret);
		return ret;
	}

	ret = clk_get_by_name(dev, "port", &priv->clk_port);
	if (ret) {
		dev_err(dev, "Can't get port clock: %d\n", ret);
		return ret;
	}

	ret = clk_get_by_name(dev, "general", &priv->clk_general);
	if (ret) {
		dev_err(dev, "Can't get port clock: %d\n", ret);
		return ret;
	}

	ret = clk_get_by_name(dev, "pclk", &priv->clk_pclk);
	if (ret) {
		dev_err(dev, "Can't get port clock: %d\n", ret);
		return ret;
	}

	ret = generic_phy_get_by_index(dev, 0, &priv->phy);
	if (ret) {
		dev_err(dev, "failed to get pcie phy (ret=%d)\n", ret);
		return ret;
	}

	return 0;
}

/**
 * meson_pcie_probe() - Probe the PCIe bus for active link
 *
 * @dev: A pointer to the device being operated on
 *
 * Probe for an active link on the PCIe bus and configure the controller
 * to enable this port.
 *
 * Return: 0 on success, else -ENODEV
 */
static int meson_pcie_probe(struct udevice *dev)
{
	struct meson_pcie *priv = dev_get_priv(dev);
	struct udevice *ctlr = pci_get_controller(dev);
	struct pci_controller *hose = dev_get_uclass_priv(ctlr);
	int ret = 0;

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

	ret = meson_pcie_parse_dt(dev);
	if (ret)
		return ret;

	ret = meson_pcie_init_port(dev);
	if (ret) {
		dm_gpio_free(dev, &priv->rst_gpio);
		return ret;
	}

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

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

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

static const struct udevice_id meson_pcie_ids[] = {
	{ .compatible = "amlogic,axg-pcie" },
	{ .compatible = "amlogic,g12a-pcie" },
	{ }
};

U_BOOT_DRIVER(meson_dw_pcie) = {
	.name			= "pcie_dw_meson",
	.id			= UCLASS_PCI,
	.of_match		= meson_pcie_ids,
	.ops			= &meson_pcie_ops,
	.probe			= meson_pcie_probe,
	.priv_auto		= sizeof(struct meson_pcie),
};
