// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * arch/arm/mach-at91/pm.c
 * AT91 Power Management
 *
 * Copyright (C) 2005 David Brownell
 */

#include <linux/genalloc.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/parser.h>
#include <linux/suspend.h>

#include <linux/clk.h>
#include <linux/clk/at91_pmc.h>
#include <linux/platform_data/atmel.h>

#include <asm/cacheflush.h>
#include <asm/fncpy.h>
#include <asm/system_misc.h>
#include <asm/suspend.h>

#include "generic.h"
#include "pm.h"
#include "sam_secure.h"

#define BACKUP_DDR_PHY_CALIBRATION	(9)

/**
 * struct at91_pm_bu - AT91 power management backup unit data structure
 * @suspended: true if suspended to backup mode
 * @reserved: reserved
 * @canary: canary data for memory checking after exit from backup mode
 * @resume: resume API
 * @ddr_phy_calibration: DDR PHY calibration data: ZQ0CR0, first 8 words
 * of the memory
 */
struct at91_pm_bu {
	int suspended;
	unsigned long reserved;
	phys_addr_t canary;
	phys_addr_t resume;
	unsigned long ddr_phy_calibration[BACKUP_DDR_PHY_CALIBRATION];
};

/**
 * struct at91_pm_sfrbu_regs - registers mapping for SFRBU
 * @pswbu: power switch BU control registers
 */
struct at91_pm_sfrbu_regs {
	struct {
		u32 key;
		u32 ctrl;
		u32 state;
		u32 softsw;
	} pswbu;
};

/**
 * enum at91_pm_eth_clk - Ethernet clock indexes
 * @AT91_PM_ETH_PCLK: pclk index
 * @AT91_PM_ETH_HCLK: hclk index
 * @AT91_PM_ETH_MAX_CLK: max index
 */
enum at91_pm_eth_clk {
	AT91_PM_ETH_PCLK,
	AT91_PM_ETH_HCLK,
	AT91_PM_ETH_MAX_CLK,
};

/**
 * enum at91_pm_eth - Ethernet controller indexes
 * @AT91_PM_G_ETH: gigabit Ethernet controller index
 * @AT91_PM_E_ETH: megabit Ethernet controller index
 * @AT91_PM_MAX_ETH: max index
 */
enum at91_pm_eth {
	AT91_PM_G_ETH,
	AT91_PM_E_ETH,
	AT91_PM_MAX_ETH,
};

/**
 * struct at91_pm_quirk_eth - AT91 PM Ethernet quirks
 * @dev: Ethernet device
 * @np: Ethernet device node
 * @clks: Ethernet clocks
 * @modes: power management mode that this quirk applies to
 * @dns_modes: do not suspend modes: stop suspending if Ethernet is configured
 *	       as wakeup source but buggy and no other wakeup source is
 *	       available
 */
struct at91_pm_quirk_eth {
	struct device *dev;
	struct device_node *np;
	struct clk_bulk_data clks[AT91_PM_ETH_MAX_CLK];
	u32 modes;
	u32 dns_modes;
};

/**
 * struct at91_pm_quirks - AT91 PM quirks
 * @eth: Ethernet quirks
 */
struct at91_pm_quirks {
	struct at91_pm_quirk_eth eth[AT91_PM_MAX_ETH];
};

/**
 * struct at91_soc_pm - AT91 SoC power management data structure
 * @config_shdwc_ws: wakeup sources configuration function for SHDWC
 * @config_pmc_ws: wakeup srouces configuration function for PMC
 * @ws_ids: wakup sources of_device_id array
 * @bu: backup unit mapped data (for backup mode)
 * @quirks: PM quirks
 * @data: PM data to be used on last phase of suspend
 * @sfrbu_regs: SFRBU registers mapping
 * @memcs: memory chip select
 */
struct at91_soc_pm {
	int (*config_shdwc_ws)(void __iomem *shdwc, u32 *mode, u32 *polarity);
	int (*config_pmc_ws)(void __iomem *pmc, u32 mode, u32 polarity);
	const struct of_device_id *ws_ids;
	struct at91_pm_bu *bu;
	struct at91_pm_quirks quirks;
	struct at91_pm_data data;
	struct at91_pm_sfrbu_regs sfrbu_regs;
	void *memcs;
};

/**
 * enum at91_pm_iomaps - IOs that needs to be mapped for different PM modes
 * @AT91_PM_IOMAP_SHDWC:	SHDWC controller
 * @AT91_PM_IOMAP_SFRBU:	SFRBU controller
 * @AT91_PM_IOMAP_ETHC:		Ethernet controller
 */
enum at91_pm_iomaps {
	AT91_PM_IOMAP_SHDWC,
	AT91_PM_IOMAP_SFRBU,
	AT91_PM_IOMAP_ETHC,
};

#define AT91_PM_IOMAP(name)	BIT(AT91_PM_IOMAP_##name)

static struct at91_soc_pm soc_pm = {
	.data = {
		.standby_mode = AT91_PM_STANDBY,
		.suspend_mode = AT91_PM_ULP0,
	},
};

static const match_table_t pm_modes __initconst = {
	{ AT91_PM_STANDBY,	"standby" },
	{ AT91_PM_ULP0,		"ulp0" },
	{ AT91_PM_ULP0_FAST,    "ulp0-fast" },
	{ AT91_PM_ULP1,		"ulp1" },
	{ AT91_PM_BACKUP,	"backup" },
	{ -1, NULL },
};

#define at91_ramc_read(id, field) \
	__raw_readl(soc_pm.data.ramc[id] + field)

#define at91_ramc_write(id, field, value) \
	__raw_writel(value, soc_pm.data.ramc[id] + field)

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 int canary = 0xA5A5A5A5;

struct wakeup_source_info {
	unsigned int pmc_fsmr_bit;
	unsigned int shdwc_mr_bit;
	bool set_polarity;
};

static const struct wakeup_source_info ws_info[] = {
	{ .pmc_fsmr_bit = AT91_PMC_FSTT(10),	.set_polarity = true },
	{ .pmc_fsmr_bit = AT91_PMC_RTCAL,	.shdwc_mr_bit = BIT(17) },
	{ .pmc_fsmr_bit = AT91_PMC_USBAL },
	{ .pmc_fsmr_bit = AT91_PMC_SDMMC_CD },
	{ .pmc_fsmr_bit = AT91_PMC_RTTAL },
	{ .pmc_fsmr_bit = AT91_PMC_RXLP_MCE },
};

static const struct of_device_id sama5d2_ws_ids[] = {
	{ .compatible = "atmel,sama5d2-gem",		.data = &ws_info[0] },
	{ .compatible = "atmel,sama5d2-rtc",		.data = &ws_info[1] },
	{ .compatible = "atmel,sama5d3-udc",		.data = &ws_info[2] },
	{ .compatible = "atmel,at91rm9200-ohci",	.data = &ws_info[2] },
	{ .compatible = "usb-ohci",			.data = &ws_info[2] },
	{ .compatible = "atmel,at91sam9g45-ehci",	.data = &ws_info[2] },
	{ .compatible = "usb-ehci",			.data = &ws_info[2] },
	{ .compatible = "atmel,sama5d2-sdhci",		.data = &ws_info[3] },
	{ /* sentinel */ }
};

