/*
 * MPC83xx suspend support
 *
 * Author: Scott Wood <scottwood@freescale.com>
 *
 * Copyright (c) 2006-2007 Freescale Semiconductor, Inc.
 *
 * 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/types.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/suspend.h>
#include <linux/fsl_devices.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/export.h>

#include <asm/reg.h>
#include <asm/io.h>
#include <asm/time.h>
#include <asm/mpc6xx.h>
#include <asm/switch_to.h>

#include <sysdev/fsl_soc.h>

#define PMCCR1_NEXT_STATE       0x0C /* Next state for power management */
#define PMCCR1_NEXT_STATE_SHIFT 2
#define PMCCR1_CURR_STATE       0x03 /* Current state for power management*/
#define IMMR_SYSCR_OFFSET       0x100
#define IMMR_RCW_OFFSET         0x900
#define RCW_PCI_HOST            0x80000000

void mpc83xx_enter_deep_sleep(phys_addr_t immrbase);

struct mpc83xx_pmc {
	u32 config;
#define PMCCR_DLPEN 2 /* DDR SDRAM low power enable */
#define PMCCR_SLPEN 1 /* System low power enable */

	u32 event;
	u32 mask;
/* All but PMCI are deep-sleep only */
#define PMCER_GPIO   0x100
#define PMCER_PCI    0x080
#define PMCER_USB    0x040
#define PMCER_ETSEC1 0x020
#define PMCER_ETSEC2 0x010
#define PMCER_TIMER  0x008
#define PMCER_INT1   0x004
#define PMCER_INT2   0x002
#define PMCER_PMCI   0x001
#define PMCER_ALL    0x1FF

	/* deep-sleep only */
	u32 config1;
#define PMCCR1_USE_STATE  0x80000000
#define PMCCR1_PME_EN     0x00000080
#define PMCCR1_ASSERT_PME 0x00000040
#define PMCCR1_POWER_OFF  0x00000020

	/* deep-sleep only */
	u32 config2;
};

struct mpc83xx_rcw {
	u32 rcwlr;
	u32 rcwhr;
};

struct mpc83xx_clock {
	u32 spmr;
	u32 occr;
	u32 sccr;
};

struct mpc83xx_syscr {
	__be32 sgprl;
	__be32 sgprh;
	__be32 spridr;
	__be32 :32;
	__be32 spcr;
	__be32 sicrl;
	__be32 sicrh;
};

struct mpc83xx_saved {
	u32 sicrl;
	u32 sicrh;
	u32 sccr;
};

struct pmc_type {
	int has_deep_sleep;
};

static struct platform_device *pmc_dev;
static int has_deep_sleep, deep_sleeping;
static int pmc_irq;
static struct mpc83xx_pmc __iomem *pmc_regs;
static struct mpc83xx_clock __iomem *clock_regs;
static struct mpc83xx_syscr __iomem *syscr_regs;
static struct mpc83xx_saved saved_regs;
static int is_pci_agent, wake_from_pci;
static phys_addr_t immrbase;
static int pci_pm_state;
static DECLARE_WAIT_QUEUE_HEAD(agent_wq);

int fsl_deep_sleep(void)
{
	return deep_sleeping;
}
EXPORT_SYMBOL(fsl_deep_sleep);

static int mpc83xx_change_state(void)
{
	u32 curr_state;
	u32 reg_cfg1 = in_be32(&pmc_regs->config1);

	if (is_pci_agent) {
		pci_pm_state = (reg_cfg1 & PMCCR1_NEXT_STATE) >>
		               PMCCR1_NEXT_STATE_SHIFT;
		curr_state = reg_cfg1 & PMCCR1_CURR_STATE;

		if (curr_state != pci_pm_state) {
			reg_cfg1 &= ~PMCCR1_CURR_STATE;
			reg_cfg1 |= pci_pm_state;
			out_be32(&pmc_regs->config1, reg_cfg1);

			wake_up(&agent_wq);
			return 1;
		}
	}

	return 0;
}

