// SPDX-License-Identifier: GPL-2.0

/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 * Copyright (C) 2018-2022 Linaro Ltd.
 */

#include <linux/types.h>
#include <linux/atomic.h>
#include <linux/bitfield.h>
#include <linux/device.h>
#include <linux/bug.h>
#include <linux/io.h>
#include <linux/firmware.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/pm_runtime.h>
#include <linux/qcom_scm.h>
#include <linux/soc/qcom/mdt_loader.h>

#include "ipa.h"
#include "ipa_power.h"
#include "ipa_data.h"
#include "ipa_endpoint.h"
#include "ipa_resource.h"
#include "ipa_cmd.h"
#include "ipa_reg.h"
#include "ipa_mem.h"
#include "ipa_table.h"
#include "ipa_smp2p.h"
#include "ipa_modem.h"
#include "ipa_uc.h"
#include "ipa_interrupt.h"
#include "gsi_trans.h"
#include "ipa_sysfs.h"

/**
 * DOC: The IP Accelerator
 *
 * This driver supports the Qualcomm IP Accelerator (IPA), which is a
 * networking component found in many Qualcomm SoCs.  The IPA is connected
 * to the application processor (AP), but is also connected (and partially
 * controlled by) other "execution environments" (EEs), such as a modem.
 *
 * The IPA is the conduit between the AP and the modem that carries network
 * traffic.  This driver presents a network interface representing the
 * connection of the modem to external (e.g. LTE) networks.
 *
 * The IPA provides protocol checksum calculation, offloading this work
 * from the AP.  The IPA offers additional functionality, including routing,
 * filtering, and NAT support, but that more advanced functionality is not
 * currently supported.  Despite that, some resources--including routing
 * tables and filter tables--are defined in this driver because they must
 * be initialized even when the advanced hardware features are not used.
 *
 * There are two distinct layers that implement the IPA hardware, and this
 * is reflected in the organization of the driver.  The generic software
 * interface (GSI) is an integral component of the IPA, providing a
 * well-defined communication layer between the AP subsystem and the IPA
 * core.  The GSI implements a set of "channels" used for communication
 * between the AP and the IPA.
 *
 * The IPA layer uses GSI channels to implement its "endpoints".  And while
 * a GSI channel carries data between the AP and the IPA, a pair of IPA
 * endpoints is used to carry traffic between two EEs.  Specifically, the main
 * modem network interface is implemented by two pairs of endpoints:  a TX
 * endpoint on the AP coupled with an RX endpoint on the modem; and another
 * RX endpoint on the AP receiving data from a TX endpoint on the modem.
 */

/* The name of the GSI firmware file relative to /lib/firmware */
#define IPA_FW_PATH_DEFAULT	"ipa_fws.mdt"
#define IPA_PAS_ID		15

/* Shift of 19.2 MHz timestamp to achieve lower resolution timestamps */
#define DPL_TIMESTAMP_SHIFT	14	/* ~1.172 kHz, ~853 usec per tick */
#define TAG_TIMESTAMP_SHIFT	14
#define NAT_TIMESTAMP_SHIFT	24	/* ~1.144 Hz, ~874 msec per tick */

/* Divider for 19.2 MHz crystal oscillator clock to get common timer clock */
#define IPA_XO_CLOCK_DIVIDER	192	/* 1 is subtracted where used */

/**
 * enum ipa_firmware_loader: How GSI firmware gets loaded
 *
 * @IPA_LOADER_DEFER:		System not ready; try again later
 * @IPA_LOADER_SELF:		AP loads GSI firmware
 * @IPA_LOADER_MODEM:		Modem loads GSI firmware, signals when done
 * @IPA_LOADER_SKIP:		Neither AP nor modem need to load GSI firmware
 * @IPA_LOADER_INVALID:	GSI firmware loader specification is invalid
 */
enum ipa_firmware_loader {
	IPA_LOADER_DEFER,
	IPA_LOADER_SELF,
	IPA_LOADER_MODEM,
	IPA_LOADER_SKIP,
	IPA_LOADER_INVALID,
};

/**
 * ipa_setup() - Set up IPA hardware
 * @ipa:	IPA pointer
 *
 * Perform initialization that requires issuing immediate commands on
 * the command TX endpoint.  If the modem is doing GSI firmware load
 * and initialization, this function will be called when an SMP2P
 * interrupt has been signaled by the modem.  Otherwise it will be
 * called from ipa_probe() after GSI firmware has been successfully
 * loaded, authenticated, and started by Trust Zone.
 */
