// SPDX-License-Identifier: GPL-2.0-only

/*
 * Copyright (C) 2021, Linaro Limited. All rights reserved.
 */
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqdesc.h>
#include <linux/irqdomain.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/firmware/qcom/qcom_scm.h>

#define LMH_NODE_DCVS			0x44435653
#define LMH_CLUSTER0_NODE_ID		0x6370302D
#define LMH_CLUSTER1_NODE_ID		0x6370312D

#define LMH_SUB_FN_THERMAL		0x54484D4C
#define LMH_SUB_FN_CRNT			0x43524E54
#define LMH_SUB_FN_REL			0x52454C00
#define LMH_SUB_FN_BCL			0x42434C00

#define LMH_ALGO_MODE_ENABLE		0x454E424C
#define LMH_TH_HI_THRESHOLD		0x48494748
#define LMH_TH_LOW_THRESHOLD		0x4C4F5700
#define LMH_TH_ARM_THRESHOLD		0x41524D00

#define LMH_REG_DCVS_INTR_CLR		0x8

#define LMH_ENABLE_ALGOS		1

struct lmh_hw_data {
	void __iomem *base;
	struct irq_domain *domain;
	int irq;
};

static irqreturn_t lmh_handle_irq(int hw_irq, void *data)
{
	struct lmh_hw_data *lmh_data = data;
	int irq = irq_find_mapping(lmh_data->domain, 0);

	/* Call the cpufreq driver to handle the interrupt */
	if (irq)
		generic_handle_irq(irq);

	return IRQ_HANDLED;
}

static void lmh_enable_interrupt(struct irq_data *d)
{
	struct lmh_hw_data *lmh_data = irq_data_get_irq_chip_data(d);

	/* Clear the existing interrupt */
	writel(0xff, lmh_data->base + LMH_REG_DCVS_INTR_CLR);
	enable_irq(lmh_data->irq);
}

static void lmh_disable_interrupt(struct irq_data *d)
{
	struct lmh_hw_data *lmh_data = irq_data_get_irq_chip_data(d);

	disable_irq_nosync(lmh_data->irq);
}

static struct irq_chip lmh_irq_chip = {
	.name           = "lmh",
	.irq_enable	= lmh_enable_interrupt,
	.irq_disable	= lmh_disable_interrupt
};

static int lmh_irq_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
{
	struct lmh_hw_data *lmh_data = d->host_data;
	static struct lock_class_key lmh_lock_key;
	static struct lock_class_key lmh_request_key;

	/*
	 * This lock class tells lockdep that GPIO irqs are in a different
	 * category than their parents, so it won't report false recursion.
	 */
	irq_set_lockdep_class(irq, &lmh_lock_key, &lmh_request_key);
	irq_set_chip_and_handler(irq, &lmh_irq_chip, handle_simple_irq);
	irq_set_chip_data(irq, lmh_data);

	return 0;
}

static const struct irq_domain_ops lmh_irq_ops = {
	.map = lmh_irq_map,
	.xlate = irq_domain_xlate_onecell,
};

