/*
 * MMP2 Power Management Routines
 *
 * This software program is licensed subject to the GNU General Public License
 * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
 *
 * (C) Copyright 2012 Marvell International Ltd.
 * All Rights Reserved
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/time.h>
#include <linux/delay.h>
#include <linux/suspend.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <mach/cputype.h>
#include <mach/addr-map.h>
#include <mach/pm-mmp2.h>
#include <mach/regs-icu.h>
#include <mach/irqs.h>

int mmp2_set_wake(struct irq_data *d, unsigned int on)
{
	unsigned long data = 0;
	int irq = d->irq;

	/* enable wakeup sources */
	switch (irq) {
	case IRQ_MMP2_RTC:
	case IRQ_MMP2_RTC_ALARM:
		data = MPMU_WUCRM_PJ_WAKEUP(4) | MPMU_WUCRM_PJ_RTC_ALARM;
		break;
	case IRQ_MMP2_PMIC:
		data = MPMU_WUCRM_PJ_WAKEUP(7);
		break;
	case IRQ_MMP2_MMC2:
		/* mmc use WAKEUP2, same as GPIO wakeup source */
		data = MPMU_WUCRM_PJ_WAKEUP(2);
		break;
	}
	if (on) {
		if (data) {
			data |= __raw_readl(MPMU_WUCRM_PJ);
			__raw_writel(data, MPMU_WUCRM_PJ);
		}
	} else {
		if (data) {
			data = ~data & __raw_readl(MPMU_WUCRM_PJ);
			__raw_writel(data, MPMU_WUCRM_PJ);
		}
	}
	return 0;
}

static void pm_scu_clk_disable(void)
{
	unsigned int val;

	/* close AXI fabric clock gate */
	__raw_writel(0x0, CIU_REG(0x64));
	__raw_writel(0x0, CIU_REG(0x68));

	/* close MCB master clock gate */
	val = __raw_readl(CIU_REG(0x1c));
	val |= 0xf0;
	__raw_writel(val, CIU_REG(0x1c));

	return ;
}

static void pm_scu_clk_enable(void)
{
	unsigned int val;

	/* open AXI fabric clock gate */
	__raw_writel(0x03003003, CIU_REG(0x64));
	__raw_writel(0x00303030, CIU_REG(0x68));

	/* open MCB master clock gate */
	val = __raw_readl(CIU_REG(0x1c));
	val &= ~(0xf0);
	__raw_writel(val, CIU_REG(0x1c));

	return ;
}

static void pm_mpmu_clk_disable(void)
{
	/*
	 * disable clocks in MPMU_CGR_PJ register
	 * except clock for APMU_PLL1, APMU_PLL1_2 and AP_26M
	 */
	__raw_writel(0x0000a010, MPMU_CGR_PJ);
}

static void pm_mpmu_clk_enable(void)
{
	unsigned int val;

	__raw_writel(0xdffefffe, MPMU_CGR_PJ);
	val = __raw_readl(MPMU_PLL2_CTRL1);
	val |= (1 << 29);
	__raw_writel(val, MPMU_PLL2_CTRL1);

	return ;
}