static const struct of_device_id sam9x60_ws_ids[] = {
	{ .compatible = "microchip,sam9x60-rtc",	.data = &ws_info[1] },
	{ .compatible = "atmel,at91rm9200-ohci",	.data = &ws_info[2] },
	{ .compatible = "usb-ohci",			.data = &ws_info[2] },
	{ .compatible = "atmel,at91sam9g45-ehci",	.data = &ws_info[2] },
	{ .compatible = "usb-ehci",			.data = &ws_info[2] },
	{ .compatible = "microchip,sam9x60-rtt",	.data = &ws_info[4] },
	{ .compatible = "cdns,sam9x60-macb",		.data = &ws_info[5] },
	{ /* sentinel */ }
};

static const struct of_device_id sama7g5_ws_ids[] = {
	{ .compatible = "microchip,sama7g5-rtc",	.data = &ws_info[1] },
	{ .compatible = "microchip,sama7g5-ohci",	.data = &ws_info[2] },
	{ .compatible = "usb-ohci",			.data = &ws_info[2] },
	{ .compatible = "atmel,at91sam9g45-ehci",	.data = &ws_info[2] },
	{ .compatible = "usb-ehci",			.data = &ws_info[2] },
	{ .compatible = "microchip,sama7g5-sdhci",	.data = &ws_info[3] },
	{ .compatible = "microchip,sama7g5-rtt",	.data = &ws_info[4] },
	{ /* sentinel */ }
};

static const struct of_device_id sam9x7_ws_ids[] = {
	{ .compatible = "microchip,sam9x7-rtc",		.data = &ws_info[1] },
	{ .compatible = "microchip,sam9x7-rtt",		.data = &ws_info[4] },
	{ .compatible = "microchip,sam9x7-gem",		.data = &ws_info[5] },
	{ /* sentinel */ }
};

static int at91_pm_config_ws(unsigned int pm_mode, bool set)
{
	const struct wakeup_source_info *wsi;
	const struct of_device_id *match;
	struct platform_device *pdev;
	struct device_node *np;
	unsigned int mode = 0, polarity = 0, val = 0;

	if (pm_mode != AT91_PM_ULP1)
		return 0;

	if (!soc_pm.data.pmc || !soc_pm.data.shdwc || !soc_pm.ws_ids)
		return -EPERM;

	if (!set) {
		writel(mode, soc_pm.data.pmc + AT91_PMC_FSMR);
		return 0;
	}

	if (soc_pm.config_shdwc_ws)
		soc_pm.config_shdwc_ws(soc_pm.data.shdwc, &mode, &polarity);

	/* SHDWC.MR */
	val = readl(soc_pm.data.shdwc + 0x04);

	/* Loop through defined wakeup sources. */
	for_each_matching_node_and_match(np, soc_pm.ws_ids, &match) {
		pdev = of_find_device_by_node(np);
		if (!pdev)
			continue;

		if (device_may_wakeup(&pdev->dev)) {
			wsi = match->data;

			/* Check if enabled on SHDWC. */
			if (wsi->shdwc_mr_bit && !(val & wsi->shdwc_mr_bit))
				goto put_device;

			mode |= wsi->pmc_fsmr_bit;
			if (wsi->set_polarity)
				polarity |= wsi->pmc_fsmr_bit;
		}

put_device:
		put_device(&pdev->dev);
	}

	if (mode) {
		if (soc_pm.config_pmc_ws)
			soc_pm.config_pmc_ws(soc_pm.data.pmc, mode, polarity);
	} else {
		pr_err("AT91: PM: no ULP1 wakeup sources found!");
	}

	return mode ? 0 : -EPERM;
}

static int at91_sama5d2_config_shdwc_ws(void __iomem *shdwc, u32 *mode,
					u32 *polarity)
{
	u32 val;

	/* SHDWC.WUIR */
	val = readl(shdwc + 0x0c);
	*mode |= (val & 0x3ff);
	*polarity |= ((val >> 16) & 0x3ff);

	return 0;
}

static int at91_sama5d2_config_pmc_ws(void __iomem *pmc, u32 mode, u32 polarity)
{
	writel(mode, pmc + AT91_PMC_FSMR);
	writel(polarity, pmc + AT91_PMC_FSPR);

	return 0;
}

static int at91_sam9x60_config_pmc_ws(void __iomem *pmc, u32 mode, u32 polarity)
{
	writel(mode, pmc + AT91_PMC_FSMR);

	return 0;
}

static bool at91_pm_eth_quirk_is_valid(struct at91_pm_quirk_eth *eth)
{
	struct platform_device *pdev;

	/* Interface NA in DT. */
	if (!eth->np)
		return false;

	/* No quirks for this interface and current suspend mode. */
	if (!(eth->modes & BIT(soc_pm.data.mode)))
		return false;

	if (!eth->dev) {
		/* Driver not probed. */
		pdev = of_find_device_by_node(eth->np);
		if (!pdev)
			return false;
		/* put_device(eth->dev) is called at the end of suspend. */
		eth->dev = &pdev->dev;
	}

	/* No quirks if device isn't a wakeup source. */
	if (!device_may_wakeup(eth->dev))
		return false;

	return true;
}