static int lmh_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct device_node *cpu_node;
	struct lmh_hw_data *lmh_data;
	int temp_low, temp_high, temp_arm, cpu_id, ret;
	unsigned int enable_alg;
	u32 node_id;

	if (!qcom_scm_is_available())
		return -EPROBE_DEFER;

	lmh_data = devm_kzalloc(dev, sizeof(*lmh_data), GFP_KERNEL);
	if (!lmh_data)
		return -ENOMEM;

	lmh_data->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(lmh_data->base))
		return PTR_ERR(lmh_data->base);

	cpu_node = of_parse_phandle(np, "cpus", 0);
	if (!cpu_node)
		return -EINVAL;
	cpu_id = of_cpu_node_to_id(cpu_node);
	of_node_put(cpu_node);

	ret = of_property_read_u32(np, "qcom,lmh-temp-high-millicelsius", &temp_high);
	if (ret) {
		dev_err(dev, "missing qcom,lmh-temp-high-millicelsius property\n");
		return ret;
	}

	ret = of_property_read_u32(np, "qcom,lmh-temp-low-millicelsius", &temp_low);
	if (ret) {
		dev_err(dev, "missing qcom,lmh-temp-low-millicelsius property\n");
		return ret;
	}

	ret = of_property_read_u32(np, "qcom,lmh-temp-arm-millicelsius", &temp_arm);
	if (ret) {
		dev_err(dev, "missing qcom,lmh-temp-arm-millicelsius property\n");
		return ret;
	}

	/*
	 * Only sdm845 has lmh hardware currently enabled from hlos. If this is needed
	 * for other platforms, revisit this to check if the <cpu-id, node-id> should be part
	 * of a dt match table.
	 */
	if (cpu_id == 0) {
		node_id = LMH_CLUSTER0_NODE_ID;
	} else if (cpu_id == 4) {
		node_id = LMH_CLUSTER1_NODE_ID;
	} else {
		dev_err(dev, "Wrong CPU id associated with LMh node\n");
		return -EINVAL;
	}

	if (!qcom_scm_lmh_dcvsh_available())
		return -EINVAL;

	enable_alg = (uintptr_t)of_device_get_match_data(dev);

	if (enable_alg) {
		ret = qcom_scm_lmh_dcvsh(LMH_SUB_FN_CRNT, LMH_ALGO_MODE_ENABLE, 1,
					 LMH_NODE_DCVS, node_id, 0);
		if (ret)
			dev_err(dev, "Error %d enabling current subfunction\n", ret);

		ret = qcom_scm_lmh_dcvsh(LMH_SUB_FN_REL, LMH_ALGO_MODE_ENABLE, 1,
					 LMH_NODE_DCVS, node_id, 0);
		if (ret)
			dev_err(dev, "Error %d enabling reliability subfunction\n", ret);

		ret = qcom_scm_lmh_dcvsh(LMH_SUB_FN_BCL, LMH_ALGO_MODE_ENABLE, 1,
					 LMH_NODE_DCVS, node_id, 0);
		if (ret)
			dev_err(dev, "Error %d enabling BCL subfunction\n", ret);

		ret = qcom_scm_lmh_dcvsh(LMH_SUB_FN_THERMAL, LMH_ALGO_MODE_ENABLE, 1,
					 LMH_NODE_DCVS, node_id, 0);
		if (ret) {
			dev_err(dev, "Error %d enabling thermal subfunction\n", ret);
			return ret;
		}

		ret = qcom_scm_lmh_profile_change(0x1);
		if (ret) {
			dev_err(dev, "Error %d changing profile\n", ret);
			return ret;
		}
	}

	/* Set default thermal trips */
	ret = qcom_scm_lmh_dcvsh(LMH_SUB_FN_THERMAL, LMH_TH_ARM_THRESHOLD, temp_arm,
				 LMH_NODE_DCVS, node_id, 0);
	if (ret) {
		dev_err(dev, "Error setting thermal ARM threshold%d\n", ret);
		return ret;
	}

	ret = qcom_scm_lmh_dcvsh(LMH_SUB_FN_THERMAL, LMH_TH_HI_THRESHOLD, temp_high,
				 LMH_NODE_DCVS, node_id, 0);
	if (ret) {
		dev_err(dev, "Error setting thermal HI threshold%d\n", ret);
		return ret;
	}

	ret = qcom_scm_lmh_dcvsh(LMH_SUB_FN_THERMAL, LMH_TH_LOW_THRESHOLD, temp_low,
				 LMH_NODE_DCVS, node_id, 0);
	if (ret) {
		dev_err(dev, "Error setting thermal LOW threshold%d\n", ret);
		return ret;
	}

	lmh_data->irq = platform_get_irq(pdev, 0);
	lmh_data->domain = irq_domain_create_linear(dev_fwnode(dev), 1, &lmh_irq_ops, lmh_data);
	if (!lmh_data->domain) {
		dev_err(dev, "Error adding irq_domain\n");
		return -EINVAL;
	}

	/* Disable the irq and let cpufreq enable it when ready to handle the interrupt */
	irq_set_status_flags(lmh_data->irq, IRQ_NOAUTOEN);
	ret = devm_request_irq(dev, lmh_data->irq, lmh_handle_irq,
			       IRQF_NO_THREAD | IRQF_NO_SUSPEND,
			       "lmh-irq", lmh_data);
	if (ret) {
		dev_err(dev, "Error %d registering irq %x\n", ret, lmh_data->irq);
		irq_domain_remove(lmh_data->domain);
		return ret;
	}

	return 0;
}

static const struct of_device_id lmh_table[] = {
	{ .compatible = "qcom,sc8180x-lmh", },
	{ .compatible = "qcom,sdm845-lmh", .data = (void *)LMH_ENABLE_ALGOS},
	{ .compatible = "qcom,sm8150-lmh", },
	{}
};
MODULE_DEVICE_TABLE(of, lmh_table);

static struct platform_driver lmh_driver = {
	.probe = lmh_probe,
	.driver = {
		.name = "qcom-lmh",
		.of_match_table = lmh_table,
		.suppress_bind_attrs = true,
	},
};
module_platform_driver(lmh_driver);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("QCOM LMh driver");