int ipa_setup(struct ipa *ipa)
{
	struct ipa_endpoint *exception_endpoint;
	struct ipa_endpoint *command_endpoint;
	struct device *dev = &ipa->pdev->dev;
	int ret;

	ret = gsi_setup(&ipa->gsi);
	if (ret)
		return ret;

	ret = ipa_power_setup(ipa);
	if (ret)
		goto err_gsi_teardown;

	ipa_endpoint_setup(ipa);

	/* We need to use the AP command TX endpoint to perform other
	 * initialization, so we enable first.
	 */
	command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX];
	ret = ipa_endpoint_enable_one(command_endpoint);
	if (ret)
		goto err_endpoint_teardown;

	ret = ipa_mem_setup(ipa);	/* No matching teardown required */
	if (ret)
		goto err_command_disable;

	ret = ipa_table_setup(ipa);	/* No matching teardown required */
	if (ret)
		goto err_command_disable;

	/* Enable the exception handling endpoint, and tell the hardware
	 * to use it by default.
	 */
	exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX];
	ret = ipa_endpoint_enable_one(exception_endpoint);
	if (ret)
		goto err_command_disable;

	ipa_endpoint_default_route_set(ipa, exception_endpoint->endpoint_id);

	/* We're all set.  Now prepare for communication with the modem */
	ret = ipa_qmi_setup(ipa);
	if (ret)
		goto err_default_route_clear;

	ipa->setup_complete = true;

	dev_info(dev, "IPA driver setup completed successfully\n");

	return 0;

err_default_route_clear:
	ipa_endpoint_default_route_clear(ipa);
	ipa_endpoint_disable_one(exception_endpoint);
err_command_disable:
	ipa_endpoint_disable_one(command_endpoint);
err_endpoint_teardown:
	ipa_endpoint_teardown(ipa);
	ipa_power_teardown(ipa);
err_gsi_teardown:
	gsi_teardown(&ipa->gsi);

	return ret;
}

/**
 * ipa_teardown() - Inverse of ipa_setup()
 * @ipa:	IPA pointer
 */
static void ipa_teardown(struct ipa *ipa)
{
	struct ipa_endpoint *exception_endpoint;
	struct ipa_endpoint *command_endpoint;

	/* We're going to tear everything down, as if setup never completed */
	ipa->setup_complete = false;

	ipa_qmi_teardown(ipa);
	ipa_endpoint_default_route_clear(ipa);
	exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX];
	ipa_endpoint_disable_one(exception_endpoint);
	command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX];
	ipa_endpoint_disable_one(command_endpoint);
	ipa_endpoint_teardown(ipa);
	ipa_power_teardown(ipa);
	gsi_teardown(&ipa->gsi);
}

static void
ipa_hardware_config_bcr(struct ipa *ipa, const struct ipa_data *data)
{
	const struct ipa_reg *reg;
	u32 val;

	/* IPA v4.5+ has no backward compatibility register */
	if (ipa->version >= IPA_VERSION_4_5)
		return;

	reg = ipa_reg(ipa, IPA_BCR);
	val = data->backward_compat;
	iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
}

static void ipa_hardware_config_tx(struct ipa *ipa)
{
	enum ipa_version version = ipa->version;
	const struct ipa_reg *reg;
	u32 offset;
	u32 val;

	if (version <= IPA_VERSION_4_0 || version >= IPA_VERSION_4_5)
		return;

	/* Disable PA mask to allow HOLB drop */
	reg = ipa_reg(ipa, IPA_TX_CFG);
	offset = ipa_reg_offset(reg);

	val = ioread32(ipa->reg_virt + offset);

	val &= ~ipa_reg_bit(reg, PA_MASK_EN);

	iowrite32(val, ipa->reg_virt + offset);
}

static void ipa_hardware_config_clkon(struct ipa *ipa)
{
	enum ipa_version version = ipa->version;
	const struct ipa_reg *reg;
	u32 val;

	if (version >= IPA_VERSION_4_5)
		return;

	if (version < IPA_VERSION_4_0 && version != IPA_VERSION_3_1)
		return;

	/* Implement some hardware workarounds */
	reg = ipa_reg(ipa, CLKON_CFG);
	if (version == IPA_VERSION_3_1) {
		/* Disable MISC clock gating */
		val = ipa_reg_bit(reg, CLKON_MISC);
	} else {	/* IPA v4.0+ */
		/* Enable open global clocks in the CLKON configuration */
		val = ipa_reg_bit(reg, CLKON_GLOBAL);
		val |= ipa_reg_bit(reg, GLOBAL_2X_CLK);
	}

	iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
}