static int at91_pm_config_quirks(bool suspend)
{
	struct at91_pm_quirk_eth *eth;
	int i, j, ret, tmp;

	/*
	 * Ethernet IPs who's device_node pointers are stored into
	 * soc_pm.quirks.eth[].np cannot handle WoL packets while in ULP0, ULP1
	 * or both due to a hardware bug. If they receive WoL packets while in
	 * ULP0 or ULP1 IPs could stop working or the whole system could stop
	 * working. We cannot handle this scenario in the ethernet driver itself
	 * as the driver is common to multiple vendors and also we only know
	 * here, in this file, if we suspend to ULP0 or ULP1 mode. Thus handle
	 * these scenarios here, as quirks.
	 */
	for (i = 0; i < AT91_PM_MAX_ETH; i++) {
		eth = &soc_pm.quirks.eth[i];

		if (!at91_pm_eth_quirk_is_valid(eth))
			continue;

		/*
		 * For modes in dns_modes mask the system blocks if quirk is not
		 * applied but if applied the interface doesn't act at WoL
		 * events. Thus take care to avoid suspending if this interface
		 * is the only configured wakeup source.
		 */
		if (suspend && eth->dns_modes & BIT(soc_pm.data.mode)) {
			int ws_count = 0;
#ifdef CONFIG_PM_SLEEP
			struct wakeup_source *ws;

			for_each_wakeup_source(ws) {
				if (ws->dev == eth->dev)
					continue;

				ws_count++;
				break;
			}
#endif

			/*
			 * Checking !ws is good for all platforms with issues
			 * even when both G_ETH and E_ETH are available as dns_modes
			 * is populated only on G_ETH interface.
			 */
			if (!ws_count) {
				pr_err("AT91: PM: Ethernet cannot resume from WoL!");
				ret = -EPERM;
				put_device(eth->dev);
				eth->dev = NULL;
				/* No need to revert clock settings for this eth. */
				i--;
				goto clk_unconfigure;
			}
		}

		if (suspend) {
			clk_bulk_disable_unprepare(AT91_PM_ETH_MAX_CLK, eth->clks);
		} else {
			ret = clk_bulk_prepare_enable(AT91_PM_ETH_MAX_CLK,
						      eth->clks);
			if (ret)
				goto clk_unconfigure;
			/*
			 * Release the reference to eth->dev taken in
			 * at91_pm_eth_quirk_is_valid().
			 */
			put_device(eth->dev);
			eth->dev = NULL;
		}
	}

	return 0;

clk_unconfigure:
	/*
	 * In case of resume we reach this point if clk_prepare_enable() failed.
	 * we don't want to revert the previous clk_prepare_enable() for the
	 * other IP.
	 */
	for (j = i; j >= 0; j--) {
		eth = &soc_pm.quirks.eth[j];
		if (suspend) {
			if (!at91_pm_eth_quirk_is_valid(eth))
				continue;

			tmp = clk_bulk_prepare_enable(AT91_PM_ETH_MAX_CLK, eth->clks);
			if (tmp) {
				pr_err("AT91: PM: failed to enable %s clocks\n",
				       j == AT91_PM_G_ETH ? "geth" : "eth");
			}
		}

		/*
		 * Release the reference to eth->dev taken in
		 * at91_pm_eth_quirk_is_valid().
		 */
		put_device(eth->dev);
		eth->dev = NULL;
	}

	return ret;
}

/*
 * Called after processes are frozen, but before we shutdown devices.
 */
static int at91_pm_begin(suspend_state_t state)
{
	int ret;

	switch (state) {
	case PM_SUSPEND_MEM:
		soc_pm.data.mode = soc_pm.data.suspend_mode;
		break;

	case PM_SUSPEND_STANDBY:
		soc_pm.data.mode = soc_pm.data.standby_mode;
		break;

	default:
		soc_pm.data.mode = -1;
	}

	ret = at91_pm_config_ws(soc_pm.data.mode, true);
	if (ret)
		return ret;

	if (soc_pm.data.mode == AT91_PM_BACKUP)
		soc_pm.bu->suspended = 1;
	else if (soc_pm.bu)
		soc_pm.bu->suspended = 0;

	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 = readl(soc_pm.data.pmc + AT91_PMC_SCSR);

	/* USB must not be using PLLB */
	if ((scsr & soc_pm.data.uhp_udp_mask) != 0) {
		pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
		return 0;
	}

	/* 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 = readl(soc_pm.data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
		if (css != AT91_PMC_CSS_SLOW) {
			pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
			return 0;
		}
	}

	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 (soc_pm.data.mode >= AT91_PM_ULP0);
}
EXPORT_SYMBOL(at91_suspend_entering_slow_clock);

static void (*at91_suspend_sram_fn)(struct at91_pm_data *);
extern void at91_pm_suspend_in_sram(struct at91_pm_data *pm_data);
extern u32 at91_pm_suspend_in_sram_sz;

static int at91_suspend_finish(unsigned long val)
{
	unsigned char modified_gray_code[] = {
		0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05, 0x0c, 0x0d,
		0x0e, 0x0f, 0x0a, 0x0b, 0x08, 0x09, 0x18, 0x19, 0x1a, 0x1b,
		0x1e, 0x1f, 0x1c, 0x1d, 0x14, 0x15, 0x16, 0x17, 0x12, 0x13,
		0x10, 0x11,
	};
	unsigned int tmp, index;
	int i;

	if (soc_pm.data.mode == AT91_PM_BACKUP && soc_pm.data.ramc_phy) {
		/*
		 * Bootloader will perform DDR recalibration and will try to
		 * restore the ZQ0SR0 with the value saved here. But the
		 * calibration is buggy and restoring some values from ZQ0SR0
		 * is forbidden and risky thus we need to provide processed
		 * values for these (modified gray code values).
		 */
		tmp = readl(soc_pm.data.ramc_phy + DDR3PHY_ZQ0SR0);

		/* Store pull-down output impedance select. */
		index = (tmp >> DDR3PHY_ZQ0SR0_PDO_OFF) & 0x1f;
		soc_pm.bu->ddr_phy_calibration[0] = modified_gray_code[index];

		/* Store pull-up output impedance select. */
		index = (tmp >> DDR3PHY_ZQ0SR0_PUO_OFF) & 0x1f;
		soc_pm.bu->ddr_phy_calibration[0] |= modified_gray_code[index];

		/* Store pull-down on-die termination impedance select. */
		index = (tmp >> DDR3PHY_ZQ0SR0_PDODT_OFF) & 0x1f;
		soc_pm.bu->ddr_phy_calibration[0] |= modified_gray_code[index];

		/* Store pull-up on-die termination impedance select. */
		index = (tmp >> DDR3PHY_ZQ0SRO_PUODT_OFF) & 0x1f;
		soc_pm.bu->ddr_phy_calibration[0] |= modified_gray_code[index];

		/*
		 * The 1st 8 words of memory might get corrupted in the process
		 * of DDR PHY recalibration; it is saved here in securam and it
		 * will be restored later, after recalibration, by bootloader
		 */
		for (i = 1; i < BACKUP_DDR_PHY_CALIBRATION; i++)
			soc_pm.bu->ddr_phy_calibration[i] =
				*((unsigned int *)soc_pm.memcs + (i - 1));
	}

	flush_cache_all();
	outer_disable();

	at91_suspend_sram_fn(&soc_pm.data);

	return 0;
}

static void at91_pm_switch_ba_to_vbat(void)
{
	unsigned int offset = offsetof(struct at91_pm_sfrbu_regs, pswbu);
	unsigned int val;

	/* Just for safety. */
	if (!soc_pm.data.sfrbu)
		return;

	val = readl(soc_pm.data.sfrbu + offset);

	/* Already on VBAT. */
	if (!(val & soc_pm.sfrbu_regs.pswbu.state))
		return;

	val &= ~soc_pm.sfrbu_regs.pswbu.softsw;
	val |= soc_pm.sfrbu_regs.pswbu.key | soc_pm.sfrbu_regs.pswbu.ctrl;
	writel(val, soc_pm.data.sfrbu + offset);

	/* Wait for update. */
	val = readl(soc_pm.data.sfrbu + offset);
	while (val & soc_pm.sfrbu_regs.pswbu.state)
		val = readl(soc_pm.data.sfrbu + offset);
}

static void at91_pm_suspend(suspend_state_t state)
{
	if (soc_pm.data.mode == AT91_PM_BACKUP) {
		at91_pm_switch_ba_to_vbat();

		cpu_suspend(0, at91_suspend_finish);

		/* The SRAM is lost between suspend cycles */
		at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn,
					     &at91_pm_suspend_in_sram,
					     at91_pm_suspend_in_sram_sz);
	} else {
		at91_suspend_finish(0);
	}

	outer_resume();
}

