// SPDX-License-Identifier: GPL-2.0

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

#include <linux/bug.h>
#include <linux/firmware.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/types.h>

#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/soc/qcom/mdt_loader.h>

#include "ipa.h"
#include "ipa_cmd.h"
#include "ipa_data.h"
#include "ipa_endpoint.h"
#include "ipa_interrupt.h"
#include "ipa_mem.h"
#include "ipa_modem.h"
#include "ipa_power.h"
#include "ipa_reg.h"
#include "ipa_resource.h"
#include "ipa_smp2p.h"
#include "ipa_sysfs.h"
#include "ipa_table.h"
#include "ipa_uc.h"
#include "ipa_version.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 */
/* IPA v5.5+ does not specify Qtime timestamp config for DPL */
#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->dev;
	int ret;

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

	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);
	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);
	gsi_teardown(&ipa->gsi);
}

static void
ipa_hardware_config_bcr(struct ipa *ipa, const struct ipa_data *data)
{
	const struct 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 + reg_offset(reg));
}

static void ipa_hardware_config_tx(struct ipa *ipa)
{
	enum ipa_version version = ipa->version;
	const struct 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 = reg_offset(reg);

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

	val &= ~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 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 = reg_bit(reg, CLKON_MISC);
	} else {	/* IPA v4.0+ */
		/* Enable open global clocks in the CLKON configuration */
		val = reg_bit(reg, CLKON_GLOBAL);
		val |= reg_bit(reg, GLOBAL_2X_CLK);
	}

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

/* Configure bus access behavior for IPA components */
static void ipa_hardware_config_comp(struct ipa *ipa)
{
	const struct 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 = reg_offset(reg);

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

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

	val |= reg_bit(reg, GSI_MULTI_INORDER_RD_DIS);
	val |= 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 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 = reg_encode(reg, GEN_QMB_0_MAX_WRITES, data0->max_writes);
	if (data->qsb_count > 1)
		val |= reg_encode(reg, GEN_QMB_1_MAX_WRITES, data1->max_writes);

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

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

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

	iowrite32(val, ipa->reg_virt + 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 reg *reg;
	u32 offset;
	u32 val = 0;

	/* 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 + reg_offset(reg));

	reg = ipa_reg(ipa, QTIME_TIMESTAMP_CFG);
	if (ipa->version < IPA_VERSION_5_5) {
		/* Set DPL time stamp resolution to use Qtime (not 1 msec) */
		val = reg_encode(reg, DPL_TIMESTAMP_LSB, DPL_TIMESTAMP_SHIFT);
		val |= reg_bit(reg, DPL_TIMESTAMP_SEL);
	}
	/* Configure tag and NAT Qtime timestamp resolution as well */
	val |= reg_encode(reg, TAG_TIMESTAMP_LSB, TAG_TIMESTAMP_SHIFT);
	val |= reg_encode(reg, NAT_TIMESTAMP_LSB, NAT_TIMESTAMP_SHIFT);

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

	/* Set granularity of pulse generators used for other timers */
	reg = ipa_reg(ipa, TIMERS_PULSE_GRAN_CFG);
	val = reg_encode(reg, PULSE_GRAN_0, IPA_GRAN_100_US);
	val |= reg_encode(reg, PULSE_GRAN_1, IPA_GRAN_1_MS);
	if (ipa->version >= IPA_VERSION_5_0) {
		val |= reg_encode(reg, PULSE_GRAN_2, IPA_GRAN_10_MS);
		val |= reg_encode(reg, PULSE_GRAN_3, IPA_GRAN_10_MS);
	} else {
		val |= reg_encode(reg, PULSE_GRAN_2, IPA_GRAN_1_MS);
	}

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

	/* Actual divider is 1 more than value supplied here */
	reg = ipa_reg(ipa, TIMERS_XO_CLK_DIV_CFG);
	offset = reg_offset(reg);

	val = 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 |= 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 reg *reg;
	u32 val;

	reg = ipa_reg(ipa, COUNTER_CFG);
	/* If defined, EOT_COAL_GRANULARITY is 0 */
	val = reg_encode(reg, AGGR_GRANULARITY, granularity);
	iowrite32(val, ipa->reg_virt + 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 reg *reg;

	/* Other than IPA v4.2, all versions enable "hashing".  Starting
	 * with IPA v5.0, the filter and router tables are implemented
	 * differently, but the default configuration enables this feature
	 * (now referred to as "cacheing"), so there's nothing to do here.
	 */
	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 + reg_offset(reg));
}

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

	if (ipa->version < IPA_VERSION_3_5_1)
		return;

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

	iowrite32(val, ipa->reg_virt + 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;

	ret = ipa_interrupt_config(ipa);
	if (ret)
		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);
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);
	ipa_mem_deconfig(ipa);
	ipa_hardware_deconfig(ipa);
}

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

	ret = of_reserved_mem_region_to_resource(dev->of_node, 0, &res);
	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,
	},
	{
		.compatible	= "qcom,sdx65-ipa",
		.data		= &ipa_data_v5_0,
	},
	{
		.compatible	= "qcom,milos-ipa",
		.data		= &ipa_data_v5_2,
	},
	{
		.compatible	= "qcom,sm8550-ipa",
		.data		= &ipa_data_v5_5,
	},
	{ },
};
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;
	struct ipa_interrupt *interrupt;
	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 (!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 IPA interrupt might not be ready when we're probed, so this
	 * might return -EPROBE_DEFER.
	 */
	interrupt = ipa_interrupt_init(pdev);
	if (IS_ERR(interrupt))
		return PTR_ERR(interrupt);

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

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

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

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

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

	ret = ipa_cmd_init(ipa);
	if (ret)
		goto err_mem_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, pdev, 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:
	(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);
err_interrupt_exit:
	ipa_interrupt_exit(interrupt);

	return ret;
}

static void ipa_remove(struct platform_device *pdev)
{
	struct ipa_interrupt *interrupt;
	struct ipa_power *power;
	struct device *dev;
	struct ipa *ipa;
	int ret;

	ipa = dev_get_drvdata(&pdev->dev);
	dev = ipa->dev;
	WARN_ON(dev != &pdev->dev);

	power = ipa->power;
	interrupt = ipa->interrupt;

	/* 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) {
			/*
			 * Not cleaning up here properly might also yield a
			 * crash later on. As the device is still unregistered
			 * in this case, this might even yield a crash later on.
			 */
			dev_err(dev, "Failed to stop modem (%pe), leaking resources\n",
				ERR_PTR(ret));
			return;
		}

		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);
	ipa_interrupt_exit(interrupt);

	dev_info(dev, "IPA driver removed");
}

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_remove,
	.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");