static irqreturn_t pmc_irq_handler(int irq, void *dev_id)
{
	u32 event = in_be32(&pmc_regs->event);
	int ret = IRQ_NONE;

	if (mpc83xx_change_state())
		ret = IRQ_HANDLED;

	if (event) {
		out_be32(&pmc_regs->event, event);
		ret = IRQ_HANDLED;
	}

	return ret;
}

static void mpc83xx_suspend_restore_regs(void)
{
	out_be32(&syscr_regs->sicrl, saved_regs.sicrl);
	out_be32(&syscr_regs->sicrh, saved_regs.sicrh);
	out_be32(&clock_regs->sccr, saved_regs.sccr);
}

static void mpc83xx_suspend_save_regs(void)
{
	saved_regs.sicrl = in_be32(&syscr_regs->sicrl);
	saved_regs.sicrh = in_be32(&syscr_regs->sicrh);
	saved_regs.sccr = in_be32(&clock_regs->sccr);
}

static int mpc83xx_suspend_enter(suspend_state_t state)
{
	int ret = -EAGAIN;

	/* Don't go to sleep if there's a race where pci_pm_state changes
	 * between the agent thread checking it and the PM code disabling
	 * interrupts.
	 */
	if (wake_from_pci) {
		if (pci_pm_state != (deep_sleeping ? 3 : 2))
			goto out;

		out_be32(&pmc_regs->config1,
		         in_be32(&pmc_regs->config1) | PMCCR1_PME_EN);
	}

	/* Put the system into low-power mode and the RAM
	 * into self-refresh mode once the core goes to
	 * sleep.
	 */

	out_be32(&pmc_regs->config, PMCCR_SLPEN | PMCCR_DLPEN);

	/* If it has deep sleep (i.e. it's an 831x or compatible),
	 * disable power to the core upon entering sleep mode.  This will
	 * require going through the boot firmware upon a wakeup event.
	 */

	if (deep_sleeping) {
		mpc83xx_suspend_save_regs();

		out_be32(&pmc_regs->mask, PMCER_ALL);

		out_be32(&pmc_regs->config1,
		         in_be32(&pmc_regs->config1) | PMCCR1_POWER_OFF);

		enable_kernel_fp();

		mpc83xx_enter_deep_sleep(immrbase);

		out_be32(&pmc_regs->config1,
		         in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF);

		out_be32(&pmc_regs->mask, PMCER_PMCI);

		mpc83xx_suspend_restore_regs();
	} else {
		out_be32(&pmc_regs->mask, PMCER_PMCI);

		mpc6xx_enter_standby();
	}

	ret = 0;

out:
	out_be32(&pmc_regs->config1,
	         in_be32(&pmc_regs->config1) & ~PMCCR1_PME_EN);

	return ret;
}

static void mpc83xx_suspend_end(void)
{
	deep_sleeping = 0;
}

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

static int mpc83xx_suspend_begin(suspend_state_t state)
{
	switch (state) {
		case PM_SUSPEND_STANDBY:
			deep_sleeping = 0;
			return 0;

		case PM_SUSPEND_MEM:
			if (has_deep_sleep)
				deep_sleeping = 1;

			return 0;

		default:
			return -EINVAL;
	}
}

static int agent_thread_fn(void *data)
{
	while (1) {
		wait_event_interruptible(agent_wq, pci_pm_state >= 2);
		try_to_freeze();

		if (signal_pending(current) || pci_pm_state < 2)
			continue;

		/* With a preemptible kernel (or SMP), this could race with
		 * a userspace-driven suspend request.  It's probably best
		 * to avoid mixing the two with such a configuration (or
		 * else fix it by adding a mutex to state_store that we can
		 * synchronize with).
		 */

		wake_from_pci = 1;

		pm_suspend(pci_pm_state == 3 ? PM_SUSPEND_MEM :
		                               PM_SUSPEND_STANDBY);

		wake_from_pci = 0;
	}

	return 0;
}