/*
 * 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.
 *
 * AT91_PM_ULP0 is like STANDBY plus slow clock mode, so drivers must
 * suspend more deeply, the master clock switches to the clk32k and turns off
 * the main oscillator
 *
 * AT91_PM_BACKUP turns off the whole SoC after placing the DDR in self refresh
 */
static int at91_pm_enter(suspend_state_t state)
{
	int ret;

	ret = at91_pm_config_quirks(true);
	if (ret)
		return ret;

	switch (state) {
	case PM_SUSPEND_MEM:
	case PM_SUSPEND_STANDBY:
		/*
		 * Ensure that clocks are in a valid state.
		 */
		if (soc_pm.data.mode >= AT91_PM_ULP0 &&
		    !at91_pm_verify_clocks())
			goto error;

		at91_pm_suspend(state);

		break;

	case PM_SUSPEND_ON:
		cpu_do_idle();
		break;

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

error:
	at91_pm_config_quirks(false);
	return 0;
}

/*
 * Called right prior to thawing processes.
 */
static void at91_pm_end(void)
{
	at91_pm_config_ws(soc_pm.data.mode, false);
}


static const struct platform_suspend_ops at91_pm_ops = {
	.valid	= at91_pm_valid_state,
	.begin	= at91_pm_begin,
	.enter	= at91_pm_enter,
	.end	= at91_pm_end,
};

static struct platform_device at91_cpuidle_device = {
	.name = "cpuidle-at91",
};

/*
 * The AT91RM9200 goes into self-refresh mode with this command, and will
 * terminate self-refresh automatically on the next SDRAM access.
 *
 * Self-refresh mode is exited as soon as a memory access is made, but we don't
 * know for sure when that happens. However, we need to restore the low-power
 * mode if it was enabled before going idle. Restoring low-power mode while
 * still in self-refresh is "not recommended", but seems to work.
 */
static void at91rm9200_standby(void)
{
	asm volatile(
		"b    1f\n\t"
		".align    5\n\t"
		"1:  mcr    p15, 0, %0, c7, c10, 4\n\t"
		"    str    %2, [%1, %3]\n\t"
		"    mcr    p15, 0, %0, c7, c0, 4\n\t"
		:
		: "r" (0), "r" (soc_pm.data.ramc[0]),
		  "r" (1), "r" (AT91_MC_SDRAMC_SRR));
}

/* We manage both DDRAM/SDRAM controllers, we need more than one value to
 * remember.
 */
static void at91_ddr_standby(void)
{
	/* Those two values allow us to delay self-refresh activation
	 * to the maximum. */
	u32 lpr0, lpr1 = 0;
	u32 mdr, saved_mdr0, saved_mdr1 = 0;
	u32 saved_lpr0, saved_lpr1 = 0;

	/* LPDDR1 --> force DDR2 mode during self-refresh */
	saved_mdr0 = at91_ramc_read(0, AT91_DDRSDRC_MDR);
	if ((saved_mdr0 & AT91_DDRSDRC_MD) == AT91_DDRSDRC_MD_LOW_POWER_DDR) {
		mdr = saved_mdr0 & ~AT91_DDRSDRC_MD;
		mdr |= AT91_DDRSDRC_MD_DDR2;
		at91_ramc_write(0, AT91_DDRSDRC_MDR, mdr);
	}

	if (soc_pm.data.ramc[1]) {
		saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
		lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
		lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
		saved_mdr1 = at91_ramc_read(1, AT91_DDRSDRC_MDR);
		if ((saved_mdr1 & AT91_DDRSDRC_MD) == AT91_DDRSDRC_MD_LOW_POWER_DDR) {
			mdr = saved_mdr1 & ~AT91_DDRSDRC_MD;
			mdr |= AT91_DDRSDRC_MD_DDR2;
			at91_ramc_write(1, AT91_DDRSDRC_MDR, mdr);
		}
	}

	saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR);
	lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB;
	lpr0 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;

	/* self-refresh mode now */
	at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
	if (soc_pm.data.ramc[1])
		at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);

	cpu_do_idle();

	at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr0);
	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
	if (soc_pm.data.ramc[1]) {
		at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr1);
		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
	}
}

static void sama5d3_ddr_standby(void)
{
	u32 lpr0;
	u32 saved_lpr0;

	saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR);
	lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB;
	lpr0 |= AT91_DDRSDRC_LPCB_POWER_DOWN;

	at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);

	cpu_do_idle();

	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
}

/* We manage both DDRAM/SDRAM controllers, we need more than one value to
 * remember.
 */
static void at91sam9_sdram_standby(void)
{
	u32 lpr0, lpr1 = 0;
	u32 saved_lpr0, saved_lpr1 = 0;

	if (soc_pm.data.ramc[1]) {
		saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
		lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
		lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
	}

	saved_lpr0 = at91_ramc_read(0, AT91_SDRAMC_LPR);
	lpr0 = saved_lpr0 & ~AT91_SDRAMC_LPCB;
	lpr0 |= AT91_SDRAMC_LPCB_SELF_REFRESH;

	/* self-refresh mode now */
	at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
	if (soc_pm.data.ramc[1])
		at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);

	cpu_do_idle();

	at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
	if (soc_pm.data.ramc[1])
		at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
}

static void sama7g5_standby(void)
{
	int pwrtmg, ratio;

	pwrtmg = readl(soc_pm.data.ramc[0] + UDDRC_PWRCTL);
	ratio = readl(soc_pm.data.pmc + AT91_PMC_RATIO);

	/*
	 * Place RAM into self-refresh after a maximum idle clocks. The maximum
	 * idle clocks is configured by bootloader in
	 * UDDRC_PWRMGT.SELFREF_TO_X32.
	 */
	writel(pwrtmg | UDDRC_PWRCTL_SELFREF_EN,
	       soc_pm.data.ramc[0] + UDDRC_PWRCTL);
	/* Divide CPU clock by 16. */
	writel(ratio & ~AT91_PMC_RATIO_RATIO, soc_pm.data.pmc + AT91_PMC_RATIO);

	cpu_do_idle();

	/* Restore previous configuration. */
	writel(ratio, soc_pm.data.pmc + AT91_PMC_RATIO);
	writel(pwrtmg, soc_pm.data.ramc[0] + UDDRC_PWRCTL);
}

struct ramc_info {
	void (*idle)(void);
	unsigned int memctrl;
};

static const struct ramc_info ramc_infos[] __initconst = {
	{ .idle = at91rm9200_standby, .memctrl = AT91_MEMCTRL_MC},
	{ .idle = at91sam9_sdram_standby, .memctrl = AT91_MEMCTRL_SDRAMC},
	{ .idle = at91_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
	{ .idle = sama5d3_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
	{ .idle = sama7g5_standby, },
};

static const struct of_device_id ramc_ids[] __initconst = {
	{ .compatible = "atmel,at91rm9200-sdramc", .data = &ramc_infos[0] },
	{ .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] },
	{ .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] },
	{ .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] },
	{ .compatible = "microchip,sama7g5-uddrc", .data = &ramc_infos[4], },
	{ /*sentinel*/ }
};

