/*
 * rmobile power management support
 *
 * Copyright (C) 2012  Renesas Solutions Corp.
 * Copyright (C) 2012  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
 *
 * based on pm-sh7372.c
 *  Copyright (C) 2011 Magnus Damm
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_clock.h>
#include <asm/io.h>
#include <mach/pm-rmobile.h>

/* SYSC */
#define SPDCR		IOMEM(0xe6180008)
#define SWUCR		IOMEM(0xe6180014)
#define PSTR		IOMEM(0xe6180080)

#define PSTR_RETRIES	100
#define PSTR_DELAY_US	10

#ifdef CONFIG_PM
static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
{
	struct rmobile_pm_domain *rmobile_pd = to_rmobile_pd(genpd);
	unsigned int mask = 1 << rmobile_pd->bit_shift;

	if (rmobile_pd->suspend) {
		int ret = rmobile_pd->suspend();

		if (ret)
			return ret;
	}

	if (__raw_readl(PSTR) & mask) {
		unsigned int retry_count;
		__raw_writel(mask, SPDCR);

		for (retry_count = PSTR_RETRIES; retry_count; retry_count--) {
			if (!(__raw_readl(SPDCR) & mask))
				break;
			cpu_relax();
		}
	}

	if (!rmobile_pd->no_debug)
		pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n",
			 genpd->name, mask, __raw_readl(PSTR));

	return 0;
}

static int __rmobile_pd_power_up(struct rmobile_pm_domain *rmobile_pd,
				 bool do_resume)
{
	unsigned int mask = 1 << rmobile_pd->bit_shift;
	unsigned int retry_count;
	int ret = 0;

	if (__raw_readl(PSTR) & mask)
		goto out;

	__raw_writel(mask, SWUCR);

	for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) {
		if (!(__raw_readl(SWUCR) & mask))
			break;
		if (retry_count > PSTR_RETRIES)
			udelay(PSTR_DELAY_US);
		else
			cpu_relax();
	}
	if (!retry_count)
		ret = -EIO;

	if (!rmobile_pd->no_debug)
		pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n",
			 rmobile_pd->genpd.name, mask, __raw_readl(PSTR));

out:
	if (ret == 0 && rmobile_pd->resume && do_resume)
		rmobile_pd->resume();

	return ret;
}

static int rmobile_pd_power_up(struct generic_pm_domain *genpd)
{
	return __rmobile_pd_power_up(to_rmobile_pd(genpd), true);
}

static bool rmobile_pd_active_wakeup(struct device *dev)
{
	bool (*active_wakeup)(struct device *dev);

	active_wakeup = dev_gpd_data(dev)->ops.active_wakeup;
	return active_wakeup ? active_wakeup(dev) : true;
}

static int rmobile_pd_stop_dev(struct device *dev)
{
	int (*stop)(struct device *dev);

	stop = dev_gpd_data(dev)->ops.stop;
	if (stop) {
		int ret = stop(dev);
		if (ret)
			return ret;
	}
	return pm_clk_suspend(dev);
}

static int rmobile_pd_start_dev(struct device *dev)
{
	int (*start)(struct device *dev);
	int ret;

	ret = pm_clk_resume(dev);
	if (ret)
		return ret;

	start = dev_gpd_data(dev)->ops.start;
	if (start)
		ret = start(dev);

	return ret;
}

static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
{
	struct generic_pm_domain *genpd = &rmobile_pd->genpd;
	struct dev_power_governor *gov = rmobile_pd->gov;

	pm_genpd_init(genpd, gov ? : &simple_qos_governor, false);
	genpd->dev_ops.stop		= rmobile_pd_stop_dev;
	genpd->dev_ops.start		= rmobile_pd_start_dev;
	genpd->dev_ops.active_wakeup	= rmobile_pd_active_wakeup;
	genpd->dev_irq_safe		= true;
	genpd->power_off		= rmobile_pd_power_down;
	genpd->power_on			= rmobile_pd_power_up;
	__rmobile_pd_power_up(rmobile_pd, false);
}

void rmobile_init_domains(struct rmobile_pm_domain domains[], int num)
{
	int j;

	for (j = 0; j < num; j++)
		rmobile_init_pm_domain(&domains[j]);
}

void rmobile_add_device_to_domain_td(const char *domain_name,
				     struct platform_device *pdev,
				     struct gpd_timing_data *td)
{
	struct device *dev = &pdev->dev;

	__pm_genpd_name_add_device(domain_name, dev, td);
	if (pm_clk_no_clocks(dev))
		pm_clk_add(dev, NULL);
}

void rmobile_add_devices_to_domains(struct pm_domain_device data[],
				    int size)
{
	struct gpd_timing_data latencies = {
		.stop_latency_ns = DEFAULT_DEV_LATENCY_NS,
		.start_latency_ns = DEFAULT_DEV_LATENCY_NS,
		.save_state_latency_ns = DEFAULT_DEV_LATENCY_NS,
		.restore_state_latency_ns = DEFAULT_DEV_LATENCY_NS,
	};
	int j;

	for (j = 0; j < size; j++)
		rmobile_add_device_to_domain_td(data[j].domain_name,
						data[j].pdev, &latencies);
}
#endif /* CONFIG_PM */