static void mpc83xx_set_agent(void)
{
	out_be32(&pmc_regs->config1, PMCCR1_USE_STATE);
	out_be32(&pmc_regs->mask, PMCER_PMCI);

	kthread_run(agent_thread_fn, NULL, "PCI power mgt");
}

static int mpc83xx_is_pci_agent(void)
{
	struct mpc83xx_rcw __iomem *rcw_regs;
	int ret;

	rcw_regs = ioremap(get_immrbase() + IMMR_RCW_OFFSET,
	                   sizeof(struct mpc83xx_rcw));

	if (!rcw_regs)
		return -ENOMEM;

	ret = !(in_be32(&rcw_regs->rcwhr) & RCW_PCI_HOST);

	iounmap(rcw_regs);
	return ret;
}

static const struct platform_suspend_ops mpc83xx_suspend_ops = {
	.valid = mpc83xx_suspend_valid,
	.begin = mpc83xx_suspend_begin,
	.enter = mpc83xx_suspend_enter,
	.end = mpc83xx_suspend_end,
};

static const struct of_device_id pmc_match[];
static int pmc_probe(struct platform_device *ofdev)
{
	const struct of_device_id *match;
	struct device_node *np = ofdev->dev.of_node;
	struct resource res;
	const struct pmc_type *type;
	int ret = 0;

	match = of_match_device(pmc_match, &ofdev->dev);
	if (!match)
		return -EINVAL;

	type = match->data;

	if (!of_device_is_available(np))
		return -ENODEV;

	has_deep_sleep = type->has_deep_sleep;
	immrbase = get_immrbase();
	pmc_dev = ofdev;

	is_pci_agent = mpc83xx_is_pci_agent();
	if (is_pci_agent < 0)
		return is_pci_agent;

	ret = of_address_to_resource(np, 0, &res);
	if (ret)
		return -ENODEV;

	pmc_irq = irq_of_parse_and_map(np, 0);
	if (pmc_irq) {
		ret = request_irq(pmc_irq, pmc_irq_handler, IRQF_SHARED,
		                  "pmc", ofdev);

		if (ret)
			return -EBUSY;
	}

	pmc_regs = ioremap(res.start, sizeof(struct mpc83xx_pmc));

	if (!pmc_regs) {
		ret = -ENOMEM;
		goto out;
	}

	ret = of_address_to_resource(np, 1, &res);
	if (ret) {
		ret = -ENODEV;
		goto out_pmc;
	}

	clock_regs = ioremap(res.start, sizeof(struct mpc83xx_pmc));

	if (!clock_regs) {
		ret = -ENOMEM;
		goto out_pmc;
	}

	if (has_deep_sleep) {
		syscr_regs = ioremap(immrbase + IMMR_SYSCR_OFFSET,
				     sizeof(*syscr_regs));
		if (!syscr_regs) {
			ret = -ENOMEM;
			goto out_syscr;
		}
	}

	if (is_pci_agent)
		mpc83xx_set_agent();

	suspend_set_ops(&mpc83xx_suspend_ops);
	return 0;

out_syscr:
	iounmap(clock_regs);
out_pmc:
	iounmap(pmc_regs);
out:
	if (pmc_irq)
		free_irq(pmc_irq, ofdev);

	return ret;
}

static int pmc_remove(struct platform_device *ofdev)
{
	return -EPERM;
};

static struct pmc_type pmc_types[] = {
	{
		.has_deep_sleep = 1,
	},
	{
		.has_deep_sleep = 0,
	}
};

static const struct of_device_id pmc_match[] = {
	{
		.compatible = "fsl,mpc8313-pmc",
		.data = &pmc_types[0],
	},
	{
		.compatible = "fsl,mpc8349-pmc",
		.data = &pmc_types[1],
	},
	{}
};

static struct platform_driver pmc_driver = {
	.driver = {
		.name = "mpc83xx-pmc",
		.of_match_table = pmc_match,
	},
	.probe = pmc_probe,
	.remove = pmc_remove
};

static int pmc_init(void)
{
	return platform_driver_register(&pmc_driver);
}
device_initcall(pmc_init);