static const struct of_device_id ramc_phy_ids[] __initconst = {
	{ .compatible = "microchip,sama7g5-ddr3phy", },
	{ /* Sentinel. */ },
};

static __init int at91_dt_ramc(bool phy_mandatory)
{
	struct device_node *np;
	const struct of_device_id *of_id;
	int idx = 0;
	void *standby = NULL;
	const struct ramc_info *ramc;
	int ret;

	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
		soc_pm.data.ramc[idx] = of_iomap(np, 0);
		if (!soc_pm.data.ramc[idx]) {
			pr_err("unable to map ramc[%d] cpu registers\n", idx);
			ret = -ENOMEM;
			of_node_put(np);
			goto unmap_ramc;
		}

		ramc = of_id->data;
		if (ramc) {
			if (!standby)
				standby = ramc->idle;
			soc_pm.data.memctrl = ramc->memctrl;
		}

		idx++;
	}

	if (!idx) {
		pr_err("unable to find compatible ram controller node in dtb\n");
		ret = -ENODEV;
		goto unmap_ramc;
	}

	/* Lookup for DDR PHY node, if any. */
	for_each_matching_node_and_match(np, ramc_phy_ids, &of_id) {
		soc_pm.data.ramc_phy = of_iomap(np, 0);
		if (!soc_pm.data.ramc_phy) {
			pr_err("unable to map ramc phy cpu registers\n");
			ret = -ENOMEM;
			of_node_put(np);
			goto unmap_ramc;
		}
	}

	if (phy_mandatory && !soc_pm.data.ramc_phy) {
		pr_err("DDR PHY is mandatory!\n");
		ret = -ENODEV;
		goto unmap_ramc;
	}

	if (!standby) {
		pr_warn("ramc no standby function available\n");
		return 0;
	}

	at91_cpuidle_device.dev.platform_data = standby;

	return 0;

unmap_ramc:
	while (idx)
		iounmap(soc_pm.data.ramc[--idx]);

	return ret;
}

static void at91rm9200_idle(void)
{
	/*
	 * Disable the processor clock.  The processor will be automatically
	 * re-enabled by an interrupt or by a reset.
	 */
	writel(AT91_PMC_PCK, soc_pm.data.pmc + AT91_PMC_SCDR);
}

static void at91sam9_idle(void)
{
	writel(AT91_PMC_PCK, soc_pm.data.pmc + AT91_PMC_SCDR);
	cpu_do_idle();
}

static void __init at91_pm_sram_init(void)
{
	struct gen_pool *sram_pool;
	phys_addr_t sram_pbase;
	unsigned long sram_base;
	struct device_node *node;
	struct platform_device *pdev = NULL;

	for_each_compatible_node(node, NULL, "mmio-sram") {
		pdev = of_find_device_by_node(node);
		if (pdev) {
			of_node_put(node);
			break;
		}
	}

	if (!pdev) {
		pr_warn("%s: failed to find sram device!\n", __func__);
		return;
	}

	sram_pool = gen_pool_get(&pdev->dev, NULL);
	if (!sram_pool) {
		pr_warn("%s: sram pool unavailable!\n", __func__);
		goto out_put_device;
	}

	sram_base = gen_pool_alloc(sram_pool, at91_pm_suspend_in_sram_sz);
	if (!sram_base) {
		pr_warn("%s: unable to alloc sram!\n", __func__);
		goto out_put_device;
	}

	sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base);
	at91_suspend_sram_fn = __arm_ioremap_exec(sram_pbase,
					at91_pm_suspend_in_sram_sz, false);
	if (!at91_suspend_sram_fn) {
		pr_warn("SRAM: Could not map\n");
		goto out_put_device;
	}

	/* Copy the pm suspend handler to SRAM */
	at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn,
			&at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz);
	return;

out_put_device:
	put_device(&pdev->dev);
	return;
}

static bool __init at91_is_pm_mode_active(int pm_mode)
{
	return (soc_pm.data.standby_mode == pm_mode ||
		soc_pm.data.suspend_mode == pm_mode);
}

static int __init at91_pm_backup_scan_memcs(unsigned long node,
					    const char *uname, int depth,
					    void *data)
{
	const char *type;
	const __be32 *reg;
	int *located = data;
	int size;

	/* Memory node already located. */
	if (*located)
		return 0;

	type = of_get_flat_dt_prop(node, "device_type", NULL);

	/* We are scanning "memory" nodes only. */
	if (!type || strcmp(type, "memory"))
		return 0;

	reg = of_get_flat_dt_prop(node, "reg", &size);
	if (reg) {
		soc_pm.memcs = __va((phys_addr_t)be32_to_cpu(*reg));
		*located = 1;
	}

	return 0;
}

static int __init at91_pm_backup_init(void)
{
	struct gen_pool *sram_pool;
	struct device_node *np;
	struct platform_device *pdev;
	int ret = -ENODEV, located = 0;

	if (!IS_ENABLED(CONFIG_SOC_SAMA5D2) &&
	    !IS_ENABLED(CONFIG_SOC_SAMA7G5))
		return -EPERM;

	if (!at91_is_pm_mode_active(AT91_PM_BACKUP))
		return 0;

	np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam");
	if (!np)
		return ret;

	pdev = of_find_device_by_node(np);
	of_node_put(np);
	if (!pdev) {
		pr_warn("%s: failed to find securam device!\n", __func__);
		return ret;
	}

	sram_pool = gen_pool_get(&pdev->dev, NULL);
	if (!sram_pool) {
		pr_warn("%s: securam pool unavailable!\n", __func__);
		goto securam_fail;
	}

	soc_pm.bu = (void *)gen_pool_alloc(sram_pool, sizeof(struct at91_pm_bu));
	if (!soc_pm.bu) {
		pr_warn("%s: unable to alloc securam!\n", __func__);
		ret = -ENOMEM;
		goto securam_fail;
	}

	soc_pm.bu->suspended = 0;
	soc_pm.bu->canary = __pa_symbol(&canary);
	soc_pm.bu->resume = __pa_symbol(cpu_resume);
	if (soc_pm.data.ramc_phy) {
		of_scan_flat_dt(at91_pm_backup_scan_memcs, &located);
		if (!located)
			goto securam_fail;
	}

	return 0;

securam_fail:
	put_device(&pdev->dev);
	return ret;
}

