/*
 * arch/arm/mach-at91rm9200/pm.c
 * AT91 Power Management
 *
 * Copyright (C) 2005 David Brownell
 *
 * 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.
 */

#include <linux/pm.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/pm.h>
#include <linux/interrupt.h>
#include <linux/sysfs.h>
#include <linux/module.h>
#include <linux/platform_device.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/atomic.h>
#include <asm/mach/time.h>
#include <asm/mach/irq.h>
#include <asm/mach-types.h>

#include <asm/arch/gpio.h>

#include "generic.h"


static int at91_pm_valid_state(suspend_state_t state)
{
	switch (state) {
		case PM_SUSPEND_ON:
		case PM_SUSPEND_STANDBY:
		case PM_SUSPEND_MEM:
			return 1;

		default:
			return 0;
	}
}


static suspend_state_t target_state;

/*
 * Called after processes are frozen, but before we shutdown devices.
 */
static int at91_pm_prepare(suspend_state_t state)
{
	target_state = state;
	return 0;
}

/*
 * Verify that all the clocks are correct before entering
 * slow-clock mode.
 */
static int at91_pm_verify_clocks(void)
{
	unsigned long scsr;
	int i;

	scsr = at91_sys_read(AT91_PMC_SCSR);

	/* USB must not be using PLLB */
	if ((scsr & (AT91_PMC_UHP | AT91_PMC_UDP)) != 0) {
		pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
		return 0;
	}

#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
	/* PCK0..PCK3 must be disabled, or configured to use clk32k */
	for (i = 0; i < 4; i++) {
		u32 css;

		if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
			continue;

		css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
		if (css != AT91_PMC_CSS_SLOW) {
			pr_debug("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
			return 0;
		}
	}
#endif

	return 1;
}

/*
 * Call this from platform driver suspend() to see how deeply to suspend.
 * For example, some controllers (like OHCI) need one of the PLL clocks
 * in order to act as a wakeup source, and those are not available when
 * going into slow clock mode.
 *
 * REVISIT: generalize as clk_will_be_available(clk)?  Other platforms have
 * the very same problem (but not using at91 main_clk), and it'd be better
 * to add one generic API rather than lots of platform-specific ones.
 */
int at91_suspend_entering_slow_clock(void)
{
	return (target_state == PM_SUSPEND_MEM);
}
EXPORT_SYMBOL(at91_suspend_entering_slow_clock);


static void (*slow_clock)(void);



static int at91_pm_enter(suspend_state_t state)
{
	at91_gpio_suspend();
	at91_irq_suspend();

	pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
			/* remember all the always-wake irqs */
			(at91_sys_read(AT91_PMC_PCSR)
					| (1 << AT91_ID_FIQ)
					| (1 << AT91_ID_SYS)
					| (1 << AT91RM9200_ID_IRQ0)
					| (1 << AT91RM9200_ID_IRQ1)
					| (1 << AT91RM9200_ID_IRQ2)
					| (1 << AT91RM9200_ID_IRQ3)
					| (1 << AT91RM9200_ID_IRQ4)
					| (1 << AT91RM9200_ID_IRQ5)
					| (1 << AT91RM9200_ID_IRQ6))
				& at91_sys_read(AT91_AIC_IMR),
			state);

	switch (state) {
		/*
		 * Suspend-to-RAM is like STANDBY plus slow clock mode, so
		 * drivers must suspend more deeply:  only the master clock
		 * controller may be using the main oscillator.
		 */
		case PM_SUSPEND_MEM:
			/*
			 * Ensure that clocks are in a valid state.
			 */
			if (!at91_pm_verify_clocks())
				goto error;

			/*
			 * Enter slow clock mode by switching over to clk32k and
			 * turning off the main oscillator; reverse on wakeup.
			 */
			if (slow_clock) {
				slow_clock();
				break;
			} else {
				/* DEVELOPMENT ONLY */
				pr_info("AT91: PM - no slow clock mode yet ...\n");
				/* FALLTHROUGH leaving master clock alone */
			}

		/*
		 * STANDBY mode has *all* drivers suspended; ignores irqs not
		 * marked as 'wakeup' event sources; and reduces DRAM power.
		 * But otherwise it's identical to PM_SUSPEND_ON:  cpu idle, and
		 * nothing fancy done with main or cpu clocks.
		 */
		case PM_SUSPEND_STANDBY:
			/*
			 * NOTE: the Wait-for-Interrupt instruction needs to be
			 * in icache so the SDRAM stays in self-refresh mode until
			 * the wakeup IRQ occurs.
			 */
			asm("b 1f; .align 5; 1:");
			asm("mcr p15, 0, r0, c7, c10, 4");	/* drain write buffer */
			at91_sys_write(AT91_SDRAMC_SRR, 1);	/* self-refresh mode */
			/* fall though to next state */

		case PM_SUSPEND_ON:
			asm("mcr p15, 0, r0, c7, c0, 4");	/* wait for interrupt */
			break;

		default:
			pr_debug("AT91: PM - bogus suspend state %d\n", state);
			goto error;
	}

	pr_debug("AT91: PM - wakeup %08x\n",
			at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR));

error:
	target_state = PM_SUSPEND_ON;
	at91_irq_resume();
	at91_gpio_resume();
	return 0;
}


static struct pm_ops at91_pm_ops ={
	.pm_disk_mode	= 0,
	.valid		= at91_pm_valid_state,
	.prepare	= at91_pm_prepare,
	.enter		= at91_pm_enter,
};

static int __init at91_pm_init(void)
{
	printk("AT91: Power Management\n");

#ifdef CONFIG_AT91_PM_SLOW_CLOCK
	/* REVISIT allocations of SRAM should be dynamically managed.
	 * FIQ handlers and other components will want SRAM/TCM too...
	 */
	slow_clock = (void *) (AT91_VA_BASE_SRAM + (3 * SZ_4K));
	memcpy(slow_clock, at91rm9200_slow_clock, at91rm9200_slow_clock_sz);
#endif

	/* Disable SDRAM low-power mode.  Cannot be used with self-refresh. */
	at91_sys_write(AT91_SDRAMC_LPR, 0);

	pm_set_ops(&at91_pm_ops);

	return 0;
}
arch_initcall(at91_pm_init);
