// SPDX-License-Identifier: GPL-2.0

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

#include <linux/clk.h>
#include <linux/device.h>
#include <linux/interconnect.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>

#include "linux/soc/qcom/qcom_aoss.h"

#include "ipa.h"
#include "ipa_data.h"
#include "ipa_endpoint.h"
#include "ipa_interrupt.h"
#include "ipa_modem.h"
#include "ipa_power.h"

/**
 * DOC: IPA Power Management
 *
 * The IPA hardware is enabled when the IPA core clock and all the
 * interconnects (buses) it depends on are enabled.  Runtime power
 * management is used to determine whether the core clock and
 * interconnects are enabled, and if not in use to be suspended
 * automatically.
 *
 * The core clock currently runs at a fixed clock rate when enabled,
 * an all interconnects use a fixed average and peak bandwidth.
 */

#define IPA_AUTOSUSPEND_DELAY	500	/* milliseconds */

/**
 * struct ipa_power - IPA power management information
 * @dev:		IPA device pointer
 * @core:		IPA core clock
 * @qmp:		QMP handle for AOSS communication
 * @interconnect_count:	Number of elements in interconnect[]
 * @interconnect:	Interconnect array
 */
struct ipa_power {
	struct device *dev;
	struct clk *core;
	struct qmp *qmp;
	u32 interconnect_count;
	struct icc_bulk_data interconnect[] __counted_by(interconnect_count);
};

/* Initialize interconnects required for IPA operation */
static int ipa_interconnect_init(struct ipa_power *power,
				 const struct ipa_interconnect_data *data)
{
	struct icc_bulk_data *interconnect;
	int ret;
	u32 i;

	/* Initialize our interconnect data array for bulk operations */
	interconnect = &power->interconnect[0];
	for (i = 0; i < power->interconnect_count; i++) {
		/* interconnect->path is filled in by of_icc_bulk_get() */
		interconnect->name = data->name;
		interconnect->avg_bw = data->average_bandwidth;
		interconnect->peak_bw = data->peak_bandwidth;
		data++;
		interconnect++;
	}

	ret = of_icc_bulk_get(power->dev, power->interconnect_count,
			      power->interconnect);
	if (ret)
		return ret;

	/* All interconnects are initially disabled */
	icc_bulk_disable(power->interconnect_count, power->interconnect);

	/* Set the bandwidth values to be used when enabled */
	ret = icc_bulk_set_bw(power->interconnect_count, power->interconnect);
	if (ret)
		icc_bulk_put(power->interconnect_count, power->interconnect);

	return ret;
}

/* Inverse of ipa_interconnect_init() */
static void ipa_interconnect_exit(struct ipa_power *power)
{
	icc_bulk_put(power->interconnect_count, power->interconnect);
}

/* Enable IPA power, enabling interconnects and the core clock */
static int ipa_power_enable(struct ipa *ipa)
{
	struct ipa_power *power = ipa->power;
	int ret;

	ret = icc_bulk_enable(power->interconnect_count, power->interconnect);
	if (ret)
		return ret;

	ret = clk_prepare_enable(power->core);
	if (ret) {
		dev_err(power->dev, "error %d enabling core clock\n", ret);
		icc_bulk_disable(power->interconnect_count,
				 power->interconnect);
	}

	return ret;
}

/* Inverse of ipa_power_enable() */
static void ipa_power_disable(struct ipa *ipa)
{
	struct ipa_power *power = ipa->power;

	clk_disable_unprepare(power->core);

	icc_bulk_disable(power->interconnect_count, power->interconnect);
}

static int ipa_runtime_suspend(struct device *dev)
{
	struct ipa *ipa = dev_get_drvdata(dev);

	/* Endpoints aren't usable until setup is complete */
	if (ipa->setup_complete) {
		ipa_endpoint_suspend(ipa);
		gsi_suspend(&ipa->gsi);
	}

	ipa_power_disable(ipa);

	return 0;
}

static int ipa_runtime_resume(struct device *dev)
{
	struct ipa *ipa = dev_get_drvdata(dev);
	int ret;

	ret = ipa_power_enable(ipa);
	if (WARN_ON(ret < 0))
		return ret;

	/* Endpoints aren't usable until setup is complete */
	if (ipa->setup_complete) {
		gsi_resume(&ipa->gsi);
		ipa_endpoint_resume(ipa);
	}

	return 0;
}

