/*
 * DaVinci Power Management Routines
 *
 * Copyright (C) 2009 Texas Instruments, Inc. http://www.ti.com/
 *
 * 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.h>
#include <linux/suspend.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/spinlock.h>

#include <asm/cacheflush.h>
#include <asm/delay.h>
#include <asm/io.h>

#include <mach/common.h>
#include <mach/da8xx.h>
#include <mach/mux.h>
#include <mach/pm.h>

#include "clock.h"
#include "psc.h"
#include "sram.h"

#define DA850_PLL1_BASE		0x01e1a000
#define DEEPSLEEP_SLEEPCOUNT_MASK	0xFFFF
#define DEEPSLEEP_SLEEPCOUNT		128

static void (*davinci_sram_suspend) (struct davinci_pm_config *);
static struct davinci_pm_config pm_config = {
	.sleepcount = DEEPSLEEP_SLEEPCOUNT,
	.ddrpsc_num = DA8XX_LPSC1_EMIF3C,
};

static void davinci_sram_push(void *dest, void *src, unsigned int size)
{
	memcpy(dest, src, size);
	flush_icache_range((unsigned long)dest, (unsigned long)(dest + size));
}

static void davinci_pm_suspend(void)
{
	unsigned val;

	if (pm_config.cpupll_reg_base != pm_config.ddrpll_reg_base) {

		/* Switch CPU PLL to bypass mode */
		val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
		val &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
		__raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);

		udelay(PLL_BYPASS_TIME);

		/* Powerdown CPU PLL */
		val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
		val |= PLLCTL_PLLPWRDN;
		__raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);
	}

	/* Configure sleep count in deep sleep register */
	val = __raw_readl(pm_config.deepsleep_reg);
	val &= ~DEEPSLEEP_SLEEPCOUNT_MASK,
	val |= pm_config.sleepcount;
	__raw_writel(val, pm_config.deepsleep_reg);

	/* System goes to sleep in this call */
	davinci_sram_suspend(&pm_config);

	if (pm_config.cpupll_reg_base != pm_config.ddrpll_reg_base) {

		/* put CPU PLL in reset */
		val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
		val &= ~PLLCTL_PLLRST;
		__raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);

		/* put CPU PLL in power down */
		val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
		val &= ~PLLCTL_PLLPWRDN;
		__raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);

		/* wait for CPU PLL reset */
		udelay(PLL_RESET_TIME);

		/* bring CPU PLL out of reset */
		val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
		val |= PLLCTL_PLLRST;
		__raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);

		/* Wait for CPU PLL to lock */
		udelay(PLL_LOCK_TIME);

		/* Remove CPU PLL from bypass mode */
		val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
		val &= ~PLLCTL_PLLENSRC;
		val |= PLLCTL_PLLEN;
		__raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);
	}
}

static int davinci_pm_enter(suspend_state_t state)
{
	int ret = 0;

	switch (state) {
	case PM_SUSPEND_MEM:
		davinci_pm_suspend();
		break;
	default:
		ret = -EINVAL;
	}

	return ret;
}

static const struct platform_suspend_ops davinci_pm_ops = {
	.enter		= davinci_pm_enter,
	.valid		= suspend_valid_only_mem,
};

int __init davinci_pm_init(void)
{
	int ret;

	ret = davinci_cfg_reg(DA850_RTC_ALARM);
	if (ret)
		return ret;

	pm_config.ddr2_ctlr_base = da8xx_get_mem_ctlr();
	pm_config.deepsleep_reg = DA8XX_SYSCFG1_VIRT(DA8XX_DEEPSLEEP_REG);

	pm_config.cpupll_reg_base = ioremap(DA8XX_PLL0_BASE, SZ_4K);
	if (!pm_config.cpupll_reg_base)
		return -ENOMEM;

	pm_config.ddrpll_reg_base = ioremap(DA850_PLL1_BASE, SZ_4K);
	if (!pm_config.ddrpll_reg_base) {
		ret = -ENOMEM;
		goto no_ddrpll_mem;
	}

	pm_config.ddrpsc_reg_base = ioremap(DA8XX_PSC1_BASE, SZ_4K);
	if (!pm_config.ddrpsc_reg_base) {
		ret = -ENOMEM;
		goto no_ddrpsc_mem;
	}

	davinci_sram_suspend = sram_alloc(davinci_cpu_suspend_sz, NULL);
	if (!davinci_sram_suspend) {
		pr_err("PM: cannot allocate SRAM memory\n");
		return -ENOMEM;
	}

	davinci_sram_push(davinci_sram_suspend, davinci_cpu_suspend,
						davinci_cpu_suspend_sz);

	suspend_set_ops(&davinci_pm_ops);

no_ddrpsc_mem:
	iounmap(pm_config.ddrpll_reg_base);
no_ddrpll_mem:
	iounmap(pm_config.cpupll_reg_base);
	return ret;
}
