// SPDX-License-Identifier: GPL-2.0
/*
 * Tegra30 SoC Thermal Sensor driver
 *
 * Based on downstream HWMON driver from NVIDIA.
 * Copyright (C) 2011 NVIDIA Corporation
 *
 * Author: Dmitry Osipenko <digetx@gmail.com>
 * Copyright (C) 2021 GRATE-DRIVER project
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/math.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/thermal.h>
#include <linux/types.h>

#include <soc/tegra/fuse.h>

#include "../thermal_core.h"
#include "../thermal_hwmon.h"

#define TSENSOR_SENSOR0_CONFIG0				0x0
#define TSENSOR_SENSOR0_CONFIG0_SENSOR_STOP		BIT(0)
#define TSENSOR_SENSOR0_CONFIG0_HW_FREQ_DIV_EN		BIT(1)
#define TSENSOR_SENSOR0_CONFIG0_THERMAL_RST_EN		BIT(2)
#define TSENSOR_SENSOR0_CONFIG0_DVFS_EN			BIT(3)
#define TSENSOR_SENSOR0_CONFIG0_INTR_OVERFLOW_EN	BIT(4)
#define TSENSOR_SENSOR0_CONFIG0_INTR_HW_FREQ_DIV_EN	BIT(5)
#define TSENSOR_SENSOR0_CONFIG0_INTR_THERMAL_RST_EN	BIT(6)
#define TSENSOR_SENSOR0_CONFIG0_M			GENMASK(23,  8)
#define TSENSOR_SENSOR0_CONFIG0_N			GENMASK(31, 24)

#define TSENSOR_SENSOR0_CONFIG1				0x8
#define TSENSOR_SENSOR0_CONFIG1_TH1			GENMASK(15,  0)
#define TSENSOR_SENSOR0_CONFIG1_TH2			GENMASK(31, 16)

#define TSENSOR_SENSOR0_CONFIG2				0xc
#define TSENSOR_SENSOR0_CONFIG2_TH3			GENMASK(15,  0)

#define TSENSOR_SENSOR0_STATUS0				0x18
#define TSENSOR_SENSOR0_STATUS0_STATE			GENMASK(2, 0)
#define TSENSOR_SENSOR0_STATUS0_INTR			BIT(8)
#define TSENSOR_SENSOR0_STATUS0_CURRENT_VALID		BIT(9)

#define TSENSOR_SENSOR0_TS_STATUS1			0x1c
#define TSENSOR_SENSOR0_TS_STATUS1_CURRENT_COUNT	GENMASK(31, 16)

#define TEGRA30_FUSE_TEST_PROG_VER			0x28

#define TEGRA30_FUSE_TSENSOR_CALIB			0x98
#define TEGRA30_FUSE_TSENSOR_CALIB_LOW			GENMASK(15,  0)
#define TEGRA30_FUSE_TSENSOR_CALIB_HIGH			GENMASK(31, 16)

#define TEGRA30_FUSE_SPARE_BIT				0x144

struct tegra_tsensor;

struct tegra_tsensor_calibration_data {
	int a, b, m, n, p, r;
};

struct tegra_tsensor_channel {
	void __iomem *regs;
	unsigned int id;
	struct tegra_tsensor *ts;
	struct thermal_zone_device *tzd;
};

struct tegra_tsensor {
	void __iomem *regs;
	bool swap_channels;
	struct clk *clk;
	struct device *dev;
	struct reset_control *rst;
	struct tegra_tsensor_channel ch[2];
	struct tegra_tsensor_calibration_data calib;
};

static int tegra_tsensor_hw_enable(const struct tegra_tsensor *ts)
{
	u32 val;
	int err;

	err = reset_control_assert(ts->rst);
	if (err) {
		dev_err(ts->dev, "failed to assert hardware reset: %d\n", err);
		return err;
	}

	err = clk_prepare_enable(ts->clk);
	if (err) {
		dev_err(ts->dev, "failed to enable clock: %d\n", err);
		return err;
	}

	fsleep(1000);

	err = reset_control_deassert(ts->rst);
	if (err) {
		dev_err(ts->dev, "failed to deassert hardware reset: %d\n", err);
		goto disable_clk;
	}

	/*
	 * Sensors are enabled after reset by default, but not gauging
	 * until clock counter is programmed.
	 *
	 * M: number of reference clock pulses after which every
	 *    temperature / voltage measurement is made
	 *
	 * N: number of reference clock counts for which the counter runs
	 */
	val  = FIELD_PREP(TSENSOR_SENSOR0_CONFIG0_M, 12500);
	val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG0_N, 255);

	/* apply the same configuration to both channels */
	writel_relaxed(val, ts->regs + 0x40 + TSENSOR_SENSOR0_CONFIG0);
	writel_relaxed(val, ts->regs + 0x80 + TSENSOR_SENSOR0_CONFIG0);

	return 0;

