/*
 * Suspend/resume support. Currently supporting Armada XP only.
 *
 * Copyright (C) 2014 Marvell
 *
 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/cpu_pm.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mbus.h>
#include <linux/of_address.h>
#include <linux/suspend.h>
#include <asm/cacheflush.h>
#include <asm/outercache.h>
#include <asm/suspend.h>

#include "coherency.h"
#include "common.h"
#include "pmsu.h"

#define SDRAM_CONFIG_OFFS                  0x0
#define  SDRAM_CONFIG_SR_MODE_BIT          BIT(24)
#define SDRAM_OPERATION_OFFS               0x18
#define  SDRAM_OPERATION_SELF_REFRESH      0x7
#define SDRAM_DLB_EVICTION_OFFS            0x30c
#define  SDRAM_DLB_EVICTION_THRESHOLD_MASK 0xff

static void (*mvebu_board_pm_enter)(void __iomem *sdram_reg, u32 srcmd);
static void __iomem *sdram_ctrl;

static int mvebu_pm_powerdown(unsigned long data)
{
	u32 reg, srcmd;

	flush_cache_all();
	outer_flush_all();

	/*
	 * Issue a Data Synchronization Barrier instruction to ensure
	 * that all state saving has been completed.
	 */
	dsb();

	/* Flush the DLB and wait ~7 usec */
	reg = readl(sdram_ctrl + SDRAM_DLB_EVICTION_OFFS);
	reg &= ~SDRAM_DLB_EVICTION_THRESHOLD_MASK;
	writel(reg, sdram_ctrl + SDRAM_DLB_EVICTION_OFFS);

	udelay(7);

	/* Set DRAM in battery backup mode */
	reg = readl(sdram_ctrl + SDRAM_CONFIG_OFFS);
	reg &= ~SDRAM_CONFIG_SR_MODE_BIT;
	writel(reg, sdram_ctrl + SDRAM_CONFIG_OFFS);

	/* Prepare to go to self-refresh */

	srcmd = readl(sdram_ctrl + SDRAM_OPERATION_OFFS);
	srcmd &= ~0x1F;
	srcmd |= SDRAM_OPERATION_SELF_REFRESH;

	mvebu_board_pm_enter(sdram_ctrl + SDRAM_OPERATION_OFFS, srcmd);

	return 0;
}

#define BOOT_INFO_ADDR      0x3000
#define BOOT_MAGIC_WORD	    0xdeadb002
#define BOOT_MAGIC_LIST_END 0xffffffff

/*
 * Those registers are accessed before switching the internal register
 * base, which is why we hardcode the 0xd0000000 base address, the one
 * used by the SoC out of reset.
 */
#define MBUS_WINDOW_12_CTRL       0xd00200b0
#define MBUS_INTERNAL_REG_ADDRESS 0xd0020080

#define SDRAM_WIN_BASE_REG(x)	(0x20180 + (0x8*x))
#define SDRAM_WIN_CTRL_REG(x)	(0x20184 + (0x8*x))

static phys_addr_t mvebu_internal_reg_base(void)
{
	struct device_node *np;
	__be32 in_addr[2];

	np = of_find_node_by_name(NULL, "internal-regs");
	BUG_ON(!np);

	/*
	 * Ask the DT what is the internal register address on this
	 * platform. In the mvebu-mbus DT binding, 0xf0010000
	 * corresponds to the internal register window.
	 */
	in_addr[0] = cpu_to_be32(0xf0010000);
	in_addr[1] = 0x0;

	return of_translate_address(np, in_addr);
}

