// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2019 NXP
 */

#include <config.h>
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <log.h>
#include <thermal.h>
#include <dm/device-internal.h>
#include <dm/device.h>
#include <asm/arch/sci/sci.h>
#include <linux/delay.h>
#include <linux/libfdt.h>

DECLARE_GLOBAL_DATA_PTR;

struct imx_sc_thermal_plat {
	int critical;
	int alert;
	int polling_delay;
	int id;
	bool zone_node;
};

static int read_temperature(struct udevice *dev, int *temp)
{
	s16 celsius;
	s8 tenths;
	int ret;

	sc_rsrc_t *sensor_rsrc = (sc_rsrc_t *)dev_get_driver_data(dev);

	struct imx_sc_thermal_plat *pdata = dev_get_platdata(dev);

	if (!temp)
		return -EINVAL;

	ret = sc_misc_get_temp(-1, sensor_rsrc[pdata->id], SC_C_TEMP,
			       &celsius, &tenths);
	if (ret) {
		printf("Error: get temperature failed! (error = %d)\n", ret);
		return ret;
	}

	*temp = celsius * 1000 + tenths * 100;

	return 0;
}

int imx_sc_thermal_get_temp(struct udevice *dev, int *temp)
{
	struct imx_sc_thermal_plat *pdata = dev_get_platdata(dev);
	int cpu_temp = 0;
	int ret;

	ret = read_temperature(dev, &cpu_temp);
	if (ret)
		return ret;

	while (cpu_temp >= pdata->alert) {
		printf("CPU Temperature (%dC) beyond alert (%dC), close to critical (%dC)",
		       cpu_temp, pdata->alert, pdata->critical);
		puts(" waiting...\n");
		mdelay(pdata->polling_delay);
		ret = read_temperature(dev, &cpu_temp);
		if (ret)
			return ret;
		if (cpu_temp >= pdata->alert && !pdata->alert)
			break;
	}

	*temp = cpu_temp / 1000;

	return 0;
}

static const struct dm_thermal_ops imx_sc_thermal_ops = {
	.get_temp	= imx_sc_thermal_get_temp,
};

static int imx_sc_thermal_probe(struct udevice *dev)
{
	debug("%s dev name %s\n", __func__, dev->name);
	return 0;
}

static int imx_sc_thermal_bind(struct udevice *dev)
{
	struct imx_sc_thermal_plat *pdata = dev_get_platdata(dev);
	int reg, ret;
	int offset;
	const char *name;
	const void *prop;

	debug("%s dev name %s\n", __func__, dev->name);

	prop = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "compatible",
			   NULL);
	if (!prop)
		return 0;

	pdata->zone_node = 1;

	reg = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "tsens-num", 0);
	if (reg == 0) {
		printf("%s: no temp sensor number provided!\n", __func__);
		return -EINVAL;
	}

	offset = fdt_subnode_offset(gd->fdt_blob, 0, "thermal-zones");
	fdt_for_each_subnode(offset, gd->fdt_blob, offset) {
		/* Bind the subnode to this driver */
		name = fdt_get_name(gd->fdt_blob, offset, NULL);

		ret = device_bind_with_driver_data(dev, dev->driver, name,
						   dev->driver_data,
						   offset_to_ofnode(offset),
						   NULL);
		if (ret)
			printf("Error binding driver '%s': %d\n",
			       dev->driver->name, ret);
	}
	return 0;
}

static int imx_sc_thermal_ofdata_to_platdata(struct udevice *dev)
{
	struct imx_sc_thermal_plat *pdata = dev_get_platdata(dev);
	struct fdtdec_phandle_args args;
	const char *type;
	int ret;
	int trips_np;

	debug("%s dev name %s\n", __func__, dev->name);

	if (pdata->zone_node)
		return 0;

	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
					     "thermal-sensors",
					     "#thermal-sensor-cells",
					     0, 0, &args);
	if (ret)
		return ret;

	if (args.node != dev_of_offset(dev->parent))
		return -EFAULT;

	if (args.args_count >= 1)
		pdata->id = args.args[0];
	else
		pdata->id = 0;

	debug("args.args_count %d, id %d\n", args.args_count, pdata->id);

	pdata->polling_delay = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
					      "polling-delay", 1000);

	trips_np = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(dev),
				      "trips");
	fdt_for_each_subnode(trips_np, gd->fdt_blob, trips_np) {
		type = fdt_getprop(gd->fdt_blob, trips_np, "type", NULL);
		if (type) {
			if (strcmp(type, "critical") == 0) {
				pdata->critical = fdtdec_get_int(gd->fdt_blob,
								 trips_np,
								 "temperature",
								 85);
			} else if (strcmp(type, "passive") == 0) {
				pdata->alert = fdtdec_get_int(gd->fdt_blob,
							      trips_np,
							      "temperature",
							      80);
			}
		}
	}

	debug("id %d polling_delay %d, critical %d, alert %d\n", pdata->id,
	      pdata->polling_delay, pdata->critical, pdata->alert);

	return 0;
}

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

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

static const struct udevice_id imx_sc_thermal_ids[] = {
	{ .compatible = "nxp,imx8qm-sc-tsens", .data =
		(ulong)&imx8qm_sensor_rsrc, },
	{ .compatible = "nxp,imx8qxp-sc-tsens", .data =
		(ulong)&imx8qxp_sensor_rsrc, },
	{ }
};

U_BOOT_DRIVER(imx_sc_thermal) = {
	.name	= "imx_sc_thermal",
	.id	= UCLASS_THERMAL,
	.ops	= &imx_sc_thermal_ops,
	.of_match = imx_sc_thermal_ids,
	.bind = imx_sc_thermal_bind,
	.probe	= imx_sc_thermal_probe,
	.ofdata_to_platdata = imx_sc_thermal_ofdata_to_platdata,
	.platdata_auto_alloc_size = sizeof(struct imx_sc_thermal_plat),
	.flags  = DM_FLAG_PRE_RELOC,
};
