/*
 * Copyright 2012 The Nouveau community
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: Martin Peres
 */
#include "priv.h"

#include <core/option.h>
#include <subdev/pmu.h>

int
nvkm_therm_temp_get(struct nvkm_therm *therm)
{
	if (therm->func->temp_get)
		return therm->func->temp_get(therm);
	return -ENODEV;
}

static int
nvkm_therm_update_trip(struct nvkm_therm *therm)
{
	struct nvbios_therm_trip_point *trip = therm->fan->bios.trip,
				       *cur_trip = NULL,
				       *last_trip = therm->last_trip;
	u8  temp = therm->func->temp_get(therm);
	u16 duty, i;

	/* look for the trip point corresponding to the current temperature */
	cur_trip = NULL;
	for (i = 0; i < therm->fan->bios.nr_fan_trip; i++) {
		if (temp >= trip[i].temp)
			cur_trip = &trip[i];
	}

	/* account for the hysteresis cycle */
	if (last_trip && temp <= (last_trip->temp) &&
	    temp > (last_trip->temp - last_trip->hysteresis))
		cur_trip = last_trip;

	if (cur_trip) {
		duty = cur_trip->fan_duty;
		therm->last_trip = cur_trip;
	} else {
		duty = 0;
		therm->last_trip = NULL;
	}

	return duty;
}

static int
nvkm_therm_compute_linear_duty(struct nvkm_therm *therm, u8 linear_min_temp,
                               u8 linear_max_temp)
{
	u8  temp = therm->func->temp_get(therm);
	u16 duty;

	/* handle the non-linear part first */
	if (temp < linear_min_temp)
		return therm->fan->bios.min_duty;
	else if (temp > linear_max_temp)
		return therm->fan->bios.max_duty;

	/* we are in the linear zone */
	duty  = (temp - linear_min_temp);
	duty *= (therm->fan->bios.max_duty - therm->fan->bios.min_duty);
	duty /= (linear_max_temp - linear_min_temp);
	duty += therm->fan->bios.min_duty;
	return duty;
}

static int
nvkm_therm_update_linear(struct nvkm_therm *therm)
{
	u8  min = therm->fan->bios.linear_min_temp;
	u8  max = therm->fan->bios.linear_max_temp;
	return nvkm_therm_compute_linear_duty(therm, min, max);
}

static int
nvkm_therm_update_linear_fallback(struct nvkm_therm *therm)
{
	u8 max = therm->bios_sensor.thrs_fan_boost.temp;
	return nvkm_therm_compute_linear_duty(therm, 30, max);
}

static void
nvkm_therm_update(struct nvkm_therm *therm, int mode)
{
	struct nvkm_subdev *subdev = &therm->subdev;
	struct nvkm_timer *tmr = subdev->device->timer;
	unsigned long flags;
	bool immd = true;
	bool poll = true;
	int duty = -1;

	spin_lock_irqsave(&therm->lock, flags);
	if (mode < 0)
		mode = therm->mode;
	therm->mode = mode;

	switch (mode) {
	case NVKM_THERM_CTRL_MANUAL:
		nvkm_timer_alarm(tmr, 0, &therm->alarm);
		duty = nvkm_therm_fan_get(therm);
		if (duty < 0)
			duty = 100;
		poll = false;
		break;
	case NVKM_THERM_CTRL_AUTO:
		switch(therm->fan->bios.fan_mode) {
		case NVBIOS_THERM_FAN_TRIP:
			duty = nvkm_therm_update_trip(therm);
			break;
		case NVBIOS_THERM_FAN_LINEAR:
			duty = nvkm_therm_update_linear(therm);
			break;
		case NVBIOS_THERM_FAN_OTHER:
			if (therm->cstate) {
				duty = therm->cstate;
				poll = false;
			} else {
				duty = nvkm_therm_update_linear_fallback(therm);
			}
			break;
		}
		immd = false;
		break;
	case NVKM_THERM_CTRL_NONE:
	default:
		nvkm_timer_alarm(tmr, 0, &therm->alarm);
		poll = false;
	}

	if (poll)
		nvkm_timer_alarm(tmr, 1000000000ULL, &therm->alarm);
	spin_unlock_irqrestore(&therm->lock, flags);

	if (duty >= 0) {
		nvkm_debug(subdev, "FAN target request: %d%%\n", duty);
		nvkm_therm_fan_set(therm, immd, duty);
	}
}

int
nvkm_therm_cstate(struct nvkm_therm *therm, int fan, int dir)
{
	struct nvkm_subdev *subdev = &therm->subdev;
	if (!dir || (dir < 0 && fan < therm->cstate) ||
		    (dir > 0 && fan > therm->cstate)) {
		nvkm_debug(subdev, "default fan speed -> %d%%\n", fan);
		therm->cstate = fan;
		nvkm_therm_update(therm, -1);
	}
	return 0;
}