/* Configure bus access behavior for IPA components */
static void ipa_hardware_config_comp(struct ipa *ipa)
{
	const struct ipa_reg *reg;
	u32 offset;
	u32 val;

	/* Nothing to configure prior to IPA v4.0 */
	if (ipa->version < IPA_VERSION_4_0)
		return;

	reg = ipa_reg(ipa, COMP_CFG);
	offset = ipa_reg_offset(reg);
	val = ioread32(ipa->reg_virt + offset);

	if (ipa->version == IPA_VERSION_4_0) {
		val &= ~ipa_reg_bit(reg, IPA_QMB_SELECT_CONS_EN);
		val &= ~ipa_reg_bit(reg, IPA_QMB_SELECT_PROD_EN);
		val &= ~ipa_reg_bit(reg, IPA_QMB_SELECT_GLOBAL_EN);
	} else if (ipa->version < IPA_VERSION_4_5) {
		val |= ipa_reg_bit(reg, GSI_MULTI_AXI_MASTERS_DIS);
	} else {
		/* For IPA v4.5 FULL_FLUSH_WAIT_RS_CLOSURE_EN is 0 */
	}

	val |= ipa_reg_bit(reg, GSI_MULTI_INORDER_RD_DIS);
	val |= ipa_reg_bit(reg, GSI_MULTI_INORDER_WR_DIS);

	iowrite32(val, ipa->reg_virt + offset);
}

/* Configure DDR and (possibly) PCIe max read/write QSB values */
static void
ipa_hardware_config_qsb(struct ipa *ipa, const struct ipa_data *data)
{
	const struct ipa_qsb_data *data0;
	const struct ipa_qsb_data *data1;
	const struct ipa_reg *reg;
	u32 val;

	/* QMB 0 represents DDR; QMB 1 (if present) represents PCIe */
	data0 = &data->qsb_data[IPA_QSB_MASTER_DDR];
	if (data->qsb_count > 1)
		data1 = &data->qsb_data[IPA_QSB_MASTER_PCIE];

	/* Max outstanding write accesses for QSB masters */
	reg = ipa_reg(ipa, QSB_MAX_WRITES);

	val = ipa_reg_encode(reg, GEN_QMB_0_MAX_WRITES, data0->max_writes);
	if (data->qsb_count > 1)
		val |= ipa_reg_encode(reg, GEN_QMB_1_MAX_WRITES,
				      data1->max_writes);

	iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));

	/* Max outstanding read accesses for QSB masters */
	reg = ipa_reg(ipa, QSB_MAX_READS);

	val = ipa_reg_encode(reg, GEN_QMB_0_MAX_READS, data0->max_reads);
	if (ipa->version >= IPA_VERSION_4_0)
		val |= ipa_reg_encode(reg, GEN_QMB_0_MAX_READS_BEATS,
				      data0->max_reads_beats);
	if (data->qsb_count > 1) {
		val = ipa_reg_encode(reg, GEN_QMB_1_MAX_READS,
				     data1->max_reads);
		if (ipa->version >= IPA_VERSION_4_0)
			val |= ipa_reg_encode(reg, GEN_QMB_1_MAX_READS_BEATS,
					      data1->max_reads_beats);
	}

	iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
}

/* The internal inactivity timer clock is used for the aggregation timer */
#define TIMER_FREQUENCY	32000		/* 32 KHz inactivity timer clock */

/* Compute the value to use in the COUNTER_CFG register AGGR_GRANULARITY
 * field to represent the given number of microseconds.  The value is one
 * less than the number of timer ticks in the requested period.  0 is not
 * a valid granularity value (so for example @usec must be at least 16 for
 * a TIMER_FREQUENCY of 32000).
 */
static __always_inline u32 ipa_aggr_granularity_val(u32 usec)
{
	return DIV_ROUND_CLOSEST(usec * TIMER_FREQUENCY, USEC_PER_SEC) - 1;
}