static void __init at91_pm_secure_init(void)
{
	int suspend_mode;
	struct arm_smccc_res res;

	suspend_mode = soc_pm.data.suspend_mode;

	res = sam_smccc_call(SAMA5_SMC_SIP_SET_SUSPEND_MODE,
			     suspend_mode, 0);
	if (res.a0 == 0) {
		pr_info("AT91: Secure PM: suspend mode set to %s\n",
			pm_modes[suspend_mode].pattern);
		soc_pm.data.mode = suspend_mode;
		return;
	}

	pr_warn("AT91: Secure PM: %s mode not supported !\n",
		pm_modes[suspend_mode].pattern);

	res = sam_smccc_call(SAMA5_SMC_SIP_GET_SUSPEND_MODE, 0, 0);
	if (res.a0 == 0) {
		pr_warn("AT91: Secure PM: failed to get default mode\n");
		soc_pm.data.mode = -1;
		return;
	}

	pr_info("AT91: Secure PM: using default suspend mode %s\n",
		pm_modes[suspend_mode].pattern);

	soc_pm.data.suspend_mode = res.a1;
	soc_pm.data.mode = soc_pm.data.suspend_mode;
}
static const struct of_device_id atmel_shdwc_ids[] = {
	{ .compatible = "atmel,sama5d2-shdwc" },
	{ .compatible = "microchip,sam9x60-shdwc" },
	{ .compatible = "microchip,sama7g5-shdwc" },
	{ /* sentinel. */ }
};

static const struct of_device_id gmac_ids[] __initconst = {
	{ .compatible = "atmel,sama5d3-gem" },
	{ .compatible = "atmel,sama5d2-gem" },
	{ .compatible = "atmel,sama5d29-gem" },
	{ .compatible = "microchip,sama7g5-gem" },
	{ },
};

static const struct of_device_id emac_ids[] __initconst = {
	{ .compatible = "atmel,sama5d3-macb" },
	{ .compatible = "microchip,sama7g5-emac" },
	{ },
};

/*
 * Replaces _mode_to_replace with a supported mode that doesn't depend
 * on controller pointed by _map_bitmask
 * @_maps: u32 array containing AT91_PM_IOMAP() flags and indexed by AT91
 * PM mode
 * @_map_bitmask: AT91_PM_IOMAP() bitmask; if _mode_to_replace depends on
 * controller represented by _map_bitmask, _mode_to_replace needs to be
 * updated
 * @_mode_to_replace: standby_mode or suspend_mode that need to be
 * updated
 * @_mode_to_check: standby_mode or suspend_mode; this is needed here
 * to avoid having standby_mode and suspend_mode set with the same AT91
 * PM mode
 */
#define AT91_PM_REPLACE_MODE(_maps, _map_bitmask, _mode_to_replace,	\
			     _mode_to_check)				\
	do {								\
		if (((_maps)[(_mode_to_replace)]) & (_map_bitmask)) {	\
			int _mode_to_use, _mode_complementary;		\
			/* Use ULP0 if it doesn't need _map_bitmask. */	\
			if (!((_maps)[AT91_PM_ULP0] & (_map_bitmask))) {\
				_mode_to_use = AT91_PM_ULP0;		\
				_mode_complementary = AT91_PM_STANDBY;	\
			} else {					\
				_mode_to_use = AT91_PM_STANDBY;		\
				_mode_complementary = AT91_PM_STANDBY;	\
			}						\
									\
			if ((_mode_to_check) != _mode_to_use)		\
				(_mode_to_replace) = _mode_to_use;	\
			else						\
				(_mode_to_replace) = _mode_complementary;\
		}							\
	} while (0)

/*
 * Replaces standby and suspend modes with default supported modes:
 * ULP0 and STANDBY.
 * @_maps: u32 array indexed by AT91 PM mode containing AT91_PM_IOMAP()
 * flags
 * @_map: controller specific name; standby and suspend mode need to be
 * replaced in order to not depend on this controller
 */
#define AT91_PM_REPLACE_MODES(_maps, _map)				\
	do {								\
		AT91_PM_REPLACE_MODE((_maps), BIT(AT91_PM_IOMAP_##_map),\
				     (soc_pm.data.standby_mode),	\
				     (soc_pm.data.suspend_mode));	\
		AT91_PM_REPLACE_MODE((_maps), BIT(AT91_PM_IOMAP_##_map),\
				     (soc_pm.data.suspend_mode),	\
				     (soc_pm.data.standby_mode));	\
	} while (0)

static int __init at91_pm_get_eth_clks(struct device_node *np,
				       struct clk_bulk_data *clks)
{
	clks[AT91_PM_ETH_PCLK].clk = of_clk_get_by_name(np, "pclk");
	if (IS_ERR(clks[AT91_PM_ETH_PCLK].clk))
		return PTR_ERR(clks[AT91_PM_ETH_PCLK].clk);

	clks[AT91_PM_ETH_HCLK].clk = of_clk_get_by_name(np, "hclk");
	if (IS_ERR(clks[AT91_PM_ETH_HCLK].clk))
		return PTR_ERR(clks[AT91_PM_ETH_HCLK].clk);

	return 0;
}

static int __init at91_pm_eth_clks_empty(struct clk_bulk_data *clks)
{
	return IS_ERR(clks[AT91_PM_ETH_PCLK].clk) ||
	       IS_ERR(clks[AT91_PM_ETH_HCLK].clk);
}

static void __init at91_pm_modes_init(const u32 *maps, int len)
{
	struct at91_pm_quirk_eth *gmac = &soc_pm.quirks.eth[AT91_PM_G_ETH];
	struct at91_pm_quirk_eth *emac = &soc_pm.quirks.eth[AT91_PM_E_ETH];
	struct device_node *np;
	int ret;

	ret = at91_pm_backup_init();
	if (ret) {
		if (soc_pm.data.standby_mode == AT91_PM_BACKUP)
			soc_pm.data.standby_mode = AT91_PM_ULP0;
		if (soc_pm.data.suspend_mode == AT91_PM_BACKUP)
			soc_pm.data.suspend_mode = AT91_PM_ULP0;
	}

	if (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SHDWC) ||
	    maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SHDWC)) {
		np = of_find_matching_node(NULL, atmel_shdwc_ids);
		if (!np) {
			pr_warn("%s: failed to find shdwc!\n", __func__);
			AT91_PM_REPLACE_MODES(maps, SHDWC);
		} else {
			soc_pm.data.shdwc = of_iomap(np, 0);
			of_node_put(np);
		}
	}

	if (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SFRBU) ||
	    maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SFRBU)) {
		np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu");
		if (!np) {
			pr_warn("%s: failed to find sfrbu!\n", __func__);
			AT91_PM_REPLACE_MODES(maps, SFRBU);
		} else {
			soc_pm.data.sfrbu = of_iomap(np, 0);
			of_node_put(np);
		}
	}

	if ((at91_is_pm_mode_active(AT91_PM_ULP1) ||
	     at91_is_pm_mode_active(AT91_PM_ULP0) ||
	     at91_is_pm_mode_active(AT91_PM_ULP0_FAST)) &&
	    (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(ETHC) ||
	     maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(ETHC))) {
		np = of_find_matching_node(NULL, gmac_ids);
		if (!np) {
			np = of_find_matching_node(NULL, emac_ids);
			if (np)
				goto get_emac_clks;
			AT91_PM_REPLACE_MODES(maps, ETHC);
			goto unmap_unused_nodes;
		} else {
			gmac->np = np;
			at91_pm_get_eth_clks(np, gmac->clks);
		}

		np = of_find_matching_node(NULL, emac_ids);
		if (!np) {
			if (at91_pm_eth_clks_empty(gmac->clks))
				AT91_PM_REPLACE_MODES(maps, ETHC);
		} else {
get_emac_clks:
			emac->np = np;
			ret = at91_pm_get_eth_clks(np, emac->clks);
			if (ret && at91_pm_eth_clks_empty(gmac->clks)) {
				of_node_put(gmac->np);
				of_node_put(emac->np);
				gmac->np = NULL;
				emac->np = NULL;
			}
		}
	}

