/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

//#define DEBUG
#include <linux/suspend.h>
#include <linux/interrupt.h>
#include <linux/sysfs.h>
#include <linux/module.h>
#include <linux/proc_fs.h>

#include <asm/mach/time.h>

#include "ctrlEnv/mvCtrlEnvLib.h"
#include "ctrlEnv/sys/mvCpuIf.h"
#include "boardEnv/mvBoardEnvLib.h"
#include "gpp/mvGpp.h"
#include "device/mvDeviceRegs.h"
#include "cntmr/mvCntmrRegs.h"
#include "cpu/mvCpu.h"

#define	MV_PMU_REGS_BASE	MV_PMU_REGS_OFFSET

#define PMU_L2C_CTRL_AND_CONF	(MV_PMU_REGS_BASE + 0x004)
#define PMU_L2C_EVENT_STATUS	(MV_PMU_REGS_BASE + 0x020)
#define PMU_CPU_CTRL_AND_CONF	(MV_PMU_REGS_BASE + 0x104)
#define PMU_CPU_STATUS_MASK	(MV_PMU_REGS_BASE + 0x10C)
#define PMU_CPU_EVENT_STATUS	(MV_PMU_REGS_BASE + 0x120)
#define PMU_CPU_BOOT_ADDR	(MV_PMU_REGS_BASE + 0x124)
#define PMU_PWR_UP_DELAY	(MV_DEV_PMU_REGS_OFFSET + 0x014)

static unsigned int   	count_standby;

extern int kw2_cpu_suspend(void);
extern int kw2_cpu_resume(void);
extern MV_CPU_DEC_WIN* mv_sys_map(void);

static int mv_pm_enter(suspend_state_t state);

static MV_AHB_TO_MBUS_DEC_WIN ahbAddrDecWin[MAX_AHB_TO_MBUS_WINS];
static MV_ADDR_WIN ahbAddrWinRemap[MAX_AHB_TO_MBUS_WINS];

#define CONFIG_PMU_PROC

void mv_kw2_cpu_idle_enter(void)
{
	mv_pm_enter(PM_SUSPEND_STANDBY);
	return;
}

void mv_kw2_cpu_idle_enter_wfi(void)
{
	/* Disable all interrupts . */
	MV_REG_WRITE(MV_IRQ_MASK_LOW_REG, 0x0);
	MV_REG_WRITE(MV_IRQ_MASK_HIGH_REG, 0x0);
	MV_REG_WRITE(MV_IRQ_MASK_ERROR_REG, 0x0);
	cpu_do_idle();
}

static void save_kw2_cpu_win_state(void)
{
	u32 i;
	MV_AHB_TO_MBUS_DEC_WIN	winInfo;

	/* Save CPU windows state, and enable access for Bootrom	*
	** according to SoC default address decoding windows.		*/
	for(i = 0; i < MAX_AHB_TO_MBUS_WINS; i++) {
		mvAhbToMbusWinGet(i, &ahbAddrDecWin[i]);
		mvAhbToMbusWinRemapGet(i, &ahbAddrWinRemap[i]);
		
		/* Disable the window */
		mvAhbToMbusWinEnable(i, MV_FALSE);
	}

	/* Open default windows for Bootrom, PnC and internal regs.	*/
	/* Bootrom */
	winInfo.target = BOOT_ROM_CS;
	winInfo.addrWin.baseLow = 0xF8000000;
	winInfo.addrWin.baseHigh = 0x0;
	winInfo.addrWin.size = _128M;
	winInfo.enable = MV_TRUE;
	mvAhbToMbusWinSet(7, &winInfo);

	/* PnC */
	winInfo.target = PNC_BM;
	winInfo.addrWin.baseLow = 0xC0060000;
	winInfo.addrWin.baseHigh = 0x0;
	winInfo.addrWin.size = _64K;
	winInfo.enable = MV_TRUE;
	mvAhbToMbusWinSet(6, &winInfo);
#if 0
	/* Internal regs */
	winInfo.target = INTER_REGS;
	winInfo.addrWin.baseLow = 0xD0000000;
	winInfo.addrWin.baseHigh = 0x0;
	winInfo.addrWin.size = _1M;
	winInfo.enable = MV_TRUE;
	mvAhbToMbusWinSet(MV_AHB_TO_MBUS_INTREG_WIN, &winInfo);
#endif
	/* Cesa SRAM */
	winInfo.target = CRYPT1_ENG;
	winInfo.addrWin.baseLow = 0xC8010000;
	winInfo.addrWin.baseHigh = 0x0;
	winInfo.addrWin.size = _64K;
	winInfo.enable = MV_TRUE;
	mvAhbToMbusWinSet(4, &winInfo);

}


static void restore_kw2_cpu_win_state(void)
{
	mvCpuIfInit(mv_sys_map());
}

unsigned long suspend_phys_addr(void * physaddr)
{
	return virt_to_phys(physaddr);
}

static void mv_enter_standby(void)
{
	u32 reg;
	static MV_U32 pwrUpDelay = 0;
	

	pr_debug("kw2_standby: Entering STANDBY mode.\n");
	
	if (pwrUpDelay == 0)
		pwrUpDelay = mvBoardPwrUpDelayGet();

	count_standby++;

	save_kw2_cpu_win_state();

	/* Prepare resume PC */
	MV_REG_WRITE(PMU_CPU_BOOT_ADDR, virt_to_phys(kw2_cpu_resume));

	MV_REG_WRITE(PMU_PWR_UP_DELAY, pwrUpDelay);

	MV_REG_WRITE(PMU_CPU_STATUS_MASK, 0x00310000);

	/* L2 Power down enable */
	if (mvCpuL2Exists())
		MV_REG_BIT_SET(PMU_L2C_CTRL_AND_CONF, BIT20);

	/* CPU Power down enable */
	MV_REG_BIT_SET(PMU_CPU_CTRL_AND_CONF, BIT20);

	/* CPU Power down request */
	MV_REG_BIT_SET(PMU_CPU_CTRL_AND_CONF, BIT16);

	/* Suspend the CPU only */
	if (kw2_cpu_suspend() == 0)
		cpu_init();

	restore_kw2_cpu_win_state();

	reg = MV_REG_READ(PMU_CPU_STATUS_MASK);
	reg &= ~0x3310000;
	MV_REG_WRITE(PMU_CPU_STATUS_MASK, reg);

	pr_debug("kw2_standby: Exiting STANDBY mode.\n");	
}


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

	switch (state) {
	case PM_SUSPEND_STANDBY:
		mv_enter_standby();
		break;
	default:
		ret = -EINVAL;
	}

	return ret;
}


int __init mv_pm_init(void)
{
	/*
	if (MV_6601_DEV_ID == mvCtrlModelGet())
		return 0;
	*/

	printk(KERN_INFO "Marvell Kirkwood2 Power Management Initializing\n");

	return 0;
}

late_initcall(mv_pm_init);