/* IPA uses unified Qtime starting at IPA v4.5, implementing various
 * timestamps and timers independent of the IPA core clock rate.  The
 * Qtimer is based on a 56-bit timestamp incremented at each tick of
 * a 19.2 MHz SoC crystal oscillator (XO clock).
 *
 * For IPA timestamps (tag, NAT, data path logging) a lower resolution
 * timestamp is achieved by shifting the Qtimer timestamp value right
 * some number of bits to produce the low-order bits of the coarser
 * granularity timestamp.
 *
 * For timers, a common timer clock is derived from the XO clock using
 * a divider (we use 192, to produce a 100kHz timer clock).  From
 * this common clock, three "pulse generators" are used to produce
 * timer ticks at a configurable frequency.  IPA timers (such as
 * those used for aggregation or head-of-line block handling) now
 * define their period based on one of these pulse generators.
 */
static void ipa_qtime_config(struct ipa *ipa)
{
	const struct ipa_reg *reg;
	u32 offset;
	u32 val;

	/* Timer clock divider must be disabled when we change the rate */
	reg = ipa_reg(ipa, TIMERS_XO_CLK_DIV_CFG);
	iowrite32(0, ipa->reg_virt + ipa_reg_offset(reg));

	reg = ipa_reg(ipa, QTIME_TIMESTAMP_CFG);
	/* Set DPL time stamp resolution to use Qtime (instead of 1 msec) */
	val = ipa_reg_encode(reg, DPL_TIMESTAMP_LSB, DPL_TIMESTAMP_SHIFT);
	val |= ipa_reg_bit(reg, DPL_TIMESTAMP_SEL);
	/* Configure tag and NAT Qtime timestamp resolution as well */
	val = ipa_reg_encode(reg, TAG_TIMESTAMP_LSB, TAG_TIMESTAMP_SHIFT);
	val = ipa_reg_encode(reg, NAT_TIMESTAMP_LSB, NAT_TIMESTAMP_SHIFT);

	iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));

	/* Set granularity of pulse generators used for other timers */
	reg = ipa_reg(ipa, TIMERS_PULSE_GRAN_CFG);
	val = ipa_reg_encode(reg, PULSE_GRAN_0, IPA_GRAN_100_US);
	val |= ipa_reg_encode(reg, PULSE_GRAN_1, IPA_GRAN_1_MS);
	val |= ipa_reg_encode(reg, PULSE_GRAN_2, IPA_GRAN_1_MS);

	iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));

	/* Actual divider is 1 more than value supplied here */
	reg = ipa_reg(ipa, TIMERS_XO_CLK_DIV_CFG);
	offset = ipa_reg_offset(reg);
	val = ipa_reg_encode(reg, DIV_VALUE, IPA_XO_CLOCK_DIVIDER - 1);

	iowrite32(val, ipa->reg_virt + offset);

	/* Divider value is set; re-enable the common timer clock divider */
	val |= ipa_reg_bit(reg, DIV_ENABLE);

	iowrite32(val, ipa->reg_virt + offset);
}

/* Before IPA v4.5 timing is controlled by a counter register */
static void ipa_hardware_config_counter(struct ipa *ipa)
{
	u32 granularity = ipa_aggr_granularity_val(IPA_AGGR_GRANULARITY);
	const struct ipa_reg *reg;
	u32 val;

	reg = ipa_reg(ipa, COUNTER_CFG);
	/* If defined, EOT_COAL_GRANULARITY is 0 */
	val = ipa_reg_encode(reg, AGGR_GRANULARITY, granularity);
	iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
}

static void ipa_hardware_config_timing(struct ipa *ipa)
{
	if (ipa->version < IPA_VERSION_4_5)
		ipa_hardware_config_counter(ipa);
	else
		ipa_qtime_config(ipa);
}

static void ipa_hardware_config_hashing(struct ipa *ipa)
{
	const struct ipa_reg *reg;

	if (ipa->version != IPA_VERSION_4_2)
		return;

	/* IPA v4.2 does not support hashed tables, so disable them */
	reg = ipa_reg(ipa, FILT_ROUT_HASH_EN);

	/* IPV6_ROUTER_HASH, IPV6_FILTER_HASH, IPV4_ROUTER_HASH,
	 * IPV4_FILTER_HASH are all zero.
	 */
	iowrite32(0, ipa->reg_virt + ipa_reg_offset(reg));
}