disable_clk:
	clk_disable_unprepare(ts->clk);

	return err;
}

static int tegra_tsensor_hw_disable(const struct tegra_tsensor *ts)
{
	int err;

	err = reset_control_assert(ts->rst);
	if (err) {
		dev_err(ts->dev, "failed to assert hardware reset: %d\n", err);
		return err;
	}

	clk_disable_unprepare(ts->clk);

	return 0;
}

static void devm_tegra_tsensor_hw_disable(void *data)
{
	const struct tegra_tsensor *ts = data;

	tegra_tsensor_hw_disable(ts);
}

static int tegra_tsensor_get_temp(void *data, int *temp)
{
	const struct tegra_tsensor_channel *tsc = data;
	const struct tegra_tsensor *ts = tsc->ts;
	int err, c1, c2, c3, c4, counter;
	u32 val;

	/*
	 * Counter will be invalid if hardware is misprogrammed or not enough
	 * time passed since the time when sensor was enabled.
	 */
	err = readl_relaxed_poll_timeout(tsc->regs + TSENSOR_SENSOR0_STATUS0, val,
					 val & TSENSOR_SENSOR0_STATUS0_CURRENT_VALID,
					 21 * USEC_PER_MSEC,
					 21 * USEC_PER_MSEC * 50);
	if (err) {
		dev_err_once(ts->dev, "ch%u: counter invalid\n", tsc->id);
		return err;
	}

	val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_TS_STATUS1);
	counter = FIELD_GET(TSENSOR_SENSOR0_TS_STATUS1_CURRENT_COUNT, val);

	/*
	 * This shouldn't happen with a valid counter status, nevertheless
	 * lets verify the value since it's in a separate (from status)
	 * register.
	 */
	if (counter == 0xffff) {
		dev_err_once(ts->dev, "ch%u: counter overflow\n", tsc->id);
		return -EINVAL;
	}

	/*
	 * temperature = a * counter + b
	 * temperature = m * (temperature ^ 2) + n * temperature + p
	 */
	c1 = DIV_ROUND_CLOSEST(ts->calib.a * counter + ts->calib.b, 1000000);
	c1 = c1 ?: 1;
	c2 = DIV_ROUND_CLOSEST(ts->calib.p, c1);
	c3 = c1 * ts->calib.m;
	c4 = ts->calib.n;

	*temp = DIV_ROUND_CLOSEST(c1 * (c2 + c3 + c4), 1000);

	return 0;
}

static int tegra_tsensor_temp_to_counter(const struct tegra_tsensor *ts, int temp)
{
	int c1, c2;

	c1 = DIV_ROUND_CLOSEST(ts->calib.p - temp * 1000, ts->calib.m);
	c2 = -ts->calib.r - int_sqrt(ts->calib.r * ts->calib.r - c1);

	return DIV_ROUND_CLOSEST(c2 * 1000000 - ts->calib.b, ts->calib.a);
}

static int tegra_tsensor_set_trips(void *data, int low, int high)
{
	const struct tegra_tsensor_channel *tsc = data;
	const struct tegra_tsensor *ts = tsc->ts;
	u32 val;

	/*
	 * TSENSOR doesn't trigger interrupt on the "low" temperature breach,
	 * hence bail out if high temperature is unspecified.
	 */
	if (high == INT_MAX)
		return 0;

	val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_CONFIG1);
	val &= ~TSENSOR_SENSOR0_CONFIG1_TH1;

	high = tegra_tsensor_temp_to_counter(ts, high);
	val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG1_TH1, high);
	writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG1);

	return 0;
}

static const struct thermal_zone_of_device_ops ops = {
	.get_temp = tegra_tsensor_get_temp,
	.set_trips = tegra_tsensor_set_trips,
};

static bool
tegra_tsensor_handle_channel_interrupt(const struct tegra_tsensor *ts,
				       unsigned int id)
{
	const struct tegra_tsensor_channel *tsc = &ts->ch[id];
	u32 val;

	val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_STATUS0);
	writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_STATUS0);

	if (FIELD_GET(TSENSOR_SENSOR0_STATUS0_STATE, val) == 5)
		dev_err_ratelimited(ts->dev, "ch%u: counter overflowed\n", id);

	if (!FIELD_GET(TSENSOR_SENSOR0_STATUS0_INTR, val))
		return false;

	thermal_zone_device_update(tsc->tzd, THERMAL_EVENT_UNSPECIFIED);

	return true;
}

