/*
 * Samsung Exynos SoC series VIPx driver
 *
 * Copyright (c) 2018 Samsung Electronics Co., Ltd
 *
 * 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/pm_runtime.h>

#include "vipx-log.h"
#include "vipx-system.h"
#include "vipx-pm.h"

#if defined(CONFIG_PM_DEVFREQ)

#if defined(CONFIG_EXYNOS_VIPX_EXYNOS9610_A)
static unsigned int cam_qos_table[] = {
	700000,
	690000,
	680000,
	670000,
	660000,
	650000,
	640000
};
#endif

#if defined(CONFIG_EXYNOS_VIPX_EXYNOS9610_R)
static unsigned int cam_qos_table[] = {
	690000,
	680000,
	670000,
	660000,
	650000,
	640000
};
#endif

static int __vipx_pm_qos_check_valid(struct vipx_pm *pm, int qos)
{
	vipx_check();
	if ((qos >= pm->qos_count) || (qos < 0)) {
		vipx_err("pm_qos level(%d) is invalid (L0 ~ L%d)\n",
				qos, pm->qos_count - 1);
		return -EINVAL;
	} else {
		return 0;
	}
}

int vipx_pm_qos_active(struct vipx_pm *pm)
{
	vipx_check();
	return pm_qos_request_active(&pm->cam_qos_req);
}

static void __vipx_pm_qos_set_default(struct vipx_pm *pm, int default_qos)
{
	vipx_enter();
	pm->default_qos = default_qos;
	vipx_info("default pm_qos level is set as L%d\n", pm->default_qos);
	vipx_leave();
}

int vipx_pm_qos_set_default(struct vipx_pm *pm, int default_qos)
{
	int ret;

	vipx_enter();
	ret = __vipx_pm_qos_check_valid(pm, default_qos);
	if (ret)
		goto p_err;

	mutex_lock(&pm->lock);
	__vipx_pm_qos_set_default(pm, default_qos);
	mutex_unlock(&pm->lock);
	vipx_leave();
	return 0;
p_err:
	return ret;
}

static void __vipx_pm_qos_update(struct vipx_pm *pm, int request_qos)
{
	vipx_enter();
	if (vipx_pm_qos_active(pm) && (pm->current_qos != request_qos)) {
		pm_qos_update_request(&pm->cam_qos_req,
				pm->qos_table[request_qos]);
		vipx_dbg("pm_qos level is changed from L%d to L%d\n",
				pm->current_qos, request_qos);
		pm->current_qos = request_qos;
	}
	vipx_leave();
}

int vipx_pm_qos_update(struct vipx_pm *pm, int request_qos)
{
	int ret;

	vipx_enter();
	ret = __vipx_pm_qos_check_valid(pm, request_qos);
	if (ret)
		goto p_err;

	mutex_lock(&pm->lock);
	__vipx_pm_qos_update(pm, request_qos);
	mutex_unlock(&pm->lock);
	vipx_leave();
	return 0;
p_err:
	return ret;
}

void vipx_pm_qos_suspend(struct vipx_pm *pm)
{
	vipx_enter();
	pm->resume_qos = pm->current_qos;
	vipx_pm_qos_update(pm, pm->qos_count - 1);
	vipx_leave();
}

void vipx_pm_qos_resume(struct vipx_pm *pm)
{
	vipx_enter();
	vipx_pm_qos_update(pm, pm->resume_qos);
	pm->resume_qos = -1;
	vipx_leave();
}

static int __vipx_pm_qos_add(struct vipx_pm *pm)
{
	vipx_enter();
	mutex_lock(&pm->lock);
	if (pm->default_qos < 0)
		__vipx_pm_qos_set_default(pm, 0);

	if (!vipx_pm_qos_active(pm)) {
		pm_qos_add_request(&pm->cam_qos_req, PM_QOS_CAM_THROUGHPUT,
				pm->qos_table[pm->default_qos]);
		pm->current_qos = pm->default_qos;
		vipx_info("The power of device is on(L%d)\n",
				pm->current_qos);
	}

	if (pm->dvfs)
		vipx_info("dvfs was enabled\n");
	else
		vipx_info("dvfs was disabled\n");

	mutex_unlock(&pm->lock);
	vipx_leave();
	return 0;
}

static void __vipx_pm_qos_remove(struct vipx_pm *pm)
{
	vipx_enter();
	mutex_lock(&pm->lock);
	if (vipx_pm_qos_active(pm)) {
		pm_qos_remove_request(&pm->cam_qos_req);
		pm->current_qos = -1;
		vipx_info("The power of device is off\n");
	}
	mutex_unlock(&pm->lock);
	vipx_leave();
}

static int __vipx_pm_qos_init(struct vipx_pm *pm)
{
	vipx_enter();
	pm->qos_count = sizeof(cam_qos_table) / sizeof(unsigned int);
	pm->qos_table = cam_qos_table;
	pm->default_qos = -1;
	pm->resume_qos = -1;
	pm->current_qos = -1;

	vipx_leave();
	return 0;
}
#else
int vipx_pm_qos_active(struct vipx_pm *pm)
{
	return 1;
}

int vipx_pm_qos_set_default(struct vipx_pm *pm, int default_qos)
{
	return 0;
}

static void __vipx_pm_qos_update(struct vipx_pm *pm, int request_qos)
{
}

int vipx_pm_qos_update(struct vipx_pm *pm, int request_qos)
{
	return 0;
}

void vipx_pm_qos_suspend(struct vipx_pm *pm)
{
}

void vipx_pm_qos_resume(struct vipx_pm *pm)
{
}

static int __vipx_pm_qos_add(struct vipx_pm *pm)
{
	vipx_info("dvfs was not supported\n");
	return 0;
}

static void __vipx_pm_qos_remove(struct vipx_pm *pm)
{
}

static int __vipx_pm_qos_init(struct vipx_pm *pm)
{
	return 0;
}
#endif

void vipx_pm_request_busy(struct vipx_pm *pm)
{
	vipx_enter();
	mutex_lock(&pm->lock);
	if (pm->dvfs) {
		if (++pm->active_count == 1)
			__vipx_pm_qos_update(pm, pm->default_qos);
	}
	mutex_unlock(&pm->lock);
	vipx_leave();
}

void vipx_pm_request_idle(struct vipx_pm *pm)
{
	vipx_enter();
	mutex_lock(&pm->lock);
	if (pm->dvfs) {
		if (!pm->active_count)
			__vipx_pm_qos_update(pm, pm->qos_count - 1);
		else if (--pm->active_count == 0)
			__vipx_pm_qos_update(pm, pm->qos_count - 1);
	}
	mutex_unlock(&pm->lock);
	vipx_leave();
}

int vipx_pm_open(struct vipx_pm *pm)
{
	int ret;

	vipx_enter();
	ret = __vipx_pm_qos_add(pm);
	if (ret)
		goto p_err;

	pm->active_count = 0;
	vipx_leave();
	return 0;
p_err:
	return ret;
}

void vipx_pm_close(struct vipx_pm *pm)
{
	vipx_enter();
	__vipx_pm_qos_remove(pm);
	vipx_leave();
}

int vipx_pm_probe(struct vipx_system *sys)
{
	struct vipx_pm *pm;

	vipx_enter();
	pm = &sys->pm;
	pm->system = sys;

	__vipx_pm_qos_init(pm);
#if defined(CONFIG_PM)
	pm_runtime_enable(sys->dev);
#endif
	mutex_init(&pm->lock);
	pm->dvfs = true;

	vipx_leave();
	return 0;
}

void vipx_pm_remove(struct vipx_pm *pm)
{
	vipx_enter();
	mutex_destroy(&pm->lock);

#if defined(CONFIG_PM)
	pm_runtime_disable(pm->system->dev);
#endif
	vipx_leave();
}