unmap_unused_nodes:
	/* Unmap all unnecessary. */
	if (soc_pm.data.shdwc &&
	    !(maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SHDWC) ||
	      maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SHDWC))) {
		iounmap(soc_pm.data.shdwc);
		soc_pm.data.shdwc = NULL;
	}

	if (soc_pm.data.sfrbu &&
	    !(maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SFRBU) ||
	      maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SFRBU))) {
		iounmap(soc_pm.data.sfrbu);
		soc_pm.data.sfrbu = NULL;
	}

	return;
}

struct pmc_info {
	unsigned long uhp_udp_mask;
	unsigned long mckr;
	unsigned long version;
};

static const struct pmc_info pmc_infos[] __initconst = {
	{
		.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP,
		.mckr = 0x30,
		.version = AT91_PMC_V1,
	},

	{
		.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP,
		.mckr = 0x30,
		.version = AT91_PMC_V1,
	},
	{
		.uhp_udp_mask = AT91SAM926x_PMC_UHP,
		.mckr = 0x30,
		.version = AT91_PMC_V1,
	},
	{	.uhp_udp_mask = 0,
		.mckr = 0x30,
		.version = AT91_PMC_V1,
	},
	{
		.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP,
		.mckr = 0x28,
		.version = AT91_PMC_V2,
	},
	{
		.mckr = 0x28,
		.version = AT91_PMC_V2,
	},

};

static const struct of_device_id atmel_pmc_ids[] __initconst = {
	{ .compatible = "atmel,at91rm9200-pmc", .data = &pmc_infos[0] },
	{ .compatible = "atmel,at91sam9260-pmc", .data = &pmc_infos[1] },
	{ .compatible = "atmel,at91sam9261-pmc", .data = &pmc_infos[1] },
	{ .compatible = "atmel,at91sam9263-pmc", .data = &pmc_infos[1] },
	{ .compatible = "atmel,at91sam9g45-pmc", .data = &pmc_infos[2] },
	{ .compatible = "atmel,at91sam9n12-pmc", .data = &pmc_infos[1] },
	{ .compatible = "atmel,at91sam9rl-pmc", .data = &pmc_infos[3] },
	{ .compatible = "atmel,at91sam9x5-pmc", .data = &pmc_infos[1] },
	{ .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] },
	{ .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] },
	{ .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] },
	{ .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[4] },
	{ .compatible = "microchip,sam9x7-pmc", .data = &pmc_infos[4] },
	{ .compatible = "microchip,sama7g5-pmc", .data = &pmc_infos[5] },
	{ /* sentinel */ },
};

static void __init at91_pm_modes_validate(const int *modes, int len)
{
	u8 i, standby = 0, suspend = 0;
	int mode;

	for (i = 0; i < len; i++) {
		if (standby && suspend)
			break;

		if (modes[i] == soc_pm.data.standby_mode && !standby) {
			standby = 1;
			continue;
		}

		if (modes[i] == soc_pm.data.suspend_mode && !suspend) {
			suspend = 1;
			continue;
		}
	}

	if (!standby) {
		if (soc_pm.data.suspend_mode == AT91_PM_STANDBY)
			mode = AT91_PM_ULP0;
		else
			mode = AT91_PM_STANDBY;

		pr_warn("AT91: PM: %s mode not supported! Using %s.\n",
			pm_modes[soc_pm.data.standby_mode].pattern,
			pm_modes[mode].pattern);
		soc_pm.data.standby_mode = mode;
	}

	if (!suspend) {
		if (soc_pm.data.standby_mode == AT91_PM_ULP0)
			mode = AT91_PM_STANDBY;
		else
			mode = AT91_PM_ULP0;

		pr_warn("AT91: PM: %s mode not supported! Using %s.\n",
			pm_modes[soc_pm.data.suspend_mode].pattern,
			pm_modes[mode].pattern);
		soc_pm.data.suspend_mode = mode;
	}
}

static void __init at91_pm_init(void (*pm_idle)(void))
{
	struct device_node *pmc_np;
	const struct of_device_id *of_id;
	const struct pmc_info *pmc;

	if (at91_cpuidle_device.dev.platform_data)
		platform_device_register(&at91_cpuidle_device);

	pmc_np = of_find_matching_node_and_match(NULL, atmel_pmc_ids, &of_id);
	soc_pm.data.pmc = of_iomap(pmc_np, 0);
	of_node_put(pmc_np);
	if (!soc_pm.data.pmc) {
		pr_err("AT91: PM not supported, PMC not found\n");
		return;
	}

	pmc = of_id->data;
	soc_pm.data.uhp_udp_mask = pmc->uhp_udp_mask;
	soc_pm.data.pmc_mckr_offset = pmc->mckr;
	soc_pm.data.pmc_version = pmc->version;

	if (pm_idle)
		arm_pm_idle = pm_idle;

	at91_pm_sram_init();

	if (at91_suspend_sram_fn) {
		suspend_set_ops(&at91_pm_ops);
		pr_info("AT91: PM: standby: %s, suspend: %s\n",
			pm_modes[soc_pm.data.standby_mode].pattern,
			pm_modes[soc_pm.data.suspend_mode].pattern);
	} else {
		pr_info("AT91: PM not supported, due to no SRAM allocated\n");
	}
}

void __init at91rm9200_pm_init(void)
{
	int ret;

	if (!IS_ENABLED(CONFIG_SOC_AT91RM9200))
		return;

	/*
	 * Force STANDBY and ULP0 mode to avoid calling
	 * at91_pm_modes_validate() which may increase booting time.
	 * Platform supports anyway only STANDBY and ULP0 modes.
	 */
	soc_pm.data.standby_mode = AT91_PM_STANDBY;
	soc_pm.data.suspend_mode = AT91_PM_ULP0;

	ret = at91_dt_ramc(false);
	if (ret)
		return;

	/*
	 * AT91RM9200 SDRAM low-power mode cannot be used with self-refresh.
	 */
	at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);

	at91_pm_init(at91rm9200_idle);
}