static irqreturn_t tegra_tsensor_isr(int irq, void *data)
{
	const struct tegra_tsensor *ts = data;
	bool handled = false;
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(ts->ch); i++)
		handled |= tegra_tsensor_handle_channel_interrupt(ts, i);

	return handled ? IRQ_HANDLED : IRQ_NONE;
}

static int tegra_tsensor_disable_hw_channel(const struct tegra_tsensor *ts,
					    unsigned int id)
{
	const struct tegra_tsensor_channel *tsc = &ts->ch[id];
	struct thermal_zone_device *tzd = tsc->tzd;
	u32 val;
	int err;

	if (!tzd)
		goto stop_channel;

	err = thermal_zone_device_disable(tzd);
	if (err) {
		dev_err(ts->dev, "ch%u: failed to disable zone: %d\n", id, err);
		return err;
	}

stop_channel:
	/* stop channel gracefully */
	val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_CONFIG0);
	val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG0_SENSOR_STOP, 1);
	writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG0);

	return 0;
}

static void tegra_tsensor_get_hw_channel_trips(struct thermal_zone_device *tzd,
					       int *hot_trip, int *crit_trip)
{
	unsigned int i;

	/*
	 * 90C is the maximal critical temperature of all Tegra30 SoC variants,
	 * use it for the default trip if unspecified in a device-tree.
	 */
	*hot_trip  = 85000;
	*crit_trip = 90000;

	for (i = 0; i < tzd->num_trips; i++) {
		enum thermal_trip_type type;
		int trip_temp;

		tzd->ops->get_trip_temp(tzd, i, &trip_temp);
		tzd->ops->get_trip_type(tzd, i, &type);

		if (type == THERMAL_TRIP_HOT)
			*hot_trip = trip_temp;

		if (type == THERMAL_TRIP_CRITICAL)
			*crit_trip = trip_temp;
	}

	/* clamp hardware trips to the calibration limits */
	*hot_trip = clamp(*hot_trip, 25000, 90000);

	/*
	 * Kernel will perform a normal system shut down if it will
	 * see that critical temperature is breached, hence set the
	 * hardware limit by 5C higher in order to allow system to
	 * shut down gracefully before sending signal to the Power
	 * Management controller.
	 */
	*crit_trip = clamp(*crit_trip + 5000, 25000, 90000);
}

static int tegra_tsensor_enable_hw_channel(const struct tegra_tsensor *ts,
					   unsigned int id)
{
	const struct tegra_tsensor_channel *tsc = &ts->ch[id];
	struct thermal_zone_device *tzd = tsc->tzd;
	int err, hot_trip = 0, crit_trip = 0;
	u32 val;

	if (!tzd) {
		val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_CONFIG0);
		val &= ~TSENSOR_SENSOR0_CONFIG0_SENSOR_STOP;
		writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG0);

		return 0;
	}

	tegra_tsensor_get_hw_channel_trips(tzd, &hot_trip, &crit_trip);

	/* prevent potential racing with tegra_tsensor_set_trips() */
	mutex_lock(&tzd->lock);

	dev_info_once(ts->dev, "ch%u: PMC emergency shutdown trip set to %dC\n",
		      id, DIV_ROUND_CLOSEST(crit_trip, 1000));

	hot_trip  = tegra_tsensor_temp_to_counter(ts, hot_trip);
	crit_trip = tegra_tsensor_temp_to_counter(ts, crit_trip);

	/* program LEVEL2 counter threshold */
	val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_CONFIG1);
	val &= ~TSENSOR_SENSOR0_CONFIG1_TH2;
	val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG1_TH2, hot_trip);
	writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG1);

	/* program LEVEL3 counter threshold */
	val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_CONFIG2);
	val &= ~TSENSOR_SENSOR0_CONFIG2_TH3;
	val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG2_TH3, crit_trip);
	writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG2);

	/*
	 * Enable sensor, emergency shutdown, interrupts for level 1/2/3
	 * breaches and counter overflow condition.
	 *
	 * Disable DIV2 throttle for now since we need to figure out how
	 * to integrate it properly with the thermal framework.
	 *
	 * Thermal levels supported by hardware:
	 *
	 *     Level 0 = cold
	 *     Level 1 = passive cooling (cpufreq DVFS)
	 *     Level 2 = passive cooling assisted by hardware (DIV2)
	 *     Level 3 = emergency shutdown assisted by hardware (PMC)
	 */
	val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_CONFIG0);
	val &= ~TSENSOR_SENSOR0_CONFIG0_SENSOR_STOP;
	val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG0_DVFS_EN, 1);
	val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG0_HW_FREQ_DIV_EN, 0);
	val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG0_THERMAL_RST_EN, 1);
	val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG0_INTR_OVERFLOW_EN, 1);
	val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG0_INTR_HW_FREQ_DIV_EN, 1);
	val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG0_INTR_THERMAL_RST_EN, 1);
	writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG0);

	mutex_unlock(&tzd->lock);

	err = thermal_zone_device_enable(tzd);
	if (err) {
		dev_err(ts->dev, "ch%u: failed to enable zone: %d\n", id, err);
		return err;
	}

	return 0;
}

