/*
 * Copyright 2017-2018 NXP.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */

#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/device_cooling.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/thermal.h>
#include <soc/imx8/sc/sci.h>

#include "thermal_core.h"

#define IMX_SC_TEMP_PASSIVE_COOL_DELTA	10000

struct imx_sc_sensor {
	struct thermal_zone_device *tzd;
	struct thermal_cooling_device *cdev;
	sc_rsrc_t hw_id;
	int temp_passive;
	int temp_critical;
};

struct imx_sc_tsens_device {
	u32 sensor_num;
	struct imx_sc_sensor sensor[0];
};

/* The driver support 1 passive trip point and 1 critical trip point */
enum imx_thermal_trip {
	IMX_TRIP_PASSIVE,
	IMX_TRIP_CRITICAL,
	IMX_TRIP_NUM,
};

static const sc_rsrc_t imx8qm_sensor_hw_id[] = {
	SC_R_A53, SC_R_A72, SC_R_GPU_0_PID0, SC_R_GPU_1_PID0,
	SC_R_DRC_0, SC_R_PMIC_0, SC_R_PMIC_1, SC_R_PMIC_2,
};

static const sc_rsrc_t imx8qxp_sensor_hw_id[] = {
	SC_R_SYSTEM, SC_R_DRC_0, SC_R_PMIC_0,
	SC_R_PMIC_1, SC_R_PMIC_2,
};

const int *sensor_hw_id;
sc_ipc_t tsens_ipcHandle;

static int imx_sc_tsens_get_temp(void *data, int *temp)
{
	struct imx_sc_sensor *sensor = data;
	sc_err_t sciErr;
	int16_t celsius;
	int8_t tenths;

	sciErr = sc_misc_get_temp(tsens_ipcHandle, sensor->hw_id,
			SC_C_TEMP, &celsius, &tenths);
	/*
	 * if the SS power domain is down, read temp will fail, so
	 * we can return the temp of CPU domain instead.
	 */
	if (sciErr != SC_ERR_NONE) {
		sciErr = sc_misc_get_temp(tsens_ipcHandle,
			sensor_hw_id[topology_physical_package_id(smp_processor_id())],
			SC_C_TEMP, &celsius, &tenths);
		if (sciErr != SC_ERR_NONE) {
			pr_err("read temp sensor:%d failed\n", sensor->hw_id);
			return -EINVAL;
		}
	}
	*temp = celsius * 1000 + tenths;

	return 0;
}

static int imx_sc_tsens_get_trend(void *p, int trip, enum thermal_trend *trend)
{
	int trip_temp;
	struct imx_sc_sensor *sensor = p;

	if (!sensor->tzd)
		return 0;

	trip_temp = (trip == IMX_TRIP_PASSIVE) ? sensor->temp_passive :
					     sensor->temp_critical;

	if (sensor->tzd->temperature >=
		(trip_temp - IMX_SC_TEMP_PASSIVE_COOL_DELTA))
		*trend = THERMAL_TREND_RAISE_FULL;
	else
		*trend = THERMAL_TREND_DROP_FULL;

	return 0;
}

static int imx_sc_set_trip_temp(void *p, int trip,
			     int temp)
{
	struct imx_sc_sensor *sensor = p;

	if (trip == IMX_TRIP_CRITICAL)
		sensor->temp_critical = temp;

	if (trip == IMX_TRIP_PASSIVE)
		sensor->temp_passive = temp;

	return 0;
}

static const struct thermal_zone_of_device_ops imx_sc_tsens_ops = {
	.get_temp = imx_sc_tsens_get_temp,
	.get_trend = imx_sc_tsens_get_trend,
	.set_trip_temp = imx_sc_set_trip_temp,
};

static const struct of_device_id imx_sc_tsens_table[] = {
	{ .compatible = "nxp,imx8qm-sc-tsens", .data = &imx8qm_sensor_hw_id, },
	{ .compatible = "nxp,imx8qxp-sc-tsens", .data = &imx8qxp_sensor_hw_id, },
	{},
};

MODULE_DEVICE_TABLE(of, imx_sc_tsens_table);

static int imx_sc_tsens_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct imx_sc_tsens_device *tsens_dev;
	struct imx_sc_sensor *sensor;
	const struct thermal_trip *trip;
	struct thermal_zone_device *tzd;
	sc_err_t sciErr;
	uint32_t mu_id;
	u32 tsens_num;
	int ret, sensor_id;

	sciErr = sc_ipc_getMuID(&mu_id);
	if (sciErr != SC_ERR_NONE) {
		dev_err(&pdev->dev, "Can not get the mu id: %d\n", sciErr);
		return -ENODEV;
	};

	sciErr = sc_ipc_open(&tsens_ipcHandle, mu_id);
	if (sciErr != SC_ERR_NONE) {
		dev_err(&pdev->dev, "open mu channel failed: %d\n", sciErr);
		return -EINVAL;
	};
	sensor_hw_id = of_device_get_match_data(&pdev->dev);

	/* get the temp sensor number from device node */
	of_property_read_u32(np, "tsens-num", &tsens_num);
	if (!tsens_num) {
		dev_err(&pdev->dev, "no temp sensor number provided!\n");
		return -EINVAL;
	}

	tsens_dev = devm_kzalloc(&pdev->dev, sizeof(*tsens_dev) +
				 tsens_num * sizeof(*sensor), GFP_KERNEL);
	if (!tsens_dev)
		return -ENOMEM;

	tsens_dev->sensor_num = tsens_num;

	for (sensor_id = 0; sensor_id < tsens_num; sensor_id++) {
		sensor = &tsens_dev->sensor[sensor_id];
		sensor->hw_id = sensor_hw_id[sensor_id];
		tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, sensor_id, sensor,
		 &imx_sc_tsens_ops);
		if (IS_ERR(tzd)) {
			dev_err(&pdev->dev, "failed to register temp sensor: %d\n", sensor_id);
			ret = -EINVAL;
			goto failed;
		}
		sensor->tzd = tzd;
		trip = of_thermal_get_trip_points(sensor->tzd);
		sensor->temp_passive = trip[0].temperature;
		sensor->temp_critical = trip[1].temperature;

		sensor->cdev = devfreq_cooling_register();
		if (IS_ERR(sensor->cdev)) {
			dev_err(&pdev->dev,
				"failed to register devfreq cooling device: %d\n",
				ret);
			goto failed;
		}

		ret = thermal_zone_bind_cooling_device(sensor->tzd,
			IMX_TRIP_PASSIVE,
			sensor->cdev,
			THERMAL_NO_LIMIT,
			THERMAL_NO_LIMIT,
			THERMAL_WEIGHT_DEFAULT);
		if (ret) {
			dev_err(&sensor->tzd->device,
				"binding zone %s with cdev %s failed:%d\n",
				sensor->tzd->type, sensor->cdev->type, ret);
			devfreq_cooling_unregister(sensor->cdev);
			goto failed;
		}
	}

	return 0;
failed:
	return ret;
}

static int imx_sc_tsens_remove(struct platform_device *pdev)
{
	return 0;
}

static struct platform_driver imx_sc_tsens_driver = {
		.probe = imx_sc_tsens_probe,
		.remove = imx_sc_tsens_remove,
		.driver = {
			.name = "i.MX-sc-tsens",
			.of_match_table = imx_sc_tsens_table,
		},
};

module_platform_driver(imx_sc_tsens_driver);

MODULE_AUTHOR("Jacky Bai<ping.bai@nxp.com");
MODULE_DESCRIPTION("Thermal driver for NXP i.MX SoCs with system controller");
MODULE_LICENSE("GPL v2");