static void ipa_idle_indication_cfg(struct ipa *ipa,
				    u32 enter_idle_debounce_thresh,
				    bool const_non_idle_enable)
{
	const struct ipa_reg *reg;
	u32 val;

	if (ipa->version < IPA_VERSION_3_5_1)
		return;

	reg = ipa_reg(ipa, IDLE_INDICATION_CFG);
	val = ipa_reg_encode(reg, ENTER_IDLE_DEBOUNCE_THRESH,
			     enter_idle_debounce_thresh);
	if (const_non_idle_enable)
		val |= ipa_reg_bit(reg, CONST_NON_IDLE_ENABLE);

	iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
}

/**
 * ipa_hardware_dcd_config() - Enable dynamic clock division on IPA
 * @ipa:	IPA pointer
 *
 * Configures when the IPA signals it is idle to the global clock
 * controller, which can respond by scaling down the clock to save
 * power.
 */
static void ipa_hardware_dcd_config(struct ipa *ipa)
{
	/* Recommended values for IPA 3.5 and later according to IPA HPG */
	ipa_idle_indication_cfg(ipa, 256, false);
}

static void ipa_hardware_dcd_deconfig(struct ipa *ipa)
{
	/* Power-on reset values */
	ipa_idle_indication_cfg(ipa, 0, true);
}

/**
 * ipa_hardware_config() - Primitive hardware initialization
 * @ipa:	IPA pointer
 * @data:	IPA configuration data
 */
static void ipa_hardware_config(struct ipa *ipa, const struct ipa_data *data)
{
	ipa_hardware_config_bcr(ipa, data);
	ipa_hardware_config_tx(ipa);
	ipa_hardware_config_clkon(ipa);
	ipa_hardware_config_comp(ipa);
	ipa_hardware_config_qsb(ipa, data);
	ipa_hardware_config_timing(ipa);
	ipa_hardware_config_hashing(ipa);
	ipa_hardware_dcd_config(ipa);
}

/**
 * ipa_hardware_deconfig() - Inverse of ipa_hardware_config()
 * @ipa:	IPA pointer
 *
 * This restores the power-on reset values (even if they aren't different)
 */
static void ipa_hardware_deconfig(struct ipa *ipa)
{
	/* Mostly we just leave things as we set them. */
	ipa_hardware_dcd_deconfig(ipa);
}

/**
 * ipa_config() - Configure IPA hardware
 * @ipa:	IPA pointer
 * @data:	IPA configuration data
 *
 * Perform initialization requiring IPA power to be enabled.
 */
static int ipa_config(struct ipa *ipa, const struct ipa_data *data)
{
	int ret;

	ipa_hardware_config(ipa, data);

	ret = ipa_mem_config(ipa);
	if (ret)
		goto err_hardware_deconfig;

	ipa->interrupt = ipa_interrupt_config(ipa);
	if (IS_ERR(ipa->interrupt)) {
		ret = PTR_ERR(ipa->interrupt);
		ipa->interrupt = NULL;
		goto err_mem_deconfig;
	}

	ipa_uc_config(ipa);

	ret = ipa_endpoint_config(ipa);
	if (ret)
		goto err_uc_deconfig;

	ipa_table_config(ipa);		/* No deconfig required */

	/* Assign resource limitation to each group; no deconfig required */
	ret = ipa_resource_config(ipa, data->resource_data);
	if (ret)
		goto err_endpoint_deconfig;

	ret = ipa_modem_config(ipa);
	if (ret)
		goto err_endpoint_deconfig;

	return 0;

err_endpoint_deconfig:
	ipa_endpoint_deconfig(ipa);
err_uc_deconfig:
	ipa_uc_deconfig(ipa);
	ipa_interrupt_deconfig(ipa->interrupt);
	ipa->interrupt = NULL;
err_mem_deconfig:
	ipa_mem_deconfig(ipa);
err_hardware_deconfig:
	ipa_hardware_deconfig(ipa);

	return ret;
}

/**
 * ipa_deconfig() - Inverse of ipa_config()
 * @ipa:	IPA pointer
 */
static void ipa_deconfig(struct ipa *ipa)
{
	ipa_modem_deconfig(ipa);
	ipa_endpoint_deconfig(ipa);
	ipa_uc_deconfig(ipa);
	ipa_interrupt_deconfig(ipa->interrupt);
	ipa->interrupt = NULL;
	ipa_mem_deconfig(ipa);
	ipa_hardware_deconfig(ipa);
}

