/*
 * SPDX-FileCopyrightText: Copyright 2021, 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
 * SPDX-License-Identifier: GPL-2.0-only
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 */

#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>

#define JUNO_FPGA_RESET_DRIVER_VERSION "0.1.0"

struct juno_fpga_reset {
	struct reset_controller_dev rst;
	struct device               *dev;
	void __iomem                *base;
};

/* Supported controller IDs */
#define JUNO_FPGA_RESET_MIN_SUPPORTED_ID 0x2010f
#define JUNO_FPGA_RESET_MAX_SUPPORTED_ID 0x20113

#define JUNO_FPGA_RESET_ID(base)          (base)
#define JUNO_FPGA_RESET_SOFT_RESET(base) ((base) + 0x140)
#define JUNO_FPGA_RESET_CPU_WAIT(base)   ((base) + 0x144)

#define JUNO_FPGA_RESET_SET_RESET       (0x1)
#define JUNO_FPGA_RESET_UNSET_RESET     (0x0)
#define JUNO_FPGA_RESET_SET_CPUWAIT     (0x1)
#define JUNO_FPGA_RESET_UNSET_CPUWAIT   (0x0)

static void __iomem *verify_and_remap(struct device *dev,
				      struct resource *res)
{
	void __iomem *base = devm_ioremap_resource(dev, res);
	u32 id;

	if (IS_ERR(base))
		return base;

	id = readl(JUNO_FPGA_RESET_ID(base));

	if (id < JUNO_FPGA_RESET_MIN_SUPPORTED_ID ||
	    id > JUNO_FPGA_RESET_MAX_SUPPORTED_ID) {
		dev_err(dev, "Unknown controller ID: %u", id);

		return IOMEM_ERR_PTR(-EINVAL);
	}

	return base;
}

static int juno_fpga_reset_assert(struct reset_controller_dev *rcdev,
				  unsigned long id)
{
	struct juno_fpga_reset *reset = container_of(rcdev,
						     struct juno_fpga_reset,
						     rst);

	/* pull reset */
	dev_dbg(reset->dev, "Asserting reset");

	/* set wait and reset */
	writel(JUNO_FPGA_RESET_SET_RESET,
	       JUNO_FPGA_RESET_SOFT_RESET(reset->base));
	writel(JUNO_FPGA_RESET_SET_CPUWAIT,
	       JUNO_FPGA_RESET_CPU_WAIT(reset->base));

	writel(JUNO_FPGA_RESET_UNSET_RESET,
	       JUNO_FPGA_RESET_SOFT_RESET(reset->base));

	return 0;
}

static int juno_fpga_reset_deassert(struct reset_controller_dev *rcdev,
				    unsigned long id)
{
	struct juno_fpga_reset *reset = container_of(rcdev,
						     struct juno_fpga_reset,
						     rst);

	/* release wait */
	dev_dbg(reset->dev, "Deasserting reset");

	writel(JUNO_FPGA_RESET_UNSET_CPUWAIT,
	       JUNO_FPGA_RESET_CPU_WAIT(reset->base));

	return 0;
}

static struct reset_control_ops juno_fpga_reset_ops = {
	.assert   = juno_fpga_reset_assert,
	.deassert = juno_fpga_reset_deassert,
};

static const struct of_device_id juno_fpga_reset_match[] = {
	{ .compatible = "arm,mali_fpga_sysctl", .data = NULL },
	{ /* sentinel */ },
};

static int juno_fpga_reset_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct juno_fpga_reset *reset;
	struct resource *res;

	reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
	if (!reset)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	reset->base = verify_and_remap(dev, res);
	reset->dev = dev;

	if (IS_ERR(reset->base)) {
		dev_err(dev, "Failed to verify and remap base address (%ld)",
			PTR_ERR(reset->base));

		return PTR_ERR(reset->base);
	}

	platform_set_drvdata(pdev, reset);

	reset->rst.owner = THIS_MODULE;
	reset->rst.nr_resets = 1;
	reset->rst.ops = &juno_fpga_reset_ops;
	reset->rst.of_node = pdev->dev.of_node;

	dev_info(dev, "registering to reset controller core");

	return devm_reset_controller_register(dev, &reset->rst);
}

static int juno_fpga_reset_remove(struct platform_device *pdev)
{
	return 0;
}

static struct platform_driver juno_fpga_reset_driver = {
	.probe                  = juno_fpga_reset_probe,
	.remove                 = juno_fpga_reset_remove,
	.driver                 = {
		.name           = "juno-fpga-reset",
		.of_match_table = of_match_ptr(juno_fpga_reset_match),
	},
};

module_platform_driver(juno_fpga_reset_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Arm Ltd");
MODULE_DESCRIPTION("Arm Juno FPGA Reset Driver");
MODULE_VERSION(JUNO_FPGA_RESET_DRIVER_VERSION);
