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

/* EXYNOS - Thermal Management Unit */

#include <device/mmio.h>
#include <console/console.h>
#include <soc/power.h>
#include <soc/tmu.h>

#define TRIMINFO_RELOAD		1
#define CORE_EN			1
#define THERM_TRIP_EN		(1 << 12)

#define INTEN_RISE0		1
#define INTEN_RISE1		(1 << 4)
#define INTEN_RISE2		(1 << 8)
#define INTEN_FALL0		(1 << 16)
#define INTEN_FALL1		(1 << 20)
#define INTEN_FALL2		(1 << 24)

#define TRIM_INFO_MASK		0xff

#define INTCLEAR_RISE0		1
#define INTCLEAR_RISE1		(1 << 4)
#define INTCLEAR_RISE2		(1 << 8)
#define INTCLEAR_FALL0		(1 << 16)
#define INTCLEAR_FALL1		(1 << 20)
#define INTCLEAR_FALL2		(1 << 24)
#define INTCLEARALL		(INTCLEAR_RISE0 | INTCLEAR_RISE1 | \
				 INTCLEAR_RISE2 | INTCLEAR_FALL0 | \
				 INTCLEAR_FALL1 | INTCLEAR_FALL2)

struct tmu_info exynos5420_tmu_info = {
	.tmu_base = 0x10060000,
	.tmu_mux = 6,
	.data = {
		.ts = {
			.min_val = 25,
			.max_val = 125,
			.start_warning = 95,
			.start_tripping = 105,
			.hardware_tripping = 110,
		},
		.efuse_min_value = 40,
		.efuse_value = 55,
		.efuse_max_value = 100,
		.slope = 0x10008802,
	},
	.dc_value = 25,
};

/*
 * After reading temperature code from register, compensating
 * its value and calculating celsius temperature,
 * get current temperature.
 *
 * @return	current temperature of the chip as sensed by TMU
 */
static int get_cur_temp(struct tmu_info *info)
{
	int cur_temp;
	struct tmu_reg *reg = (struct tmu_reg *)info->tmu_base;

	/* Temperature code range between min 25 and max 125 */
	cur_temp = read32(&reg->current_temp) & 0xff;

	/* Calibrate current temperature */
	if (cur_temp)
		cur_temp = cur_temp - info->te1 + info->dc_value;

	return cur_temp;
}

/*
 * Monitors status of the TMU device and exynos temperature
 *
 * @info	TMU info
 * @temp	pointer to the current temperature value
 * @return	enum tmu_status_t value, code indicating event to execute
 */
enum tmu_status_t tmu_monitor(struct tmu_info *info, int *temp)
{
	if (info->tmu_state == TMU_STATUS_INIT)
		return -1;

	int cur_temp;
	struct tmu_data *data = &info->data;

	/* Read current temperature of the SOC */
	cur_temp = get_cur_temp(info);
	*temp = cur_temp;

	/* Temperature code lies between min 25 and max 125 */
	if (cur_temp >= data->ts.start_tripping &&
			cur_temp <= data->ts.max_val)
		return TMU_STATUS_TRIPPED;
	else if (cur_temp >= data->ts.start_warning)
		return TMU_STATUS_WARNING;
	else if (cur_temp < data->ts.start_warning &&
			cur_temp >= data->ts.min_val)
		return TMU_STATUS_NORMAL;
	/* Temperature code does not lie between min 25 and max 125 */
	else {
		info->tmu_state = TMU_STATUS_INIT;
		printk(BIOS_DEBUG, "EXYNOS_TMU: Thermal reading failed\n");
		return -1;
	}
	return 0;
}

/*
 * Calibrate and calculate threshold values and
 * enable interrupt levels
 *
 * @param	info pointer to the tmu_info struct
 */
static void tmu_setup_parameters(struct tmu_info *info)
{
	unsigned int te_temp, con;
	unsigned int warning_code, trip_code, hwtrip_code;
	unsigned int cooling_temp;
	unsigned int rising_value;
	struct tmu_data *data = &info->data;
	struct tmu_reg *reg = (struct tmu_reg *)info->tmu_base;

	/* Must reload for using efuse value at EXYNOS */
	write32(&reg->triminfo_control, TRIMINFO_RELOAD);

	/* Get the compensation parameter */
	te_temp = read32(&reg->triminfo);
	info->te1 = te_temp & TRIM_INFO_MASK;
	info->te2 = ((te_temp >> 8) & TRIM_INFO_MASK);

	if ((data->efuse_min_value > info->te1) ||
			(info->te1 > data->efuse_max_value)
			||  (info->te2 != 0))
		info->te1 = data->efuse_value;

	/* Get RISING & FALLING Threshold value */
	warning_code = data->ts.start_warning
			+ info->te1 - info->dc_value;
	trip_code = data->ts.start_tripping
			+ info->te1 - info->dc_value;
	hwtrip_code = data->ts.hardware_tripping
			+ info->te1 - info->dc_value;

	cooling_temp = 0;

	rising_value = ((warning_code << 8) |
			(trip_code << 16) |
			(hwtrip_code << 24));

	/* Set interrupt level */
	write32(&reg->threshold_temp_rise, rising_value);
	write32(&reg->threshold_temp_fall, cooling_temp);

	/*
	 * Need to init all register settings after getting parameter info
	 * [28:23] vref [11:8] slope - Tuning parameter
	 *
	 * WARNING: this slope value writes into many bits in the tmu_control
	 * register, with the default FDT value of 268470274 (0x10008802)
	 * we are using this essentially sets the default register setting
	 * from the TRM for tmu_control.
	 * TODO(bhthompson): rewrite this code such that we are not performing
	 * a hard wipe of tmu_control and re verify functionality.
	 */
	write32(&reg->tmu_control, data->slope);

	write32(&reg->intclear, INTCLEARALL);
	/* TMU core enable */
	con = read32(&reg->tmu_control);
	con |= (info->tmu_mux << 20) | THERM_TRIP_EN | CORE_EN;

	write32(&reg->tmu_control, con);

	/* Enable HW thermal trip */
	power_enable_hw_thermal_trip();

	/* LEV1 LEV2 interrupt enable */
	write32(&reg->inten, INTEN_RISE1 | INTEN_RISE2);
}

/*
 * Initialize TMU device
 *
 * @return	int value, 0 for success
 */
int tmu_init(struct tmu_info *info)
{
	info->tmu_state = TMU_STATUS_INIT;

	tmu_setup_parameters(info);
	info->tmu_state = TMU_STATUS_NORMAL;

	return 0;
}