static int ipa_firmware_load(struct device *dev)
{
	const struct firmware *fw;
	struct device_node *node;
	struct resource res;
	phys_addr_t phys;
	const char *path;
	ssize_t size;
	void *virt;
	int ret;

	node = of_parse_phandle(dev->of_node, "memory-region", 0);
	if (!node) {
		dev_err(dev, "DT error getting \"memory-region\" property\n");
		return -EINVAL;
	}

	ret = of_address_to_resource(node, 0, &res);
	of_node_put(node);
	if (ret) {
		dev_err(dev, "error %d getting \"memory-region\" resource\n",
			ret);
		return ret;
	}

	/* Use name from DTB if specified; use default for *any* error */
	ret = of_property_read_string(dev->of_node, "firmware-name", &path);
	if (ret) {
		dev_dbg(dev, "error %d getting \"firmware-name\" resource\n",
			ret);
		path = IPA_FW_PATH_DEFAULT;
	}

	ret = request_firmware(&fw, path, dev);
	if (ret) {
		dev_err(dev, "error %d requesting \"%s\"\n", ret, path);
		return ret;
	}

	phys = res.start;
	size = (size_t)resource_size(&res);
	virt = memremap(phys, size, MEMREMAP_WC);
	if (!virt) {
		dev_err(dev, "unable to remap firmware memory\n");
		ret = -ENOMEM;
		goto out_release_firmware;
	}

	ret = qcom_mdt_load(dev, fw, path, IPA_PAS_ID, virt, phys, size, NULL);
	if (ret)
		dev_err(dev, "error %d loading \"%s\"\n", ret, path);
	else if ((ret = qcom_scm_pas_auth_and_reset(IPA_PAS_ID)))
		dev_err(dev, "error %d authenticating \"%s\"\n", ret, path);

	memunmap(virt);
out_release_firmware:
	release_firmware(fw);

	return ret;
}

static const struct of_device_id ipa_match[] = {
	{
		.compatible	= "qcom,msm8998-ipa",
		.data		= &ipa_data_v3_1,
	},
	{
		.compatible	= "qcom,sdm845-ipa",
		.data		= &ipa_data_v3_5_1,
	},
	{
		.compatible	= "qcom,sc7180-ipa",
		.data		= &ipa_data_v4_2,
	},
	{
		.compatible	= "qcom,sdx55-ipa",
		.data		= &ipa_data_v4_5,
	},
	{
		.compatible	= "qcom,sm6350-ipa",
		.data		= &ipa_data_v4_7,
	},
	{
		.compatible	= "qcom,sm8350-ipa",
		.data		= &ipa_data_v4_9,
	},
	{
		.compatible	= "qcom,sc7280-ipa",
		.data		= &ipa_data_v4_11,
	},
	{ },
};
MODULE_DEVICE_TABLE(of, ipa_match);

/* Check things that can be validated at build time.  This just
 * groups these things BUILD_BUG_ON() calls don't clutter the rest
 * of the code.
 * */
static void ipa_validate_build(void)
{
	/* At one time we assumed a 64-bit build, allowing some do_div()
	 * calls to be replaced by simple division or modulo operations.
	 * We currently only perform divide and modulo operations on u32,
	 * u16, or size_t objects, and of those only size_t has any chance
	 * of being a 64-bit value.  (It should be guaranteed 32 bits wide
	 * on a 32-bit build, but there is no harm in verifying that.)
	 */
	BUILD_BUG_ON(!IS_ENABLED(CONFIG_64BIT) && sizeof(size_t) != 4);

	/* Code assumes the EE ID for the AP is 0 (zeroed structure field) */
	BUILD_BUG_ON(GSI_EE_AP != 0);

	/* There's no point if we have no channels or event rings */
	BUILD_BUG_ON(!GSI_CHANNEL_COUNT_MAX);
	BUILD_BUG_ON(!GSI_EVT_RING_COUNT_MAX);

	/* GSI hardware design limits */
	BUILD_BUG_ON(GSI_CHANNEL_COUNT_MAX > 32);
	BUILD_BUG_ON(GSI_EVT_RING_COUNT_MAX > 31);

	/* The number of TREs in a transaction is limited by the channel's
	 * TLV FIFO size.  A transaction structure uses 8-bit fields
	 * to represents the number of TREs it has allocated and used.
	 */
	BUILD_BUG_ON(GSI_TLV_MAX > U8_MAX);

	/* This is used as a divisor */
	BUILD_BUG_ON(!IPA_AGGR_GRANULARITY);

	/* Aggregation granularity value can't be 0, and must fit */
	BUILD_BUG_ON(!ipa_aggr_granularity_val(IPA_AGGR_GRANULARITY));
}