static void mvebu_pm_store_armadaxp_bootinfo(u32 *store_addr)
{
	phys_addr_t resume_pc;

	resume_pc = virt_to_phys(armada_370_xp_cpu_resume);

	/*
	 * The bootloader expects the first two words to be a magic
	 * value (BOOT_MAGIC_WORD), followed by the address of the
	 * resume code to jump to. Then, it expects a sequence of
	 * (address, value) pairs, which can be used to restore the
	 * value of certain registers. This sequence must end with the
	 * BOOT_MAGIC_LIST_END magic value.
	 */

	writel(BOOT_MAGIC_WORD, store_addr++);
	writel(resume_pc, store_addr++);

	/*
	 * Some platforms remap their internal register base address
	 * to 0xf1000000. However, out of reset, window 12 starts at
	 * 0xf0000000 and ends at 0xf7ffffff, which would overlap with
	 * the internal registers. Therefore, disable window 12.
	 */
	writel(MBUS_WINDOW_12_CTRL, store_addr++);
	writel(0x0, store_addr++);

	/*
	 * Set the internal register base address to the value
	 * expected by Linux, as read from the Device Tree.
	 */
	writel(MBUS_INTERNAL_REG_ADDRESS, store_addr++);
	writel(mvebu_internal_reg_base(), store_addr++);

	/*
	 * Ask the mvebu-mbus driver to store the SDRAM window
	 * configuration, which has to be restored by the bootloader
	 * before re-entering the kernel on resume.
	 */
	store_addr += mvebu_mbus_save_cpu_target(store_addr);

	writel(BOOT_MAGIC_LIST_END, store_addr);
}

static int mvebu_pm_store_bootinfo(void)
{
	u32 *store_addr;

	store_addr = phys_to_virt(BOOT_INFO_ADDR);

	if (of_machine_is_compatible("marvell,armadaxp"))
		mvebu_pm_store_armadaxp_bootinfo(store_addr);
	else
		return -ENODEV;

	return 0;
}

static int mvebu_enter_suspend(void)
{
	int ret;

	ret = mvebu_pm_store_bootinfo();
	if (ret)
		return ret;

	cpu_pm_enter();

	cpu_suspend(0, mvebu_pm_powerdown);

	outer_resume();

	mvebu_v7_pmsu_idle_exit();

	set_cpu_coherent();

	cpu_pm_exit();
	return 0;
}

static int mvebu_pm_enter(suspend_state_t state)
{
	switch (state) {
	case PM_SUSPEND_STANDBY:
		cpu_do_idle();
		break;
	case PM_SUSPEND_MEM:
		pr_warn("Entering suspend to RAM. Only special wake-up sources will resume the system\n");
		return mvebu_enter_suspend();
	default:
		return -EINVAL;
	}
	return 0;
}

static int mvebu_pm_valid(suspend_state_t state)
{
	if (state == PM_SUSPEND_STANDBY)
		return 1;

	if (state == PM_SUSPEND_MEM && mvebu_board_pm_enter != NULL)
		return 1;

	return 0;
}

static const struct platform_suspend_ops mvebu_pm_ops = {
	.enter = mvebu_pm_enter,
	.valid = mvebu_pm_valid,
};

static int __init mvebu_pm_init(void)
{
	if (!of_machine_is_compatible("marvell,armadaxp") &&
	    !of_machine_is_compatible("marvell,armada370") &&
	    !of_machine_is_compatible("marvell,armada380") &&
	    !of_machine_is_compatible("marvell,armada390"))
		return -ENODEV;

	suspend_set_ops(&mvebu_pm_ops);

	return 0;
}


late_initcall(mvebu_pm_init);

int __init mvebu_pm_suspend_init(void (*board_pm_enter)(void __iomem *sdram_reg,
							u32 srcmd))
{
	struct device_node *np;
	struct resource res;

	np = of_find_compatible_node(NULL, NULL,
				     "marvell,armada-xp-sdram-controller");
	if (!np)
		return -ENODEV;

	if (of_address_to_resource(np, 0, &res)) {
		of_node_put(np);
		return -ENODEV;
	}

	if (!request_mem_region(res.start, resource_size(&res),
				np->full_name)) {
		of_node_put(np);
		return -EBUSY;
	}

	sdram_ctrl = ioremap(res.start, resource_size(&res));
	if (!sdram_ctrl) {
		release_mem_region(res.start, resource_size(&res));
		of_node_put(np);
		return -ENOMEM;
	}

	of_node_put(np);

	mvebu_board_pm_enter = board_pm_enter;

	return 0;
}
