// SPDX-License-Identifier: GPL-2.0-only
/*
 *  arch/arm/mach-socfpga/pm.c
 *
 * Copyright (C) 2014-2015 Altera Corporation. All rights reserved.
 *
 * with code from pm-imx6.c
 * Copyright 2011-2014 Freescale Semiconductor, Inc.
 * Copyright 2011 Linaro Ltd.
 */

#include <linux/bitops.h>
#include <linux/genalloc.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/of_platform.h>
#include <linux/suspend.h>
#include <asm/suspend.h>
#include <asm/fncpy.h>
#include "core.h"

/* Pointer to function copied to ocram */
static u32 (*socfpga_sdram_self_refresh_in_ocram)(u32 sdr_base);

static int socfpga_setup_ocram_self_refresh(void)
{
	struct platform_device *pdev;
	phys_addr_t ocram_pbase;
	struct device_node *np;
	struct gen_pool *ocram_pool;
	unsigned long ocram_base;
	void __iomem *suspend_ocram_base;
	int ret = 0;

	np = of_find_compatible_node(NULL, NULL, "mmio-sram");
	if (!np) {
		pr_err("%s: Unable to find mmio-sram in dtb\n", __func__);
		return -ENODEV;
	}

	pdev = of_find_device_by_node(np);
	if (!pdev) {
		pr_warn("%s: failed to find ocram device!\n", __func__);
		ret = -ENODEV;
		goto put_node;
	}

	ocram_pool = gen_pool_get(&pdev->dev, NULL);
	if (!ocram_pool) {
		pr_warn("%s: ocram pool unavailable!\n", __func__);
		ret = -ENODEV;
		goto put_device;
	}

	ocram_base = gen_pool_alloc(ocram_pool, socfpga_sdram_self_refresh_sz);
	if (!ocram_base) {
		pr_warn("%s: unable to alloc ocram!\n", __func__);
		ret = -ENOMEM;
		goto put_device;
	}

	ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base);

	suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
						socfpga_sdram_self_refresh_sz,
						false);
	if (!suspend_ocram_base) {
		pr_warn("%s: __arm_ioremap_exec failed!\n", __func__);
		ret = -ENOMEM;
		goto put_device;
	}

	/* Copy the code that puts DDR in self refresh to ocram */
	socfpga_sdram_self_refresh_in_ocram =
		(void *)fncpy(suspend_ocram_base,
			      &socfpga_sdram_self_refresh,
			      socfpga_sdram_self_refresh_sz);

	WARN(!socfpga_sdram_self_refresh_in_ocram,
	     "could not copy function to ocram");
	if (!socfpga_sdram_self_refresh_in_ocram)
		ret = -EFAULT;

put_device:
	put_device(&pdev->dev);
put_node:
	of_node_put(np);

	return ret;
}

static int socfpga_pm_suspend(unsigned long arg)
{
	u32 ret;

	if (!sdr_ctl_base_addr)
		return -EFAULT;

	ret = socfpga_sdram_self_refresh_in_ocram((u32)sdr_ctl_base_addr);

	pr_debug("%s self-refresh loops request=%d exit=%d\n", __func__,
		 ret & 0xffff, (ret >> 16) & 0xffff);

	return 0;
}

static int socfpga_pm_enter(suspend_state_t state)
{
	switch (state) {
	case PM_SUSPEND_MEM:
		outer_disable();
		cpu_suspend(0, socfpga_pm_suspend);
		outer_resume();
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

static const struct platform_suspend_ops socfpga_pm_ops = {
	.valid	= suspend_valid_only_mem,
	.enter	= socfpga_pm_enter,
};

static int __init socfpga_pm_init(void)
{
	int ret;

	ret = socfpga_setup_ocram_self_refresh();
	if (ret)
		return ret;

	suspend_set_ops(&socfpga_pm_ops);
	pr_info("SoCFPGA initialized for DDR self-refresh during suspend.\n");

	return 0;
}
arch_initcall(socfpga_pm_init);