static enum ipa_firmware_loader ipa_firmware_loader(struct device *dev)
{
	bool modem_init;
	const char *str;
	int ret;

	/* Look up the old and new properties by name */
	modem_init = of_property_read_bool(dev->of_node, "modem-init");
	ret = of_property_read_string(dev->of_node, "qcom,gsi-loader", &str);

	/* If the new property doesn't exist, it's legacy behavior */
	if (ret == -EINVAL) {
		if (modem_init)
			return IPA_LOADER_MODEM;
		goto out_self;
	}

	/* Any other error on the new property means it's poorly defined */
	if (ret)
		return IPA_LOADER_INVALID;

	/* New property value exists; if old one does too, that's invalid */
	if (modem_init)
		return IPA_LOADER_INVALID;

	/* Modem loads GSI firmware for "modem" */
	if (!strcmp(str, "modem"))
		return IPA_LOADER_MODEM;

	/* No GSI firmware load is needed for "skip" */
	if (!strcmp(str, "skip"))
		return IPA_LOADER_SKIP;

	/* Any value other than "self" is an error */
	if (strcmp(str, "self"))
		return IPA_LOADER_INVALID;
out_self:
	/* We need Trust Zone to load firmware; make sure it's available */
	if (qcom_scm_is_available())
		return IPA_LOADER_SELF;

	return IPA_LOADER_DEFER;
}

/**
 * ipa_probe() - IPA platform driver probe function
 * @pdev:	Platform device pointer
 *
 * Return:	0 if successful, or a negative error code (possibly
 *		EPROBE_DEFER)
 *
 * This is the main entry point for the IPA driver.  Initialization proceeds
 * in several stages:
 *   - The "init" stage involves activities that can be initialized without
 *     access to the IPA hardware.
 *   - The "config" stage requires IPA power to be active so IPA registers
 *     can be accessed, but does not require the use of IPA immediate commands.
 *   - The "setup" stage uses IPA immediate commands, and so requires the GSI
 *     layer to be initialized.
 *
 * A Boolean Device Tree "modem-init" property determines whether GSI
 * initialization will be performed by the AP (Trust Zone) or the modem.
 * If the AP does GSI initialization, the setup phase is entered after
 * this has completed successfully.  Otherwise the modem initializes
 * the GSI layer and signals it has finished by sending an SMP2P interrupt
 * to the AP; this triggers the start if IPA setup.
 */
static int ipa_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	enum ipa_firmware_loader loader;
	const struct ipa_data *data;
	struct ipa_power *power;
	struct ipa *ipa;
	int ret;

	ipa_validate_build();

	/* Get configuration data early; needed for power initialization */
	data = of_device_get_match_data(dev);
	if (!data) {
		dev_err(dev, "matched hardware not supported\n");
		return -ENODEV;
	}

	if (!ipa_version_supported(data->version)) {
		dev_err(dev, "unsupported IPA version %u\n", data->version);
		return -EINVAL;
	}

	if (!data->modem_route_count) {
		dev_err(dev, "modem_route_count cannot be zero\n");
		return -EINVAL;
	}

	loader = ipa_firmware_loader(dev);
	if (loader == IPA_LOADER_INVALID)
		return -EINVAL;
	if (loader == IPA_LOADER_DEFER)
		return -EPROBE_DEFER;

	/* The clock and interconnects might not be ready when we're
	 * probed, so might return -EPROBE_DEFER.
	 */
	power = ipa_power_init(dev, data->power_data);
	if (IS_ERR(power))
		return PTR_ERR(power);

	/* No more EPROBE_DEFER.  Allocate and initialize the IPA structure */
	ipa = kzalloc(sizeof(*ipa), GFP_KERNEL);
	if (!ipa) {
		ret = -ENOMEM;
		goto err_power_exit;
	}

	ipa->pdev = pdev;
	dev_set_drvdata(dev, ipa);
	ipa->power = power;
	ipa->version = data->version;
	ipa->modem_route_count = data->modem_route_count;
	init_completion(&ipa->completion);

	ret = ipa_reg_init(ipa);
	if (ret)
		goto err_kfree_ipa;

	ret = ipa_mem_init(ipa, data->mem_data);
	if (ret)
		goto err_reg_exit;

	ret = gsi_init(&ipa->gsi, pdev, ipa->version, data->endpoint_count,
		       data->endpoint_data);
	if (ret)
		goto err_mem_exit;

	/* Result is a non-zero mask of endpoints that support filtering */
	ret = ipa_endpoint_init(ipa, data->endpoint_count, data->endpoint_data);
	if (ret)
		goto err_gsi_exit;

	ret = ipa_table_init(ipa);
	if (ret)
		goto err_endpoint_exit;

	ret = ipa_smp2p_init(ipa, loader == IPA_LOADER_MODEM);
	if (ret)
		goto err_table_exit;

	/* Power needs to be active for config and setup */
	ret = pm_runtime_get_sync(dev);
	if (WARN_ON(ret < 0))
		goto err_power_put;

	ret = ipa_config(ipa, data);
	if (ret)
		goto err_power_put;

	dev_info(dev, "IPA driver initialized");

	/* If the modem is loading GSI firmware, it will trigger a call to
	 * ipa_setup() when it has finished.  In that case we're done here.
	 */
	if (loader == IPA_LOADER_MODEM)
		goto done;

	if (loader == IPA_LOADER_SELF) {
		/* The AP is loading GSI firmware; do so now */
		ret = ipa_firmware_load(dev);
		if (ret)
			goto err_deconfig;
	} /* Otherwise loader == IPA_LOADER_SKIP */

	/* GSI firmware is loaded; proceed to setup */
	ret = ipa_setup(ipa);
	if (ret)
		goto err_deconfig;