static int ipa_suspend(struct device *dev)
{
	struct ipa *ipa = dev_get_drvdata(dev);

	/* Increment the disable depth to ensure that the IRQ won't
	 * be re-enabled until the matching _enable call in
	 * ipa_resume(). We do this to ensure that the interrupt
	 * handler won't run whilst PM runtime is disabled.
	 *
	 * Note that disabling the IRQ is NOT the same as disabling
	 * irq wake. If wakeup is enabled for the IPA then the IRQ
	 * will still cause the system to wake up, see irq_set_irq_wake().
	 */
	ipa_interrupt_irq_disable(ipa);

	return pm_runtime_force_suspend(dev);
}

static int ipa_resume(struct device *dev)
{
	struct ipa *ipa = dev_get_drvdata(dev);
	int ret;

	ret = pm_runtime_force_resume(dev);

	/* Now that PM runtime is enabled again it's safe
	 * to turn the IRQ back on and process any data
	 * that was received during suspend.
	 */
	ipa_interrupt_irq_enable(ipa);

	return ret;
}

/* Return the current IPA core clock rate */
u32 ipa_core_clock_rate(struct ipa *ipa)
{
	return ipa->power ? (u32)clk_get_rate(ipa->power->core) : 0;
}

static int ipa_power_retention_init(struct ipa_power *power)
{
	struct qmp *qmp = qmp_get(power->dev);

	if (IS_ERR(qmp)) {
		if (PTR_ERR(qmp) == -EPROBE_DEFER)
			return -EPROBE_DEFER;

		/* We assume any other error means it's not defined/needed */
		qmp = NULL;
	}
	power->qmp = qmp;

	return 0;
}

static void ipa_power_retention_exit(struct ipa_power *power)
{
	qmp_put(power->qmp);
	power->qmp = NULL;
}

/* Control register retention on power collapse */
void ipa_power_retention(struct ipa *ipa, bool enable)
{
	static const char fmt[] = "{ class: bcm, res: ipa_pc, val: %c }";
	struct ipa_power *power = ipa->power;
	int ret;

	if (!power->qmp)
		return;		/* Not needed on this platform */

	ret = qmp_send(power->qmp, fmt, enable ? '1' : '0');
	if (ret)
		dev_err(power->dev, "error %d sending QMP %sable request\n",
			ret, enable ? "en" : "dis");
}

/* Initialize IPA power management */
struct ipa_power *
ipa_power_init(struct device *dev, const struct ipa_power_data *data)
{
	struct ipa_power *power;
	struct clk *clk;
	size_t size;
	int ret;

	clk = clk_get(dev, "core");
	if (IS_ERR(clk))
		return dev_err_cast_probe(dev, clk, "error getting core clock\n");

	ret = clk_set_rate(clk, data->core_clock_rate);
	if (ret) {
		dev_err(dev, "error %d setting core clock rate to %u\n",
			ret, data->core_clock_rate);
		goto err_clk_put;
	}

	size = struct_size(power, interconnect, data->interconnect_count);
	power = kzalloc(size, GFP_KERNEL);
	if (!power) {
		ret = -ENOMEM;
		goto err_clk_put;
	}
	power->dev = dev;
	power->core = clk;
	power->interconnect_count = data->interconnect_count;

	ret = ipa_interconnect_init(power, data->interconnect_data);
	if (ret)
		goto err_kfree;

	ret = ipa_power_retention_init(power);
	if (ret)
		goto err_interconnect_exit;

	pm_runtime_set_autosuspend_delay(dev, IPA_AUTOSUSPEND_DELAY);
	pm_runtime_use_autosuspend(dev);
	pm_runtime_enable(dev);

	return power;

err_interconnect_exit:
	ipa_interconnect_exit(power);
err_kfree:
	kfree(power);
err_clk_put:
	clk_put(clk);

	return ERR_PTR(ret);
}

/* Inverse of ipa_power_init() */
void ipa_power_exit(struct ipa_power *power)
{
	struct device *dev = power->dev;
	struct clk *clk = power->core;

	pm_runtime_disable(dev);
	pm_runtime_dont_use_autosuspend(dev);
	ipa_power_retention_exit(power);
	ipa_interconnect_exit(power);
	kfree(power);
	clk_put(clk);
}

const struct dev_pm_ops ipa_pm_ops = {
	.suspend		= ipa_suspend,
	.resume			= ipa_resume,
	.runtime_suspend	= ipa_runtime_suspend,
	.runtime_resume		= ipa_runtime_resume,
};