void mmp2_pm_enter_lowpower_mode(int state)
{
	uint32_t idle_cfg, apcr;

	idle_cfg = __raw_readl(APMU_PJ_IDLE_CFG);
	apcr = __raw_readl(MPMU_PCR_PJ);
	apcr &= ~(MPMU_PCR_PJ_SLPEN | MPMU_PCR_PJ_DDRCORSD | MPMU_PCR_PJ_APBSD
		 | MPMU_PCR_PJ_AXISD | MPMU_PCR_PJ_VCTCXOSD | (1 << 13));
	idle_cfg &= ~APMU_PJ_IDLE_CFG_PJ_IDLE;

	switch (state) {
	case POWER_MODE_SYS_SLEEP:
		apcr |= MPMU_PCR_PJ_SLPEN;		/* set the SLPEN bit */
		apcr |= MPMU_PCR_PJ_VCTCXOSD;		/* set VCTCXOSD */
		/* fall through */
	case POWER_MODE_CHIP_SLEEP:
		apcr |= MPMU_PCR_PJ_SLPEN;
		/* fall through */
	case POWER_MODE_APPS_SLEEP:
		apcr |= MPMU_PCR_PJ_APBSD;		/* set APBSD */
		/* fall through */
	case POWER_MODE_APPS_IDLE:
		apcr |= MPMU_PCR_PJ_AXISD;		/* set AXISDD bit */
		apcr |= MPMU_PCR_PJ_DDRCORSD;		/* set DDRCORSD bit */
		idle_cfg |= APMU_PJ_IDLE_CFG_PJ_PWRDWN;	/* PJ power down */
		apcr |= MPMU_PCR_PJ_SPSD;
		/* fall through */
	case POWER_MODE_CORE_EXTIDLE:
		idle_cfg |= APMU_PJ_IDLE_CFG_PJ_IDLE;	/* set the IDLE bit */
		idle_cfg &= ~APMU_PJ_IDLE_CFG_ISO_MODE_CNTRL_MASK;
		idle_cfg |= APMU_PJ_IDLE_CFG_PWR_SW(3)
			| APMU_PJ_IDLE_CFG_L2_PWR_SW;
		break;
	case POWER_MODE_CORE_INTIDLE:
		apcr &= ~MPMU_PCR_PJ_SPSD;
		break;
	}

	/* set reserve bits */
	apcr |= (1 << 30) | (1 << 25);

	/* finally write the registers back */
	__raw_writel(idle_cfg, APMU_PJ_IDLE_CFG);
	__raw_writel(apcr, MPMU_PCR_PJ);	/* 0xfe086000 */
}

static int mmp2_pm_enter(suspend_state_t state)
{
	int temp;

	temp = __raw_readl(MMP2_ICU_INT4_MASK);
	if (temp & (1 << 1)) {
		printk(KERN_ERR "%s: PMIC interrupt is handling\n", __func__);
		return -EAGAIN;
	}

	temp = __raw_readl(APMU_SRAM_PWR_DWN);
	temp |= ((1 << 19) | (1 << 18));
	__raw_writel(temp, APMU_SRAM_PWR_DWN);
	pm_mpmu_clk_disable();
	pm_scu_clk_disable();

	printk(KERN_INFO "%s: before suspend\n", __func__);
	cpu_do_idle();
	printk(KERN_INFO "%s: after suspend\n", __func__);

	pm_mpmu_clk_enable();		/* enable clocks in MPMU */
	pm_scu_clk_enable();		/* enable clocks in SCU */

	return 0;
}

/*
 * Called after processes are frozen, but before we shut down devices.
 */
static int mmp2_pm_prepare(void)
{
	mmp2_pm_enter_lowpower_mode(POWER_MODE_SYS_SLEEP);

	return 0;
}

/*
 * Called after devices are re-setup, but before processes are thawed.
 */
static void mmp2_pm_finish(void)
{
	mmp2_pm_enter_lowpower_mode(POWER_MODE_CORE_INTIDLE);
}

static int mmp2_pm_valid(suspend_state_t state)
{
	return ((state == PM_SUSPEND_STANDBY) || (state == PM_SUSPEND_MEM));
}

/*
 * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
 */
static const struct platform_suspend_ops mmp2_pm_ops = {
	.valid		= mmp2_pm_valid,
	.prepare	= mmp2_pm_prepare,
	.enter		= mmp2_pm_enter,
	.finish		= mmp2_pm_finish,
};

static int __init mmp2_pm_init(void)
{
	uint32_t apcr;

	if (!cpu_is_mmp2())
		return -EIO;

	suspend_set_ops(&mmp2_pm_ops);

	/*
	 * Set bit 0, Slow clock Select 32K clock input instead of VCXO
	 * VCXO is chosen by default, which would be disabled in suspend
	 */
	__raw_writel(0x5, MPMU_SCCR);

	/*
	 * Clear bit 23 of CIU_CPU_CONF
	 * direct PJ4 to DDR access through Memory Controller slow queue
	 * fast queue has issue and cause lcd will flick
	 */
	__raw_writel(__raw_readl(CIU_REG(0x8)) & ~(0x1 << 23), CIU_REG(0x8));

	/* Clear default low power control bit */
	apcr = __raw_readl(MPMU_PCR_PJ);
	apcr &= ~(MPMU_PCR_PJ_SLPEN | MPMU_PCR_PJ_DDRCORSD
			| MPMU_PCR_PJ_APBSD | MPMU_PCR_PJ_AXISD | 1 << 13);
	__raw_writel(apcr, MPMU_PCR_PJ);

	return 0;
}

late_initcall(mmp2_pm_init);