static bool tegra_tsensor_fuse_read_spare(unsigned int spare)
{
	u32 val = 0;

	tegra_fuse_readl(TEGRA30_FUSE_SPARE_BIT + spare * 4, &val);

	return !!val;
}

static int tegra_tsensor_nvmem_setup(struct tegra_tsensor *ts)
{
	u32 i, ate_ver = 0, cal = 0, t1_25C = 0, t2_90C = 0;
	int err, c1_25C, c2_90C;

	err = tegra_fuse_readl(TEGRA30_FUSE_TEST_PROG_VER, &ate_ver);
	if (err) {
		dev_err_probe(ts->dev, err, "failed to get ATE version\n");
		return err;
	}

	if (ate_ver < 8) {
		dev_info(ts->dev, "unsupported ATE version: %u\n", ate_ver);
		return -ENODEV;
	}

	/*
	 * We have two TSENSOR channels in a two different spots on SoC.
	 * Second channel provides more accurate data on older SoC versions,
	 * use it as a primary channel.
	 */
	if (ate_ver <= 21) {
		dev_info_once(ts->dev,
			      "older ATE version detected, channels remapped\n");
		ts->swap_channels = true;
	}

	err = tegra_fuse_readl(TEGRA30_FUSE_TSENSOR_CALIB, &cal);
	if (err) {
		dev_err(ts->dev, "failed to get calibration data: %d\n", err);
		return err;
	}

	/* get calibrated counter values for 25C/90C thresholds */
	c1_25C = FIELD_GET(TEGRA30_FUSE_TSENSOR_CALIB_LOW, cal);
	c2_90C = FIELD_GET(TEGRA30_FUSE_TSENSOR_CALIB_HIGH, cal);

	/* and calibrated temperatures corresponding to the counter values */
	for (i = 0; i < 7; i++) {
		t1_25C |= tegra_tsensor_fuse_read_spare(14 + i) << i;
		t1_25C |= tegra_tsensor_fuse_read_spare(21 + i) << i;

		t2_90C |= tegra_tsensor_fuse_read_spare(0 + i) << i;
		t2_90C |= tegra_tsensor_fuse_read_spare(7 + i) << i;
	}

	if (c2_90C - c1_25C <= t2_90C - t1_25C) {
		dev_err(ts->dev, "invalid calibration data: %d %d %u %u\n",
			c2_90C, c1_25C, t2_90C, t1_25C);
		return -EINVAL;
	}

	/* all calibration coefficients are premultiplied by 1000000 */

	ts->calib.a = DIV_ROUND_CLOSEST((t2_90C - t1_25C) * 1000000,
					(c2_90C - c1_25C));

	ts->calib.b = t1_25C * 1000000 - ts->calib.a * c1_25C;

	if (tegra_sku_info.revision == TEGRA_REVISION_A01) {
		ts->calib.m =     -2775;
		ts->calib.n =   1338811;
		ts->calib.p =  -7300000;
	} else {
		ts->calib.m =     -3512;
		ts->calib.n =   1528943;
		ts->calib.p = -11100000;
	}

	/* except the coefficient of a reduced quadratic equation */
	ts->calib.r = DIV_ROUND_CLOSEST(ts->calib.n, ts->calib.m * 2);

	dev_info_once(ts->dev,
		      "calibration: %d %d %u %u ATE ver: %u SoC rev: %u\n",
		      c2_90C, c1_25C, t2_90C, t1_25C, ate_ver,
		      tegra_sku_info.revision);

	return 0;
}