void __init sam9x60_pm_init(void)
{
	static const int modes[] __initconst = {
		AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1,
	};
	static const int iomaps[] __initconst = {
		[AT91_PM_ULP1]		= AT91_PM_IOMAP(SHDWC),
	};
	int ret;

	if (!IS_ENABLED(CONFIG_SOC_SAM9X60))
		return;

	at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
	at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps));
	ret = at91_dt_ramc(false);
	if (ret)
		return;

	at91_pm_init(NULL);

	soc_pm.ws_ids = sam9x60_ws_ids;
	soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws;
}

void __init sam9x7_pm_init(void)
{
	static const int modes[] __initconst = {
		AT91_PM_STANDBY, AT91_PM_ULP0,
	};
	int ret;

	if (!IS_ENABLED(CONFIG_SOC_SAM9X7))
		return;

	at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
	ret = at91_dt_ramc(false);
	if (ret)
		return;

	at91_pm_init(NULL);

	soc_pm.ws_ids = sam9x7_ws_ids;
	soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws;
}

void __init at91sam9_pm_init(void)
{
	int ret;

	if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))
		return;

	/*
	 * Force STANDBY and ULP0 mode to avoid calling
	 * at91_pm_modes_validate() which may increase booting time.
	 * Platform supports anyway only STANDBY and ULP0 modes.
	 */
	soc_pm.data.standby_mode = AT91_PM_STANDBY;
	soc_pm.data.suspend_mode = AT91_PM_ULP0;

	ret = at91_dt_ramc(false);
	if (ret)
		return;

	at91_pm_init(at91sam9_idle);
}

void __init sama5_pm_init(void)
{
	static const int modes[] __initconst = {
		AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST,
	};
	static const u32 iomaps[] __initconst = {
		[AT91_PM_ULP0]		= AT91_PM_IOMAP(ETHC),
		[AT91_PM_ULP0_FAST]	= AT91_PM_IOMAP(ETHC),
	};
	int ret;

	if (!IS_ENABLED(CONFIG_SOC_SAMA5))
		return;

	at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
	at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps));
	ret = at91_dt_ramc(false);
	if (ret)
		return;

	at91_pm_init(NULL);

	/* Quirks applies to ULP0, ULP0 fast and ULP1 modes. */
	soc_pm.quirks.eth[AT91_PM_G_ETH].modes = BIT(AT91_PM_ULP0) |
						 BIT(AT91_PM_ULP0_FAST) |
						 BIT(AT91_PM_ULP1);
	/* Do not suspend in ULP0, ULP0 fast if GETH is the only wakeup source. */
	soc_pm.quirks.eth[AT91_PM_G_ETH].dns_modes = BIT(AT91_PM_ULP0) |
						     BIT(AT91_PM_ULP0_FAST);
}

void __init sama5d2_pm_init(void)
{
	static const int modes[] __initconst = {
		AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1,
		AT91_PM_BACKUP,
	};
	static const u32 iomaps[] __initconst = {
		[AT91_PM_ULP0]		= AT91_PM_IOMAP(ETHC),
		[AT91_PM_ULP0_FAST]	= AT91_PM_IOMAP(ETHC),
		[AT91_PM_ULP1]		= AT91_PM_IOMAP(SHDWC) |
					  AT91_PM_IOMAP(ETHC),
		[AT91_PM_BACKUP]	= AT91_PM_IOMAP(SHDWC) |
					  AT91_PM_IOMAP(SFRBU),
	};
	int ret;

	if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
		return;

	if (IS_ENABLED(CONFIG_ATMEL_SECURE_PM)) {
		pr_warn("AT91: Secure PM: ignoring standby mode\n");
		at91_pm_secure_init();
		return;
	}

	at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
	at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps));
	ret = at91_dt_ramc(false);
	if (ret)
		return;

	at91_pm_init(NULL);

	soc_pm.ws_ids = sama5d2_ws_ids;
	soc_pm.config_shdwc_ws = at91_sama5d2_config_shdwc_ws;
	soc_pm.config_pmc_ws = at91_sama5d2_config_pmc_ws;

	soc_pm.sfrbu_regs.pswbu.key = (0x4BD20C << 8);
	soc_pm.sfrbu_regs.pswbu.ctrl = BIT(0);
	soc_pm.sfrbu_regs.pswbu.softsw = BIT(1);
	soc_pm.sfrbu_regs.pswbu.state = BIT(3);

	/* Quirk applies to ULP0, ULP0 fast and ULP1 modes. */
	soc_pm.quirks.eth[AT91_PM_G_ETH].modes = BIT(AT91_PM_ULP0) |
						 BIT(AT91_PM_ULP0_FAST) |
						 BIT(AT91_PM_ULP1);
	/*
	 * Do not suspend in ULP0, ULP0 fast if GETH is the only wakeup
	 * source.
	 */
	soc_pm.quirks.eth[AT91_PM_G_ETH].dns_modes = BIT(AT91_PM_ULP0) |
						     BIT(AT91_PM_ULP0_FAST);
}

void __init sama7_pm_init(void)
{
	static const int modes[] __initconst = {
		AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP1, AT91_PM_BACKUP,
	};
	static const u32 iomaps[] __initconst = {
		[AT91_PM_ULP0]		= AT91_PM_IOMAP(SFRBU),
		[AT91_PM_ULP1]		= AT91_PM_IOMAP(SFRBU) |
					  AT91_PM_IOMAP(SHDWC) |
					  AT91_PM_IOMAP(ETHC),
		[AT91_PM_BACKUP]	= AT91_PM_IOMAP(SFRBU) |
					  AT91_PM_IOMAP(SHDWC),
	};
	int ret;

	if (!IS_ENABLED(CONFIG_SOC_SAMA7))
		return;

	at91_pm_modes_validate(modes, ARRAY_SIZE(modes));

	ret = at91_dt_ramc(true);
	if (ret)
		return;

	at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps));
	at91_pm_init(NULL);

	soc_pm.ws_ids = sama7g5_ws_ids;
	soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws;

	soc_pm.sfrbu_regs.pswbu.key = (0x4BD20C << 8);
	soc_pm.sfrbu_regs.pswbu.ctrl = BIT(0);
	soc_pm.sfrbu_regs.pswbu.softsw = BIT(1);
	soc_pm.sfrbu_regs.pswbu.state = BIT(2);

	/* Quirks applies to ULP1 for both Ethernet interfaces. */
	soc_pm.quirks.eth[AT91_PM_E_ETH].modes = BIT(AT91_PM_ULP1);
	soc_pm.quirks.eth[AT91_PM_G_ETH].modes = BIT(AT91_PM_ULP1);
}

static int __init at91_pm_modes_select(char *str)
{
	char *s;
	substring_t args[MAX_OPT_ARGS];
	int standby, suspend;

	if (!str)
		return 0;

	s = strsep(&str, ",");
	standby = match_token(s, pm_modes, args);
	if (standby < 0)
		return 0;

	suspend = match_token(str, pm_modes, args);
	if (suspend < 0)
		return 0;

	soc_pm.data.standby_mode = standby;
	soc_pm.data.suspend_mode = suspend;

	return 0;
}
early_param("atmel.pm_modes", at91_pm_modes_select);