done:
	pm_runtime_mark_last_busy(dev);
	(void)pm_runtime_put_autosuspend(dev);

	return 0;

err_deconfig:
	ipa_deconfig(ipa);
err_power_put:
	pm_runtime_put_noidle(dev);
	ipa_smp2p_exit(ipa);
err_table_exit:
	ipa_table_exit(ipa);
err_endpoint_exit:
	ipa_endpoint_exit(ipa);
err_gsi_exit:
	gsi_exit(&ipa->gsi);
err_mem_exit:
	ipa_mem_exit(ipa);
err_reg_exit:
	ipa_reg_exit(ipa);
err_kfree_ipa:
	kfree(ipa);
err_power_exit:
	ipa_power_exit(power);

	return ret;
}

static int ipa_remove(struct platform_device *pdev)
{
	struct ipa *ipa = dev_get_drvdata(&pdev->dev);
	struct ipa_power *power = ipa->power;
	struct device *dev = &pdev->dev;
	int ret;

	/* Prevent the modem from triggering a call to ipa_setup().  This
	 * also ensures a modem-initiated setup that's underway completes.
	 */
	ipa_smp2p_irq_disable_setup(ipa);

	ret = pm_runtime_get_sync(dev);
	if (WARN_ON(ret < 0))
		goto out_power_put;

	if (ipa->setup_complete) {
		ret = ipa_modem_stop(ipa);
		/* If starting or stopping is in progress, try once more */
		if (ret == -EBUSY) {
			usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
			ret = ipa_modem_stop(ipa);
		}
		if (ret)
			return ret;

		ipa_teardown(ipa);
	}

	ipa_deconfig(ipa);
out_power_put:
	pm_runtime_put_noidle(dev);
	ipa_smp2p_exit(ipa);
	ipa_table_exit(ipa);
	ipa_endpoint_exit(ipa);
	gsi_exit(&ipa->gsi);
	ipa_mem_exit(ipa);
	ipa_reg_exit(ipa);
	kfree(ipa);
	ipa_power_exit(power);

	dev_info(dev, "IPA driver removed");

	return 0;
}

static void ipa_shutdown(struct platform_device *pdev)
{
	int ret;

	ret = ipa_remove(pdev);
	if (ret)
		dev_err(&pdev->dev, "shutdown: remove returned %d\n", ret);
}

static const struct attribute_group *ipa_attribute_groups[] = {
	&ipa_attribute_group,
	&ipa_feature_attribute_group,
	&ipa_endpoint_id_attribute_group,
	&ipa_modem_attribute_group,
	NULL,
};

static struct platform_driver ipa_driver = {
	.probe		= ipa_probe,
	.remove		= ipa_remove,
	.shutdown	= ipa_shutdown,
	.driver	= {
		.name		= "ipa",
		.pm		= &ipa_pm_ops,
		.of_match_table	= ipa_match,
		.dev_groups	= ipa_attribute_groups,
	},
};

module_platform_driver(ipa_driver);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Qualcomm IP Accelerator device driver");