static void
nvkm_therm_alarm(struct nvkm_alarm *alarm)
{
	struct nvkm_therm *therm =
	       container_of(alarm, struct nvkm_therm, alarm);
	nvkm_therm_update(therm, -1);
}

int
nvkm_therm_fan_mode(struct nvkm_therm *therm, int mode)
{
	struct nvkm_subdev *subdev = &therm->subdev;
	struct nvkm_device *device = subdev->device;
	static const char *name[] = {
		"disabled",
		"manual",
		"automatic"
	};

	/* The default PPWR ucode on fermi interferes with fan management */
	if ((mode >= ARRAY_SIZE(name)) ||
	    (mode != NVKM_THERM_CTRL_NONE && nvkm_pmu_fan_controlled(device)))
		return -EINVAL;

	/* do not allow automatic fan management if the thermal sensor is
	 * not available */
	if (mode == NVKM_THERM_CTRL_AUTO &&
	    therm->func->temp_get(therm) < 0)
		return -EINVAL;

	if (therm->mode == mode)
		return 0;

	nvkm_debug(subdev, "fan management: %s\n", name[mode]);
	nvkm_therm_update(therm, mode);
	return 0;
}

int
nvkm_therm_attr_get(struct nvkm_therm *therm, enum nvkm_therm_attr_type type)
{
	switch (type) {
	case NVKM_THERM_ATTR_FAN_MIN_DUTY:
		return therm->fan->bios.min_duty;
	case NVKM_THERM_ATTR_FAN_MAX_DUTY:
		return therm->fan->bios.max_duty;
	case NVKM_THERM_ATTR_FAN_MODE:
		return therm->mode;
	case NVKM_THERM_ATTR_THRS_FAN_BOOST:
		return therm->bios_sensor.thrs_fan_boost.temp;
	case NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST:
		return therm->bios_sensor.thrs_fan_boost.hysteresis;
	case NVKM_THERM_ATTR_THRS_DOWN_CLK:
		return therm->bios_sensor.thrs_down_clock.temp;
	case NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST:
		return therm->bios_sensor.thrs_down_clock.hysteresis;
	case NVKM_THERM_ATTR_THRS_CRITICAL:
		return therm->bios_sensor.thrs_critical.temp;
	case NVKM_THERM_ATTR_THRS_CRITICAL_HYST:
		return therm->bios_sensor.thrs_critical.hysteresis;
	case NVKM_THERM_ATTR_THRS_SHUTDOWN:
		return therm->bios_sensor.thrs_shutdown.temp;
	case NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST:
		return therm->bios_sensor.thrs_shutdown.hysteresis;
	}

	return -EINVAL;
}

int
nvkm_therm_attr_set(struct nvkm_therm *therm,
		    enum nvkm_therm_attr_type type, int value)
{
	switch (type) {
	case NVKM_THERM_ATTR_FAN_MIN_DUTY:
		if (value < 0)
			value = 0;
		if (value > therm->fan->bios.max_duty)
			value = therm->fan->bios.max_duty;
		therm->fan->bios.min_duty = value;
		return 0;
	case NVKM_THERM_ATTR_FAN_MAX_DUTY:
		if (value < 0)
			value = 0;
		if (value < therm->fan->bios.min_duty)
			value = therm->fan->bios.min_duty;
		therm->fan->bios.max_duty = value;
		return 0;
	case NVKM_THERM_ATTR_FAN_MODE:
		return nvkm_therm_fan_mode(therm, value);
	case NVKM_THERM_ATTR_THRS_FAN_BOOST:
		therm->bios_sensor.thrs_fan_boost.temp = value;
		therm->func->program_alarms(therm);
		return 0;
	case NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST:
		therm->bios_sensor.thrs_fan_boost.hysteresis = value;
		therm->func->program_alarms(therm);
		return 0;
	case NVKM_THERM_ATTR_THRS_DOWN_CLK:
		therm->bios_sensor.thrs_down_clock.temp = value;
		therm->func->program_alarms(therm);
		return 0;
	case NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST:
		therm->bios_sensor.thrs_down_clock.hysteresis = value;
		therm->func->program_alarms(therm);
		return 0;
	case NVKM_THERM_ATTR_THRS_CRITICAL:
		therm->bios_sensor.thrs_critical.temp = value;
		therm->func->program_alarms(therm);
		return 0;
	case NVKM_THERM_ATTR_THRS_CRITICAL_HYST:
		therm->bios_sensor.thrs_critical.hysteresis = value;
		therm->func->program_alarms(therm);
		return 0;
	case NVKM_THERM_ATTR_THRS_SHUTDOWN:
		therm->bios_sensor.thrs_shutdown.temp = value;
		therm->func->program_alarms(therm);
		return 0;
	case NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST:
		therm->bios_sensor.thrs_shutdown.hysteresis = value;
		therm->func->program_alarms(therm);
		return 0;
	}

	return -EINVAL;
}

