/*
 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com/
 *
 * EXYNOS5 INT clock frequency scaling support using DEVFREQ framework
 * Based on work done by Jonghwan Choi <jhbird.choi@samsung.com>
 * Support for only EXYNOS5250 is present.
 *
 * 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/module.h>
#include <linux/devfreq.h>
#include <linux/io.h>
#include <linux/opp.h>
#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/opp.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/pm_qos.h>
#include <linux/regulator/consumer.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>

#include "exynos_ppmu.h"

#define MAX_SAFEVOLT			1100000 /* 1.10V */
/* Assume that the bus is saturated if the utilization is 25% */
#define INT_BUS_SATURATION_RATIO	25

enum int_level_idx {
	LV_0,
	LV_1,
	LV_2,
	LV_3,
	LV_4,
	_LV_END
};

enum exynos_ppmu_list {
	PPMU_RIGHT,
	PPMU_END,
};

struct busfreq_data_int {
	struct device *dev;
	struct devfreq *devfreq;
	struct regulator *vdd_int;
	struct exynos_ppmu ppmu[PPMU_END];
	unsigned long curr_freq;
	bool disabled;

	struct notifier_block pm_notifier;
	struct mutex lock;
	struct pm_qos_request int_req;
	struct clk *int_clk;
};

struct int_bus_opp_table {
	unsigned int idx;
	unsigned long clk;
	unsigned long volt;
};

static struct int_bus_opp_table exynos5_int_opp_table[] = {
	{LV_0, 266000, 1025000},
	{LV_1, 200000, 1025000},
	{LV_2, 160000, 1025000},
	{LV_3, 133000, 1025000},
	{LV_4, 100000, 1025000},
	{0, 0, 0},
};

static void busfreq_mon_reset(struct busfreq_data_int *data)
{
	unsigned int i;

	for (i = PPMU_RIGHT; i < PPMU_END; i++) {
		void __iomem *ppmu_base = data->ppmu[i].hw_base;

		/* Reset the performance and cycle counters */
		exynos_ppmu_reset(ppmu_base);

		/* Setup count registers to monitor read/write transactions */
		data->ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT;
		exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3,
					data->ppmu[i].event[PPMU_PMNCNT3]);

		exynos_ppmu_start(ppmu_base);
	}
}

static void exynos5_read_ppmu(struct busfreq_data_int *data)
{
	int i, j;

	for (i = PPMU_RIGHT; i < PPMU_END; i++) {
		void __iomem *ppmu_base = data->ppmu[i].hw_base;

		exynos_ppmu_stop(ppmu_base);

		/* Update local data from PPMU */
		data->ppmu[i].ccnt = __raw_readl(ppmu_base + PPMU_CCNT);

		for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
			if (data->ppmu[i].event[j] == 0)
				data->ppmu[i].count[j] = 0;
			else
				data->ppmu[i].count[j] =
					exynos_ppmu_read(ppmu_base, j);
		}
	}

	busfreq_mon_reset(data);
}

static int exynos5_int_setvolt(struct busfreq_data_int *data,
				unsigned long volt)
{
	return regulator_set_voltage(data->vdd_int, volt, MAX_SAFEVOLT);
}

static int exynos5_busfreq_int_target(struct device *dev, unsigned long *_freq,
			      u32 flags)
{
	int err = 0;
	struct platform_device *pdev = container_of(dev, struct platform_device,
						    dev);
	struct busfreq_data_int *data = platform_get_drvdata(pdev);
	struct opp *opp;
	unsigned long old_freq, freq;
	unsigned long volt;

	rcu_read_lock();
	opp = devfreq_recommended_opp(dev, _freq, flags);
	if (IS_ERR(opp)) {
		rcu_read_unlock();
		dev_err(dev, "%s: Invalid OPP.\n", __func__);
		return PTR_ERR(opp);
	}

	freq = opp_get_freq(opp);
	volt = opp_get_voltage(opp);
	rcu_read_unlock();

	old_freq = data->curr_freq;

	if (old_freq == freq)
		return 0;

	dev_dbg(dev, "targetting %lukHz %luuV\n", freq, volt);

	mutex_lock(&data->lock);

	if (data->disabled)
		goto out;

	if (freq > exynos5_int_opp_table[0].clk)
		pm_qos_update_request(&data->int_req, freq * 16 / 1000);
	else
		pm_qos_update_request(&data->int_req, -1);

	if (old_freq < freq)
		err = exynos5_int_setvolt(data, volt);
	if (err)
		goto out;

	err = clk_set_rate(data->int_clk, freq * 1000);

	if (err)
		goto out;

	if (old_freq > freq)
		err = exynos5_int_setvolt(data, volt);
	if (err)
		goto out;

	data->curr_freq = freq;
out:
	mutex_unlock(&data->lock);
	return err;
}

