/*
 * 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/sched/signal.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(*pmc_regs));

	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(*clock_regs));

	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
};

builtin_platform_driver(pmc_driver);