static int tegra_tsensor_register_channel(struct tegra_tsensor *ts,
					  unsigned int id)
{
	struct tegra_tsensor_channel *tsc = &ts->ch[id];
	unsigned int hw_id = ts->swap_channels ? !id : id;

	tsc->ts = ts;
	tsc->id = id;
	tsc->regs = ts->regs + 0x40 * (hw_id + 1);

	tsc->tzd = devm_thermal_zone_of_sensor_register(ts->dev, id, tsc, &ops);
	if (IS_ERR(tsc->tzd)) {
		if (PTR_ERR(tsc->tzd) != -ENODEV)
			return dev_err_probe(ts->dev, PTR_ERR(tsc->tzd),
					     "failed to register thermal zone\n");

		/*
		 * It's okay if sensor isn't assigned to any thermal zone
		 * in a device-tree.
		 */
		tsc->tzd = NULL;
		return 0;
	}

	if (devm_thermal_add_hwmon_sysfs(tsc->tzd))
		dev_warn(ts->dev, "failed to add hwmon sysfs attributes\n");

	return 0;
}

static int tegra_tsensor_probe(struct platform_device *pdev)
{
	struct tegra_tsensor *ts;
	unsigned int i;
	int err, irq;

	ts = devm_kzalloc(&pdev->dev, sizeof(*ts), GFP_KERNEL);
	if (!ts)
		return -ENOMEM;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	ts->dev = &pdev->dev;
	platform_set_drvdata(pdev, ts);

	ts->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(ts->regs))
		return PTR_ERR(ts->regs);

	ts->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(ts->clk))
		return dev_err_probe(&pdev->dev, PTR_ERR(ts->clk),
				     "failed to get clock\n");

	ts->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
	if (IS_ERR(ts->rst))
		return dev_err_probe(&pdev->dev, PTR_ERR(ts->rst),
				     "failed to get reset control\n");

	err = tegra_tsensor_nvmem_setup(ts);
	if (err)
		return err;

	err = tegra_tsensor_hw_enable(ts);
	if (err)
		return err;

	err = devm_add_action_or_reset(&pdev->dev,
				       devm_tegra_tsensor_hw_disable,
				       ts);
	if (err)
		return err;

	for (i = 0; i < ARRAY_SIZE(ts->ch); i++) {
		err = tegra_tsensor_register_channel(ts, i);
		if (err)
			return err;
	}

	err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
					tegra_tsensor_isr, IRQF_ONESHOT,
					"tegra_tsensor", ts);
	if (err)
		return dev_err_probe(&pdev->dev, err,
				     "failed to request interrupt\n");

	for (i = 0; i < ARRAY_SIZE(ts->ch); i++) {
		err = tegra_tsensor_enable_hw_channel(ts, i);
		if (err)
			return err;
	}

	return 0;
}

static int __maybe_unused tegra_tsensor_suspend(struct device *dev)
{
	struct tegra_tsensor *ts = dev_get_drvdata(dev);
	unsigned int i;
	int err;

	for (i = 0; i < ARRAY_SIZE(ts->ch); i++) {
		err = tegra_tsensor_disable_hw_channel(ts, i);
		if (err)
			goto enable_channel;
	}

	err = tegra_tsensor_hw_disable(ts);
	if (err)
		goto enable_channel;

	return 0;

enable_channel:
	while (i--)
		tegra_tsensor_enable_hw_channel(ts, i);

	return err;
}

static int __maybe_unused tegra_tsensor_resume(struct device *dev)
{
	struct tegra_tsensor *ts = dev_get_drvdata(dev);
	unsigned int i;
	int err;

	err = tegra_tsensor_hw_enable(ts);
	if (err)
		return err;

	for (i = 0; i < ARRAY_SIZE(ts->ch); i++) {
		err = tegra_tsensor_enable_hw_channel(ts, i);
		if (err)
			return err;
	}

	return 0;
}

static const struct dev_pm_ops tegra_tsensor_pm_ops = {
	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(tegra_tsensor_suspend,
				      tegra_tsensor_resume)
};

static const struct of_device_id tegra_tsensor_of_match[] = {
	{ .compatible = "nvidia,tegra30-tsensor", },
	{},
};
MODULE_DEVICE_TABLE(of, tegra_tsensor_of_match);

static struct platform_driver tegra_tsensor_driver = {
	.probe = tegra_tsensor_probe,
	.driver = {
		.name = "tegra30-tsensor",
		.of_match_table = tegra_tsensor_of_match,
		.pm = &tegra_tsensor_pm_ops,
	},
};
module_platform_driver(tegra_tsensor_driver);

MODULE_DESCRIPTION("NVIDIA Tegra30 Thermal Sensor driver");
MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
MODULE_LICENSE("GPL");