static int exynos5_get_busier_dmc(struct busfreq_data_int *data)
{
	int i, j;
	int busy = 0;
	unsigned int temp = 0;

	for (i = PPMU_RIGHT; i < PPMU_END; i++) {
		for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
			if (data->ppmu[i].count[j] > temp) {
				temp = data->ppmu[i].count[j];
				busy = i;
			}
		}
	}

	return busy;
}

static int exynos5_int_get_dev_status(struct device *dev,
				      struct devfreq_dev_status *stat)
{
	struct platform_device *pdev = container_of(dev, struct platform_device,
						    dev);
	struct busfreq_data_int *data = platform_get_drvdata(pdev);
	int busier_dmc;

	exynos5_read_ppmu(data);
	busier_dmc = exynos5_get_busier_dmc(data);

	stat->current_frequency = data->curr_freq;

	/* Number of cycles spent on memory access */
	stat->busy_time = data->ppmu[busier_dmc].count[PPMU_PMNCNT3];
	stat->busy_time *= 100 / INT_BUS_SATURATION_RATIO;
	stat->total_time = data->ppmu[busier_dmc].ccnt;

	return 0;
}
static void exynos5_int_exit(struct device *dev)
{
	struct platform_device *pdev = container_of(dev, struct platform_device,
						    dev);
	struct busfreq_data_int *data = platform_get_drvdata(pdev);

	devfreq_unregister_opp_notifier(dev, data->devfreq);
}

static struct devfreq_dev_profile exynos5_devfreq_int_profile = {
	.initial_freq		= 160000,
	.polling_ms		= 100,
	.target			= exynos5_busfreq_int_target,
	.get_dev_status		= exynos5_int_get_dev_status,
	.exit			= exynos5_int_exit,
};

static int exynos5250_init_int_tables(struct busfreq_data_int *data)
{
	int i, err = 0;

	for (i = LV_0; i < _LV_END; i++) {
		err = opp_add(data->dev, exynos5_int_opp_table[i].clk,
				exynos5_int_opp_table[i].volt);
		if (err) {
			dev_err(data->dev, "Cannot add opp entries.\n");
			return err;
		}
	}

	return 0;
}

static int exynos5_busfreq_int_pm_notifier_event(struct notifier_block *this,
		unsigned long event, void *ptr)
{
	struct busfreq_data_int *data = container_of(this,
					struct busfreq_data_int, pm_notifier);
	struct opp *opp;
	unsigned long maxfreq = ULONG_MAX;
	unsigned long freq;
	unsigned long volt;
	int err = 0;

	switch (event) {
	case PM_SUSPEND_PREPARE:
		/* Set Fastest and Deactivate DVFS */
		mutex_lock(&data->lock);

		data->disabled = true;

		rcu_read_lock();
		opp = opp_find_freq_floor(data->dev, &maxfreq);
		if (IS_ERR(opp)) {
			rcu_read_unlock();
			err = PTR_ERR(opp);
			goto unlock;
		}
		freq = opp_get_freq(opp);
		volt = opp_get_voltage(opp);
		rcu_read_unlock();

		err = exynos5_int_setvolt(data, volt);
		if (err)
			goto unlock;

		err = clk_set_rate(data->int_clk, freq * 1000);

		if (err)
			goto unlock;

		data->curr_freq = freq;
unlock:
		mutex_unlock(&data->lock);
		if (err)
			return NOTIFY_BAD;
		return NOTIFY_OK;
	case PM_POST_RESTORE:
	case PM_POST_SUSPEND:
		/* Reactivate */
		mutex_lock(&data->lock);
		data->disabled = false;
		mutex_unlock(&data->lock);
		return NOTIFY_OK;
	}

	return NOTIFY_DONE;
}