void
nvkm_therm_clkgate_enable(struct nvkm_therm *therm)
{
	if (!therm || !therm->func->clkgate_enable || !therm->clkgating_enabled)
		return;

	nvkm_debug(&therm->subdev,
		   "Enabling clockgating\n");
	therm->func->clkgate_enable(therm);
}

void
nvkm_therm_clkgate_fini(struct nvkm_therm *therm, bool suspend)
{
	if (!therm || !therm->func->clkgate_fini || !therm->clkgating_enabled)
		return;

	nvkm_debug(&therm->subdev,
		   "Preparing clockgating for %s\n",
		   suspend ? "suspend" : "fini");
	therm->func->clkgate_fini(therm, suspend);
}

static void
nvkm_therm_clkgate_oneinit(struct nvkm_therm *therm)
{
	if (!therm->func->clkgate_enable || !therm->clkgating_enabled)
		return;

	nvkm_info(&therm->subdev, "Clockgating enabled\n");
}

static void
nvkm_therm_intr(struct nvkm_subdev *subdev)
{
	struct nvkm_therm *therm = nvkm_therm(subdev);
	if (therm->func->intr)
		therm->func->intr(therm);
}

static int
nvkm_therm_fini(struct nvkm_subdev *subdev, bool suspend)
{
	struct nvkm_therm *therm = nvkm_therm(subdev);

	if (therm->func->fini)
		therm->func->fini(therm);

	nvkm_therm_fan_fini(therm, suspend);
	nvkm_therm_sensor_fini(therm, suspend);

	if (suspend) {
		therm->suspend = therm->mode;
		therm->mode = NVKM_THERM_CTRL_NONE;
	}

	return 0;
}

static int
nvkm_therm_oneinit(struct nvkm_subdev *subdev)
{
	struct nvkm_therm *therm = nvkm_therm(subdev);
	nvkm_therm_sensor_ctor(therm);
	nvkm_therm_ic_ctor(therm);
	nvkm_therm_fan_ctor(therm);
	nvkm_therm_fan_mode(therm, NVKM_THERM_CTRL_AUTO);
	nvkm_therm_sensor_preinit(therm);
	nvkm_therm_clkgate_oneinit(therm);
	return 0;
}

static int
nvkm_therm_init(struct nvkm_subdev *subdev)
{
	struct nvkm_therm *therm = nvkm_therm(subdev);

	if (therm->func->init)
		therm->func->init(therm);

	if (therm->suspend >= 0) {
		/* restore the pwm value only when on manual or auto mode */
		if (therm->suspend > 0)
			nvkm_therm_fan_set(therm, true, therm->fan->percent);

		nvkm_therm_fan_mode(therm, therm->suspend);
	}

	nvkm_therm_sensor_init(therm);
	nvkm_therm_fan_init(therm);
	return 0;
}

void
nvkm_therm_clkgate_init(struct nvkm_therm *therm,
			const struct nvkm_therm_clkgate_pack *p)
{
	if (!therm || !therm->func->clkgate_init || !therm->clkgating_enabled)
		return;

	therm->func->clkgate_init(therm, p);
}

static void *
nvkm_therm_dtor(struct nvkm_subdev *subdev)
{
	struct nvkm_therm *therm = nvkm_therm(subdev);
	kfree(therm->fan);
	return therm;
}

static const struct nvkm_subdev_func
nvkm_therm = {
	.dtor = nvkm_therm_dtor,
	.oneinit = nvkm_therm_oneinit,
	.init = nvkm_therm_init,
	.fini = nvkm_therm_fini,
	.intr = nvkm_therm_intr,
};

void
nvkm_therm_ctor(struct nvkm_therm *therm, struct nvkm_device *device,
		int index, const struct nvkm_therm_func *func)
{
	nvkm_subdev_ctor(&nvkm_therm, device, index, &therm->subdev);
	therm->func = func;

	nvkm_alarm_init(&therm->alarm, nvkm_therm_alarm);
	spin_lock_init(&therm->lock);
	spin_lock_init(&therm->sensor.alarm_program_lock);

	therm->fan_get = nvkm_therm_fan_user_get;
	therm->fan_set = nvkm_therm_fan_user_set;
	therm->attr_get = nvkm_therm_attr_get;
	therm->attr_set = nvkm_therm_attr_set;
	therm->mode = therm->suspend = -1; /* undefined */

	therm->clkgating_enabled = nvkm_boolopt(device->cfgopt,
						"NvPmEnableGating", false);
}

int
nvkm_therm_new_(const struct nvkm_therm_func *func, struct nvkm_device *device,
		int index, struct nvkm_therm **ptherm)
{
	struct nvkm_therm *therm;

	if (!(therm = *ptherm = kzalloc(sizeof(*therm), GFP_KERNEL)))
		return -ENOMEM;

	nvkm_therm_ctor(therm, device, index, func);
	return 0;
}