static int exynos5_busfreq_int_probe(struct platform_device *pdev)
{
	struct busfreq_data_int *data;
	struct opp *opp;
	struct device *dev = &pdev->dev;
	struct device_node *np;
	unsigned long initial_freq;
	unsigned long initial_volt;
	int err = 0;
	int i;

	data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data_int),
				GFP_KERNEL);
	if (data == NULL) {
		dev_err(dev, "Cannot allocate memory.\n");
		return -ENOMEM;
	}

	np = of_find_compatible_node(NULL, NULL, "samsung,exynos5250-ppmu");
	if (np == NULL) {
		pr_err("Unable to find PPMU node\n");
		return -ENOENT;
	}

	for (i = PPMU_RIGHT; i < PPMU_END; i++) {
		/* map PPMU memory region */
		data->ppmu[i].hw_base = of_iomap(np, i);
		if (data->ppmu[i].hw_base == NULL) {
			dev_err(&pdev->dev, "failed to map memory region\n");
			return -ENOMEM;
		}
	}
	data->pm_notifier.notifier_call = exynos5_busfreq_int_pm_notifier_event;
	data->dev = dev;
	mutex_init(&data->lock);

	err = exynos5250_init_int_tables(data);
	if (err)
		goto err_regulator;

	data->vdd_int = regulator_get(dev, "vdd_int");
	if (IS_ERR(data->vdd_int)) {
		dev_err(dev, "Cannot get the regulator \"vdd_int\"\n");
		err = PTR_ERR(data->vdd_int);
		goto err_regulator;
	}

	data->int_clk = clk_get(dev, "int_clk");
	if (IS_ERR(data->int_clk)) {
		dev_err(dev, "Cannot get clock \"int_clk\"\n");
		err = PTR_ERR(data->int_clk);
		goto err_clock;
	}

	rcu_read_lock();
	opp = opp_find_freq_floor(dev,
			&exynos5_devfreq_int_profile.initial_freq);
	if (IS_ERR(opp)) {
		rcu_read_unlock();
		dev_err(dev, "Invalid initial frequency %lu kHz.\n",
		       exynos5_devfreq_int_profile.initial_freq);
		err = PTR_ERR(opp);
		goto err_opp_add;
	}
	initial_freq = opp_get_freq(opp);
	initial_volt = opp_get_voltage(opp);
	rcu_read_unlock();
	data->curr_freq = initial_freq;

	err = clk_set_rate(data->int_clk, initial_freq * 1000);
	if (err) {
		dev_err(dev, "Failed to set initial frequency\n");
		goto err_opp_add;
	}

	err = exynos5_int_setvolt(data, initial_volt);
	if (err)
		goto err_opp_add;

	platform_set_drvdata(pdev, data);

	busfreq_mon_reset(data);

	data->devfreq = devfreq_add_device(dev, &exynos5_devfreq_int_profile,
					   "simple_ondemand", NULL);

	if (IS_ERR(data->devfreq)) {
		err = PTR_ERR(data->devfreq);
		goto err_devfreq_add;
	}

	devfreq_register_opp_notifier(dev, data->devfreq);

	err = register_pm_notifier(&data->pm_notifier);
	if (err) {
		dev_err(dev, "Failed to setup pm notifier\n");
		goto err_devfreq_add;
	}

	/* TODO: Add a new QOS class for int/mif bus */
	pm_qos_add_request(&data->int_req, PM_QOS_NETWORK_THROUGHPUT, -1);

	return 0;

err_devfreq_add:
	devfreq_remove_device(data->devfreq);
	platform_set_drvdata(pdev, NULL);
err_opp_add:
	clk_put(data->int_clk);
err_clock:
	regulator_put(data->vdd_int);
err_regulator:
	return err;
}

static int exynos5_busfreq_int_remove(struct platform_device *pdev)
{
	struct busfreq_data_int *data = platform_get_drvdata(pdev);

	pm_qos_remove_request(&data->int_req);
	unregister_pm_notifier(&data->pm_notifier);
	devfreq_remove_device(data->devfreq);
	regulator_put(data->vdd_int);
	clk_put(data->int_clk);
	platform_set_drvdata(pdev, NULL);

	return 0;
}

static int exynos5_busfreq_int_resume(struct device *dev)
{
	struct platform_device *pdev = container_of(dev, struct platform_device,
						    dev);
	struct busfreq_data_int *data = platform_get_drvdata(pdev);

	busfreq_mon_reset(data);
	return 0;
}

static const struct dev_pm_ops exynos5_busfreq_int_pm = {
	.resume	= exynos5_busfreq_int_resume,
};

/* platform device pointer for exynos5 devfreq device. */
static struct platform_device *exynos5_devfreq_pdev;

static struct platform_driver exynos5_busfreq_int_driver = {
	.probe		= exynos5_busfreq_int_probe,
	.remove		= exynos5_busfreq_int_remove,
	.driver		= {
		.name		= "exynos5-bus-int",
		.owner		= THIS_MODULE,
		.pm		= &exynos5_busfreq_int_pm,
	},
};

static int __init exynos5_busfreq_int_init(void)
{
	int ret;

	ret = platform_driver_register(&exynos5_busfreq_int_driver);
	if (ret < 0)
		goto out;

	exynos5_devfreq_pdev =
		platform_device_register_simple("exynos5-bus-int", -1, NULL, 0);
	if (IS_ERR_OR_NULL(exynos5_devfreq_pdev)) {
		ret = PTR_ERR(exynos5_devfreq_pdev);
		goto out1;
	}

	return 0;
out1:
	platform_driver_unregister(&exynos5_busfreq_int_driver);
out:
	return ret;
}
late_initcall(exynos5_busfreq_int_init);

static void __exit exynos5_busfreq_int_exit(void)
{
	platform_device_unregister(exynos5_devfreq_pdev);
	platform_driver_unregister(&exynos5_busfreq_int_driver);
}
module_exit(exynos5_busfreq_int_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("EXYNOS5 busfreq driver with devfreq framework");
